高效使用 Vim 的七个习惯
Vim 是一个流行的文本编辑器,原作者是 Bram Moolenaar (1961 ~ 2023-08-03)。
2000 年 11 月,Bram Moolenaar 有一篇文章:高效文本编辑的七个习惯,专门讲述文本编辑的技巧和策略。2007 年 2 月,他在谷歌演讲,题目是 高效文本编辑的七个习惯 2.0,B 站有录制的现场视频。
提升文本编辑效率分三个基本步骤:
- Detect inefficiency 发现低效操作
- Find a quicker way 找到更快的方法
- Make it a habit 形成习惯
编辑一个文件
1. 快速移动
程序员的大部分时间是在阅读代码、查找错误、寻找最佳修改位置,相比之下,真正插入新代码的时间不多。
在 Vim 中,/pattern
随时启动一次查找。n
在匹配字符间跳转。
如果你想查找光标下的单词,执行 *
命令。
如果开启了 incsearch
选项,Vim 会先匹配命中的第一个位置,随着输入不断变化。这种快速反馈让你很轻松就能发现错误。
如果开启了 hlsearch
选项,Vim 会使用黄色背景高亮显示命中的位置。
在结构化文本中,Vim 提供了更多跳转选项。比如,在 C 语言中,%
可以在配对括号间跳转,或者在 #if
和匹配的 #endif
间跳转。其实,%
可以在很多不同的匹配符号间来回跳转。
使用 [{
可以跳转到当前代码块的开始括号 {
位置处。
使用 gd
命令,可以跳转到变量的局部声明的位置。
类似的移动命令还有很多,全部掌握需要投入时间。关键是时刻关注你的编辑操作,如果发现需要提高效率,就去学习,并内化为自己的习惯。
比如,编辑 C 语言代码时,经常需要查找函数的定义。一开始,你可能使用 *
查找,但是这会造成大量的无效跳转。
通过查找手册,你发现可以使用标签跳转功能。 然后你尝试使用 Vim 自带的 ctags
程序,生成标签文件,学着使用 Ctrl-]
跳转指令,就能感受到效率极大提升。
在 Makefile 中增加一些指令,自动化生成标签文件,可以让效率进一步提升。
2. 避免重复输入
如果想在一个文件内,把一个文本替换为另一个,可以使用 :s
替换指令。
如果需要替换的位置较少,可以使用 *
定位,使用 cw
替换。然后使用 n
继续查找下一个,使用 .
重复指令继续上一次的编辑操作。
.
会重复上一次的修改操作。如果修改操作组织得当,可以用 .
代替大量的重复操作。
如果在重复操作中,需要进行其他的操作,可以使用 m
标记一下位置,等完成所有重复操作再回来特殊处理。
有些函数名字很长,难以记忆和输入,比如 XpmCreatePixmapFromData
。Vim 提供了自动补全功能,你输入前几个字母,比如 XpmCr
,然后输入按键 CTRL-N
,Vim 会从当前文件中查询字符串,并自动扩展为完整的字符串。
如果你需要反复输入一些段落,Vim 的宏(macro)更方便。执行 qa
,开始录制宏,接下来的操作序列将存储到寄存器 “a” 中。再次按下 q
会结束宏的录制。当你想重复宏的操作,执行 @a
即可。这样的寄存器有 26 个。
3. 修复错误
人非圣贤,谁能无错。编辑器应该可以帮你修正错误,前提是要提前告知它何为对,何为错。
通常,同样的错误会一犯再犯。使用简写功能可以帮忙修正这类输入错误:
:abbr Lunix Linux
:abbr accross across
:abbr hte the
当你输入错误时,它们就会被即时修正。 同样的机制也可以用来输入超长单词。
:abbr pn penguin
:abbr MS Mandrake Software
编辑多个文件
4. 文件通常有多个关联
人们通常不会只编辑一个文件,而是同时编辑多个文件。
前面提过的标签机制,也可以在多个文件之间跳转。常规做法是为一个项目创建标签文件,然后就能在多个文件间跳转。
另一个强大的机制是在多个文件中搜索关键字,使用 :grep
命令。Vim 会把匹配项组成一个列表,并跳转到第一个匹配项。使用 :cn
跳转到下一个匹配项。
Vim 可以拆分窗口,在不同区域编辑不同文件,方便对比、复制等操作。
多窗口还有很多功能,比如预览标签(preview-tag)机制,它会打开一个特殊的预览窗口,光标位置依然在原始文件中。预览窗口中可以包含光标下函数的函数定义等上下文内容。
5. 协同工作
编辑器用来编辑文本,邮件客户端用于收发消息,操作系统是运行程序的,每个程序都有自己的任务,它们协同作战,能力加倍。
比如,你在编写总结,要求不能超过 500 字。你可使用 vip
选中当前段落,并写入到 wc
程序:vip:w !wc -w
,其中的外部命令 wc -w
用来统计单词数量。
再比如,如果想执行当前编辑的 Python 文件,可以执行 :!python3 %
,其中的特殊变量 %
表示当前文件名。
Unix 的精神是每个程序做好自己的份内事,然后通过组合完成更大的任务。
6. 文本是有结构的
通常我们处理的文本都有一些结构,但是这些结构可能和现有的命令要求的不一样。此时,你需要利用编辑器提供的“基础块”,搭建自己的宏或脚本,处理自己的文本结构。
比如,Vim 自带的 :make
命令,可以编译 C 语言,捕获可能发生的报错,我们可以跳转到错误所在的代码位置。如果你使用不同的编译器,错误信息可能不同,你可以调整 errorformat
选项,告诉 Vim 你的错误信息长什么样子,如何提取文件名、行号等关键信息。通过这种方法,你应该可以处理所有的编译器错误。
适配一种新的语言,通常就是设置一些参数,增加一些宏,仅此而已。
打磨工具
7. 内化为习惯
学习开车需要大量练习,学习任何技能都需要投入时间,文本编辑也不例外。我们需要学习新的命令,不断练习,内化为习惯。
但是,你并不需要学习编辑器提供的所有功能,这是一种浪费时间的行为。大部分人只需掌握 10% 到 20% 的命令,就能很好的完成工作。只不过每个人掌握的命令并不相同。
完