镇冮市工程建设网:Emacs 零海拔入门

来源:百度文库 编辑:九乡新闻网 时间:2024/04/29 13:22:36
  • 文档属主: 刘鑫

  • 版本历史:
    • v0.6~070910 修订
    • v0.5~070819 创立

Emacs Now!

长期以来,我对瑞士军刀式的工具心有独钟。虽然长期使用的是Windows上各种身形庞大的破解版IDE,却一直对Emacs/VIM心向往之。自从在工作中介入Python,就有意的开始学习Emacs的使用。从去年起,适逢GNU Emacs23浮出水面,困扰已久的中文问题基本上成为历史了,于是,我便开始大力转向Emacs。现在,应该说学习和使用Emacs已经不再像前几年那样麻烦,对Emacs抱有兴趣,又心生向往的同学,现在可以考虑向宝山进发了。

地图与旅游手册

去一个陌生地方旅游时,你需要在出发前读一下旅游手册,看一看地图。在学习Emacs之前,也有一些内容需要你先了解一下。

可能会困扰你,但应该接受的

Emacs 是一个通用编辑器,一个非常古老的编辑器,甚至比现在你见到的很多操作系统(及发行版)都要古老的多。所以,它有一些操作习惯,会令你感到不适应。然而,如果你坚持下去,会有收获的。

Emacs发展了数十年,积累了大量的技术资源,数量之大,质量之高,是很多新潮工具难以望其项背的。需知编码工作的本质是文本编辑。Emacs在文本编辑方面的积累,比我们的年龄更长,所以,在Emacs不能满足你的时候,请先搜索教程,看看是否你漏过了什么操作要点。如果确信Emacs中没有这个内置功能,请搜索相关的mode。

Emacs 有着方便的扩展和定制机制,然而它使用的Emacs Lisp语言,作为一种Lisp的变种,可能是你从来没有见过的。然而尽管它的样子看起来古怪,却是一种非常值得学习,也非常好用的语言,不妨一试。

Emacs是一个高度可扩展的环境。你在学习它的同时,也应该不断的改变它,使你们相互磨合。这是一个有趣的体验过程。

Emacs 有若干实现版本,其中影响最大的是GNU Emacs。出于中文支持的考虑,后面的内容以GNU Emacs 23为准,

插件与配置

Emacs的插件,被称为mode。首先emacs有着优秀的可扩展性,使用elisp可以编写它的插件。事实上几十年来积累的开源插件足以满足大多数的需求。很多时候,定制Emacs就是寻找适合的插件。在后面,我也会以一些常用的插件介绍为主。

快捷键

Emacs 中定义了大量的快捷键,各种插件也经常会定义自己的快捷键。在Emacs的文档中,通常会使用一种简短的方式来介绍快捷键:

  • 大写 C 表示 Control 键
  • 大写 M 表示 Alt 键 -- 它的出处在于有些机器的键盘上会有称为Meta的功能键。
  • 同时按下若干键时,用 - 号表示分隔,如 C-f 表示同时按下 Control 和 f 键。
  • 按键有先后时,用空格分隔,如C-x f,表示同时按下 Control 和 x,然后松开,再按下 f。

Emacs 安装

GNU Emacs 目前正在经历一次变革,除了正式发布的21版、正在Beta阶段的22版,还并行开发了Emacs的Unicode内核版:GNU Emacs 23。这个版本解决了困扰我很久的“半个中文字符”的问题,我也是因此才欣然使用GNU Emacs。

