【GNU/Linux实战手记之Emacs篇 下——Emacs是个IDE】
作者:叶魏彬 MSN:fritz_yea@hotmail.com
Copyright(C)Free Software Library,Org(http://yea.xiloo.com)
本文依照GNU Free Document Lience发布,任何人都可以将本文原封不动的复制、转载,但请务必保留此声明。作者不对本文所导致的任何结果负责。
十、定制你的Emacs
其实,有关Emacs的争论一直没有停息过。有人坚持Emacs是个庞大的史前生物,也有人坚持Emacs是神造的万能工具。总之,一切都是围绕着它的复杂性而论。毋庸置疑的,单作为一个文本编辑器而言,Emacs的确是太庞大了(它足有70多兆!)。但是,如果把Emacs视为一个环境(它也的确是一个环境),则它是非常优秀的,70兆的体积也就不算什么了。作为普通用户,我不推荐你去使用Emacs,vi就可以了--但我不并不是在贬低vi,相反,vi同样是令我们尊敬的一个优秀的编辑器--它将复杂性隐藏在了幕后,通过各种命令实现,而这些命令我们也许永远也用不到,所以我们不必去理睬它,它就是一个小巧、简洁和直观的文本编辑器。但是如果你是一个程序员,或是系统管理员,你所关心的就不会是绚丽的界面,而是强大的功能和工作的效率。而这就是Emacs能带给你的。平心而论,Emacs并不比我们平常所惯用的其他编辑器,如UltraEdit、TextPad、EmEditor等难用多少,只是我们在使用Emacs的时候,要从新适应Emacs定义的快捷键罢了。而正是这一点,给许多浅尝辄止的人眼前蒙上了一层纱,他们也就以讹传讹,大肆宣扬起Emacs的“复杂”来。其实,一旦你熟悉了它的快捷键,你就能像用其它软件一样自如。
(如果你只是为了写几个字,你会固执的坚持使用Word吗?如果你要写C/C++程序,你会用Word吗?要是我,我宁可用notepad。当我初次接触电脑的时候,我还是在黑底白字的DOS时代。我曾为Turbo C里的IDE环境惊叹不已。那时的剪贴、粘贴的快捷键是Ctrl-Ins、Shift-Ins,删除一行是Ctrl-y,直到现在我还忍不住想用Ctrl-y来删除一行。其实统一软件快捷键的不是MS,而是WordPerfect,正是因为它的流行,使得之后的软件都纷纷效仿它,以增加亲和力。F1代表“帮助”就是它最先使用的。所以不要再抱怨Emacs的快捷键了。Emacs可以在没有图形显示的终端环境下出色的工作,和它在X下一模一样。UltraEdit可以吗?)
废话少说,言归正传。我们的目的是定制我们的工作环境,使之最适合我们的工作。因此,我们必须首先澄清一些概念。
缓冲区(Buffer)
缓冲区(Buffer)的概念听起来很玄,其实就是一块用来保存我们输入的东西的内存区域,你可以把它理解为文件。在Emacs里,一切都是在内存中进行,直到你按下C-x C-s来保存,你的文件才会被改变。这是一个普遍的文本保存策略,几乎所有的文本编辑器都是这样工作的。
窗口(Frame)
窗口(Frame)不是Window,它是指你所编辑的文本被显示的区域。这一点类似于你在UltraEdit里打开的各个文件所在的小窗口。
模式(mode)
模式(mode)是Emacs里最重要的概念,Emacs的强大功能基本上都是由各种模式提供的。常用的有C/C++模式、shell模式、Perl模式、SGML/HTML模式等等。
基于上面的概念,让我们来逐步研究Emacs的IDE环境
10.1、文件,缓冲区和窗口
首先,我们可以在Emacs里同时编辑多个文件。你随时可以使用C-x C-f来打开(或者创建)文件。但是默认情况是,编辑器自动进入到新的文件窗口中(所有的编辑器都这样)。如果我们希望同时看到两个文件(比如比对两个文件),我们就必须首先对窗口进行分割。使用C-x 2对窗口进行水平分割。分割完毕后你会失望的发现,两个窗口里的内容竟然完全一样(包括你对任一窗口的修改,都会同步显示在另一个窗口中)!是的,我们只是分割了窗口,但是并没有切换缓冲区,因此依旧是显示原来缓冲区的内容。使用C-x o切换到你想去的窗口,然后在缓冲区列表(C-x C-b)里选择目标文件。这样你就可以在同一屏终审视两个文件了。
你也可以用C-x 3垂直分割屏幕,分成左右两个区域。窗口理论上可以无限分割,只要你觉得分那么多的小窗口有意义(试试看,连Emacs都会觉得你这样做很愚蠢),因此你完全可以将屏幕分割成倒“品”字形,只需依次按下C-x 2、C-x 3即可。
窗口和缓冲区的概念是完全不同的,因此我们可以“关闭”窗口,而非“关闭”缓冲区,让它暂时从我们的视线里消失。这相当于图形环境下的“最小化窗口”。使用C-x 0关闭当前窗口,使用C-x 1关闭当前窗口以外的其他窗口。
下面的这个列表很直观的显示了对窗口和缓冲区的键盘操作:
-------------------------------------------------------------------------------------------------------
窗口操作:
功能键 功能
C-x 0 删除当前窗口,对缓冲区无影响。注意这里是数字0。 (最小化当前窗口)
C-x 1 删除当前以外的所有窗口,对缓冲区无影响。 (最小化其他窗口)
C-x 2 水平分割当前窗口。
C-x 3 垂直分割当前窗口。
C-x o 切换窗口(当且仅当有一个以上的窗口存在)。注意这里是字母o。
缓冲区操作:
功能键 功能
C-x C-f 打开(创建)文件,创建一个新的缓冲区。
C-x C-s 保存当前缓冲区到文件。
C-x C-w 保存当前缓冲区到其他文件(文件另存为)。
C-x k 关闭当前缓冲区。
C-x C-b 缓冲区列表。你可以用方向键来选择要切换的缓冲区。
C-x C-c 关闭所有的缓冲区,退出Emacs。
-------------------------------------------------------------------------------------------------------
10.2、模式
接下来我们看看Emacs里的模式(Mode)。
在Emacs里,无论何时编辑一个文件,都要使用一个特定的模式(Mode)。Emacs里的“模式”不同于vi里的“模式”。vi里分“命令”和“编辑”两种模式,而Emacs里只有一种模式,就是编辑模式,Emacs里的命令全靠功能键完成。但是我说的“模式”不是指这个模式,而是指Emacs里的各种辅助环境。当我们编辑普通文本时,用的是“文本模式(Txt Mode)”,而当我们写程序时,比如前面的Bash脚本,用的则是“Shell(bash)模式”。
当我们启动某一文件时,Emacs会判断文件的类型,从而自动选择相应的模式。当然,我们也可以手动启动各种模式。先按M-x,然后输入模式的名称。比如启动“C模式”,就是M-x c-mode。直接按下M-x,然后按两下Tab键,你将得到所有可执行的命令,这里面当然包括所有的模式。因此,你要想不起来某个命令的名称,就用这个方法。
10.2.1、C模式
在强大的C模式下,我们拥有“自动缩进”、“注释”、“预处理扩展”、“自动状态”等强大功能。
当我们在“C模式”下编辑代码的时候,可以用Tab键自动的将当前行的代码产生适当的缩进,使代码结构清晰、美观。我们也可以指定缩进的规则。Emacs支持的缩进规则有:bsd、cc-mode、ellemtel、gnu、java、k&r、linux、python、stroustrup、user、whitesmith,通过M-x c-set-style命令指定。
源代码要有良好可读性,必须要有良好的注释。用M-;可以产生一条右缩进的注释。C模式下是“/* comments */”形式的注释,C++模式下是“// comments”形式的注释。当我们高亮选定某段文本,然后按C-c C-c,就可以把这段文字给注释掉。
Emacs可以使用C预处理其运行代码的一部分,以便让程序员检测宏、条件编译以及include语句的效果。比如想象下面的这种情况:
1、在顶层窗口输入看到的代码。
2、高亮显示一个区域。
3、按C-c C-e调用宏扩展。也可以从菜单C中选择 Macro Expand Region。
Emacs将创间谍热窗口,显示宏扩展的结果。
Emacs中的C环境还有许多特性,可以帮助程序员加速开发过程。运行在自动状态下的时候,且程序员输入代码的时候,C环境会自动地插入新行、处理缩进并完成其他相关任务。在许多情况下,编程时都不用按EnteAr键,系统会自动处理。
按C-c C-a或者运行M-x c-toggle-auto-stat,就可以开启自动模式。在这种模式下敲击键盘时,程序员会注意到无论何时,只要输入分号,编辑器就会自动把光标定位到下一行,并自动缩进。最终代码看起来好像没有使用自动模式一样;它只是减少了程序员创建文件敲击键盘的次数。
如果想要关闭自动模式,只需要按C-c C-a或者运行M-x c-toggle-auto-state,系统将恢复一般状态。
10.2.2、编译程序
Emacs可以让程序员在Emacs环境里编译自己的软件。这样做的时候,编辑器把编译器的输出和程序代码连接起来。这意味着程序员只需要单击出错的命令(按个回车),就可以立刻定位那些警告和错误信息。
可以在Tools菜单里找到这些选项。在从菜单中选择Compile时,Emacs要求输入编译命令。如果有一个Make文件,可以接受默认设置。否则,程序员必须为正确编译程序而填写编译命令行。
如果在编译时遇到错误或警告,Emacs将在分开的窗口中显示它们。
此时用Enter单击错误信息,就可以直接跳到发生错误的源代码处。有时,在输出窗口重将有几百条警告信息;直接跳到出错的地方,可大量的节省时间。
正如你看到的,默认的编辑命令是对一个make的调用。Emacs可以完美使用make并处理大量文件,对Emacs是否能支持大的工程项目的担心,是完全没有必要的。
10.2.3、调试
许多集成的开发环境提供一个调试器。虽然多数只是一个有限的调试器,但是Emacs为gdb调试器提供了一个功能齐全的借口。
在Emacs中使用gdb的时候,程序员能获得gdb在其他任何方式运行时所具有的全部标准特性。但是还是包括了一些通过接口增强而获得的其他性能。
在Emacs中使用gdb调试程序,可以观察自己的代码是如何从头到尾运行的。这个选项比默认的gdb操作更容易使用,默认的操作只是显示的指令。
此外,由于可以直接在Emacs中重新编译调试器运行在缓冲器内的代码,在调试器内对代码进行改动、重新编译和运行是简单的方法。
为了在Emacs里调用调试器,在Tools菜单中选择gdb,会出现系统提示,要求输入可运行文件以便进行调试。当输入了名字时,gdb被调用。最初将看到一个和标准gdb一样的窗口。在程序的适当地方设置断点后运行程序,源代码窗口将会有=>标记指向断点位置的代码并高亮显示。gdb窗口将不再显示代码。
在gdb窗口中,可以使用所有的常用gdb命令。在Emacs中使用gdb,程序员必须要学习任何新的命令。
10.2.3、使用标记
Emacs的另外一个强大的功能是使用标记(tag)的能力。根据标记,编辑器可以区分哪些文件属于同一个项目。更重要的是,标记还能准确指出每个文件都包含了什么。比如在C程序中,标记指出那个文件包含了特定的函数。当编译文件的时候,可以直接跳到任何函数所在——而不管文件的路径。此外,可以对一组文件而不仅仅对当前文件使用命令。比如,一个搜索命令可以对一组文件起作用。
为了提供这个功能,Emacs需要分析文件,并且保存将要被使用到的标记信息。一般而言,实现这种功能要使用一个叫TAGS的文件。在命令行中运行etags程序创建这个文件,并且给它需要索引的文件名字。例如:
$etags *.c
etags程序分析源代码,并产生一个TAGS文件,便于以后在Emacs中使用。
现在,可以在Tools菜单中使用Tags选项,对文件进行操作。可以使用Find Tag(M-.)来看看到底发生了些什么。比如,输入一个函数的名字,Emacs将直接跳到包含该函数的文件,如果需要则带开该文件,并且定位光标于该函数的第一行;如果该函数在一个以上的文件中出现,就可以使用M-,继续搜索其他的文件。
10.3、在Emacs里用Shell
Emacs独一无二的地方就在于它可以在内部运行shell。Emacs里的Shell与普通的Shell没有区别,我们编写的shell脚本可以直接运行测试,而不必退出Emacs。但是,在Emacs的shell环境下,不能运行某些需要对控制台进行控制的程序,比如mc。这是我们可以用term模式代替,只需运行M-x term-mode命令。
我们已经在前面体验过Emacs里的shell了,我就不再重复了。
10.4、其他,但不是鸡肋
Emacs集成了万维网浏览器、邮件阅读器、ftp、telnet、新闻组阅读器、版本控制系统等等。实在是太多了,我在这里肯定无法一一谈到。学习Emacs的最好方法就是“看书+实践”,我就是这么学习Emacs的。多多摸索,你也可以成为Emacs高手。征服Emacs并不是“不可完成的使命”。
10.5、累了,玩玩游戏吧
F10->Tools->Games,尽情娱乐吧,我们的宗旨是——劳逸结合。
【GNU/Linux实战手记】到此就全部结束了。我希望这短短的五篇文章能起到点作用,这样也不妄费我痛苦的敲键盘。感谢大家的阅读。:)