字符与词:让光标飞起来
学习目标
- 彻底戒掉方向键:h j k l 成为手指的默认方向
- 按词移动:w b e,以及大词版 W B E
- 行首行尾瞬移:0 ^ $ g_
- 行内直达任意字符:f F t T 与重复键 ; ,
- 第一次体验「移动 = 动词的射程」:dt, 这样的组合句子
- 建立本章的物理学直觉:一行之内,任何位置两键可达
1. 为什么专门用一章讲「移动」
回忆第 1 章的论断:写代码的大部分时间不在打字,在读、跳、改。而「读和跳」的本质是同一件事 —— 把光标送到目的地。移动是 Vim 里被使用频率最高的一类命令,没有之一;它也是后面一切的地基:第 5 章你会学到「删除的范围 = 移动的射程」,移动练不熟,编辑语言就永远说不利索。
方向键有三宗罪:
- 远:在键盘右下角,每次去够,右手都要离开主键区,回来时还得重新定位(手指一离位,盲打就断);
- 慢:一次一格,从行首到第 40 列要按 39 次;
- 破坏节奏:手的位置一变,眼睛就得离开屏幕确认一下 —— 每次半秒,一天几百次。
本章的任务:让字符级移动(hjkl)接管方向键的职责,再给你三层越来越快的跳法 —— 按词、按行端、按字符直达。下一章再把战场扩大到整个文件(行与行之间的跳跃)。
先算一笔经济账。假设你每天在编辑器里做 300 次行内定位:鼠标方案 = 手离键盘 + 找指针 + 精确点击,平均 2.5 秒;方向键方案 = 平均 15 次按键 × 0.2 秒 = 3 秒,且右手来回搬家;本章的方案 = 平均 2 键 × 0.3 秒 ≈ 0.6 秒,手不离位、眼不离码。每天省下的十来分钟倒在其次,注意力不断线才是真正的收益 —— 光标听话之后,你才会开始「用移动思考」,而不是「用定位忍耐」。
2. h j k l:主键区的方向键
四个字母,画在键盘上正好是十字:
| 按键 | 方向 | 记法 | 指法 |
|---|---|---|---|
| h | ← 左 | 十字最左 | 右手食指(从 j 左移一格) |
| j | ↓ 下 | j 键上有小凸点,食指盲摸即知 | 右手食指 home 位 |
| k | ↑ 上 | 十字最上 | 右手中指 |
| l | → 右 | 十字最右 | 右手无名指 |
注意演示里的计数前缀:先按 3 再按 j,一次跳三行。所有移动命令都吃数字前缀,这是 Vim「数格子交给机器」的第一课 —— 永远不要连按 8 次 l,要么 8l,要么干脆用下面更聪明的跳法。
怎么练:不要专门「背」,而是给自己立一条规矩 —— 接下来三天,方向键只准用于你还没学的场景(其实没有这种场景,所以等于禁用)。头半天会慢 30%,第二天追平,第三天开始反超。这是所有 Vim 学习者都走过的曲线,没有人例外。
3. 词的三兄弟:w b e
字符级移动是保底,真正的高频武器是词级。Vim 对「词」(word)的定义:连续的字母、数字、下划线算一个词;标点符号也各自成词 —— 连续的同类标点(比如 ) 后面跟 ; 不同类则分开,同类如 == 算一个)。听起来复杂,看一遍动画就懂:
| 按键 | 含义 | 什么时候用 |
|---|---|---|
| w | 下一个词的开头 | 最常用的前进键,「去下一个变量」 |
| b | 上一个词的开头(back) | 往回找,w 的镜像 |
| e | 当前/下一个词的结尾(end) | 要去词尾做事时(词尾加后缀、看边界) |
| ge | 上一个词的结尾 | 冷门但有用:倒着按词尾走 |
决策法:问自己「我要去的其实是词的开头还是结尾?」 —— 开头用 w/b,结尾用 e。比如把光标放到一个函数名的最后一个字母上准备加后缀,e 一步到位;而「从行中间快速往左回到行首方向」,bbb 比 h×10 优雅得多。
用一个真实场景把三兄弟串起来:你在检查一行老代码 const total = price + tax;,想知道 total 是从哪来的 —— 光标停在行首,连按 w 逐个标识符「点名」;发现要看 price 的结尾有没有后缀,fp 直达后再 e 落在词尾;看完想回头核对 total,bbb(或 Ft 更快,下一节)。整个过程眼睛没离开过代码,手没离开过主键区 —— 这就是「用移动思考」的雏形。
至于词边界的精确规则,记住三条就够日常用了:①字母 / 数字 / 下划线互相粘连算一词(data_dir 是一个词);②标点同类粘连算一词(==、::、-> 各算一个);③字母和标点之间永远是边界(a,b 是三个词:a、逗号、b)。不确定的时候,在靶场里按 w 走一遍,眼睛会替你归纳 —— 比背规则快。
4. 大词:W B E
「小词」把每个标点都当成独立单位,在代码里有时太碎 —— parse(data_dir, 里 w 要踩四五脚。大词(WORD)的定义粗暴得多:空白符(空格 / Tab)分隔的一切。于是 URL、路径、file.txt、a=>b 这种整体都算一个 WORD:
| 场景 | 用小写(w/b/e) | 用大写(W/B/E) |
|---|---|---|
| 逐个变量、逐个符号地看 | ✅ 精细 | 跳太快 |
跨过 foo(bar, 这种粘连片段 | 要踩好几脚 | ✅ 一步跨过 |
| URL / 路径内部移动 | ✅ 按 . / 分段 | 整体一个词,一步出界 |
一句话决策:想「逐个标识符」走用小写,想「大步跨过标点海洋」用大写。Shift 顺手就有,不用白不用。
两个高频例子帮你建立体感:①光标在 https://example.com/api/v2 的开头,想走到 api:小写 w 要踩过 //、.、/ 一堆碎词,而大写 W 把整个 URL 当一个词,一步跳出界外再 b 回来反而快 —— 反过来,要在 URL 内部按段走,就得用小写;②一行模板字符串里嵌了好几处 ${...},用 W 按空白大步跳过插值块,比小写碎步清爽得多。大小写的切换,本质是在粒度之间换挡。
5. 行内瞬移:0 ^ $ g_
四个键,两两成对:行首一对(0 绝对 / ^ 非空白),行尾一对($ 绝对 / g_ 非空白):
| 按键 | 落点 | 典型场景 |
|---|---|---|
| 0(数字零) | 绝对行首,第 0 列 | 要去缩进前面;配合可视化模式(ch07) |
| ^ | 第一个非空白字符 | 代码里的"行首":到行首改代码用它 |
| $ | 行尾最后一个字符(含尾随空格) | 快去行尾;$ 后接 a = 手动版 A |
| g_ | 最后一个非空白字符 | 行尾有空格时,精确落在代码上 |
^const 匹配行首的 const,而 Vim 里 ^ 就是「跳到行首(第一个真字符)」。
代码场景里 ^ 的出场率远高于 0:大多数时候你要的是「这行代码从哪开始」,而不是「缩进前面那两个空格在哪」。什么时候才真需要 0?—— 要选中包含缩进的整行、或者检查缩进本身(空格还是 Tab、几个)的时候。一句话:看代码用 ^,看排版用 0。
6. 行内直达:f F t T 与 ; ,
本章最快的武器。f(find)后跟任意一个字符,光标直接送到本行下一处该字符上;t(till)则是送到目标前一格。大写 F/T 反向找。重复键 ;/, 沿同一目标继续前进 / 后退:
| 按键 | 含义 | 什么时候用 |
|---|---|---|
| f+字符 | 跳到本行下一处该字符上 | 眼睛能看到目标行内的锚点字符 |
| t+字符 | 跳到该字符前一格 | 目标是"字符之前的那段"(配合动词!) |
| F/T+字符 | 同上,但往回找 | 目标在光标左边时 |
| ; / , | 重复刚才的 f/t:下一处 / 上一处 | 一行里有多个同名锚点(逗号、点号) |
几个实战细节:①目标在左边就用大写 F/T 反向找,比 b 猜词更精确;②一行里有重复字符时,先 f 一次再用 ; 踩点,别每次都重新按 fx —— 重复键存在的意义就是把三键变一键;③t 平时看起来只是 f 的「差一格版」,但配合动词时这一格就是护城河(下一节),所以别嫌它多余;④按错字符?f 之后按 Esc 取消待决,或直接再按一次对的字符前先 ; 会跳错 —— 习惯上,f 按错了就当无事发生,重新按就是,成本极低。
7. 移动即射程:dt, 的第一次合体
第 0 章预告过「动词 + 名词」。现在你手里的移动键,全都是现成的「名词」—— 给 d(删)当射程:
dt, = 「删,删到逗号前」。看懂这一步,你就看懂了 Vim 的核心机制:动词不自己带范围,范围由移动键给出。把 t, 换成 w 就是删一个词,换成 $ 就是删到行尾,换成 f; 就是删到下一个分号 —— 动词不变,射程随便换。第 5 章会把这套语法讲全,这里先把「移动很值钱」这件事刻进手感里。
给你三个今天就能用的「射程三连」,在靶场里各做五遍找感觉:dw(删掉光标往后一个词)、d$(删到行尾,也可以按 D —— 打包版)、df;(删到行内下一个分号,分号本身也删掉,和 dt, 只差「含不含终点」)。不用记结论,按一遍、撤销一遍,手感自然形成 —— u 就是你的免费回放键。
8. 行内组合拳:任何位置,两键以内
把本章的键合起来用,会得到一个很爽的性质:一行之内,光标从任何位置到任何位置,最多两三键。原理:先用 f/W/$/^ 做大跨度跳跃,再用 wehl 微调一格。
| 目标在哪 | 首选 | 微调 |
|---|---|---|
| 行首 / 行尾 | ^ / $ | —(一击必中) |
| 行内某个显眼字符附近 | f+字符 | hlwb |
| 下一个标识符 | w | e 到词尾 |
| 跨过一段标点粘合物 | W / B | ; 接力 |
| 同字符多处(逗号、点) | f+字符 | ;; 踩点 |
组合的心法只有一条:先粗后细。大跨度交给 f/W/$/^,落地后如果差一格半格,再用 hlwe 微调。新手常见的顺序错误是反过来 —— 先一格一格挪到目标附近再犹豫 —— 那是方向键时代的肌肉记忆在作祟。练到后来,「两键到达」会变成一种条件反射:眼睛落在目标上的同时,手指已经出发。
9. 一句话处理折行:gj gk
如果编辑器开了软折行(wordWrap),一个逻辑行会折成多个屏幕行,此时 jk 走的是逻辑行,gj / gk 走屏幕行。写代码推荐直接关掉折行(见本章 IDE 备注),需要时再记这对前缀键不迟。
10. 每日训练计划(30 分钟 × 3 天)
本章内容建议拆三天消化,别一口气练完:
| 天 | 时间盒 | 内容 | 通过标准 |
|---|---|---|---|
| 第 1 天 | 0–10 分钟 | 重放 7 个演示(单步),读 §1–§4 | 能说出 w/b/e 各自落点 |
| 10–30 分钟 | 练习 1 + 练习 2:hjkl 盲走 + w/e/b 词表 | 全程不看键盘和手指 | |
| 第 2 天 | 0–10 分钟 | 复习昨天的键,读 §5–§6 | 0/^/$/g_ 各落点张口就来 |
| 10–30 分钟 | 练习 3:f 跳转游戏 + ; 连踩 | 10 行代码不用方向键走完 | |
| 第 3 天 | 0–10 分钟 | 读 §7–§8,重点体会 dt, | 能自己造 3 个「动词+射程」句子 |
| 10–30 分钟 | 练习 4:两键挑战 + 盲测 | 盲测 8/10,本章毕业 |
11. 如果本章只记住三件事
- 方向键退役:hjkl + 词级移动,手从此住进主键区;
- 眼睛看哪,光标就去哪:看到锚点字符就 f 它,看到词就 w 它 —— 不数格子;
- 移动就是射程:今天记住 dt, 这一个例子,第 5 章会还你一片森林。
下一章把战场从「一行」扩大到「整个文件」:相对行号、gg / G、段落跳跃、% 配对跳转 —— 光标开始在整个文件里飞。
练习
练习 1:hjkl 盲走网格(10 分钟)
靶场文件里随便找一块 10 行左右的代码,右手放在 j 凸点上,眼睛只看屏幕,用 hjkl 走出一个「口」字再走一个「之」字,最后走回起点。中途一旦手去摸方向键,从头再来。进阶:给自己计数,比如 5j3l,一次到位。
练习 2:w / e / b 词表朗读(10 分钟)
光标放到任意一行代码开头,连续 w 走到行尾,每按一次读出落点的标识符(不读标点也算过,读出来更好);再连续 b 走回行首;再 e 走一遍。三个键各走 10 行。你会自然记住「=、+、, 都是独立词」这个事实。
练习 3:f 跳转游戏 + ; 连踩(10 分钟)
找一行有多个逗号/点号的代码(比如参数列表),光标行首:f, 到第一个逗号,然后只用 ; 踩到行尾、只用 , 走回行首。再换 f.、f( 各来一轮。要点:; 长在手边,别每跳一次都重新按 f。
练习 4:两键挑战 + 盲测毕业考(10 分钟)
让同事(或自己随机)指定行内某个字符作为目标,要求最多两键把光标放上去,做 20 组。然后闭眼完成序列:^ → f; → ; → e → $ → bb → 0,睁眼检查光标位置是否符合预期,10 组对 8 组毕业。
常见陷阱
parse(data_dir, 里连按 w 踩四脚,不是你笨,是用错档位 —— 换 W 一步跨过。记住:小写=精细档,大写=越野档。
VSCode / IDEA 差异
VSCode(VSCodeVim)
- 本章全部按键 VSCodeVim 原生支持,零额外配置
- 建议关闭软折行,让 j/k 保持逻辑行语义:设置搜
editor.wordWrap设为off(默认就是 off) - Cmd←/→(行首/行尾)依然可用,但既然学了 ^/$,让它们退休
- 下一章要用相对行号:现在就可以把
editor.lineNumbers设为relative(第 1 章配置里已有)
IntelliJ IDEA(IdeaVim)
- IdeaVim 对本章按键同样全支持;f 查找还会有黄色高亮提示所有候选
- 软折行同理:建议
Settings → Editor → General → Soft Wraps不勾选代码场景 - 开了折行的 Markdown 长段落,记得用 gj/gk 走屏幕行
- 相对行号在
~/.ideavimrc里set relativenumber(第 1 章配置已有,下一章讲为什么)
本章速记
| 按键 | 作用 | 按键 | 作用 |
|---|---|---|---|
| h j k l | 左 下 上 右 | 0 / ^ | 行首 / 首个非空白 |
| w / b / e | 下一词头 / 上一词头 / 词尾 | $ / g_ | 行尾 / 尾个非空白 |
| W B E | 大词版(空白分隔) | fx / tx | 到字符 x / 到 x 前一格 |
| 3j 等 | 数字前缀 = 一次跳 N 格 | ; / , | 重复 f/t:下一处 / 上一处 |
| gj / gk | 屏幕行上下(折行时) | dt, | 删到逗号前(射程预告) |
一句话心法:眼睛看到哪,光标就去哪 —— 词用 w,锚点用 f,行端用 0^$。