目前Emacs 23还处于Alpha阶段,但是实际上已经非常可靠,我一直在使用这个版本。Windows用户可以到 [http://ntemacs.sourceforge.net] 下载编译好的版本,Ubuntu 用户可以将以下的源添加到软件源列表中:

deb http://ppa.launchpad.net/avassalotti/ubuntu RELEASE main deb-src http://ppa.launchpad.net/avassalotti/ubuntu RELEASE main

金山内部,可以直接从我们自己的内部镜像取到这个版本。

当然,如果你喜欢,也可以从GNU的CVS站签出源码,自己编译,这是一个漫长的过程,不过对于一个Hacker,也是个不错的学习机会。网上有大量的文章介绍如何编译emacs,这里就不多介绍了。需要注意的是,大多数关于编码的配置介绍,对于GNU Emacs23的用户都可以置之不理,基本上我们只需要关注这样几个主要步骤:

  • 安装CVS
  • 安装GCC
  • sudo apt-get build-dep emacs21 (注:这是一个取巧的办法,通过build-dep尽可能的获取依赖的包)
  • ./configure
  • make install
  • 观察错误提示,查阅网上资料,安装缺少的包,重复上一步骤以至成功……

Emacs 与文本编辑

打开/新建文件

打开 Emacs 后,我们做的第一件事,往往是打开一个(新)文件进行操作。在Emacs中,打开文件的快捷键是C-x f。需要注意的是,Emacs并不像普通的文本编辑器那样,区分打开现有文件和新建文件,而是依据这样的规则:

  • 打开文件时,实际上是在Emacs中打开一个同名的缓冲区(buffer)。
  • 如果硬盘上存在这个文件,就把其内容读入缓冲区。
  • 保存时,如果该文件不存在,就新建一个,否则覆盖。

前面我们提到了缓冲区。这是一种重要的概念,不过暂时我们可以把它视为Emacs中管理的一块数据内容。通常它会对应可见的文本编辑区。实际上,我们可以直接新建一个不对应任何文件的缓冲区,后面我们会讨论到。

关闭缓冲区

当然,直接把Emacs关掉,你就关掉了所有的缓冲区。不过,我们通常需要的是关掉当前的缓冲区。它的快捷键是 C-x k。需要注意的是,如果缓中区有未保存的数据,会提示你,注意看提示:)。

保存文件

保存文件的快捷键是 C-x s。如果需要另存到一个指定的文件,使用C-x w。

文本编辑的基本操作

会有一些教材告诉你一些很神奇的快捷键,比如C-p是光标上移什么的。它们为Emacs提供了最大可能的兼容性。即使一些紧凑的,只有82键的键盘上,熟练用户也可以使用自如。如果你在这样的环境下工作,不妨学习一下这类快捷键。

然而,实话说,这些快捷键我从来没有背下来过。对于我这样使用101键盘的用户,就直接使用方向键、翻页键这样的标准键来移动光标好了。删除之类的也一样。

然而还是有几个有用的快捷键值得记忆一下:

  • C-k 是删除光标向右直至行尾的内容,我惊讶的发现这个操作居然比我想象的常用的多。
  • C-del 是向右删除至单词末尾,对于中文,它是删除子句。
  • C-s 会进入搜索模式,后面我们会讨论一下搜索相关的操作。
  • 所有被删除的内容会进入一个称为删除环的地方,按C-y就可以把它粘贴到光标所在的位置,如果想要取再前一次的删除数据,就在C-y之后(不要做其它操作!)继续按M-y,重复按M-y可以遍历整个删除环。
  • 复制是 M-w,剪切是C-w,粘贴是C-y,切记!
  • C加左或右,可以整单词(或中文子句)跳转,Emacs有一整套完整的文本跳转快捷键,我也只记住了这么一个。
  • C-t 交换光标所在字符及其前一个字符的位置。说真的,我对这个快捷键很怨念,这得多么大的手才能一手按住这两个键啊……实事证明,两个字符写反了,是非常常见的事情,这样功能非常实用,生生就被这个组合快捷键给废了……

对于程序员,另有几个快捷键非常值得一记:

  • TAB,在编码使用的各种程序语言mode中,通常tab都是按设定的缩进格式对齐当前行。
  • M-/,代码自动完成。黑夜的自动完成并不算强,只是搜索当前已经出现过的子句,但是非常实用。
  • C-M-\,对当前选区重排,这个功能也经常会用到。

特别提一下M-x,这个组合是打开emacs最下面的mini-buffer。然后你可以在里面输入一行命令。通常这个命令就是一个emacs函数。一般写做M-x command,意思就是按下Alt-x,然后输入command,回车。

文本块的选取

