VIM:在寄存器中存储多个命令时如何处理新线?
-
02-10-2019 - |
题
我有一个文件,可以存储VIM命令的片段。当我需要摘要时,我会拉动它,然后用它执行 @"
. 。摘要存储为脚本,每个命令一行,诸如此类:
:s/foo/bar/g
:echo "hello"
:s/1/2/g
编辑:我从示例中删除了普通模式命令,因为它们不是问题的一部分。
现在,此过程不再起作用:执行摘要时,它只是在第一行停止,就好像在等待新线一样。
是否有某个选择影响的选择 @
执行?我很确定它是在某个时候工作的...
用a ^m角色替换新线,但可以使文件更难处理。
附加信息:
这是另一个症状:当我拉动摘要时,如果我执行它 @"
正如我刚刚解释的那样,它停在第一行。但是,如果我执行 :@
有用。但是,帮助文件似乎并不意味着两个命令如何处理寄存器的内容...
解决方案 2
我终于找到了罪魁祸首。不知何故,我有一个命令映射 <C-J>
在我的.vimrc文件中。默认阅读时 cpoptions
, ,这变成了映射 <NL>
.
我的发现:我注意到与 -u ~/.vimrc
, ,它确实会执行洋基片段。我在有或没有该命令行选项的情况下生成了一个会话文件,并比较了它们。这样我发现一组不同的 cpoptions
在曾经读取相同的.vimrc文件的地方,因此在一种情况下,映射确实在 <C-J>
, ,另一方面,它被转换为映射 <NL>
!
如果某人有类似的问题,我建议您仔细查看当前设置的命令映射,并使用 :cmap
.
其他提示
我不认为问题是 ^M
VS. ^J
. 。 VIM宏将把任何一个视为记录宏的有效终端字符。我认为问题是额外的新线。
在您的示例中,至少有一个虚假的新线 2j
, ,除非您在复制片段时特别小心,否则可能还有另一个 10k
也是。这些额外的新线就像按压 <Enter>
在正常模式下 - 他们将光标向下移动一行。
这是我认为您希望片段的外观:
:s/foo/bar/g
2j:s/1/2/g
10k
(即使那有点误导 - 您仍然必须小心,不要在 10k
.)
为什么这些额外的新线条如此巨大?好吧,一方面,它们使您至少要距离您期望的位置一行,这会抛出您想在特定行上做的任何事情(例如执行 :s//
命令)。
但是,更重要的是 - 这就是我示例中正在发生的事情 - 如果宏观尝试使用,VIM会停止宏播放 <Enter>
在缓冲区的最后一行。 (我猜VIM认为它是错误的,任何错误都会导致宏停止运行。)
这是一个例子。假设您将此摘要存储在寄存器X中:
4j
:echo "Done"
(注意之后的新线 4j
.)
此外,假设您在缓冲区中有以下五行(仅这五行):
line 1
line 2
line 3
line 4
line 5
如果您现在按 @x
在 line 1
, , 这 :echo "Done"
永不执行。 VIM将光标向下移动4行 line 5
, ,然后由于额外的新线而尝试沿着一行往下移动,但不能。宏在此时停止执行 :echo
命令有机会运行。
但是,如果将X寄存器更改为此:它可以正常工作:
4j:echo "Done"
因此,要返回您的原始示例,我敢打赌,发生的事情是 2j
正在尝试将光标移动到无法走的地方,这会导致宏停止。屏幕的底线包含执行的最后一个命令(:s/foo/bar/g
),这使得VIM正在等待您按返回。
最后,我强烈建议使用另一种方法存储和执行VIM命令序列。您使用的技术对于简单的情况是可以忍受的,但是它很脆弱,并且缩放不佳。 VIM具有完整的脚本语言,其中包含功能和自定义命令,并且可以用来完成您现在正在做的所有事情,但以更强大的方式来完成。 vim脚本是一个大话题,但我会从这里开始:
:help script
确保阅读有关 :normal
命令,该命令使您可以执行普通模式命令(例如 2j
和 10k
)在脚本中。
祝你好运!