How to define a new Vim operator with a parameter?

前端 未结 3 1351
慢半拍i
慢半拍i 2020-12-24 08:35

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

3条回答
  •  轮回少年
    2020-12-24 09:08

    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.

提交回复
热议问题