通常我们在文本编辑器中都可以按住shift移动光标来选取文本,但是在emacs中不行。emacs使用一个称为“锚点”的概念。当你按下M-@时,就设定了一个锚点,光标和锚点之间,即为选取区域。只要不点击鼠标,不重设锚点,这个选取区就会一直随你的光标而变。

矩形剪切是C-x r k,矩形粘贴是C-x r y。矩形复制还没有找到:)。

常见编程语言支持

基本上你常用的编程语言,都已经有了内置的mode支持。你需要的只是M-x 语言名-mode。需要注意的是,shell脚本的编辑mode称为sh-mode。而perl常用的不是内置的perl-mode,是随perl源码发布的cperl-mode。

如果你像我一样有时候会用一些比较罕见的编程语言,可以在互联网上搜索“Emacs 语言 mode”(请将语言换为你想要emacs支持的语言),一般都能找到。如果你是debian/ubuntu用户,请先在软件源中搜索。

.emacs与插件

emacs在启动时,会自动查找$HOME/.emacs文件,如果有,就执行它。所以我们都在这个文件中使用elisp编写自己的配置。

之前我们说过,定制emacs,大部分时间就是在寻找对应的插件并安装。在 [http://code.google.com/p/usemacs] 项目中,我上传了自己的.emacs文件。通常来说,我们定制自己的emacs环境,可以从现成的资源开始。事实上我的配置也是收集自几个不同的来源。下面简单介绍一下我的.emacs配置。

文字与背景

- 其实我的.emacs配置文件第一行是设定环境的编码:

(set-language-environment 'UTF-8)

不过现在我越来越感觉这个代码应该是没有用的,因为我现在都在用 Gnu Emacs 23,它内核就是 unicode 的……

Emacs 的界面调整有很多细节,我是说不完的,这里只介绍几个比较有意思的。 都是一些视觉上的效果。

  • 首先是设置字体的大小和字型。用计算机久了,真的比较容易疲劳,现在电脑

屏幕都大了,我就不吝惜这点面积了,有健康才有未来:)。其中中文我使用了 文泉驿字体,这个字体在 Linux 下很好找,但是 Windows 下我不知道,可能 你要另找一个适合自己的。

;; 設置默認字體,我現在喜歡大一點的字體,養眼。(set-default-font "Bitstream Vera Sans Mono-12");; 设置中文字体(set-fontset-font "fontset-default" 'unicode '("WenQuanYi Bitmap Song" . "unicode-bmp"))
  • 设置颜色,曾经我在这里手工选择背景色,不过后来我偶然发现了一个叫

color-theme 的插件,这里面已经有很多配置好的很漂亮的风格,所以我改用它。关 于这个漂亮的插件,我决定单独分出一个短文来介绍一下。我目前的配置是:

;; 如果你要手工选背景色,可以使用;; (set-background-color xxx);; 我现在使用的是下面的代码,如果你不是从ubuntu软件库中安装的这个;; 插件,可能需要注释中的这行代码:;; (require color-theme)(color-theme-gray30);; 将mmm-mode的背景色设深一些,与当前的背景色匹配(set-face-background 'mmm-default-submode-face "DarkSlateGray4")

功能与提示

其实这里介绍的只是一部分。我也是从网上搜集来的。大家想看比较完整的介绍, 可以看 [http://code.google.com/p/usemacs] 中的代码。

  • 首先是这个很实用的设置,它可能会让你减少大量的击键:

(fset 'yes-or-no-p 'y-or-n-p) ; 将yes/no替换为y/n
  • 接下来是时间和日期的显示,专心工作的你,可以一眼看到当前的时间了。

(display-time-mode 1) ; 显示时间(setq display-time-24hr-format t) ; 24小时格式(setq display-time-day-and-date t) ; 显示日期
  • 光标靠近鼠标的时候,鼠标自动弹开。这个功能看起来只是个趣味游戏,

其实非常非常的实用。我就经常会下意识的把鼠标放在文字编辑的必经之 路,在使用其它工具的时候,这个问题实在是让我很困扰。现在有这个功 能。不但它不再拦路,还会给你带来一些有趣的休闲感觉。

(mouse-avoidance-mode 'animate) ; 光标移动到鼠标下时,鼠标自动弹开
  • 显示列号,这个功能有多重要我就不说了,每个程序员都知道的。

(column-number-mode t) ; 显示列号
  • 在标题栏上显示当前正在编辑的文档,其实是显示当前的 Buffer 名。这

个功能对于在字符界面下使用emacs的朋友我想没什么用途,如果你和我一样也 在Gnome桌面上使用它,那这个功能还是有帮助的,当你使用其它应用程序时, 看到Emacs标题的提示,会更容易回到Emacs这边的工作状态。

(setq frame-title-format "March Liu@%b") ; 显示当前编辑的文档
  • - 在文档中插入当前时间,早年找到这段代码的时候,因为疏忽没有记下原作者

的名字,很惭愧。这个功能虽然简单,却也很实用。原作者好像还加了快捷键。我 记得因为自己记不住那么多快捷键,就把它去掉了。

;; insert-date(defun insert-date () "Insert date at point." (interactive) (insert (format-time-string "%Y年%m月%e日 %l:%M %a %p")))

一些功能支持插件

ubuntu 的软件库

基本上你使用 Emacs 做某方面的开发,就需要对应的一个甚至几个插件。在我最新的 usemacs 项目中,目前在维护的 ubuntu 目录,,很多功能 mode 的注册代码都去 掉了。无它,ubuntu 下提供了大量插件的自动安装。我从ubuntu的新立得软件管理 器中安装了大量的插件,大量的编程语言支持就不多介绍了,基本上都是傻瓜化配置, 下面我介绍几个比较有特色的:

  • ecb,这是程序员非常值得一试的工具,它的主站在 http://ecb.sourceforge.net 。

大家可以在上面下载到文档,还可以看到一些截图。可以说这是一个相当叛逆和颠覆性 的插件。普通的emacs插件大多强调“简单、易安装、够用、透明学习”。而这个插件 要依赖多达四个第三方插件(好在如果你没有安装这些插件,它会替你下载),使用手 册更达到了228页A4纸(以官方发布的PDF版为准)!这个庞大的插件(集)中包含了 目录树显示、代码语法(对象)树、文档列表等实用的视觉效果,即使在没有深入学习 其手册的情况下,也可以给程序员带来相当的便利。相信通过深入的学习和调配,ECB 会是一个绝对的开发利器。可以说它把Emacs这个神秘的古老咒符,改造为了现代化的 强大武器。

  • muse 是一个非常强大的文档发布工具。它把标记文本的简单和格式化文档的生成

发挥到了一个极致。关于这个插件,有太多的内容可以介绍,我想还是另开一个文章 比较好。而且更深入的介绍,还是推荐大家读它的官方文档。值得一提的是这份文档就 是以muse编写并发布的。

  • planner 是一个基于 muse 的个人日程和任务管理工具。简单可爱。
  • emacs-goodies-el 同样是一个插件集,其中包括了大量实用的插件,比如我

非常喜欢的 color-theme,还有apache配置支持,df工具,htmlize等等。可以说 目前我发掘出来目前的连十分之一都没有。如果你有什么功能需求,不妨先看看 goodies 中的说明,说不定已经有了现成的解决方案:

Miscellaneous add-ons for EmacsThis package contains: :: - align-string - align string components over several lines; - all - edit all lines matching a given regexp; - apache-mode - major mode for editing Apache configuration files; - ascii - ASCII code display for character under point; - auto-fill-inhibit - finer grained control over auto-fill-mode; - bar-cursor - change your cursor to a bar instead of a block; - boxquote - quote texts in nice boxes; - browse-huge-tar - browse tar files without reading them memory; - browse-kill-ring - browse, search, modify the kill ring; - clipper - save strings of data for further use; - coffee - now Emacs can even brew coffee; - color-theme - changes the colors used within Emacs; - csv-mode - major mode for comma-separated value files; - ctypes - enhanced Font lock support for custom defined types; - cua - emulate CUA key bindings (C-z undo, C-x cut, C-c copy, C-v paste); - cyclebuffer - select buffer by cycling through; - cwebm - a modified CWEB/WEB modified mode; - dedicated - make a window dedicated to a single buffer; - df - display in the mode line space left on devices; - dict - wrapper around the 'dict' command. (Depends on bash and dict) - diminish - shorten or erase modeline presence of minor modes; - dirvars - provides directory-wide local variables; - edit-env - display, edit, delete and add environment variables; - egocentric - highlight your name inside emacs buffers; - ff-paths - $PATH-like searching in C-x C-f; - filladapt - enhances Emacs's built-in adaptive fill; - floatbg - slowly modify background color; - framepop - display temporary buffers in a dedicated frame; - highlight-beyond-fill-column - highlight lines that are too long; - highlight-completion - highlight completions in the minibuffer; - highlight-current-line - highlight line where the cursor is; - home-end - alternative Home and End commands; - htmlize - HTML-ize font-lock buffers; - initsplit - split customizations into different files; - joc-toggle-buffer - fast switching between two buffers; - joc-toggle-case - a set of functions to toggle the case of characters; - keydef - a simpler way to define key mappings; - keywiz - Emacs key sequence quiz; - lcomp - list-completion hacks; - maplev - major mode for Maple; - map-lines - map a command over lines matching a regexp; - markdown-mode - major mode for editing Markdown files; - marker-visit - navigate through a buffer's marks in order; - matlab - major mode for MatLab dot-m files; - minibuf-electric - electric minibuffer behavior from XEmacs; - minibuffer-complete-cycle - cycle through the *Completions* buffer; - mutt-alias - lookup and insert the expansion of mutt mail aliases; - muttrc-mode - major mode for editing Mutt config files; - nuke-trailing-whitespace - kill the trailing blanks at end of lines; - obfusurl - obfuscate an URL; - pack-windows - resize all windows to display as much info as possible; - perldoc - show help for Perl functions and modules. (Depends on perl-doc) - pod-mode - major mode for editing POD files - projects - create project-based meaningful buffer names; - prot-buf - protect buffers from accidental killing; - protocols - perform lookups in /etc/protocols; - rfcview - view IETF RFCs with readability-improved formatting; - services - perform lookups in /etc/services; - session - menu to restore files visited in previous editing session; - setnu - setnu-mode, a vi-style line number mode; - shell-command - enables tab-completion for shell-command; - show-wspace - highlight whitespaces of various kinds; - silly-mail - generate bozotic mail headers; - slang-mode.el - a major-mode for editing slang scripts; - sys-apropos - interface for the =*nix= apropos command; - tabbar - Display a tab bar in the header line; - tail - "tail -f" a file or a command form within Emacs; - tc - cite text with proper filling; - thinks - quote texts in cartoon-like think bubbles; - tlc - major mode for editing Target Language Compiler scripts; - tld - explain top-level domain names; - todoo - major mode for editing TODO files; - toggle-option - easily toggle frequently toggled options; - twiddle - mode line hacks to keep you awake; - under - underline a region with ^ characters; - wdired - rename files editing their names in dired buffers; - xrdb-mode - mode for editing X resource database files.As well as some packages included in emacs22 for use in other flavours: :: - cfengine - major mode for editing cfengine scripts; - ibuffer - advanced replacement for the `buffer-menu'; - ido - a faster way to switch buffers and get files; - newsticker - a newsticker for Emacs. (Depends on wget) - newsticker - a newsticker for Emacs. (Depends on wget) - table - create and edit WYSIWYG text based embedded tables;See /usr/share/doc/emacs-goodies-el/README.Debian.gz for a shortdescription of all files, or the Info node `emacs-goodies-el' fordetails.

附带介绍一下两个emacs内置的插件。一个是nxml-mode,这个mode以前是第三方工具,在 GNU Emascs 23 中它正式取代原来的 pxml-mode 成为标准的内置 xml 插件。这个插 件的功能非常强大齐全,而且内置的很多配置功能都是使用XML标准工具管理的。另一个是 org-mode,这是一个类似于planner的事务管理工具,有不少用户认为它的功能比planner 更为强大合理。

ubuntu 下仍需手工安装的插件

即使需要手工添加的插件,安装过程大部分都简化到了非常傻瓜化的程度。基本上在 Emacs中手工安装插件只需要这样几个步骤:

  • 把插件所在位置用 (add-to-list 'load-path "xxx") 代码添加到load-path

列表中。其中xxx指插件所在的位置,我通常放在~/site-lisp中。

  • 用 (require 'xxx) 加载库,或者用 add-to-list 函数将插件绑定到其对应的

文件类型上。一般来说,在插件中会有readme说明安装方式,如果某个插件只有一个 .el文件,通常它就写在代码最前面的注释中。

  • 在 [http://code.google.com/p/usemacs[usemacs]] 中,我除了从ubuntu中安装的大量插件,还手工安装了这样几个:

    • csharp-mode:C#语言的支持,这个……其实我很久没有用过了……
    • psvn,在 Emacs 的shell中使用svn commit的话,无法直接填写说明,有这

个东西就好很多。不过可能新手会觉得有些别扭。

  • docbook-xml-mode,其实ubuntu中有这个插件,只是前面试用时发现,如果不

require一下,就不能用。后面我可能会去掉这个插件的设置。

  • mercurial ,非常强大的分布式版本管理系统。这个插件是 mercurial 内置的。

很好用。

  • django-html-mode,django模板的支持插件,来自html-mode。在django的网

站上提供了两款模板编辑插件,我比较了下,这个在 ubuntu + emacs 23的组合下工作 良好。

  • cperl-mode,perl源码中带的插件,功能很强,支持perl5和perl6。

Hook 功能

Hook,也就是钩子,是 Emacs 中重要的功能。它允许我们在某个mode上挂载执行我们的 定制代码。复杂的hook自然要涉及深入的Lisp编程知识,但是即使只会复制粘贴和基本语 法知识,我们一样可以使用很多实用的钩子。例如:

  • - 下面这个钩子中,我为 Python 代码编辑功能增加了代码折叠。这个功能的实现代

码来自网络上的一些资源,注释中说明了出处:

;; set Python mode;; 代码折叠设置来自 gb@cs.unc.edu, 感谢他。(add-hook 'python-mode-hook 'python-mode-hook t)(defun py-outline-level () (let (buffer-invisibility-spec) (save-excursion (skip-chars-forward "\t ") (current-column))))(defun python-mode-hook () ; this gets called by outline to deteremine the level. Just use the length of the whitespace (custom-set-variables '(indent-tabs-mode nil) '(tab-width 4) '(tab-width 4) '(tab-stop-list nil) ) ; outline uses this regexp to find headers. I match lines with no indent and indented "class" ; and "def" lines. ; 这里我利用了 Martin Sand Christensen 提供的正则表达式,感谢他。 (setq outline-regexp "[^ \t]\\|[ \t]*\\(def\\|class\\|if\\|elif\\|else\\|while\\|for\\|try\\|except\\|finally|with\\) ") ; enable our level computation (setq outline-level 'py-outline-level) ; turn on outline mode (outline-minor-mode t) ; make paren matches visible (show-paren-mode 1))
  • cperl-mode 的设置也有一些复杂,其实cperl的排版风格我仍然没有调整到一个很满意的程度,

以后慢慢再调整吧。

;; Use cperl-mode instead of the default perl-mode(add-to-list 'auto-mode-alist '("\\.\\([pP][Llm]\\|al\\)\\'" . cperl-mode))(add-to-list 'interpreter-mode-alist '("perl" . cperl-mode))(add-to-list 'interpreter-mode-alist '("perl5" . cperl-mode))(add-to-list 'interpreter-mode-alist '("miniperl" . cperl-mode))(add-hook 'cperl-mode-hook 'cperl-mode-hook t)(defun cperl-mode-hook () (setq cperl-continued-statement-offset 0) (setq cperl-extra-newline-before-brace t) (set-face-background 'cperl-array-face "wheat") (set-face-background 'cperl-hash-face "wheat") (cperl-set-style "CPerl") (setq cperl-indent-level 4))