我刚刚开始查看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
使用文件根据我之前所做的事情拉出线条(上面或下面有多少行我改变了文字或猛拉过)。
但是,如果我用与运动操作符绑定的上述函数调用相同的命令 行为与回显当前光标下的字符不一样。
我使用的动议是:
vi(<leader>g
为什么这两种行为都不符合vim帮助文档。
感谢。
答案 0 :(得分:2)
你是对的,Vim“重载”了'[
和']
更改标记来表示运算符函数中的移动文本。这避免了引入另一个特殊标记。一般:help '[
不适用于此。
严格来说,运算符函数仅适用于普通模式{opfunc}{motion}
,但通常您也希望它们在可视模式下工作({Visual}{opfunc}
)。您也定义了:nmap
和:vmap
。
type
函数参数是操作符函数如何区分这两种模式的方法。正如您使用vi(<leader>g
一样,这是可视模式变体(<leader>gi(
应该已经有效)。不幸的是,你的实现错过了代码;到目前为止它只处理正常模式(并且只处理那个特征性运动)。在可视模式下,type
参数包含v
/ V
/ <C-v>
值;你也需要处理它:
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'
的不同值。