I have been looking to map a new operator in Vim that takes an extra parameter.
For example, we know that ciw
will “cut inside word” and will put you int
Here is an example implementation of the command described in the question, for illustrative purposes.
nnoremap s :set opfunc=Surroundg@
vnoremap s :call Surround(visualmode(), 1)
function! Surround(vt, ...)
let s = InputChar()
if s =~ "\" || s =~ "\"
return
endif
let [sl, sc] = getpos(a:0 ? "'<" : "'[")[1:2]
let [el, ec] = getpos(a:0 ? "'>" : "']")[1:2]
if a:vt == 'line' || a:vt == 'V'
call append(el, s)
call append(sl-1, s)
elseif a:vt == 'block' || a:vt == "\"
exe sl.','.el 's/\%'.sc.'c\|\%'.ec.'c.\zs/\=s/g|norm!``'
else
exe el 's/\%'.ec.'c.\zs/\=s/|norm!``'
exe sl 's/\%'.sc.'c/\=s/|norm!``'
endif
endfunction
To get user input, the function InputChar()
is used, assuming that
the required argument is a single character.
function! InputChar()
let c = getchar()
return type(c) == type(0) ? nr2char(c) : c
endfunction
If it is necessary to accept a string argument, change the call to
InputChar()
in Surround()
to the call to input()
, instead.