跳到主要内容

08 重复修改:先完成一次,再用 . 重放

有些操作的目标数量事先并不确定:你先把一个地方改对,再到下一个类似位置重复相同修改。. 正是 为这种情况准备的。

执行一次修改

移动到下一个目标

.

重复修改

. 重放的是修改,不是位置

先完成一次完整 Change:

Before — Normal Mode

const firstName = user.first_name;
^

Keys

ciwfirstName<Esc>

After — Normal Mode

const firstName = user.firstName;
^

然后移动到下一处:

const lastName = user.last_name;
^

Keys

.

After — Normal Mode

const lastName = user.firstName;
^

上面故意展示了一个重要事实:. 会重放修改本身,不会理解你的语义。它把 last_name 也改成了 firstName。这说明在使用 . 前,要先确认“下一处需要的是完全相同的编辑”。如果目标是把 snake_case 逐个改成不同 camelCase 名称,. 不是正确工具。

更适合的例子是,把多处相同的占位符改成同一值:

// TODO: add validation
// TODO: add validation
// TODO: add validation

第一次把一处 TODO 改成 DONE 后,使用 Search 或 n 到下一处,再按 . 重放同一修改。

Count、. 与 Macro

需要优先工具
连续范围且次数已知Count,例如 3dw
多个位置做完全相同的一次修改.
多步移动和编辑序列重复执行Macro,后续章节学习。

. 不会做什么

  • 单独的 Motion 不会变成可重放修改;
  • 它不会自动找到下一个语义相同的位置;
  • 它不能替你判断当前对象是否合适;
  • 某些宿主编辑器的扩展动作可能不遵循原生 Vim 的 repeat 语义。

因此,稳定工作流是:先做一次小而正确的修改,检查结果,定位到下一个目标,再按 .

练习

const status = "pending";
const fallbackStatus = "pending";
const defaultStatus = "pending";
  1. 先把第一处字符串改成相同的新值。
  2. 使用 Search 或 Motion 到第二处。
  3. . 重放修改。
  4. 在第三处重复,并检查三处结果是否一致。
  5. 试着撤销一次,观察 u. 分别影响什么。

本章必须记住

. 重放最近一次修改。
先移动到下一个目标,再重复。
Count、. 和 Macro 分别适合不同类型的重复。

暂时不用记

暂时不用记所有可重复命令的边界,或马上学习 Macro。先让“修改一次、移动、点号”成为可观察的习惯。

评论