我最近无意中发现一个名为Intel HEX的文件格式。据我所知,Intel HEX文件(使用.hex后缀)是通过将二进制文件变为十六进制数据来降低它的不可读性。明显它们由那些编写微控制器程序或者将数据刻录到ROM中的人使用。无论如何,当我首次使用Vim打开一个十六进制文件,我感到震惊。至少对我来说,这种文件格式非常深奥,但是Vim已经对其了如指掌。每行十六进制文件都分成不同区域——Vim已经先一步为每一个字段都标记了不同的颜色。set ft? 我敬畏地问道。filetype-hex,Vim得意地回答。
Vim无处不在。这么多人都在使用它,像对十六进制文件的支持并不值得惊讶。Vim是Mac OS的预装程序,而且在Linux世界广泛应用。它甚至对讨厌它的人来说都很熟悉,由于很多热门的命令行工具都默认让用户进入Vim,以至于那些未入门的人会被困到Vim中,这已经变成了一个热门问题。有一些主流网站,包括Facebook,当你按下j键之后,页面会滚到下面,而当按下k键则会滚到上面——Vim在数字文化中的广泛传播达到了意想不到的程度。
Vim仍然很神秘。例如,它不像React,每个人都知道它是由Facebook开发和维护的,Vim没有明确的作者。尽管它是如此的普遍和重要,却没有任何类型的委员会或组织来为Vim做决策。你可能花了几分钟来浏览Vim网站,但是却找不到关于谁创建了Vim或者为什么创造它的有效信息。如果你启动Vim时没有提供文件参数,你会看到Vim的启动信息,说的是Vim是由“Bram Moolenaar等人”开发的。但是没有更多信息。谁是Bram Moolenaar,他的神秘同盟都有谁?
当我们在提问的时候,也许更重要的是,为什么退出Vim需要输入:wq?没错,这是一个“写(write)”操作,后面还跟了一个“退出(quit)”操作,但是这并不是一个特别直观的惯例。谁来决定当复制文本的时候应该调用“复制命令(yanking)”?为什么:%s/foo/bar/gc是“查找并替换”的缩写?Vim的用法太随意了,看起来没有好好决策,但是它们到底源于何处?
情况往往如此,问题答案源自于古老的计算机构,贝尔实验室。从某种意义上来说,Vim只是一个软件——名为“wq文件编辑器”——的最新版本,它从Unix时代开始已经持续开发并完善。
Ken Thompson 写了一个行编辑器(Line Editor)
1966年,贝尔实验室骋请了 Ken Thompson。Thompson 刚刚在加州大学伯克利分校获得了电子工程和计算机科学硕士学位。在那里,他使用了一个叫 QED 的文件编辑器,这是为 1965 年至 1966 年间的伯克利分时系统编写的。1Thompson 抵达贝尔实验室后所做的第一件事就是为麻省理工学院兼容的分时系统重写了 QED。后来他为 Multics 项目编写了另一个版本的 QED。在此过程中,他扩展了程序,以便用户可以搜索文件中的行并使用正则表达式进行替换。2
Multics 项目,跟伯克利分时系统(Berkeley Timesharing System)一样,旨在创建一个商业上可行的分时操作系统,由麻省理工学院、通用电气和贝尔实验室之间协作进行。AT&T 最终认为该项目前途堪忧而选择退出。Thompson 和贝尔实验室的研究员 Dennis Ritchie,当时没有访问分时系统的权限,失去了这种系统带来的“交互式计算感”,于是着手创建自己的版本,最终在 1969 年 8 月被称为 Unix 3。当时他的妻子和年少的儿子正在加里福尼亚度假,Thompson 将新系统的基本组件整合到一起,分配开发操作系统、shell、编辑器、汇编程序的时间为每周一项。4
编辑器被命名为 ed。它基于 QED,但不是一个完全的重新实现。Thompson 决定放弃某些 QED 特性。对正则表达式的支持被削减,因此只能理解相对简单的正则表达式。QED 允许用户通过打开多个缓冲区并同时编辑多个文件,但是 ed 同时只能使用一个缓冲区工作。而且 QED 可以执行一个包含命令的缓冲区,而 ed 则不会这样做。这些简化是需要的。Dennis Ritchie 表示,没有 QED 的高级正则表达式并“没有太大的损失”。5
ed 现在是 POSIX 规范的一部分,所以如果你有一个符合 POSIX 标准的系统,你可以将它安装到你的计算机上。这值得一试,因为许多 ed 的命令都是今天的 Vim 的一部分。举例来说,为了将缓冲区的内容写入磁盘,你需要使用 w 命令;为了退出编辑器,你需要使用 q 命令。这两个命令可以同时写到同一行 —— 即 wq。与 Vim 相似,ed 是一个模态编辑器;从命令模式进入输入模式,你可以使用插入命令(i),追加命令(a),或者修改命令(c),取决于你要怎样去改变你的文本。ed 也引入了 s/foo/bar/g 的语法,用来查找和替换,或者“替换”文本。
有这么多的相似之处,你可能认为一般的 Vim 用户使用 ed 也没问题。不过 ed 在其它一些重要方面却一点也不像 Vim。ed 是一个真正的行编辑器。它是在电传打印机的时代编写并广泛使用的。当 Ken Thompson 和 Dennis Ritchie 在 Unix 上进行编码时,他们看起来是这样的:
ed 不允许你在打开的缓冲区中的其它行之间进行编辑和移动光标,因为每次对其进行更改时,ed 都需要重新打印整个文件。1969 年的 ed 还没有清空整个屏幕内容的机制,因为那时的屏幕是一张纸,而且所有需要被打印的将会使用墨水打印。如果有必要,你可以使用列表命令(l)告诉 ed 打印出一系列的行,但大部分时间你都在操作你看不到的文字。因此,使用 ed 有点像带着一个不怎么亮的灯在一所黑暗的房子里试图找到一条路径。你只能一次看到这么多,所以你必须尽力记住一切都在哪里。
这里有一个 ed 会话的例子。我已经添加了注释(在#号之后的)来解释每一行的目的,如果这些注释被实际输入到了 ed,则不会将它们识别为注释,而且可能会出错:
[sinclairtarget 09:49 ~]$ ed
i # Enter input mode
Hello world!
Isn't it a nice day?
. # Finish input
1,2l # List lines 1 to 2
Hello world!$
$
2d # Delete line 2
,l # List entire buffer
Hello world!$
Isn't it a nice day?$
s/nice/terrible/g # Substitute globally
,l
Hello world!$
Isn't it a terrible day?$
w foo.txt # Write to foo.txt
38 # (bytes written)
q # Quit
[sinclairtarget 10:50 ~]$ cat foo.txt
Hello world!
Isn't it a terrible day?
正如你所看到的,ed 并不是一个很方便的交互式程序。
Bill Joy 写了一个文本编辑器
ed 对于 Thompson 和 Ritchie 来说已经足够用了。不过其他人觉得它很难使用,并因其成为 Unix 对新手来说很困难的一个特别典型例子而出名。6 1975年,一个叫 George Coulouris 的人在伦敦玛丽皇后学院安装的 Unix 系统上开发了 ed 的一个改进版。Coulouris 利用他在玛丽皇后学院得到的视频显示来编写他的编辑器。Coulouris 的程序允许用户在屏幕上编辑某一行,在这一行上进行码字(想像一下在一行上使用 VIM)。Coulouris 将他的程序称为 em,或者“普通人的编辑器”,这是他在 Thompson 访问了玛丽皇后学院后受到的启发,据说 Thompson 看到了 Coulouris 构建的程序,然后驳回了它,并说他在编辑的时候不需要看文件的状态。7
1976年,Coulouris 带着 em 到了加州大学伯克利分校,在这里,他在计算机学院度过了一个夏天。这距 Ken Thompson 离开加州大学伯克利分校到贝尔实验室工作已经整整十年。在加州大学伯克利分校,Coulouris 遇到了 Bill Joy,一个在伯克利软件发行版(BSD)工作的研究生。Coulouris 向 Joy 展示了 em,Joy 从 Coulouris 的源代码开始,开发了一个 ed 的改进版,被称为 ex,意思是“扩展的 ed”。ex 的 1.1 版本与1978年第一版 BSD Unix 捆绑在一起。ex 在很大程度上与 ed 兼容,但是它添加了两个模式:一个“open”模式,它可以进行单行编辑,就像在 em 中一样,还有一个“visual”模式,接管了整个屏幕,并启用了我们今天习惯的整个文件的实时编辑。
对于 1979 年发布的第二个 BSD 版本,引入了一个名叫 vi 的可执行程序,它只能在可视模式下打开 ex。8
ex/vi(以下称为 vi)定义了现在我们使用 Vim 的大多数规则,这些规则已经不是 ed 的一部分。Joy 使用的视频终端是 Lear Siegler ADM-3A,它有一个没有光标的键盘。取而代之的是在 h,j,k,和 l 键的地方绘制了一个箭头,这就是 Joy 在 vi 中使用这些键来移动光标的原因、ADM-3A 键盘上的退出键也是今天我们可以找到 tab 键的地方,它解释了如何为这样一个难以触及的键分配了一个与退出模式相同的操作。命令的前缀冒号“:”也是来自于 vi,在常规模式下(即运行 ex 后进入的模式)使用冒号“:”作为提示。这解决了关于 ed 的长期抱怨,曾经的 ed 在这种情况下是不会提示用户的。在可视模式下,保存和退出现在可以输入经典的“:wq”命令。“Yanking”和“puts”标记以及用于设置选项的 set 命令都是原始 vi 的一部分。今天我们在 Vim 中进行基本的文本编辑使用的功能大部分都是 vi 的功能。
vi 是除了 ed 之外唯一与 BSD Unix 捆绑在一起的文本编辑器。那时,Emacs 需要花费上百美元(在GNU Emacs之前),所以 vi 变得非常流行。但是 vi 是 ed 的直接后裔,这意味着没有 AT&T 源码许可证就无法修改源代码。因此激励了一些人去创建 vi 的开源版本。STEVIE(VI爱好者的 ST 编辑器)出现于 1987 年,百度排名查询,Elvis 诞生于 1990 年,nvi 出现于 1994 年。其中一些克隆的版本增加了额外的功能,如语法高亮和分割窗口。Elvis 尤其将它的许多功能都纳入到了 Vim 中,因为许多 Elvis 用户都为此做出了努力。9
Bram Moolenaar 编写了 Vim
“Vim”,现在可称为“Vi Improved”(Vi改进版),原来也被称为“Vi Imitation”(Vi模拟版)。与许多其它 vi 克隆版一样,Vim 的初衷是尝试复制 Vi,使其在不支持 Vi 的平台上使用。Bram Moolenaar,一位在荷兰芬洛一家复印公司工作的软件工程师,想要为他的全新 Amiga 2000 提供类似 vi 的东西。Moolenaar 已经习惯于在他的大学的 Unix 系统上使用 vi,现在已经熟练到“就像在使用他的手指”。10 因此,在 1988 年,使用现有的 vi 克隆版 STEVIE 作为起点,Moolenaar 开始开发 Vim。
Moolenaar 使用 STEVIE,是因为 STEVIE 之前曾出现在 Fred Fish 磁盘上。Fred Fish 是一名美国程序员每个月选择 Amiga 平台上最好的开源软件,放到一张软盘上并寄出。任何人都可以请求索取磁盘,而仅仅只需要邮费。STEVIE 的若干个版本在 Fred Fish Disk 上被发布。Moolenaar 使用的版本已在 Fred Fish Disk 256 上发布。11(令人失望的是,Fred Fish Disk 似乎与 Freddi Fish 无关)。
Moolenaar 喜欢 STEVIE,但是他很快发现缺少了许多 vi 命令。12 因此,对于 Vim 的第一个版本,Moolenaar 将 vi 兼容性作为他的首要任务。其他人编写了一系列 vi 宏,当通过正确的 vi 兼容编辑器运行时,可以解决随机生成的迷宫。Moolenaar 能够让这些宏在 Vim 中运行。1991年,电视剧大全,Vim 首次发布于 Fred Fish Disk 591 中,被称为“Vi Imitation”。13 Moolenaar 添加了一些功能(包括多级撤消和编译错误的“quickfix”模式),这意味着 Vim 超越了 vi。但是 Vim 在 1993 年通过 FTP 发布 Vim 2.0 之前,一直保持着“Vi Imitation”的名字。
在各种互联网合作者的偶尔帮助下,Moolenaar 为 Vim 增加了一些稳定的功能。Vim 2.0 引入了对 wrap 选项的支持以及通过长行文本的水平滚动。Vim 3.0 增加了对分割窗口和缓冲区的支持,这一功能的灵感来自 vi,克隆了 nvi。Vim 现在还将每个缓冲区保存到交换文件中,以便编辑后的文本可以在崩溃中存活。Vimscript 首次亮相于 Vim 5.0,同时支持语法高亮。一直以来,Vim 的受欢迎程度都在增长。它被移植到 MS-DOS,Windows,Mac,甚至 Unix,在以上操作系统与原始的 vi 竞争。
2006年,Vim 被《Linux Journal》读者选为最受欢迎的编辑工具。14今天,根据 Stack Overflow 的 2018 年开发者调查,Vim 是最受欢迎的文本模式(即终端模拟器)编辑器,25.8% 的软件开发者使用它(和 40% 的系统管理员/DevOps 工程师)。15有一段时间,在20世纪80年代后期和整个20世纪90年代,程序员发起了“编辑器战争”,使得 Emacs 用户与 vi(以及最终的Vim)用户进行了对抗。虽然 Emacs 肯定还会继续发展,但有些人认为编辑大战已经结束,Vim 赢了。162018 Stack Overflow 开发者调查显示这是真的;只有 4.1% 的受访者使用过 Emacs。
Vim是如何变得如此成功的?显然人们喜欢Vim所提供的功能。但我认为,Vim背后的悠久历史表明它拥有比其功能集更多的优势。Vim的代码库可以追溯到1988年,当时Moolenaar开始致力于此。另一方面,“wq文本编辑器” – 一个关于Unix风格的文本编辑器应该如何工作的更宽泛视角 – 可以追溯到半个世纪之前。“wq文本编辑器”有一些不同的具体表达方式,但部分归功于Bill Joy和Bram Moolenaar对后向兼容性的特别关注,随着时间的推移逐渐积累了好的想法。从这个意义上说,“wq文本编辑器”是运行时间最长、最成功的开源项目之一,享用了计算机世界一些最伟大的思想家的贡献。我不认为“初创公司 – 抛弃所有先例 – 并创造 – 破坏性 – 全新-软件”的发展方法必然是坏事,但Vim提醒世人:协作和增量方法也可以产生奇迹。