03|移动与小修改
写代码时频繁使用鼠标,很容易打断节奏;方向键离主键区又远。这一章先练普通模式下的移动,同时修改几处内容,把 pyproject.toml 和 README 补齐。
这些按键分四轮来学:
- h j k l;
- w b e 与 0 ^ $;
- g g G 与文件内搜索;
- I A o O、x、r。
每一轮先做个短练习,再把刚学会的操作用到项目里。
1. 填写 pyproject.toml
在终端进入项目:
cd ~/playground/pocket-tasks
nvim pyproject.toml
按 i,输入下面的完整内容:
[project]
name = "pocket-tasks"
version = "0.1.0"
requires-python = ">=3.11"
[tool.basedpyright]
extraPaths = ["src"]
typeCheckingMode = "standard"
输完以后按 Esc。
输入引号和方括号时,mini.pairs 会自动补上右半边。之后照常输入右引号或右方括号就行,光标会直接越过已经存在的字符。
先别保存,下面就拿这八行文字练习移动。
2. 第一轮:单格移动 h j k l
普通模式中:
| 按键 | 效果 |
|---|---|
| h | 左移一个字符 |
| j | 下一行 |
| k | 上一行 |
| l | 右移一个字符 |
这四个键排在同一行,左手不用离开主键区。先随便移动十几次,看看当前行高亮和行号是怎么跟着光标变化的。
有两个边界规则:
- h 到行首就停;
- l 到行尾就停。
碰到边界就会停住,不会自己跳到相邻行。
小练习
- 用 j 到
version那一行。 - 用 l 向右移动到
0.1.0附近。

- 用 k 回到
name行。 - 用 h 向左移动。
这一轮主要是找方向感,不用非得停在某个字符上。
3. 第二轮:按词和按行跳
一个字符一个字符地挪,适合最后微调;距离远一点时,就该用下面这些按键了。
按词移动
| 按键 | 效果 |
|---|---|
| w | 跳到下一个词块的开头 |
| b | 跳到前一个词块的开头 |
| e | 跳到当前或下一个词块的末尾 |
标点也会单独形成词边界。所以在 version = "0.1.0" 这一行里,等号、引号和句点都可能让 w 停下来。
在一行内直达
| 按键 | 效果 |
|---|---|
| 0 | 到这一行的第 1 列 |
| ^ | 到这一行第一个非空白字符 |
| $ | 到这一行最后一个字符 |
这份 TOML 的行首没有缩进,所以 0 和 ^ 看起来没什么区别。等写到 Python 类时,0 会停在缩进空格上,^ 则会停在第一个代码字符上。
精确练习
- 用 j / k 到
requires-python行。 - 按 0,光标到行首的 r。
- 连续按几次 w,观察它依次越过键名、连字符、等号和字符串。

- 按 $,光标到最后一个引号。
- 按 b,向前回到前一个词块。
- 按 ^,回到行首第一个有效字符。
4. 第三轮:文件级跳转
| 按键 | 效果 |
|---|---|
| g g | 文件第一行 |
| G | 文件最后一行 |
数字 G | 跳到指定行,例如 3 G 去第 3 行 |
依次试:
- g g:到
[project]。 - G:到
typeCheckingMode。

- 3 G:到
version。
很多普通模式操作都能在前面加数字。5 j 是向下五行,3 w 是往前跳三个词块。暂时把数字理解成“动作的倍数”就行。
现在用 F1、write、Enter、Enter 保存 pyproject.toml。

5. 文件内搜索:/、n、N
你已经会用 Space / 调出 Snacks Grep,在整个项目里搜索。去掉前面的 Space,单独按 /,搜的就是当前 Buffer。
打开 README:
- 按 Space e 打开 Explorer。
- 用 j / k 高亮
README.md。

- 按 Enter。
焦点切到 README 后,输入 /tasks,先别回车。

搜索词会先出现在底部。按下 Enter 后,光标会跳到下一处小写的 tasks。

