我是如何从 vim 转向 emacs 的

以前,我多次试图从 vim 转变到 emacs 都失败了。原因很多,主要 原因是 vim 的确一个很强大的 editor 不愧为 emacs 的主要竞争对 手,vim 很多强大的功能,很难在 emacs 中找到相应的功能,那个 时候还没有这个版,如果有的话,情况会好一些, 还有一个原因就是 我周围几乎没有人用 emacs ,现在也是。

emacs 的入门比较 vim 要困难很多,我指的入门不是指简单的使用, 而是高效的使用。vim 的很多操作几乎不需要配置就可以完成了,但 是如果离开我那些复杂的 .emacs 文件,我认为 emacs 并不比 vim 好。有了我的 .emacs , emacs 绝对是最好的 platform (not only an editor) ,因为他是我的软件,一些我常用的功能,都是按照我 的方式工作的,而且我可以随时实现我喜欢的功能,也许别人不喜欢 这样的操作,但是我喜欢,我可以让 emacs 让我喜欢的方式操作。 几乎没有其它软件可以做到这一点。

我转变到 emacs 是一个痛苦和偶然的过程。我曾经煞有介事的“学 习” emacs , 写了很多笔记,现在看来,很傻,emacs 不是学出来 的,是用出来的,很多功能不是用脑子记住的,而是用手记住的,我 们不得不承认,有的时候肌肉的记忆能力,要比脑子的记忆能力强, 而且快速,实用。很多体育运动员不就是用大量的训练提高肌肉对动 作的记忆吗?

一次偶然的机会我发现了几个 vim 无法代替的几个功能,于是我开 始真正喜欢 emacs 了。

首先是编写 TeX 文件的时候,很多数学符号可以快速的输入,可以 方便的生成 dvi 文件,可以快速的输入 TeX 特有的特殊符号。

然后是 Python mode ,他是非常好的 Python 的 IDE ,可以很容易 的编写 Python 程序,尤其是 Python 程序中用缩进来表示语法结构, 在 Emacs 中很容易处理缩进。很容易把一段代码放入到Python 的解 释器中执行,然后在解释器中交互的测试程序。参见 我的Python 学习笔记

一个编辑 C or C++ 的时候的一些功能,例如 auto insert 功能, hungry delete, M-SPC(M-x just-on-space) indent 功能 (TAB) , 在 emacs 中写出来的程序,是最漂亮的格式。最重要的是还可以选 择自己喜欢的 c style 。 当然 vim 中也可以,但是默认的是用 tab 键格式化 ,这样的缺点就是不能保证程序在所有的编辑器中都 是一样的效果,但是我以前也用 TAB 来 indent ,原因是我不愿意 输入很多 space 。而且 vim 对重新 indent 一段代码的功能也不是 很好,尽管 g= 等等键也可以工作,但是不如 emacs 中的好。

vim 中的很多编辑命令要比 emacs 快的多,只要输入很少的键。

但是, 我认为中 emacs 的理念是,有很多工作,做好不要让用户 记住那些快键,按照用户的习惯,猜想用户(主人)的意思,默默的 做好(讨好)用户就行了。

例如,在 C 中,我们习惯用 tab 键来 indent 程序。那么就用 tab 键来 完成 M-x indent-line 的功能。我们经常在输入分号之后, 输入一个回车,那好,emacs 就根据上下文猜测应该回车的地方,自 动回车。你想删除很多空格,那好,emacs 就会根据上下文,只留下 一个空格(M-x just-on-line) 或者空行(M-x delete-blank-line) ,如果你在只有一个空行下还要 M-x delete-blank-line ,那么就 把single blank line 也删掉。

还有的功能也很好用。

C-c C-c (M-x comment-region)
C-u C-c C-c uncomment-region

还有自动补齐右边括号,补齐引号的功能,还有补齐大花括号的功能。 参见Emacs 中自动添加有半边括号的功能写C程序,输入左大花扩号自动补齐很多东西

还有 abbrivate 扩展的功能。

还有 fly spell 的功能。 emacs 知道主人是个粗心的人自动提 示主人错了,但是 emacs 从来不把主人当傻瓜,不会自作聪明的改 动,只有主人真的承认说,我错了 (按M-$)(注:我记不住具体的 M-x 命令了,可以用C-h k 查一个键的bind 的函数,记做 help key bind , 也可以用 C-h w 记做 help where, 查找一个函数的快键是 什么 ) ,emacs 就提示很多可选的单词,供主人选择。 我记得有一 个著名的把用户当作傻瓜的软件,总是把句子的行首单词 Capitalize,而且自动把他认为错了的单词改过来,每次我都要费尽 心机想办法,怎么把这个功能关掉。

