如何用参数定义一个新的 Vim 操作符? [英] How to define a new Vim operator with a parameter?
问题描述
我一直在寻找在 Vim 中映射一个带有额外参数的新运算符.
I have been looking to map a new operator in Vim that takes an extra parameter.
例如,我们知道 ciw
将切入单词"并将您置于插入模式.我正在寻找的是有一个自定义操作来替换 c
(例如,s
),它需要像 iw
这样的动作,但需要额外的参数.
For example, we know that ciw
will "cut inside word" and will put you into Insert mode. What I am looking for is having a custom action to replace c
(for example, s
) that takes movements like iw
, but requires an extra parameter.
一个简单的例子是:
Given a line in a text file
在普通模式下执行 siw*
(假设光标在第一列上)让它用 *
包围第一个单词,如下所示:
Execute siw*
in Normal mode (assuming the cursor is on the first column) for it to surround the first word with *
like so:
*Given* a line in a text file
我知道,这是最优秀的 surround.vim 插件所做的.但我只是在这里举一个例子,并寻找有关如何获取映射以便上述工作的答案.
I know, this is what the most excellent surround.vim plugin does. But I am just giving an example here, and looking for an answer as to how to get the mappings so that the above work.
我尝试使用 onoremap
和 opfunc
,但似乎无法让它们按照我想要的方式播放.
I tried playing with onoremap
and opfunc
, but can’t seem to get them to play the way I want.
所以,我正在寻找的是运动加运算符待定映射的组合.
So, what I am looking for is a combination of motions plus operator pending mappings.
推荐答案
这是在问题,用于说明目的.
Here is an example implementation of the command described in the question, for illustrative purposes.
nnoremap <silent> s :set opfunc=Surround<cr>g@
vnoremap <silent> s :<c-u>call Surround(visualmode(), 1)<cr>
function! Surround(vt, ...)
let s = InputChar()
if s =~ "\<esc>" || s =~ "\<c-c>"
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 == "\<c-v>"
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
为了获取用户输入,使用函数 InputChar()
,假设必需的参数是单个字符.
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
如果需要接受字符串参数,将调用更改为InputChar()
在 Surround()
中,改为调用 input()
.
If it is necessary to accept a string argument, change the call to
InputChar()
in Surround()
to the call to input()
, instead.
这篇关于如何用参数定义一个新的 Vim 操作符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!