这段录像像一枚时间胶囊:4:3 画幅,投影幕上是 Vim 7,一屋子听众正在了解当时还很新的补全功能。Bram Moolenaar 2007 年 2 月在 Google 的这场演讲,却比一趟旧软件功能巡礼更经得起时间。其持久主题超出了某个特定的按键绑定,落在一个更宽的问题上:人怎样精进一门以工具为媒介的技艺,同时让改进始终服务于工作,避免它本身变成一种爱好。[1][2][5]
Moolenaar 把这个问题收束成一条循环:发现低效之处,找到更快的做法,再让新做法成为习惯。顺序很重要。起点放在你真实从事的工作上,绕开别人列出的“必知”命令清单;终点落在练习上,发现新方法只是中途一步。只见过一次的巧妙命令仍是零散知识;在恰当时刻想起一个朴素命令,日常反复操作的方式会随之改变。[1][2]
所以,即使你只把 Vim 当作另一款编辑器里的兼容层,甚至日常使用的编辑器与 Vim 毫无关系,这场演讲仍值得看。例子带有鲜明的 Vim 印记,其中更有力量的观念却能迁移到别处:改进反复出现的编辑动作,选择足以消除阻力的最小手段,并在回报消失时停止优化。
约 4:00:真正的界面是一条反馈回路
统领全场的幻灯片在四分钟左右出现。“发现低效”排在第一,因为缺少观察的优化只能靠猜测。“找到更快的做法”排在第二,因为给麻烦起了名字,麻烦依然存在。“让它成为习惯”排在最后,因为在反复练习降低想起新做法的成本之前,旧路径在当下仍然省力。[1][2]
这条循环也给两种常见的失败方式设下护栏。第一种是眼前文档带着紧迫感,人因而拒绝停下来,日后的每份文档便继续承担同一份代价。第二种是试图彻底学会编辑器的每项功能。Moolenaar 的配套材料提醒,掌握全部功能与高效工作分属两件事:闲置知识也有习得成本。[2]
从工程角度,可以按三个属性给阻力排序:频率、代价和可重复性。每天要笨拙执行二十次的动作,比每年只用两次的炫目技巧更值得先处理。结果确定的编辑动作,比高度依赖判断的动作更适合自动化。这套排序源自对 Moolenaar 循环的工程解读,与基准测试结论有别。方法的本意始终是减少可避免的付出;只有总成本随之下降时,少按键才算收益。
约 9:30:用目的地命名取代距离计数
第一个习惯是“快速移动”。Moolenaar 从察觉导航迟缓,转向寻找更好的路线。约 9:30,幻灯片已经讲到搜索高亮和基于单词的搜索;再往后一点,演示用折叠把大文件收成若干有意义的区域。[1][2]
贯穿其中的概念是可寻址性。连续移动光标描述的是距离:向下十七行,再跨过四个单词。搜索、分隔符配对、marks(标记)、tags(标签)和折叠描述的是目的地:下一个匹配项、成对的花括号、命名位置、隐藏区域。Vim 用户手册也体现了这一区分,把移动、搜索、编辑、重复、折叠和程序导航组织成彼此关联的系统,超出了平铺快捷键清单的范围。[3]
语义跳转的优势也有条件。目标已经在近处清晰可见时,普通移动命令的心智成本最低。当计数或扫视反复出现,改进才开始显现,此时文本本身可以充当坐标系。旧折叠演示留下的长期启示是“给反复抵达的目的地一个稳定名称”;把它概括为“始终折叠代码”,会缩窄这段演示的意义。
从 12:00 到 16:00:“同样的内容只输入一次”是一条阶梯
第二个习惯从 12:00 左右开始,起点是一个敲起来很慢、又容易敲错的别扭标识符。Moolenaar 给出的应对方式逐级增强:先用补全复用已经出现的单词,再在语言上下文能够给出更窄的候选范围时,使用能够感知文件类型的全能补全(omni completion)。全能补全的演示约在 15:00 出现。[1][2]
把这一节视作阶梯,它的价值超过一次功能比较。Vim 可以复用上一次修改、补全一个 token、展开缩写、回放寄存器内容,或者运行脚本。这些手段各有能力范围,也各有设置成本、可见性和出错波及范围。用 . 重复一次安全的修改,成本低且只作用于局部。录制的宏覆盖范围更广,过程依然可检查。永久映射或脚本能够省下更多工作,同时也会变成一份配置,需要有人记住并维护。[3]
实际运用时,只有一段重复操作带来的收益足以抵偿成本,才值得逐级升级。先使用编辑器现成的复用功能,等操作序列的形态稳定后,再把它提升为自动化。若例外占据多数,就把人的判断留在循环中。这也是演讲对工具尝鲜风气的一次悄然抵抗:如果反复出现的问题只是重输屏幕上已有的单词,编辑器内置的单词补全已经足够;安装更庞大的补全系统与改进无关。
从 20:00 到 31:00:文档的范围超出缓冲区
约 20:00,“文件很少单独出现”扩大了工作的基本单元。示例依次展示 tags、用于跟随文件名的 gf、include 文件搜索和 quickfix 窗口。几分钟后,:make 或 :grep 的结果已经变成用户可以逐项跳转的条目。接近 30:00 时,一个新示例把嘈杂的 lint 输出当作结构化文本,用一个小型清理函数过滤反复出现的警告模式,省去逐行人工扫视。[1][2]
这些片段揭示了第二种可寻址性:把外部系统的组织关系转成编辑器可以抵达的位置。tag 把标识符连到定义,quickfix 条目把诊断输出连到文件与行,通常还包括列。这两项功能只要求编辑器读入外部引用,编译器、代码库和编程语言可以继续留在编辑器之外。Vim 正是在这样的系统接缝处发挥作用。[3]
lint 过滤器也带来一重警示。这类输出可以转换,但过滤熟悉噪声的规则也有一项风险:含义已经改变的警告会被一并隐藏。一旦清理命令进入惯常流程,它就该接受与任何小程序相同的审查:匹配模式要窄,输出要可见,还要能轻松查看哪些内容被移除。
现代语言服务器和 IDE 带来了更丰富的体验,但系统分工的原则仍有价值。需要依次追问:哪个系统是权威来源,什么表示形式进入编辑器,以及跳转能否复现。有构建结果作为依据的可点击诊断,比一套隐藏答案来源的巧妙界面更可靠。2007 年的命令已有年代感,这项集成检验仍然有效。
约 36:00:打磨工具要回应已经观察到的阻力
第七个习惯以“磨利锯子”为题,把折叠、缩进、插件、网络编辑和脚本归在一起。约 36:00,清单中的项目跨度很大,容易让人把它读成一份永远配置下去的邀请。前面的三步循环已经限定了打磨工具的起止:从已经观察到的阻力开始,到替代办法变得可靠时收尾。[1][2]
这条界线对团队尤其重要。个人映射对编写它的人几乎没有成本,对其他人却晦涩难懂。共享脚本需要命名、审查、文档和负责人。因此,编辑器自动化也应按小型内部工具的标准来评估:运行频率有多高,出错时会发生什么,行为是否可见,以及周边工作流变化后由谁修复。
Vim 的生产力价值因人而异。Linux Foundation 的入门指南明确指出学习要付出成本,也提到,若缺少持续的文本编辑或系统管理需求,放弃这笔投入是合理选择。[4] Vim 内部同样如此:一个始终无法在需要时被想起的命令,摩擦仍在,只是转移到了记忆里。
放到今天,这场演讲最适合拿来做一项为期一周的实验。找出一个反复打断思路的编辑动作,再找一种更小、更安全的表达方式。刻意使用它,直到它融入日常,或者证明保留它的代价过高。只有当它在真实工作中减少了付出或错误,才把这项改进留下来。“掌握你的编辑器”这句承诺更加耀眼;这里的承诺朴素一些,也可信得多。
来源
- Google,《高效文本编辑的 7 个习惯 2.0》:Bram Moolenaar 2007 年 Google 演讲,本文嵌入视频与时间点的参照来源。
- Bram Moolenaar,《高效文本编辑的七个习惯 2.0》(2007 年 2 月 13 日):作者托管的演示幻灯片与讲者笔记存档副本。
- Vim,《Vim 用户手册:目录》:通往移动、编辑、重复、折叠、补全、标签与 quickfix 文档的官方入口。
- Linux Foundation,《经典系统管理:Vim 101——Vim 入门指南》(2022 年 5 月 14 日):独立入门资料,也说明何种需求值得投入学习成本。
- Google Developers Blog,《Google 开源开发者演讲系列:Bram Moolenaar》(2007 年 2 月 5 日):活动、讲者、场地与演讲来源记录。
- Sebastian Bergmann,《2007 年的 Bram Moolenaar》:Wikimedia Commons 收录的历史照片与来源记录。