May 24, 2021 Vim
Our new "grep operator" works well, but the purpose of writing Vimscript is to thoughtfully improve the lives of your users. There are two additional things we can do to make our operators more in line with the requirements of the Vim ecosystem.
By copying the text to an unnamed register, we destroyed what was there before.
This is not what our users want, so let's save the contents of the register and reload it before copying it. Modify the code to this:
nnoremap <leader>g :set operatorfunc=GrepOperator<cr>g@
vnoremap <leader>g :<c-u>call GrepOperator(visualmode())<cr>
function! GrepOperator(type)
let saved_unnamed_register = @@
if a:type ==# 'v'
normal! `<v`>y
elseif a:type ==# 'char'
normal! `[v`]y
else
return
endif
silent execute "grep! -R " . shellescape(@@) . " ."
copen
let @@ = saved_unnamed_register
endfunction
We added two let statements at the beginning and end
let
function.
The first saves the contents of
@@
variable, and the second reloads the saved content.
Save and source files.
Test it, copy some text, then press the operator by
<leader>giw
and then
p
the previously copied text.
When writing a Vim plug-in, you should try to save the original settings and register values before modifying them and load them back later. This avoids the possibility of panicking users.
Our script created the function
GrepOperator
That's probably not a big deal, but when you write Vimscript, don't apologize in the event that it's any better.
With just a few lines of code, we can avoid contaminating the global namespace. Modify the code to this:
nnoremap <leader>g :set operatorfunc=<SID>GrepOperator<cr>g@
vnoremap <leader>g :<c-u>call <SID>GrepOperator(visualmode())<cr>
function! s:GrepOperator(type)
let saved_unnamed_register = @@
if a:type ==# 'v'
normal! `<v`>y
elseif a:type ==# 'char'
normal! `[v`]y
else
return
endif
silent execute "grep! -R " . shellescape(@@) . " ."
copen
let @@ = saved_unnamed_register
endfunction
The first three lines of the script have been changed.
First, we add the prefix
s:
before the function name so that it is in the namespace of the current script.
We've also modified the mapping to add
<SID>
before
GrepOperator
so Vim can find this function.
If we don't, Vim will try to find the function in the global namespace, which is impossible to find.
Cheers, our
grep-operator.vim
is not only very useful, but also a good Vimscript citizen!
Read:
:help <SID>
Enjoy it, eat some snacks and treat yourself.