| 按键 | 效果 |
|---|---|
/文字 ,Enter | 在当前文件中向后搜索 |
| n | 沿相同方向找下一处 |
| N | 反方向找上一处 |
| Ctrl+l | 清掉屏幕上的搜索高亮并重绘界面 |
注意这是大小写敏感的,所以 /tasks 找不到标题里的 Tasks。搜到文件末尾后,它会绕回开头继续找,同时在底部提醒你一声。
练习:先按两次 n。

再按一次 N。

最后按 Ctrl+l 清掉高亮。

6. 第四轮:四个插入入口
你已经会用 i 和 A,现在把这一组常用按键补全:
| 按键 | 进入插入模式的位置 |
|---|---|
| i | 光标字符之前 |
| I | 当前行第一个非空白字符之前 |
| A | 当前行末尾之后 |
| o | 在当前行下方新建一行 |
| O | 在当前行上方新建一行 |
o 和 O 都会新开一行,并直接进入插入模式。写代码时经常会用到。
用 o 添加 Quick start
- 按 G 到 README 最后一行。
- 按 o,下方出现新行并进入插入模式。
- 先按一次 Enter,留下空行。
- 输入
## Quick start。

- 连按两次 Enter,留下标题后的空行。
- 输入
`PYTHONPATH=src python -m pocket_tasks.cli`。

- 按 Esc。
现在最后一行还只有一段命令。接着用两个入口把它补成一句话:
- 按 I,输入
Run后跟一个空格,按 Esc。

- 按 A,输入
.,按 Esc。

最后应该是这样:
## Quick start
Run `PYTHONPATH=src python -m pocket_tasks.cli`.用 O 做一次可撤销实验
- 输入
/Quick,按 Enter,光标落在标题上。 - 按 O,在标题上方新建一行。
- 输入
temporary note,按 Esc。

- 按 u,临时行消失。

这样既练了 O,也没把临时内容留在 README 里。
7. 单字符删除与替换:x 和 r
| 按键 | 效果 |
|---|---|
| x | 删除光标下的一个字符 |
r 字符 | 用新字符替换光标下的一个字符,仍留在普通模式 |
x 练习
- 按 g g 到第一行。
- 按 A,输入
!,按 Esc。

- 光标此时在感叹号上,按 x。
按完以后,感叹号会被删掉,标题恢复成 # Pocket Tasks。

r 练习
- 输入
/Goals,按 Enter。 - 光标落在 G 上,按 r X。
- 标题暂时变成
## Xoals。

- 按 u,恢复
## Goals。

r 很适合改一个字母、换一种引号,或者动一下布尔值里的某个字符。它只处理光标下的字符,也不会进入插入模式。
8. 保存与结果检查
用 F1、write、Enter、Enter 保存 README。现在它应该是:
# Pocket Tasks
A tiny task tracker for terminal-loving humans.
## Goals
- Add tasks
- Complete tasks
- List open tasks
## Quick start
Run `PYTHONPATH=src python -m pocket_tasks.cli`.
pyproject.toml 应该是:
[project]
name = "pocket-tasks"
version = "0.1.0"
requires-python = ">=3.11"
[tool.basedpyright]
extraPaths = ["src"]
typeCheckingMode = "standard"
结束时按 F1,输入 wqa,连按两次 Enter。
本章肌肉记忆
| 范围 | 按键 |
|---|---|
| 单字符移动 | h j k l |
| 按词移动 | w b e |
| 行首 / 首个非空白 / 行尾 | 0 / ^ / $ |
| 文件首 / 文件尾 / 指定行 | g g / G / 数字 G |
| 当前文件搜索 | /,然后 n / N |
| 行首插入 / 行尾追加 | I / A |
| 下方 / 上方开新行 | o / O |
| 删一个字符 / 换一个字符 | x / r 字符 |
上一章:Explorer 与项目骨架 · 下一章:编辑语法与文本对象