Emacs与Vi的40年——计算机世上最漫长的竞争

早期Vi手册封面图(早期Emacs手册封面图,1981)

在这个许多软硬件刚发布就可能面临淘汰的世界里,有两个老对手可以自信的宣称:我们是有史以来寿命最长的应用程序。这两个程序都即将进入他们的第五个十年了,两个都是文本编辑器,用来输入和编辑代码、数据文件、原始的HTML网页以及其他种种东西,两者是不共戴天的仇敌。

他们分别是Emacs和Vi(程序员称为“Vi”),不夸张地说,他们是古老的传奇,最少可以追溯到1976年,比大多数正在使用他们的人年纪都要大。两个程序都是文本编辑器,这意味着他们不是WYSIWYG(所见即所得,what you see is what you get),不像文字处理器(比如Microsoft Word),他们不会格式化屏幕上的文字。编程与文字处理有很大的不同,Emacs和Vi基本的功能都是快速编辑源代码(和其他文本文件)——现在大多已经过时了。但是他们俩以及持续发展了近40年。

从未有两个程序像他们这样如此旗鼓相当,如果你身边有个程序员在用其中一个,那么很有可能他会讨厌另一个。我用Emacs已经有很多年了,但我的妻子却喜欢用Vim(Vi的增强版,Vi Improved),所以我们俩很少讨论编辑器的问题,以免引发所谓的“编辑器之战”。

