09 综合练习:把编辑意图翻译成 Vim 操作
这一章不新增 vocabulary。目标是从“看命令,想作用”转为“看编辑意图,选择 Action 和 Target”。 请在可丢弃副本中完成任务;每一题都可能有多种正确操作。
先用一个已学过的组合确认练习方式:
Before — Normal Mode
const state = "draft";
^
Keys
ciwstatus<Esc>
After — Normal Mode
const status = "draft";
^
先核对文本、光标和最终 Mode,再解释这次操作的 Action 与 Target。正式练习的每一题都从下面代码的全新副本开始,避免前一题的修改影响后一题。
function buildLabel(user: User, options: LabelOptions) {
const prefix = "user";
const displayName = user.profile.name;
const fallback = "anonymous";
const primaryStatus = "pending";
const fallbackStatus = "pending";
return `${prefix}: ${displayName || fallback} (${primaryStatus || fallbackStatus})`;
}
Level 1:直接应用
- 从函数名开头移动到
options。 - 移动到
displayName的结尾。 - 在
return行定位到第一个:。 - 搜索
fallback,再返回前一个匹配项。
Level 2:组合
- 把
buildLabel改成另一个函数名。 - 分别修改参数名
options和类型LabelOptions。 - 删除函数参数列表中的全部内容,但保留圆括号。
- 删除
return后到行尾的内容。 - Yank 整个
const fallback行,并在函数体中另一个位置 Put 一份。 - 删除
profile这个单词。
Level 3:表达意图
下面只描述目标,不给出命令:
- 修改
"anonymous"中的内容,但保留双引号。 - 删除模板字符串
${...}内部的一个对象,但保留花括号。 - 把参数列表中的内容替换成一个新参数,同时保留圆括号。
- 将两处
"pending"改成同一个新值:先完成第一处,再在下一处重放。 - 删除连续两个 word;先决定 Count 应放在哪里,再执行。
对照答案的方式
先写下你的意图:
Action:
Target:
Control:
再检查结果是否符合任务。参考思路可以是:
修改单词 → change + inner word
清空括号内容 → delete + inside parentheses
Yank 一整行 → yank + line target
重复同一修改 → move + .
不要把这组思路当作唯一按键答案。若你的操作保留了要求保留的文本、得到正确结果,并能解释选择的 Target, 它就是有效答案。
完成标准
完成后,你应能解释:
- 为什么
di(不必被当作独立快捷键; cw与dw为什么不应简单视为完全对称;- 什么时候应该用 Count,什么时候应该用
.; - 删除为何可能覆盖刚刚 Yank 的 unnamed Register;
- 当一个操作范围不确定时,为什么可以先用 Motion 或 Search 定位,再执行编辑。
如果某项仍需要反复查表,回到对应章节做一个新的 Before / Keys / After 小练习。Vim 的熟练来自多次 可观察的正确重复,而不是一次背完所有命令。
评论