重复执行 Vim 宏直到缓冲区末尾

103

我想在vim中对打开缓冲区从光标到缓冲区末尾的每一行运行我刚刚录制到寄存器"x"中的宏。我该如何做到这一点?

我知道我可以重复播放宏n次:

15@x

...或者只需按住@直到我到达最后一行,但我想只需按几个按键即可完成。


15@x 在 Windows gVIM 上无法工作。 - Mingjiang Shi
5个回答

117

就我个人而言,我会这样做

VG:normal @x

编辑:已更改为您指定的注册表项。


1
不错。我喜欢这个解决方案仅在所选区域上运行的方式。 - Kevin
我将其映射到 nnoremap <C-@> VG:norm@q<CR>。 - PAS
我尝试使用宏“1z=]s”,但它只会修正每行的第一个单词,跳过其余部分。 - elig
@elig 你可能想要创建一个递归宏,以便在所有行中查找缺失的单词。 - raman

75

你可以在命令模式下执行以下操作:

:%normal @x

1
我喜欢这个解决方案,但它会在缓冲区的每一行执行宏,OP只要求从光标到结尾。 - NIEL Alexandre
1
@Porunga :.,$norm @x 可以工作 (其中的 .,$ 表示从当前行 . 到最后一行 $)。 - mattb

27

制作递归宏:

qa@aq

例:

qa0gUwj@aq

使用单个@a,将当前行的第一个单词大写并将其到文件结尾的所有内容都转换为大写。但要确保"a寄存器为空:

let @a=""

4
很好。这种方法比%:normal方法更有用,因为它考虑了宏内的任何行移动,所以在行的形式不完全相同时很有用。我觉得更容易创建一个名为'a'的宏来定义操作,然后让名为'b'的宏做递归部分,即qb@a@bq。 - Paul Ruane
4
如果你的宏涉及搜索,请避免这样做,因为它会从顶部继续。如果发生这种情况,请使用ctrl-c停止! - Iain Ballard
5
@IainBallard, :set nowrapscan 让其在到达文件末尾时失败并停止。 - ericbn
1
要清除寄存器a,只需在宏之前执行qaq即可:qaqqa0gUwj@aq。此外,如果您忘记在结尾处放置@q,则始终可以执行qA开始附加一个寄存器,然后执行@q。我通常记录到寄存器q中,因为这很容易(特别是对于递归宏),通常会执行qqqqqgUiwj@qq而不是两个宏。前三个q清除寄存器q,后两个q开始记录。请参见http://vim.wikia.com/wiki/Record_a_recursive_macro。 - dylnmc
我认为要清除“A”寄存器,可以简单地键入“qaq”。 - Peter Perháč
我同意 :set nowrapscan 可以防止在文件中出现无限循环,因为它使得当到达 EOF 时 n 命令 失败,但我有一个疑问:@MaximKim,在你的示例中,宏是如何防止无限循环的? - Enlico

14

999999@x除非你有一个非常大的缓冲区...


8
为什么不直接使用 %:normal @x 或者 1,$:normal @x - Nathan Fellman
3
这绝对是更优雅的解决方案 - 我想当你匆忙时,99999@x 只是自然而然的东西 :) - Peter
2
除非你恰好有999999行,否则最后一行不会多次运行9999999@x。 - David Oneill
3
刚试了一下,它卡住了会话。可能会在行末无限循环运行一百万次而没有停止。 - CDR
1
在某些情况下,这种行为可能不会按预期发生。考虑编写一个宏,并将其中的“查找下一个”/ “查找上一个”功能添加进去。因此,一旦宏重复到达文件结尾,它将从开头继续执行。vim文档相关主题。为了防止搜索换行,可以使用“:set nowrapscan”。这是我想到的一个例子,但这并不意味着没有其他更好的方法。“:%normal @x”是一种方法,正如@ryan_s在其回答中建议的一样。 - Sergey M
显示剩余4条评论

-1

从vim维基,简化版本: qqqqq来记录宏 @qq来结束录制 @q来执行它(并将运行到文件的结尾)


1
请问,您能否添加对文档的引用? - aturegano
2
@aturegano 我认为作者的意思是要使用递归宏。请参阅The Vim Wiki: Record a Recursive Macro以获取更多信息。 - dylnmc

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