首页 文章

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

提问于
浏览
5

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

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

  • 7

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

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

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

  • 11

    实际上,问题是由通过映射创建命令对条形字符的特殊处理引起的 .

    Vim中的键映射机制是一种将按键序列解释为另一个键序列的方法;在这个级别上没有对Vim脚本语言进行语义解释 . 由于要创建映射,有必要将两个键序列参数分开,以通过确定这两个参数的边界来确定 :map -family命令之间的映射 . 要在映射中使用可能干扰此过程的字符,必须使用为该字符提供的转义语法(其中包括回车符,空格,反斜杠和条形码) .

    因为条形字符可用于将映射命令与下一个Ex命令分开,因此,为了定义映射右侧的结束边界,它不能在按键序列中按原样使用 . 根据 :help map_bar ,根据设置,条形字符可以转义为 <bar>\|^V| (其中 ^V 表示文字Ctrl V键代码) .

    记住这一点,让我们按照默认配置中解释它们的方式来跟踪有问题的映射(在 \| / \\| 部分周围) . 在第一个映射中, \| 序列被视为单个 | 字符 . 因此,执行该映射命令后,按 t 将与键入相同

    :调用搜索('\ m \(a | b \)','W')输入

    运行第二个映射命令时, \\| 字符串被解释为文字反斜杠字符(除了嵌套的字符串之外,不需要在映射的右侧转义 \ ),后跟表示条形字符的 \| 说明符 . 因此,此命令将 t 映射到以下内容:

    :调用搜索('\ m \(a \ | b \)','W')输入

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

相关问题