在Vim映射中的文本对象复制顺序

3
我想提取映射中 <...>(...) 表达式的内部内容。
在正常模式下,我可以输入两个 yank 命令: yi<yi(。其中一个命令会返回空值,另一个会匹配所需的内容。这样做的效果是无论内容位于 () 还是 <> 中,都能匹配到其中的内容。
现在,如果我将相同的命令序列放入映射中,它似乎会在第一个 yank 失败时中止,因此它只会匹配 <...> 表达式中的内部内容(因为在我的示例中,yi< 是第一个尝试的 yank)。
相反,如果我输入 :normal yi<<CR>:normal yi(<CR>,则映射的效果与在正常模式下手动输入 yi<yi( 相同。此外,:normal yi<yi( 也会失败。
对我来说,提取未匹配的文本对象总是以错误结束并中止当前映射或 :normal 执行。但我找不到 vim 文档中明确记录这种行为。虽然已经说明了 E 标志会影响 y{motion} 而不是 y{object},但我的 cpoptions 中并未包含该标志。
有人能澄清这种奇怪的行为吗?
1个回答

2
请注意,当:normal包含在try...catch循环中或通过:silent!执行时,其语义会发生变化:如果没有它,则在遇到错误时中止命令序列的执行;其余序列将被丢弃(就像在宏中一样)。如果有它,则所有命令都会执行,即使出现错误。
当您手动连续输入这两个yank时,实际上是忽略了错误。
解决方法:
因此,您可以使用以下方法获得所需的行为:
:silent! normal! yi<yi(

备选方法

另一种方法是先清除寄存器,执行第一次复制操作,只有在寄存器仍为空时才执行第二次备选复制操作。


谢谢Ingo,除了澄清这一点,我发现你的建议比两次调用:normal更加简洁。为什么两次调用:normal也能起作用呢?难道:normal不会传播执行的正常命令引发的错误吗? - memeplex
调用 :normal 两次就像是交互式输入一样;你正在丢弃第一个 yank 后发生的错误。这里没有“传播”,因为这只是一个蜂鸣声,意味着“不能在这里这样做”。 - Ingo Karkat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接