我刚刚开始研究 vim 插件并尝试为自己编写一个。我想使用 Vim 的标记功能。我在一本书中发现以下内容:
nnoremap <leader>g :set operatorfunc=GrepOperator<cr>g@
vnoremap <leader>g :<c-u>call GrepOperator(visualmode())<cr>
function! GrepOperator(type)
if a:type ==# 'char'
normal! `[v`]y
else
return
endif
echom shellescape(@@)
endfunction
vim 帮助中提到的 `[ 和 `] 的行为与这里函数中提到的不同。 Vim 帮助说:
`[ To the first character of previously changed or yanked text.
`] To the last character of the previously changed or yanked text.
当我在 vim 的正常模式下输入以下命令时:
normal! `[v`]y
对于一个文件,它根据我之前所做的事情来拉动行(我更改了文本或拉动了上面或下面的行数)。
但是如果我使用与运动运算符绑定(bind)的上述函数调用相同的命令 其行为与回显当前光标下的字符不同。
The motion i used is:
vi(<leader>g
为什么这两种行为都不符合 vim 帮助文档。
谢谢。
最佳答案
你是对的,Vim“重载”了 '[
和']
更改标记以表示运算符函数中移动的文本。这避免了引入另一个特殊标记。一般:help '[
不适用于此处。
严格来说,操作符功能仅适用于普通模式{opfunc}{motion}
,但通常您也希望它们在视觉模式下工作( {Visual}{opfunc}
)。您已经定义了 :nmap
和:vmap
,也是。
type
函数参数是运算符函数如何区分两种模式的方式。正如您所使用的 vi(<leader>g
,这是视觉模式变体( <leader>gi(
应该已经可以工作了)。不幸的是,您的实现错过了该代码;到目前为止,它仅处理正常模式(并且仅处理字符运动)。在视觉模式下,type
参数包含 v
/V
/<C-v>
值(value);你也需要处理这个问题:
function! GrepOperator(type)
if a:type ==# 'char'
normal! `[v`]y
elseif a:type ==# 'v'
normal! `<v`>y
else
return
endif
echom shellescape(@@)
endfunction
由于视觉选择是由 '<,'>
定义的标记,您需要使用那些,而不是前面提到的 '[,']
.
:help :map-operator
还有另一个示例(并使用稍微不同的方法),并且还演示了如何处理 'selection'
的不同值正确。
关于vim 特殊标记行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46211989/