还有 auto fill 的功能, M-q 也总能干正确的事情。

还有 version control 的功能,emacs 几乎不用主人亲自备份文件了, 他知道应该在合适的时候,备份文件。

还有 auto insert 的功能,他会自动根据环境,把当前的文件 增加可执行权限,参见在保存文件的时候,会自动给脚本增加可执行权限

还可以自动增加

#!/bin/bash or #!/bin/perl #!/bin/python 。
参见Emacs 在创建文件的时候,自动添加 template 的内容

header.el的扩展还可以自动插入和更新 C 文件中的开头的一些 信息,包括文件名称,创建日期,改动次数,纪录谁在什么时候为什 么做了修改。还有公司信息,作者信息,版权信息等等。参见 轻轻松松为源 程序增加文件头信息

还有 emacs 有很多程序无缝结合 ,如 python, perl, octave(matlab), gdb, pydb 等等,emacs 是最好的 IDE 了。

总之,驯化了的 emacs 是你的忠实的奴仆,他会按照主人的方式 工作,猜想主人的意图。

然而,有的时候 emacs 是奔放的野马,总是难以驾驭,要想emacs 按照主人的意志工作,那么主人就有义务详细的告诉他该如何工作。

有两种办法,一种是向其他主人学习,请教,按照他的办法驯化 emacs 。

另一种办法是掌握 emacs 的高级用法,只有了解他的语言, Elisp (Emacs Lisp) ,明白了 emacs 的语言,才能够和 emacs 很 好的交流,沟通, emacs 是一个很听话的孩子。

如果要融入 emacs 的文化,或者叫理念,甚至叫宗教, 那么就 要 Hack 他的程序,了解他的五脏六腑,做一个 hacker。(注: hacker is NOT cracker ) 除了安装emacs-x-xx.rpm 还要安装 emacs-el.x-xx.rpm , 然后用 M-x find-function 看任何一个函数 是如何实现的。

浏览了一会儿,你会感到什么是自由软件,什么是真正的自由。 只要你愿意,你可以探索任何一个功能是怎么实现的。

使用其他的软件的时候,我总是在想办法发现软件提供给我什么 功能,我怎样按照软件定义好的方式工作,我怎么去适应软件。

如果运气不好,碰到一个自以为是的软件,我会觉得被软件的作者 愚弄。

如果运气再差一点,我会觉得被软件的作者侮辱,因为他把我 当成傻瓜。

当然,也有运气好的时候,例如 vim ,他的编辑方式是最快的方 式。

但是 emacs 不同,使用 emacs 的时候,我会想我喜欢用什么样 的方式完成某个功能,大多数的情况,都可以简单的用 global-set-key, or local-set-key 解决掉。如果功能很复杂,就 查找一下是不是有人实现过了, emacs 的社区中有很多好心人, www.emacswiki.org 是一个好地方。如果没有人实现,那么就自己写 一个,然后贴到网上去。

开放,自由,这就是 emacs 。

emacs 总是想办法如何适用用户的方式,当然,缺点就是,初看 上去 , emacs 不是很友好, 用户需要学习如何配置emacs 。

现在我很喜欢摆弄 emacs , 我知道,只要我想得到,emacs 一般是 可以做得到, 当然我想的要合理,我想买彩票中500万,emacs 肯定做不到 , 而且还不能和其他你需要的功能冲突。

有一项功能我一直没有想办法办到,就是类似 source in sight 的自动搜索一个函数的 caller ,自动 成员变量补全,class browser 等等。 这个功能很难,因为他要包含语言的语法语义分析。 C++ 中的 template , typedef , #define #if , inline function, inner class (or structure, enum) , name space 等等的语言特性,增加了其难度。

尽管 semantic 号称可以,但是和 source in sight 还有差距。 我用了几次,不好用, ECB 也是不伦不类。

我认为 semantic 的目标太大了,他要容纳所有语言的语法语义模糊分析的功能, 这个很难,尽管他的作者是大名鼎鼎的 eric 。

我还是很喜欢 semantic ,因为我相信他行,于是我试图 hack semantic ,实现那些功能,尽管自动补全成员变量的功能, 勉强可以了,但是其他复杂的功能,还是很难实现。semantic 太复杂了。

但是一有时间,我还是喜欢看上 semantic 几眼。

我这篇文章是用 notepad 编辑的,于是顺便列举一些 emacs 和 notepad 类似的功能,参见类似Notepad 基本操作快速入门