我不明白为什么下面的命令会做不同的事情。
粘贴在.vimrc
文件中,这两个命令都定义了在正常模式下按t
触发的映射的两个版本:
nnoremap t :call search('m(a|b)', 'W')<CR>
nnoremap t :call search('m(a\|b)', 'W')<CR>
将上述映射的效果与直接从命令行运行这些搜索调用的结果进行比较:
:call search('m(a|b)', 'W')
:call search('m(a\|b)', 'W')
具体来说,在nnoremap
示例中,"预期"行为需要\|
,但在call
搜索示例中需要|
。
我知道对竖条字符(:help :bar
)的特殊处理是Vim为我设置的陷阱之一,但它仍然没有意义。文档明确表示"此命令列表将把bar作为其参数的一部分",但这些例外都不适用于此。
本例中涉及的所有命令都将bar视为元连接字符。此外,在这种情况下,酒吧在一根绳子里面,我想--作为字符串的一部分进行解析优先于元连接语法。
事实上,这个问题是由酒吧的特殊处理引起的字符的映射创建命令。
Vim中的密钥映射机制是生成密钥序列的一种方式按下被解释为另一个按键序列;无语义Vimscript语言的解释就发生在这个层次上。自,年为了创建映射,有必要将要映射的键序列参数,:map
-家族的命令首先确定两个参数的边界。利用在映射中可能干扰此过程的字符数必须使用为这些字符提供的转义语法(其中是回车符、空格、反斜杠和条形字符)。
因为条形字符可以用来分隔映射命令从下一个Ex命令,因此,定义结束边界在映射的右侧,它不能在中按原样使用密钥序列。根据:help map_bar
,条形字符可以转义为<bar>
、|
或^V|
(其中^V
表示文本Ctrl+V密钥代码)。
记住这一点,让我们遵循有问题的映射(围绕|
/\|
部分)——默认情况下对它们的解释方式配置在第一个映射中,|
序列被视为单个CCD_ 17字符。因此,在该映射命令之后执行时,按t
与键入相同
:call search('m(a|b)', 'W')
输入
运行第二个映射命令时,\|
字符串为解释为字面反斜杠字符(不需要转义映射右侧的,嵌套映射除外)后面跟着表示条形字符的CCD_ 22说明符。因此,该命令将
t
映射到以下内容:
:call search('m(a|b)', 'W')
输入
但是当在命令行模式中键入映射的搜索调用时,与映射中的键序列不同,它们被解释为Ex命令马上这些条形字符出现在字符串文字中,因此不可能将它们误解为Ex命令的分隔符。当直接键入时,命令将按原样发送执行书面的因此,它们之间的差异是由于正则表达式m(a|b)
和m(a\|b)
,不是由于任何逃避行为。
当您使用vim的*map
和command
命令时,vimscript引擎不会解释该命令,而是将其原样存储为击键序列(对于*map
)或字符串(对于command
)。该命令只有在您使用时才会被解释。
正因为如此,当你映射命令时,vim并不真正知道你的管道角色在字符串中,因为他不知道或不在乎你的命令中是否有字符串,至少在那个阶段没有。
如果要在*map
中使用|
,则需要使用<bar>
。