我不明白为什么这些命令会做不同的事情 .
粘贴在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')
具体来说:"intended"行为在 nnoremap
示例中需要 \\|
,但在 call
搜索示例中需要 \|
.
我知道bar( :help :bar
)的特殊处理是Vim为我设计的那些陷阱之一,但它仍然没有意义 . 文档清楚地说"this list of commands will see bar as part of their argument"但这些例外都不适用于此 . 此示例中涉及的所有命令都将条视为元连接字符 . 同样在这种情况下,条形码在一个字符串中,并且(我认为?)被解析为字符串的一部分优先于元连接语法 .
2 回答
当您使用vim的
*map
和command
命令时,vimscript引擎不会解释该命令 - 它将其按原样存储,作为击键序列(在*map
的情况下)或作为字符串(在command
的情况下) . 该命令仅在您使用时解释 .因此,当您映射命令时,vim并不真正知道您的管道字符在字符串中,因为他不知道或不关心命令中是否有字符串,至少不在该阶段 .
如果要在
*map
中使用|
,则需要使用<bar>
.实际上,问题是由通过映射创建命令对条形字符的特殊处理引起的 .
Vim中的键映射机制是一种将按键序列解释为另一个键序列的方法;在这个级别上没有对Vim脚本语言进行语义解释 . 由于要创建映射,有必要将两个键序列参数分开,以通过确定这两个参数的边界来确定
:map
-family命令之间的映射 . 要在映射中使用可能干扰此过程的字符,必须使用为该字符提供的转义语法(其中包括回车符,空格,反斜杠和条形码) .因为条形字符可用于将映射命令与下一个Ex命令分开,因此,为了定义映射右侧的结束边界,它不能在按键序列中按原样使用 . 根据
:help map_bar
,根据设置,条形字符可以转义为<bar>
,\|
或^V|
(其中^V
表示文字Ctrl V键代码) .记住这一点,让我们按照默认配置中解释它们的方式来跟踪有问题的映射(在
\|
/\\|
部分周围) . 在第一个映射中,\|
序列被视为单个|
字符 . 因此,执行该映射命令后,按t
将与键入相同运行第二个映射命令时,
\\|
字符串被解释为文字反斜杠字符(除了嵌套的字符串之外,不需要在映射的右侧转义\
),后跟表示条形字符的\|
说明符 . 因此,此命令将t
映射到以下内容:但是,当在命令行模式下键入映射的搜索调用时,与映射中的键序列不同,它们会立即被解释为Ex命令 . 这些条形字符出现在字符串文字中,因此不可能将它们误解为Ex命令的分隔符 . 直接输入时,命令会在写入时发送到执行 . 因此,它们之间的工作差异是由于正则表达式
\m\(a\|b\)
和\m\(a\\|b\)
的含义,而不是由于某些转义行为 .