我已经在Vim 8.1和Neovim(nvr 2.1.10)中使用和/或不使用〜/ .vimrc(后者检查vimrc条目是否具有因果关系-无效)进行了尝试。
给出这个例子
apple banana carrot dates
我可以记录一个宏(@a)
yy p
拉动并粘贴(即复制)一条线。当我将该宏(@a)应用于单独的行,并在单独的行上重复该宏(@@)时,它将复制该行。
但是,当我直观地选择这些行并尝试应用宏时,尝试其中的任何一条
:'<,>'norm @a ## :'<,>'norm @a on single line works :'<,>'normal @a :'<,>'norm! @a :'<,>':norm @a :'<,>':normal @a :'<,>':norm! @a :1,4norm! @a ## /sf/ask/17360801/
等等。宏会复制(每行一次)所选文本的第一行:
apple apple apple apple apple banana carrot dates
这是什么问题?
您看到此问题的原因是因为范围在ex命令上的工作方式。
指定范围时,在进行任何操作之前,该范围将被评估为行号。在这种情况下,因为这些是线性操作,所以将其'<
评估为1,并将'>
其评估为4。当您第一次在第1行运行宏时,将使用“ apple”创建新行。当宏在第2行上运行时,该行包含“ apple”,因此该单词被复制,依此类推。使用该命令执行时该行上的内容。如果使用%
(对于所有行)或2,4
选择“香蕉”及以下,您将看到相同的行为。
但是,POSIX为:g
命令指定了不同的行为:
全局和v命令在逻辑上是两次通过操作。首先,在指定行中标记除终止符以外的行匹配(全局)或不匹配(v或全局!)指定模式的行。其次,执行命令给定的ex命令,并将当前行('。')设置为每个标记行。
这就是:g/^/norm yyp
在这里工作的原因:因为要修改的行在执行之前就被标记了,只有被标记的行才执行命令。不考虑事实之后插入的行。:g
正如您所指出的,它确实接受范围,因此您可以将操作限制为要处理的一组行。