插入与替换模式:打字这最后一公里
学习目标
- 把进入插入模式的全部姿势变成选型本能:i a I A o O + 第 5 章的 C S s,外加本章新主角 gi
- 掌握从哪进、从哪出的节奏感:进入点选对了,Esc 之后的落点才顺
- 学会插入模式内的编辑键:打错不用逃出去 —— Ctrl+w 删词、Ctrl+u 清行、Ctrl+t/d 调缩进、Ctrl+o 发单发子弹
- 掌握替换模式 R:原位覆写,与 r、ciw 的分工
- 建立「打字前先选门」的习惯:同一个意图永远走同一扇门,肌肉记忆才能沉淀
1. 插入模式不是休息区
第 1 章教你用 i 进、Esc 出活了下来;第 5 章的 c 家族让「删完就打」一句话说完。现在把镜头对准插入模式本身 —— 一个被严重低估的地方。多数人的使用画像:不管三七二十一 i 进去,打字,发现光标位置不对,在插入模式里用方向键挪,打错词用退格键一格一格吃回去,打完再 Esc。全程插入模式像个「休息区」:进了就躺平,所有精细操作都退化成原始人的打字机操作。
正确的画像应该反过来:插入模式是一次有预定座位的短途通勤 —— 上车前你就知道坐在哪(进入姿势)、坐多久(打完就走)、中途要办什么事(插入模式内的编辑键)。衡量 Vim 功底的隐性指标之一,就是单次插入的平均停留时长:高手打十个字符就出来,新手一进去半分钟不出来 —— 因为把移动、改错、调整缩进全塞进了打字里。本章的任务就是把这段「最后一公里」也优化掉。
先立一个总原则:打字前先选门。进入插入模式有十扇门,每扇门对应一种意图。选错门的代价是「进了再找位置」—— 用方向键或空格在插入模式里挪光标,那是全 Vim 最亏的按键。门的清单见下一节,先把心态摆正:门的选型不是知识,是要练成条件反射的习惯。
2. 十扇门全景:按意图选门
进入插入模式的键,你已经见过的有九个,本章补上第十个(gi)。逐个背没有意义,按意图分组一张表收走:
| 意图 | 按键 | 进入点 | 典型场景 |
|---|---|---|---|
| 原地插 | i | 光标前 | 在行中间补一个词 |
| a | 光标后 | 紧贴某字符后面追加(光标在引号上时进引号内) | |
| 行两端 | I | 本行第一个非空白字符前 | 补 const、加行首注释 —— 自动跳过缩进 |
| A | 行尾(最后一个字符后) | 补分号、行尾追加 —— 不用肉眼找行尾 | |
| 开新行 | o | 下方新行,缩进自动 | 往列表/参数里加下一项 |
| O | 上方新行,缩进自动 | 往列表头部插一项、函数上方加注释 | |
| 清范围再打 | C / c$ | 删到行尾后 | 重新赋值(第 5 章) |
| S / cc | 整行清空后 | 整行重写(第 5 章) | |
| 回上次插入点 | gi | 上次离开插入模式处 | 续写刚才没打完的话(本章新朋友) |
| 覆写不打 | R | 原地,打一个盖一个 | 替换模式,严格说是「第十一种模式」(§8) |
读表的方式不是「背按键」,是反过来:每次按之前,先在脑子里报意图 ——「我要在行尾补东西」→ A;「我要在下面加一项」→ o。前两周刻意为之,之后意图会直接变成手指动作。这张表同时是第 5 章 c 家族的复习:C、S 与 A、I 是同一家族的两代 —— 都是「动词 + 进入点」的打包键,只不过前者先删一段,后者只定位。
3. I 与 A:行两端的体贴
小写 i/a 只管光标前后一格;大写 I/A 管逻辑上的行首和行尾。它们的体贴藏在细节里:I 落在第一个非空白字符前(缩进自动跳过),A 落在最后一个字符后(哪怕行尾看不见):
对比一下小写的尴尬:光标停在一行中间,想往行首补 const,按 i?它插在光标前 —— 不是行首。先 0 再 i?插在第 0 列的缩进空格前面,打完 const 还得手动补对齐。I 把这两步糊涂账一次算清。A 同理 = $ + a 的打包(第 5 章讲过这个打包家族),补分号场景里它是无可争议的王者。日常代码里行尾追加的频率远高于行中插入,所以 A 大概率会成为你按得最多的大写键。
4. o 与 O:新行的两个方向
想在数组里加个元素、在 import 块里加一行、在函数头上加注释 —— 这些场景的共同点是「新起一行打字」。传统编辑器按 End 再回车(还得手动缩进);Vim 给了专用门:o(open)在下方开新行,O 在上方开新行,缩进自动对齐:
体会演示里最爽的部分:新行的缩进是猜出来的 —— 根据上一行(或下一行)的缩进和 IDE 的语言规则自动带好,你只管打内容。在 IDE 里这一点更明显:VSCode 和 IDEA 的智能缩进(VSCodeVim/IdeaVim 都接管了 o/O)比裸 Vim 的 autoindent 聪明得多,打 } 还会自动回弹一级。O 最闪光的地方是「头部插入」:往数组第一项前面、函数第一行上面插内容,传统做法要把光标挪到顶再想办法,而 O 在任何位置都是两键。
一个必须提前打的预防针:o/O 是开新行,不是「复制上一行」—— 把 o 当复制用是新手常见误解(复制行是 yy + p,第 5 章)。另外 o 顺手吃计数:3o 开三行 —— 但连续空行不如 3o + Esc 后统一处理,知道即可。
5. gi:回到上次打字的地方
一个高频到被忽视的场景:你正在打一段长注释/长字符串,Esc 出去核实个函数名、查个拼写,回来想接着刚才的地方继续打。gi = go to last insert —— 直达上次离开插入模式的位置,而且直接带着插入模式回来:
gi 的底层是 ^ 标记(注意:这是「插入标记」,和第 2 章行首的 ^ 同形不同物,这里的 ^ 是「上次插入点」的代号,Vim 里叫 '^)。不进插入、只把光标移到上次插入点的话,按 '^ 或 g^。实战中记 gi 一个就够 —— 因为「回去」的意图 90% 是续写。它和第 3 章的书签 'a 分工明确:书签是你手动设的存档点,gi 是系统自动维护的「上次工地」。写长注释、填一堆表单式代码(配置文件、测试用例)时,「打一段 → Esc 去看 → gi 续写」的循环会让手感明显变顺。
6. 插入模式内的小剪刀:Ctrl-w、Ctrl-u、Ctrl-t
打错词的第一反应是什么?多数人是退格键按住不放 —— 一格一格吃到错处,再重打。更糟的选择是 Esc 回普通模式用 db —— 为了一个词换模式,得不偿失。正确答案:插入模式自带编辑键,其中最常用三把小剪刀:
| 按键(插入模式内) | 作用 | 普通模式里的等价物 |
|---|---|---|
| Ctrl+w | 删掉光标前一个词(空格留下) | b + dw 的即时版 |
| Ctrl+u | 清空本行(本次插入的内容) | dd 再 O?不用了,就地重来 |
| Ctrl+t / Ctrl+d | 本行右移 / 左移一级缩进 | >> / << 的就地版 |
| Ctrl+h | 退格一格(等于退格键) | —(手小拇指懒得挪时用) |
值得单独强调 Ctrl+w 的哲学:它删词但留下空格 —— 和第 5 章 cw 不吃尾部空格是同一个设计:你在打字,排版应该自动保持正确。练到「打错词 → Ctrl+w → 重打」不假思索,你的插入模式停留时长会再降一截。Ctrl+u 则是「这行打歪了」的止损键 —— 整行重来比修修补补快时,果断用它。至于 Ctrl+t/d,记一个场景就够:写了半行发现「这行该缩进一级」,Ctrl+t 就地解决,不用 Esc 出去按 >> 再回来。
7. Ctrl-o:插入模式里发一颗普通模式子弹
还有一类尴尬:正在插入模式里打字,想顺手干一件普通模式的小事 —— 看一眼行号、把屏幕滚一下、跳到行首 —— 但这事不值得换模式。插入模式里的 Ctrl+o 专治:按下去后可以执行一个普通模式命令,执行完自动弹回插入模式,光标还回到刚才打字的地方。常见搭配:
| 组合 | 意思 |
|---|---|
| Ctrl+o zz | 打着字把当前行滚到屏幕中央(长函数里写码必备) |
| Ctrl+o g^ | 瞄一眼上次插入点的位置 |
| Ctrl+o :num | 临时开个行号/设置看看(命令也算一颗子弹) |
注意同名不同物的陷阱:第 3 章的 Ctrl+o 是普通模式下的「跳转表后退」,本章的是插入模式下的「单发子弹」—— 同一个键,模式不同含义完全不同。这正是 Vim「模式即上下文」的又一次现身:看一个键干什么,先问自己在哪个模式。单发子弹的边界也要知道:它只适合不移动光标或移动后无所谓的命令(滚动、设置类);想「跳到行尾看看再回来接着打」这种带位移的,老老实实 Esc → 干活 → gi,两个工具各守各的边界。
8. 替换模式 R:打一个盖一个
最后一位主角。r 换一个字符(第 5 章),但换一串等长的字符时逐个 r 很蠢 —— 该用替换模式:R 进入后,状态栏变 REPLACE,此后打的每个字符原位覆盖旧字符,光标随打随走,直到 Esc:
R 的甜蜜区是等长改写:insert → visual(6→6)、margin → padding(6→7,尾部多一个字符会顺成插入,少一个会留尾巴)、对齐表格、改日志级别 INFO → WARN。长度不齐时它就露怯了 —— 后面的演示专门展示了「只打一半」的后果,感受一下覆写的机械性。所以三件换字符工具的选型口诀是:r 换一个,R 覆一串(等长),ciw 换整词(随便多长)。前两个不进(或瞬间离开)普通节奏,第三个要进插入模式 —— 按破坏半径和长度差选工具。
两个边界提醒:①替换模式里按退格是撤回刚覆写的字符(恢复原字符),不是删掉它 —— 和插入模式的退格方向相反,玩一下就懂;②到行尾后再打字,行为自动变为追加(相当于 A)—— 毕竟没有字符可盖了。中文/全角字符在 R 下按「字符」覆盖,一个全角算一个位置,中英混排的表格慎用。
9. 实战节奏:把十扇门串成一次编辑
本章没有综合大演示,因为真正的综合演出你在第 5 章毕业考里看过 —— 这里只把本章的零件放进一个日常剧本,纸面推演一遍。任务:一段配置代码,要①补漏的 const ②给第二行补分号 ③往数组尾部加一个元素 ④回头把刚加的元素改个名。按本章思路走:
- 第一行任意位置 → I 进门跳过缩进 →
const→ Esc; - j 到第二行 → A 直达行尾 →
;→ Esc; - 光标挪到数组最后一项 → o 下方开新行(缩进已对好)→ 打元素名 → Esc;
- 发现名字打错了 → gi 回到刚才的插入点 → Ctrl+w 删错词 → 重打 → Esc。
数一数:四次进出插入模式,每次进门都落点即工位,没有一个方向键、没有一次退格长按、没有一次「进去之后再找位置」。这就是本章要的手感 —— 插入模式的效率不在于打字快,在于进出零损耗。顺带预告:第 4 步这种「换个词再重来」的重复劳作,第 10 章的 . 重复键会给出更狠的解法,这里先把门修好。
10. 每日训练计划(30 分钟 × 3 天)
| 天 | 时间盒 | 内容 | 通过标准 |
|---|---|---|---|
| 第 1 天 | 0–10 分钟 | 重放演示 1–2,读 §1–§4;靶场里 I/A/o/O 各 10 次(故意把光标放行中间起手) | 进门即落点,不用方向键找位置 |
| 10–30 分钟 | 练习 1 + 练习 2 | A 补分号 20 行不卡壳 | |
| 第 2 天 | 0–10 分钟 | 重放演示 3–4,读 §5–§7;靶场打长注释,Esc 查东西后 gi 续写 | Ctrl+w 改词不看键盘 |
| 10–30 分钟 | 练习 3 | 三种换字工具选型不犹豫 | |
| 第 3 天 | 0–10 分钟 | 重放演示 5,读 §8–§9;把 §2 的十扇门表抄进便签 | 能背出按意图分组的门 |
| 10–30 分钟 | 练习 4:盲测毕业考 | 10 题对 7 题,本章毕业 |
11. 如果本章只记住三件事
- 打字前先选门:原地 i/a、两端 I/A、新行 o/O、清范围 C/S、续写 gi —— 意图决定门,进门即工位;
- 打错不逃门:插入模式自带剪刀 —— Ctrl+w 删词、Ctrl+u 清行、Ctrl+t/d 调缩进、Ctrl+o 发单发子弹(注意与普通模式跳转表后退同名不同义);
- 换字符按半径选工具:一个 r、一串等长 R(覆写,不是插入)、整词 ciw —— 长度不齐就别用 R。
至此,「语法篇」三章全部完成:名词(移动 + 文本对象)、动词、进出打字的门 —— 编辑语言的基本词汇和句法已经齐了。下一章进入进阶篇:可视化模式与块编辑,把「选」这个动作也纳入语言。
练习
练习 1:十扇门点名(10 分钟)
靶场任选 20 行代码,光标随机放置,每行完成一次「报意图 → 按门」:心里默念「行尾补」→ A;「下加一行」→ o;「行首补」→ I;「上方插」→ O…… 进门后随便打两个字,Esc 出来,u 撤销。20 次为一组。通过线:报意图和按键之间零延迟,且落点全部正确(尤其 I 不落在缩进空格里)。
练习 2:A 补分号马拉松 + o 扩数组(10 分钟)
造 20 行没有分号的代码(或拿一段冒号写成等号的任务代替),只用 A → ; → Esc → j 循环补完 —— 感受「进门即工位」的节奏,禁止用方向键或 End。然后再造一个数组,分别用 o 往尾部加 5 个元素、用 O 往头部加 2 个元素,体会两个方向的对称。
练习 3:打错不逃门(10 分钟)
在插入模式里连续打十句话(代码注释或散文都行),规则:打错词必须用 Ctrl+w 修正、打歪行必须用 Ctrl+u 重来,全程禁用退格键和 Esc。中途想看屏幕外的东西用 Ctrl+o zz 滚一下屏幕。这个练习会别扭十分钟,但之后插入模式在你手里就从「打字机」升级成「工作台」了。
练习 4:盲测毕业考(10 分钟)
10 个任务先说按键再看答案:①在带缩进的行首补 const ②行尾补分号 ③数组末尾加一项 ④数组开头插一项 ⑤回上次没打完的地方续写 ⑥插入模式里删掉刚打的词 ⑦本次插入的整行作废重打 ⑧插入模式里把本行右移一级缩进 ⑨把 INFO 改成 WARN(提示:长度)⑩把 mode 改成 model(提示:长度变了,别用 R)。答案:I/A/o/O/gi/Ctrl+w/Ctrl+u/Ctrl+t/R(等长覆写)/ciw(R 会吃掉后面的字符)。10 对 7 毕业。
常见陷阱
REPLACE 亮着就保持警惕;②覆写完立刻 Esc,把 R 当「冲刺」用,不当「巡航」用。真盖坏了也别慌,u 一键全回。
VSCode / IDEA 差异
VSCode(VSCodeVim)
- 十扇门 + Ctrl+w/u/t/d + gi + R:VSCodeVim 全部原生支持,照本章内容用即可
- o/O 的自动缩进走 VSCode 的
editor.autoIndent(默认 full)—— 比裸 Vim 聪明,打}自动回弹也在线 - 自动补全与 Esc:弹窗开着时 Esc 先关建议、再按才退插入;建议用 Tab 接受、继续打字忽略,让 Esc 语义单一
- 插入模式内 Ctrl+o 单发子弹:VSCodeVim 支持(如 Ctrl+o zz 可用);个别 IDE 快捷键冲突时以 Keyboard Shortcuts 实测为准
IntelliJ IDEA(IdeaVim)
- 同样全部支持;o/O 缩进取 IDEA 的 Code Style 引擎,嵌套块的自动缩进甚至更准
- mac 注意:Cmd+W 是关闭标签页(IDEA 原生),Vim 的删词是 Ctrl+w(半角 Ctrl)—— 手别快,两个键差一个 Cmd
- 补全弹窗与 Esc 的关系同 VSCode:先关弹窗再退插入;用 Tab/Enter 接受建议
- R 替换模式由 IdeaVim 提供(IDEA 原生没有 overtype 模式),行为与 Vim 一致;插入模式内的 Ctrl 系小剪刀同理
本章速记
| 按键 | 作用 | 按键 | 作用 |
|---|---|---|---|
| I / A | 行首(跳缩进)/ 行尾进入插入 | Ctrl+w / Ctrl+u | 插入内删词 / 清行 |
| o / O | 下方 / 上方开新行(缩进自动) | Ctrl+t / Ctrl+d | 插入内右移 / 左移缩进 |
| gi | 回上次插入点续写 | Ctrl+o(插入内) | 发一颗普通模式子弹 |
| R | 替换模式:打一个盖一个 | r / ciw | 换单个 / 换整词(R 的边界) |
| Esc | 退出(弹窗开着时按两次) | '^ | 只移动到上次插入点(不进插入) |
一句话心法:打字前先选门(进门即工位),打错不逃门(Ctrl-w / Ctrl-u),换字符看半径(r / R / ciw)。