共212行
2026-07-17 12:50:39
Neovim(Vim)里的**宏(Macro)本质上是把一系列按键操作录制到一个寄存器(register)**里,然后再回放执行。它不依赖插件,是内置最核心的批量编辑能力之一。
在 Normal 模式下输入:
qa
q:开始 / 停止录制的开关a:指定存入寄存器 a(可用任意 a–z 字母)此时底部会显示 recording @a,表示正在录制。
比如在当前行:
0 到行首i// <Esc> 插入注释j 下一行这些按键都会被原样记录。
再按一次:
q
底部 recording @a 消失,录制完成。
@a:执行一次寄存器 a 里的宏@@:重复上一次执行的宏5@a:连续执行 5 次宏宏存在寄存器里,可以用寄存器相关命令查看和改写。
:registers a
或简写:
:reg a
会看到类似:
a 0i// ^[j
其中 ^[ 是 <Esc> 的转义表示。
宏本质是字符串,可以直接赋值修改:
:let @a = '0i// ^[j'
注意:
^[在命令行里要用<C-v><Esc>输入,不能直接粘文本。
也可以在普通模式下把宏粘贴出来改:
"ap " 把寄存器 a 的内容粘贴到当前缓冲区
"ayy " 改完后把这行再存回寄存器 a
这是宏最强用的场景之一。
qa ... qV4j " 选中当前行 + 下面 4 行:normal @a会对每一行分别执行一次宏。
宏里尽量用:
j / k 而不是绝对行号0 / ^ / $ 而不是固定列比如在宏最后加 j,这样:
@a 执行完自动到下一行100@a 就能一口气处理 100 行如果宏 a 的最后一步是 @a,会形成递归,直到出错或无法执行才停(常用于“处理到文件尾”)。
更安全的方式是条件退出,比如配合搜索:
/pattern^M " 找不到会报错停止
全局寄存器内容在默认 ShaDa 里会持久化(前提是没禁用 shada),重启 Neovim 后 @a 仍然可用。
.)<Up> 等终端序列),回放容易异常 → 尽量用 hjkl。j 会失败,导致宏中断 → 可用 +} 或搜索代替。宏卡住通常是因为宏在无限循环(比如递归宏)或者等待某个输入(比如搜索不到内容时停在提示状态)。以下是几种退出方法:
Ctrl + C(最快)Ctrl + C
这是最通用的中断键,能打断大多数卡住的宏。
Esc 多次Esc Esc Esc
连按几次,有时候能退出等待状态。
q 停止录制如果宏还在录制状态(底部显示 recording @a),按一次 q 停止录制。
如果以上都不管用:
:q!
或
:qa!
强制退出所有窗口。
错误的写法:
qa/patternEnterjq
如果搜索不到,宏会停在 / 等待输入。
安全的写法:
qa/patternEnterjjq
或者加个 ? 反向搜索兜底。
qa
...
/END_OF_FILEEnter " 如果找到 END_OF_FILE 就停
@a " 否则继续
q
不确定宏会不会卡住时,先试:
5@a " 只执行 5 次
而不是直接 1000@a。
下次遇到宏卡住,按这个顺序试:
Ctrl + C(大概率解决)Esc:q! 强退一般来说 Ctrl + C 就够了,除非 Neovim 本身崩溃。!
| 方法 | 命令 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|
| 暴力次数法 | 999@a |
文件行数确定且不太多 | 简单直接,不用记命令 | 行数超了会报错中断;少了执行不完 |
| 递归宏 | 宏末尾加 @a,然后执行 @a |
不确定行数,想自动跑到末尾 | 一次触发,自动执行到底 | 宏里必须有移动指令,否则死循环 |
:normal 范围法 |
:.,$ normal @a |
从当前行执行到文件末尾 | 精准控制起始行,不依赖宏内移动 | 需要手动输入范围 |
:global 全文件法 |
:%normal @a |
对整个文件每行执行一次宏 | 最推荐,清晰可控,不易出错 | 宏必须设计成每行独立可执行 |
| 选中区域法 | 先 V 选中多行,再 :normal @a |
只想对部分行执行 | 可视化选择,直观 | 需要先手动选中 |
| 场景 | 最佳方案 |
|---|---|
| 处理整个文件 | :%normal @a |
| 从当前位置处理到文件尾 | :.,$ normal @a |
| 处理选中的几行 | 选中后 :normal @a |
| 快速搞一下,不管报错 | 999@a |
| 想炫技 | 递归宏 @a 末尾加 @a |