Appearance
重复与撤销:点命令、宏与寄存器
Vim 高效的秘密不仅在于单次操作快,更在于重复操作极其简单。本章将介绍 Vim 最强大的效率工具:点命令、宏和寄存器。
点命令:一键重复
.(点命令)是 Vim 中最强大的单个命令——它重复上一次的编辑操作。
基础用法
javascript
const foo = 1;
const bar = 2;
const baz = 3;想把所有 const 改成 let:
- 移动到第一个
const ciwlet<Esc>→ 修改为let- 移动到下一个
const .→ 重复上次修改- 移动到下一个
.→ 再次重复
三行只需要一次完整输入,后面全是 .。
什么算"一次编辑操作"
点命令重复的是"从进入 Insert 模式到退出"的整个过程:
ciw+ 输入内容 +<Esc>→ 整体算一次操作dd→ 一次删除操作>>→ 一次缩进操作
设计可重复的操作
点命令的威力取决于你如何设计操作。
不好的设计:
javascript
const value = oldValue;想把 oldValue 改成 newValue:
f"跳到odwi→ 删除词,进入 Insert- 输入
new <Esc>
这样 . 只能重复"输入 new",不实用。
好的设计:
- 光标在
oldValue上 ciw→ 删除整个词,进入 Insert- 输入
newValue <Esc>
现在 . 可以重复"把当前词改成 newValue"。
实战:批量添加分号
javascript
const a = 1
const b = 2
const c = 3想在每行末尾添加分号:
A;<Esc>→ 到行尾添加分号j.→ 下一行,重复j.→ 下一行,重复
A 是"在行尾进入 Insert 模式",配合 . 可以批量在行尾添加内容。
撤销与重做
| 命令 | 效果 |
|---|---|
u | 撤销(undo) |
Ctrl+R | 重做(redo) |
U | 撤销整行修改 |
撤销粒度
Vim 的撤销粒度是"一次编辑操作":
- 在 Insert 模式输入 100 个字符,
u会撤销全部 - 每次从 Normal 进入 Insert 再退出,算一个撤销点
如果你在 Insert 模式下想创建撤销点,按 Ctrl+G u:
输入一些内容 Ctrl+G u 输入更多内容这样 u 只会撤销"输入更多内容"。
撤销分支
Vim 维护完整的撤销历史树,而非线性历史。但在 VSCode Vim 中,这个功能有限。了解 u 和 Ctrl+R 足够日常使用。
寄存器:智能剪贴板
Vim 有多个"寄存器",可以理解为多个剪贴板。
默认寄存器
y、d、c 的内容默认存入 " 寄存器。p 从 " 寄存器粘贴。
命名寄存器
"a 到 "z 是命名寄存器,你可以指定存储位置:
| 操作 | 效果 |
|---|---|
"ayy | 复制当前行到寄存器 a |
"ap | 从寄存器 a 粘贴 |
"bdiw | 删除词并存入寄存器 b |
数字寄存器
"0 到 "9 自动保存最近的内容:
"0:最近一次 yank(y 命令)的内容"1-"9:最近 9 次删除的内容
这解决了一个常见问题:
- 你复制了一些内容(
yy) - 你删除了一些内容(
dd) - 你想粘贴之前复制的内容
- 但
p粘贴的是刚删除的内容!
解决方案:"0p → 粘贴最近复制的内容(而非删除的)。
系统剪贴板
如果配置了 vim.useSystemClipboard: true,y/p 直接使用系统剪贴板。
如果没有,可以用 "+ 寄存器手动访问系统剪贴板:
| 操作 | 效果 |
|---|---|
"+yy | 复制到系统剪贴板 |
"+p | 从系统剪贴板粘贴 |
查看寄存器
使用 :reg 命令查看所有寄存器内容。在 VSCode Vim 中,这个命令显示最近几个寄存器的内容。
宏:录制与回放
宏是"录制操作序列,然后回放"的功能。它比点命令更强大——可以录制多个命令的组合。
基础用法
| 命令 | 效果 |
|---|---|
q{a-z} | 开始录制到寄存器 |
q | 停止录制 |
@{a-z} | 回放宏 |
@@ | 重复上次宏 |
实战:批量格式化
javascript
name: "John"
age: "30"
city: "NYC"想把每行改成:
javascript
"name": "John",
"age": "30",
"city": "NYC",- 光标在第一行
qa→ 开始录制到寄存器 aI"<Esc>→ 行首添加引号f:i"<Esc>→ 冒号前添加引号A,<Esc>→ 行尾添加逗号j→ 移动到下一行q→ 停止录制2@a→ 执行宏 2 次
整个操作只需设计一次,然后批量应用。
宏的设计原则
原则 1:让宏自包含
宏应该从一个明确的位置开始,结束在下一个同样的位置。比如:
- 开始:行首
- 结束:下一行行首
这样连续执行不会出错。
原则 2:使用相对定位
不要使用"第 5 个字符"这样的绝对定位,而是用 f{char}、w、$ 等相对定位。
原则 3:先测试再批量执行
录制后,先用 @a 执行一次,确认正确,再用 100@a 批量执行。
宏的常见模式
模式 1:行处理
qa0...操作...j q从行首开始,操作完移动到下一行,方便连续执行。
模式 2:搜索处理
qa/pattern<CR>...操作...q搜索找到目标,操作,然后可以用 n@a 或直接 @a(如果宏里包含了搜索)。
模式 3:数字递增
这在 VSCode Vim 中支持有限,但基本思路是:
qa...操作...<C-a>...qCtrl+A 让数字 +1。
组合使用
点命令、寄存器、宏可以组合使用:
场景:复制函数到多个位置
"ayip→ 复制函数到寄存器 a- 移动到位置 1
"ap→ 粘贴- 移动到位置 2
"ap→ 粘贴
场景:宏中使用寄存器
- 先复制一些内容到寄存器 a
- 录制宏时使用
"ap粘贴 - 宏中的粘贴内容是固定的,不受当前剪贴板影响
效率对比
任务:在 10 个 console.log 后添加分号
传统方式:
- 手动定位 10 次
- 手动输入分号 10 次
- 时间:约 60 秒
Vim 方式(使用 A; + .):
A;<Esc>一次/console<CR>+.重复 9 次- 时间:约 10 秒
Vim 方式(使用宏):
- 录制
qaA;<Esc>/console<CR>q 9@a- 时间:约 5 秒
练习
点命令练习:
- 创建 5 行相似的变量声明
- 用
ciw+.批量修改变量名
寄存器练习:
- 复制一段代码到寄存器 a(
"ayip) - 删除另一段代码
- 用
"ap粘贴寄存器 a 的内容
- 复制一段代码到寄存器 a(
宏练习:
- 创建 5 行需要格式化的数据
- 录制宏处理第一行
- 用
4@a处理剩余行
本章收获:
- ✅ 掌握点命令(
.)的使用 - ✅ 理解撤销与重做机制
- ✅ 学会使用寄存器系统
- ✅ 能够录制和回放宏
效率提升:
- 点命令让重复编辑效率提升 5-10 倍
- 宏让批量操作效率提升 10-50 倍
- 正确使用寄存器避免内容丢失,节省 无数时间