两者的对立并不限于此,Vi是由传奇人物Bill Joy(也就是他在以后创立了Sun公司,发明了Java)在伯克利大学读研究生时开发的,之后成为大多数Unix系统自带的封闭源代码软件,尽管在1980年代中期开源克隆软件就已经出现并且主宰了今天。Emacs始于美国麻省理工大学Guy Steele和Richard Stallman的一个软件项目,但直到同样具有传奇色彩的Stallman开发出了一个更强大的变种GNU Emacs(19世纪80年代中期,由Stallman牵头的自由软件运动http://www.gnu.org/  兴起,GNU Emacs是其中的一部分),Emacs才逐渐脱颖而出。Vi小巧而灵活,Emacs可拓展却身躯庞大(有个关于Emacs的笑话是这么说的:“Emacs Makes a Computer Slow” 、“Eight Megabytes and Constantly Swapping”,意思就是说Emacs会占用大量内存,使电脑变得缓慢,要知道,那个时候8MB是相当巨大的内存量了)。Emacs及其灵活,如果你愿意的话,甚至可以将它的界面和使用方式配置得和Vi一模一样。

1976年时Vi的用户界面(1976年时Vi的用户界面)

Emacs仿真Vi(Emacs仿真Vi)

Emacs的拥护者说对于Vi,你只需要之道一个命令——三个字符的组合“:q!”,因为这是退出命令。第一次用Vi的时候,我都懵逼了,因为我甚至连怎样输入文本都搞不清,打字只听到噼里啪啦声,箭头连动都没动一下,当然了,我也不知道怎么退出(尴尬)。我的一个同学向我解释了这是为什么,因为Vi是以常规模式启动的,不允许输入新的文本,只能够编辑现有的文本。你需要先键入“i”以进入输入模式,在输入模式下才可以正常输入文本。按下Esc键,就可以回到常规模式,然后我就键入了“:q!”(也是刚知道),慌忙地切换到了Emacs。

这个貌似残酷的介绍也反映了Vi的学习曲线,一旦你掌握了Vi神秘的命令集(http://www.emerson.emory.edu/services/editors/vi/vi.html),它就会变身为一个强大的、如闪电般快速的编辑器。我相信专业的Vi使用者能够让Vi比其他所有的程序都更快,不仅是因为相关命令已经被极度压缩,非常简短,而且Vi本身的内存开销非常非常小,所有的任务几乎都能实现瞬时响应。Vi是无可匹敌的,Larry Marburger将其称为“文本手术”。倒退5个单词?“5b”!删除后面6行?“d6j”!在文件中的每一行放置匹配的引号?只需按下18个按键:“:%s/\(^\|$\)/\”/g”。

巧合的是,大多数人看到这串命令时反映都跟我一样,骂骂咧咧( obscenicons,无中文翻译,意义参看http://languagelog.ldc.upenn.edu/nll/?p=2483,大致就是诅咒的意思)。我对这些命令比较生疏,写出这串组合花了我几分钟的时间,但真的不骗你,Vi的老手只需要几秒钟。

Vi小抄(记住这份Vi小抄,你就能达到闪电般的速度)

Vi出生的时代,计算机非常慢以至于你不希望任何东西造成不必要的延时,比如额外的按键或图形细节。Joy说Vi是为那些有网络连接的电脑定制的(那时候显示文本的速度还赶不上人阅读的速度)。就像Joy在1999年所说,“我试图让他能够在一个300波特率调制解调器上使用……Vi被优化到你在编辑的过程中就能明显感受到它惊人的效率”。即使到现在,Vi无与伦比的效率也使它保有相当多的粉丝,对他们来说,丝毫的延迟就会让他们发狂(比如软件工程师)。Vi是少有的几个使用过程中甚至不需要移动手位置(标准打字姿势)的程序,甚至连箭头键也不需要(用H、J、K、L就可以)。

Emacs,从另一方面来说,提供了一个更加传统和方便的编辑环境,带有基于合理直觉的组合命令:Ctrl-S用来搜索,Ctrl-X Ctrl-C将文件保存到磁盘上并退出,等等。Emacs为用户提供了更多的反馈,不容易像Vi那样受到新手的吐槽。Emacs还提供了漂亮的文本格式,以及为各种语言的程序员准备的众多有用的功能。

但是,如果Emacs止步于此的话,它也不会变得如此特别。Emacs的过人之处在于它的灵活性,你可以自定义所有东西。例如,大多数命令都是以Esc或者Ctrl键开头的,包括Esc-X——可以自动补全所有的命令。但是,这两个按键常被程序员指责谋杀了他们的小拇指,因为重复性地使用小指以致于小指劳损了;甚至在我写这篇文章的时候,小指还有刺痛感。但对于Emacs来说,这不会成为一个问题,因为Emacs可以轻松的完成键映射绑定,所以你可以把Ctrl的键改为CapsLK键,Esc键改为Alt键。除此之外,几乎所有的命令都可以被映射到任何键或组合键,程序员可以在很微小的细节方面进行定制以满足个人特定的需求。上帝保佑那些那些试图用你的Emacs的笨蛋不被气死,当然那不是你的问题,如果你也曾尝试用其他人的Emacs你就知道了。

Emacs有自己内部的编程语言——Lisp的一个变种,能够让你编辑程序中的所有功能:绝不仅仅是文本编辑和格式化功能,而是真正所有的东西,它是一个文件系统,一个时钟,一个Web浏览器,一个文字冒险游戏,一个即时通讯软件等等等。如果你愿意的话,你可以在Emacs中完成大部分的日常工作,就像我所知的许多Emacs忠实粉丝一样——你完全不需要切换窗口!相比Vi,Emacs的初始学习曲线更加平滑,但曲线永远不会结束,只有陷入不断增长的复杂性,Emacs的无穷可能性会一直消耗你的生命和生产力。

这么看来,两大交战程序的特点就很明晰了。Vi以优雅著称,帮助你在尽可能少的移动手指的情况下完成任务;而Emacs,支持自定义,支持拓展,包罗万象,非常灵活,能够满足你几乎所有的特殊要求。Vi标准化的完善和Emacs抽象的普遍性是两个工程师的最高理想。这两个程序的战争也告诉我们这些想法与特性往往是不兼容的。

有时候这两个程序的选择要归结为个人的性格:是否是愿意屈从于一个刚性的但更受欢迎的系统(Vi),还是愿意自己创造一个奇特的定制化环境(Emacs)。Tim O‘Reilly在他自定义设置的Emacs无意中被毁以后,开始转向Vi。他决定要遵循“Vi崇拜”,赞美Vi的普遍性,“不管我用什么系统,它都在那里,不离不弃”,(他也说,“我并不想火上浇油”)。而Linux的发明人Linus Torvalds,不仅更喜欢Emacs(准确的说,是精简版的Emacs,MicroEmacs),甚至还修改了Emacs的底层代码以使它更符合自己的需求。

尽管Emacs能够仿真Vi,但性能上却不能跟真正的Vi比。即使最激烈的Vi诋毁者也不会否认,Vi比Emacs更快(Vi的狂热支持者甚至说,你可以在启动Emacs的时间内学习Vi的命令集)。事实上,Emacs远远快于其他图形化编辑器,例如Eclipse和Microsoft Visual Studio,但是Vi党仍然表示,找不到任何理由为了Emacs的臃肿而牺牲其效率。而Emacs党则回应称,一旦你启动了Emacs,就最好不要停下来,直到永远,让Emacs成为你的操作系统。

作为操作系统的Emacs(作为操作系统的Emacs)

所有程序员逗不可避免要在不同的操作系统上工作,也许还是一个没有安装Emacs的操作系统(恐怖),到那个时候没有Emacs将会严重的拖慢你的工作速度,所以许多Emacs用户都会勉强地学习一些Vi的基础知识,以便在不得以的情况下使用。而相反,Vi的固执在近些年已经有所软化,像它的克隆软件Vim,也新增了诸多新的特性和拓展,提供了那些使得Emacs更受欢迎的主流编辑功能(包括俄罗斯方块)。

现在,两个曾经的敌人也已经逐渐走向趋同。偏爱其中一种常常是不实际不理智的,专注与灵活,哪个更贴近你的心?如果房子着火了,你会首先抢救出什么东西?软件工程在很大程度上也是应对不完美、不相容的一门艺术,做出妥协绝不是纯粹的功利主义,而是反映出了一个工程师的审美理念,什么是美的,或者至少——什么是丑的。