许多插件可以通过<Plug>
映射访问其公共映射接口。然后,用户可以将这些映射用作自己映射的钩子,例如 :nmap <Leader>fu <Plug>fooPluginUnlinkRootDir
.
最近我遇到了一些插件,它们将它们的地图名称放在括号中,例如
-
<Plug>(textobj-indent-a)
在textobj-edent插件中, -
<Plug>(LineJugglerBlankUp)
在 LineJuggler 插件中。
此语法未记录在帮助文件中的任何位置,任何捆绑的 Vim 运行时文件也不使用它。尽管如此,这些插件可以很好地完成它们的工作。
括号的动机是什么?使用它们有什么好处吗?是否应该鼓励插件作者遵循这种做法(作为最佳实践)?
谢谢ZyX;你的回答已经涵盖了基础知识,所以让我补充一下为什么我采用了<Plug>(PluginNameAndMore)
符号。(我想我第一次看到它是在夏野加奈的插件中。
两个原因:
-
当将映射与其他内容包装在一起时,更容易直观地解析各个映射目标,如下所示:
imap <C-x><C-c> <Plug>(CompleteStart)<Plug>(CamelCaseComplete)<SID>(CamelCaseCompleteModifyUndo)<Plug>(CamelCasePostComplete)<Plug>(CompleteoptLongestSelect)
-
当为一个插件定义多个映射时,必须注意一个映射的 LHS 不包含在另一个映射中。否则,触发映射时会有延迟,因为 Vim 需要等待额外的击键才能解决歧义。右括号可防止任何此类歧义。
BAD GOOD
<Plug>MyFunc <Plug>MyFuncNext, <Plug>(MyFunc)
<Plug>MyFuncReverse <Plug>MyFuncPrev, <Plug>(MyFuncReverse)
映射命令中的{lhs}
和{rhs}
都是字节序列,只要它具有自然字节数,就可以包含任意数据(NUL 字节除外)(对于{rhs}
也允许具有零字节数)。从这个角度来看(…)
实践与另一种实践没有任何优势。
特别是对于(textobj-…)
来说,有一个小优势:您可以选择整个{lhs}
<Plug>
而无需a)
运动的部分,并且在单词之间具有更多可读的破折号。我不知道为什么要这样做,因为整个{lhs}
都可以用aW
(<Plug>
部分)进行选择。
我看不出LineJuggler版本有任何理由。
你最好问问作者这个问题。 @IngoKarkat在这里,在stackoverflow上,可能很快就会读到这个问题。我不知道如何联系夏野加奈。
<Plug>
调用后映射中有其他击键时,括号使(对人类)更清楚。例如,我有这样的映射:
nmap ]c <Plug>GitGutterNextHunkzv
这使得]c
跳到下一个 Git 大块头,然后做zv
打开那里的任何折叠。但是由于<Plug>
名称是任意的,因此该命令可以称为GitGutterNextHunkzv
。一般来说,使用<Plug>
映射读取文件的人无法知道整个事情是否是一个名称或后面还有其他字符。
如果 GitGutter 插件在 <Plug>
名称中使用了括号,那么看到发生了什么会更清楚:
nmap ]c <Plug>(GitGutterNextHunk)zv