Vim 修炼场
CHAPTER 05 · 语法篇 中(全站核心)

编辑动词与语法:把句子说完整

预计阅读 45 分钟(含练习约 1.5 小时)· 前置:第 4 章 · 本章演示 10 个

学习目标

  • 把「编辑语言」的语法公式刻进本能:[count] 动词 [count] 名词
  • 掌握三大主力动词的完整家族:d(删)、c(改)、y(复制)
  • 掌握粘贴 p/P 的两种语义:行有行的粘法,字有字的粘法
  • 会用小动词干小活:r 单字替换、s/S、大小写 ~/gU、缩进 >>/==、合并 J
  • 理解计数前缀的自由:2dw 与 d2w 是同一句话的两种语序
  • 毕业演出:用三句「编辑语言」完成一次真实的函数签名重构

1. 语法总纲:一句话的完整结构

第 0 章预告、第 1 章埋线、第 2 章备料(移动 = 名词)、第 4 章扩编(文本对象 = 名词)—— 现在把动词补齐,这门「编辑语言」就成句了。它的语法只有一条:

[数字] 动词 [数字] 名词

读几个例句找找感觉:3dw = 「删三个词」;c2w = 「改两个词」;d2i(……好吧这句是病句,但 2daw(删两个词)、y3w(复制三个词)都是地道表达。数字可以出现在动词前、名词前、或两边都出现 —— 效果是相乘的,位置随你喜欢:

这条公式真正的威力在于组合爆炸:十来个动词 × 几十个名词,自动生成上百条命令,而你需要「背」的只有每个词本身的含义。传统编辑器教你的每个快捷键都是一条孤立的知识;Vim 教你的是一套能自己造句的语法。这也是本教程把 ch04、ch05 称为「语法篇」的原因 —— 学完这两章,后面所有章节(可视化、查找、宏)不过是往这套语法里添几个新词。

把公式用顺,还有三条「说话纪律」值得贴在显示器边上:

  • 说完整的句子。按了 d 却还没想好名词?宁可 Esc 取消重来,也别糊一个错的范围 —— 半截句子是最常见的误删来源;
  • 先想名词,再配动词。动手前先自问「我要动的东西是什么」(词?括号?行?)—— 名词定了,动词往往只有一两个候选;反过来先按动词再找名词,说明还没想清就出手了;
  • 数字是量词,不是口令。3dw 里的 3 和中文「删三个词」的「三个」是同一个词性 —— 它修饰后面的名词,不该被当成需要背的「快捷键编号」。
💡 说话习惯养成法 改代码前先在心里把意图翻译成一句中文:「删到分号」(df;)、「改这个词」(ciw)、「复制整行」(yy)—— 再按出来。前两周刻意为之,之后中文会直接变成按键,跳过翻译。这一步没有任何技巧,纯靠本章的练习堆出来。

2. d 家族:射程菜单系统化

d 你已经用了一章半,现在把它系统化 —— d + 任何名词,一表全收:

句子读法备注
dw / de删到下一词头 / 本词尾从光标处起算 —— 注意与 daw 的区别
d$ / D删到行尾D 是打包键,等价 d$
dfx / dtx删到 x(含)/ 删到 x 前第 2 章的 dt, 就是它
dd删当前行名词 = 当前行,与 yy 同构
diw / daw删词(词本身 / 带空格)第 4 章词典,光标在词内即可
di( / da{清空括号 / 连壳删块跨行也罩得住

一个此刻必须说清的设定:d 不是「删除」,是「剪切」。删掉的内容并没有蒸发,它躺在寄存器里,随时可以被 p 粘回来 —— 这既是福利(删了后悔有药),也是伏笔(第 9 章的「复制被删除顶掉」陷阱就从这来)。眼下你只需要知道:删掉的东西按 p 能再拿出来。

什么时候不该用 d?两个信号:①删完马上要打字 —— 换 c,一句话说完;②删的目的是「挪走」—— 直接规划成 d + p 的组合(下一节),别用 x 一个字符一个字符地抠。反过来,凡是「这段彻底不要了」,d + 大名词(dap、di{)是终点站,后面接 u 就是免费的回程票。

3. c 家族:删了就开工

c(change)和 d 只差一步:删完立刻进入插入模式。经验法则一句话:接下来要打字,就用 c;纯删除,才用 d。用 d 删完再按 i,等于把一句话拆成两句说。

看演示时盯住一个细节:cw 删词时不吃尾部空格(dw 才吃)。为什么?因为你删词是要接着打字的 —— 空格留下,新词直接顶上,排版天然正确。这是 Vim 里少见的「cw 特殊照顾」,也算语言的贴心之处(严格说 cw 从词中按起行为等同 ce:总是删到本词结尾)。

句子读法打包键
cw / ciw改词(后者光标随处,第 4 章 ⭐)—
c$改到行尾C(大写打包)
cc清空整行重写S
ci( / ci"重写参数 / 重写字符串—
ct,改到逗号前—

大写打包键家族可以串起来记:D = d$、C = c$、S = cc,再加上第 1 章的 A = $a、I = ^i —— 行尾、行首、整行,Shift 一下直达。它们不是为了省一个键,是为了让「打到行尾」变成一个单拍动作,节奏更顺。

从 d 换到 c,心理上要过的坎只有一个:你不再需要「删干净再进入插入」的两段式。传统编辑器的肌肉记忆是「选中 → 删除 → 打字」,三步各自为政;Vim 的 c 把后两步焊死成一步 —— 范围一旦圈定,光标已经就位、模式已经切换、就等你开口。练习时专门体会那个瞬间:ciw 按下去的下一毫秒,手不应该有任何停顿地开始打字。c 的节奏是一口气,断了就说明又回去想「删了多少」了。

4. y 家族:无痕的复制

y(yank,Vim 里「复制」的黑话)是三个主力动词里最安静的 —— 按下去屏幕上什么也不发生。这让新手很没安全感:「我复制了吗?」答案统一是:按对了就复制了,想看证据,第 9 章的 :reg 命令能打开寄存器查验。眼下先信任它:

y 的名词表和 d 完全同源 —— yw 复制词、y$ 复制到行尾、yy 复制整行、yiw 复制光标所在的词(第 4 章词典直接继承)、yi( 复制括号内全部。学动词不学搭配:动词认识名词库,搭配自动成立。

日常最高频的三连是:yiw(抓个词)→ 移动 → p(放下)。比如把一个变量名抄去别处、把参数列表复制到注释里当文档。黄金搭档 yiw + ciw + p 还能玩「用寄存器里的词替换当前词」,第 9 章展开。

复制要养成三个小习惯:①复制前先选好名词再按 —— y 无声,按错也不响铃,错了的复制会在粘贴时才爆雷;②复制行用 yy 而不是 y$ —— 前者是行形状(粘出来新起一行),后者是字符形状,粘贴行为完全不同;③大段复制宁可先 v 选中看一眼范围(第 7 章)再 y —— 复制是不可见的操作,可见的确认值得多花半秒。

5. p 与 P:行有行的粘法,字有字的粘法

p(paste)在光标后粘贴,P(大写)在光标前粘贴。但它粘贴的「形状」不由你决定,由寄存器里内容的形状决定:yy/dd 存的是「行」,粘出来就是新起一行;yw/dw/yiw 存的是「字符」,粘出来就插进当前行:

这个演示藏了两个日后天天用的「搬家技巧」:dd + p = 把当前行往下移一行(行序调整,比剪切板来回倒快得多);dw + P = 词序调整(把词搬到光标前)。本质都是「剪切 + 粘贴」= 移动 —— Vim 没有单独的「移动」命令,语言自己组合出来了。

按键粘贴位置行寄存器时字符寄存器时
p光标后粘到下方成新行插在光标字符之后
P光标前粘到上方成新行插在光标字符之前
3p同上,×3粘贴也吃计数:三份副本一次到位
💡 快捷键 xp:交换两个字符 把 verison 的 i 和 s 换回来:光标放到 i 上,按 x(删掉 i)再 p(粘到后面)—— verison 变 version,两键修完一处笔误。同理 ddp 交换相邻两行、dwP 交换相邻词。「删 + 粘」的化学反应值得专门玩十分钟。

6. r 与 s:小改不打草稿

不是每次修改都值得「清范围 + 重打」。改一个字符,r(replace)连插入模式都不进:

r 后面跟一个字符,原地换掉光标处的字符,光标不动、模式不变、节奏不断。x1 变 x2、i 变 j,这类「只差一个字母」的场景它是绝对王者(还能 3r- 把三个字符换成 ---)。s(substitute)则是「删一个字符并顺势进入插入」,是 cl 的打包;S 上节已见过 = cc。选型口诀:换一个字符用 r,要接着打字用 s,成片修改回 c + 名词。

7. 大小写:~ 与 gU / gu

三个换挡动词:~ 翻转光标处一个字符(光标右移,可连按);gU 把名词变大写、gu 变小写 —— g 是前缀(第 2 章的 g_ 见过),后面接一个完整的动词-名词组合:

最值得练熟的是 gUiw:光标所在的词整个变大写 —— url 变 URL、api_key 风格的常量命名信手拈来(下划线不改,Snake Case 里逐段 gUiw + w 正好)。整行版是 gUU/guu。注意读法:gU 读「变大写」,它和 d 平级 —— 所以 gUiw 是标准的「动词 + i + 名词」句式,g 只是动词的姓氏。

8. 缩进与格式化:>> << ==

在 IDE 里写代码,缩进大多是被回车键自动带出来的;但改别人的代码、贴代码、删了外层块之后,缩进就乱了。三个动词专治:

>> 当前行右移一级、<< 左移一级(> 和 d 一样是等名词的动词 —— >i{ 缩进整个块、2>> 缩进两行,都是合法句);== 自动缩进当前行 —— 按语言规则摆正。在 IDE 里 = 背后调用的是编辑器/语言服务的格式化引擎,表现比纯 Vim 更聪明,放心用。想格式化整个文件,别想着 gg=G(虽然它确实行),直接用 IDE 的格式化快捷键更省心 —— 第 12 章会讲「Vim 管编辑、IDE 管工程」的分工哲学,这里是第一次预演。

9. J:把下一行拉上来

J(Join)把下一行合并到当前行尾,自动吃掉下一行的缩进、在连接处补一个空格;gJ 则原样拼接不补空格:

J 的高频场景:①别人代码里的无脑断行拼回去;②把两段字符串字面量拼成一个(配 J 还是 gJ 看引号里有没有空格);③写 markdown 时把软折行的段落并回一行。反向操作(一行拆两行)是 r+回车 —— 把某个字符原地换成换行,又见 r 的百变。

顺带交代一个家族惯例:J 不吃计数前缀?吃 —— 3J 把下面两行一起并上来。但在 IDE 里我更推荐单步 JJ 地按:合并是不可视的操作(你看不到下一行是什么就并了),一步一步按、每步看清再继续,比赌三行一次到位稳妥 —— 这是少数「宁慢勿快」的命令,快有 u 兜底,稳靠自己。

10. 毕业演出:三句话的重构

把本章所有零件组装起来,做一次真实的重构:函数 area(w, h) 参数名太吝啬,要改成 width, height,函数体同步更新。传统做法:选中、删、打、再选中、再删、再打…… 现在你说三句话:

数一下:第一句 ci((改内括号)重写签名;第二、三句 fw + ciw、fh + ciw(找旧名、改内词)同步函数体 —— 全程 15 个左右的按键,没有一次方向键、没有一次鼠标、没有一个多余字符。这就是「编辑即说话」的完成态:眼睛看到意图,嘴里是中文,手上是语法。

复盘这次重构用到的词法:名词两个(i(、iw,第 4 章),动词两个(c、隐含的 f 移动,第 2 章),连一个本章新词都没有 —— 但只有把「动词 + 名词」的公式内化成本能,这些零件才能在两秒内自动组装成句子。往后的章节会不断给你新词(v 选择的名词、/ 查找的名词、宏的自动化),而句子结构,永远只有这一条。

11. 每日训练计划(30 分钟 × 3 天)

天时间盒内容通过标准
第 1 天0–10 分钟重放演示 1–3,读 §1–§3;靶场把 d/c 的名词各配 5 个cw 和 dw 的空格差异说得清
10–30 分钟练习 1:三动词轮换同一词上 diw/ciw/yiw 不假思索
第 2 天0–10 分钟重放演示 4–6,读 §4–§6能说出 p/P 行级字符级的判断规则
10–30 分钟练习 2 + 练习 3dd+p 移行 10 次不卡壳
第 3 天0–10 分钟重放演示 7–10,读 §7–§10,重点看毕业演出能默写 capstone 的三句话
10–30 分钟练习 4:盲测毕业考12 题对 9 题,本章毕业

12. 如果本章只记住三件事

  1. 语法公式:[数字] 动词 [数字] 名词 —— 数字相乘、位置随便,动词 × 名词组合爆炸,你背的只有词,不是句子;
  2. 要打字用 c,纯删用 d,搬运用 d+ p:剪切粘贴合起来就是「移动」,dd+p 移行、dw+P 移词、xp 修笔误;
  3. 小活用小工具:一个字符 r、大小写 gUiw、缩进 ==、并线 J —— 别动不动清一大片再重打。

下一章回到插入模式本身:进出的全部姿势、插入模式内的快捷键、替换模式 R —— 把「打字」这最后一公里也优化掉。

练习

练习 1:三动词轮换(10 分钟)

靶场任选 20 个标识符,每个上面连做三件事:diw → u;ciw 输入 foo → Esc → u;yiw → w → P → u。感受同一个名词在三个动词下的三种手感。通过线:手指不再在 d/c/y 之间犹豫。

练习 2:行搬运工(10 分钟)

找一段 15 行左右的代码,只用 dd + p(和 k/j 移动)把乱序的行排成你想要的顺序(比如把 import 全挪到顶部)。规则:全程禁用鼠标和 Cmd+X。体会「删行 = 剪切行」和「p 粘到下方」的组合 —— 十几分钟下来你对行级移动的恐惧会消失。

练习 3:大小写与缩进工坊(10 分钟)

①找 10 个全小写变量,逐个 gUiw 变大写,u 撤销;~ 连按翻转一个词。②把一段故意弄乱的缩进(你手动加空格)用 >>/<</== 修回整齐;再试试 >i{ 整块右移 —— 又一次「对象当名词」。

练习 4:盲测毕业考(10 分钟)

对着真实代码,12 个任务先说按键再验证:①删三个词 ②改两个词 ③删到行尾(两种按键)④清空整行重写(两种按键)⑤复制整行并粘到下面 ⑥把当前行下移一行 ⑦交换相邻两行 ⑧修一个笔误字母 ⑨变量名整个变大写 ⑩当前行自动缩进 ⑪合并下两行(补空格/不补各一次)⑫改某函数的参数列表。答案例:3dw/c2w/D 或 d$/cc 或 S/yyp/ddp/ddp/rp 或 xp/gUiw/==/J 与 gJ/ci(。12 对 9 毕业。

常见陷阱

🕳 期待 cw 删掉尾部空格 从 dw 迁移过来的肌肉记忆会撞墙:cw 只删到词尾,空格留着 —— 这是为了你打完新词排版直接正确。真想连空格一起换,用 caw 或先 daw 再 i。分不清时想:c 是「改内容」,不是「打扫房间」。
🕳 p 粘出了奇怪的位置 以为是 bug,其实是寄存器形状在决定:yy 存的是行,粘出来必是新行;想粘在光标后却插进了行中间,说明寄存器里是字符级的。先想「我刚才 y/dd 的是什么形状」,再选 p/P。习惯后这反而是可控的精确。
🕳 指望 . 能重复一切 本章你可能已经发现按 . 有时能把刚才的修改再来一遍 —— 很诱人,但它重复的是「最后一次变更」,移动和纯 yank 不算数,边界微妙。先别急着把工作流押在它身上,第 10 章专门讲它的适用边界和宏这个完全体。
🕳 用 == 格式化整个文件 == 只管当前行;虽然 gg=G 确实能全文件格式化,但在 IDE 里请把「全文件格式化」交给 IDE 自己的快捷键(VSCode Shift+Alt+F,IDEA Cmd+Alt+L)—— 语言服务排的版比 Vim 的内置规则聪明。Vim 的 = 留给「顺手修一两行」。

VSCode / IDEA 差异

VSCode(VSCodeVim)

  • 本章动词全家(d/c/y/p/r/s/~ / gU / >> / == / J)VSCodeVim 全部原生支持
  • == 会调用语言服务的格式化(和 Shift+Alt+F 同源),格式化结果一致
  • Cmd+c/v 与 y/p 默认各自为政:开了 vim.useSystemClipboard(第 1 章配置)后共用系统剪贴板,互不打架
  • 整行移动有个原生对手 Alt+↑/↓ —— 和 ddp 二选一,顺手就行,但在纯 Vim 环境(远程/终端)只有后者永远在线

IntelliJ IDEA(IdeaVim)

  • IdeaVim 同样全支持;.J 合并、gU 大小写这类冷门键也在线
  • == 走 IDEA 的 Code Style 引擎;全文件格式化用 Cmd+Alt+L
  • 重要分工:跨文件重命名千万别用 ciw,用 IDEA 的 Rename 重构(Shift+F6)—— 它改的是符号引用,不是文本。ciw 只管单文件内的字面改名
  • IDEA 的 Cmd+D(Duplicate Line)与 yyp 等价,知道即可,继续用 Vim 侧保持手感统一

本章速记

按键作用按键作用
N动词N名词计数相乘,位置随便C / D / Sc$ / d$ / cc 打包键
d / c / y删(=剪切)/ 改 / 复制rx / s换单字符 / 删一个顺势改
p / P粘到后 / 前(形状随寄存器)~ / gUiw翻转一字符 / 词变大写
yy + p复制行 + 粘下行>> / ==缩进一级 / 自动缩进行
dd + p当前行下移(搬家)J / gJ并行(补/不补空格)

一句话心法:数字 × 动词 × 名词 —— 想清楚要说什么,再动手;删即剪切,y 无痕,p 看形状。