Vim:逃避连接Ex命令的“栏”

时间:2012-03-14 02:36:55

标签: vim command-line escaping

我不明白为什么这些命令会做不同的事情。

粘贴在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

我知道bar(:help :bar)的特殊处理是Vim为我设计的那些陷阱之一,但它仍然没有意义。文档明确指出“这个命令列表会将栏视为其论点的一部分”,但这些例外都不适用于此。此示例中涉及的所有命令都将条视为元连接字符。同样在这种情况下,条形码在一个字符串中,并且(我认为?)被解析为字符串的一部分优先于元连接语法。

2 个答案:

答案 0 :(得分:11)

事实上,这个问题是由酒吧角色的特殊处理引起的 映射创建命令。

Vim中的键映射机制是一种按键序列 被解释为另一个键序列;没有语义解释 Vim脚本语言在此级别完成。既然要创建映射就可以了 必须将两个键序列参数分开以说明映射 之间,:map - 家族的命令从确定边界开始 这两个论点。使用可能干扰此的字符 在映射过程中,必须使用为此提供的转义语法 字符(其中包括回车符,空格,反斜杠和小节)。

因为bar字符可用于从中分离映射命令 下一个Ex命令,因此,定义的结束边界 映射的右侧,它不能按键序列使用。 根据{{​​1}},根据设置,可以使用条形字符 转义为:help map_bar<bar>\|(其中^V|表示字面值 Ctrl + V 键码。)

记住这一点,让我们按照有关的映射(围绕着 ^V / \|部分)在默认配置中解释它们的方式。在 在第一个映射中,\\|序列被视为单个\|字符。 因此,在执行该映射命令后,按|将是 与输入相同

  

t 输入

运行第二个映射命令时,:call search('\m\(a|b\)', 'W')字符串被解释为 一个字面反斜杠字符(无需转义\\| 映射的右侧,嵌套的除外)后跟\ 表示条形字符的说明符。因此,此命令将\|映射到 以下内容:

  

t 输入

但是,当在命令行模式下键入映射的搜索调用时,不像 映射中的键序列,它们被立即解释为Ex命令。 这些条形字符出现在字符串文字中,因此不可能 将它们误解为Ex命令的分隔符。直接输入时, 命令在写入时发送到执行。因此,差异 他们之间的工作是由于正则表达式的意义 :call search('\m\(a\|b\)', 'W')\m\(a\|b\),不是由于某些逃避行为造成的。

答案 1 :(得分:7)

当你使用vim的*mapcommand命令时,vimscript引擎不解释命令 - 它按原样存储,作为击键序列(在*map的情况下)或作为字符串(在command的情况下)。该命令仅在您使用时解释。

因此,当您映射命令时,vim并不真正知道您的管道字符在字符串中,因为他不知道或不关心命令中是否有字符串,至少不在该阶段。

如果您想在|中使用*map,则需要使用<bar>