isware

Emacs + C++

http://forum.ubuntu.org.cn/viewtopic.php?t=40522

获得emacs


emacs有两种主流版本,一个是Gnu emacs,一个是Xemacs。其中Gnu emacs使用者较多,我们一般说的emacs就是GNU emacs。以下说到的emacs就默认是Gnu emacs了。
emacs的官方网站是:http://www.gnu.org/software/emacs/
在这个网站上,你可以下载到各个平台的最新稳定版的emacs,包括windows和linux。在我写这段文字的时候,emacs最新稳定版是 21.4。然而,正在开发中的cvs版中有许多我们非常感兴趣的新特性。一个是我们期待已久的unicode的支持,一个是我们同样期待已久的GTK2 的支持。而且就我使用而言,最新的CVS版已经相当的稳定。那么我们是不是必须用CVS工具提取CVS代码然后自己编译生成emacs可执行程序呢?不 用!有一个叫做ntemacs的项目已经帮我们做了这个工作了。
ntemacs的官方网站是:http://www.ntemacs.sf.net
下载最新的ntemacs,将其解压到任意一个目录就可以使用了。运行emacs的脚本是 bin/runemacs.bat。你可以将这个脚本创建一个快捷方式到sendto文件 夹。
还有一个可供选择的emacs的windows版本是winmacs。他的下载地址是http://sourceforge.net/projects/winmacs。这个版本有一个问题,你必须设置HOME系统变量,将其设置为c:\


获得辅助插件


纯粹的emacs已经足够强大,借助其cc-mode已经可以进行C/C++开发。但是我们前面说过,要进行高效的开发。那么,我们需要一些辅助的“插件”。

cscope:这是一个可以使emacs实现类似source insight那种符号查找等功能的软件。它最常用的功能就是找到任何一个变量、函数、结构体等是在哪里被定义,被引用的。cscope的官方网站在 http://cscope.sourceforge.net/。这里可以下载到cscope的源码,源码中有一个叫做xcscope的目录,将其拷贝到 你emacs的site-lisp目录下。xcscope是 lisp脚本,它是与平台无关的语言。然而,这个脚本依赖cscope可执行文件。但cscope是不能直接在windows下运行的。我在网上找了很 久,终于在一个俄罗斯网站上找到了cscope的windows编译。这个网站是:http://iamphet.nm.ru/cscope /index.html。下载后将cscope.exe解压到emacs的bin目录下即可。

cedet+ecb:这两个“插件”无比强大,专门为emacs作为IDE而设计的。我现在只使用了其中很小一部分功能,就领略到了它带给我的高效。官方网站:http://ecb.sourceforge.net/ ; http://cedet.sourceforge.net/。下载这两个插件,和xcscope一样,复制到site-lisp目录。

session : 这个插件可以让你的emacs显示最近编辑和最近访问的文件。官方网站是:http://sourceforge.net/projects/emacs-session

doxymacs : 这是一个按照doxy风格生成注释的工具。使代码可以更方便的生成文档。官方网站是:http://sourceforge.net/projects/doxymacs


配置emacs


一切就绪后,就需要配置emacs了。在C盘根目录下建立一个.emacs文本文件,输入配置内容。以下是我的配置文件内容:
(require 'xcscope) ;;加载xcscope
(require 'cedet) ;;加载cedet
(require 'ecb) ;;加载ecb
(require 'session) ;;加载session
(add-hook 'after-init-hook 'session-initialize) ;; 启动时初始化session
(require 'doxymacs) ;; 启动doxymacs
(add-hook 'c-mode-common-hook 'doxymacs-mode) ;; 启动doxymacs-mode
(add-hook 'c++-mode-common-hook 'doxymacs-mode) ;; 启动doxymacs-mode
(desktop-load-default) ;;读取默认desktop设置
(desktop-read) ;;读取当前目录保存的desktop设置
(set-face-background 'default "LightCyan3") ;;设置背景色为 浅青色3
(set-face-font 'default "-outline-新宋体-normal-r-normal-normal-*-*-96-96-c-*-iso8859-1") ;;设置字体为新宋体 ( Only for windows )
(global-set-key [f12] 'ecb-activate) ;;定义F12键为激活ecb
(global-set-key [C-f12] 'ecb-deactivate) ;;定义Ctrl+F12为停止ecb
(global-set-key [f11] 'delete-other-windows) ;;设置F11为删除其它窗口
(global-set-key [(meta return)] 'semantic-ia-complete-symbol-menu) ;;设置Alt+Enter为自动补全菜单
(global-set-key [C-\;] 'ecb-goto-window-edit-last) ;;切换到编辑窗口
(global-set-key [C-\'] 'ecb-goto-window-methods) ;;切换到函数窗口
(global-set-key [C-.] 'cscope-find-global-definition) ;;搜索定义
(global-set-key [C-,] 'cscope-pop-mark) ;; 跳出转向
(enable-visual-studio-bookmarks) ;; 启动VS书签子程序
;;(setq semanticdb-project-roots (list "d:/work")) ;; 设置cemanticdb的扫描根目录
(add-hook 'c-mode-common-hook ( lambda() ( c-set-style "k&r" ) ) ) ;;设置C语言默认格式
(add-hook 'c++-mode-common-hook ( lambda() ( c-set-style "k&r" ) ) ) ;;设置C++语言默认格式


常用快捷键


(这部分还没有时间写,事实上学习emacs基本上就是学习其快捷键和命令。这些东西网上有很多,书上也有很多)


参考资料


这里只是设计了emacs的皮毛,想要获得更加了解emacs这个强大的编辑器,学习更多emacs的使用技巧请参考以下资料:
《学习GNU emacs》机械工业出版社
《生活在emacs中》IBM开发者网
附件:
ecb-2.32.tar.gz [875.37 KiB]
cscope-15.6.tar.gz [382.05 KiB]
cedet-1.0pre3.tar.gz [1.29 MiB]

在Emacs环境下编译文件的按键组合
小枫儿 发表于 2005-7-9 13:44:00

首先编写Makefile文件,然后在Emacs环境下击键:
Alt-x compile RET(回车键)
在小缓冲区出现:
Compile command : make -k
如果当前目录下只有一个Makefile文件,回车即可编译。
接下来的击键组合是在出现编译错误的时候通过这些击键可以快速地在源代码中找到错误:
———————————————————————————————————————
Ctrl-x ` next-error 移动到下一条出错信息并访问与之相对应的代码(` 按键在数字键1的左边)
Alt-n compilation-next-error 移动到下一条出错信息
Alt-p compilation-previous-error 移动到上一条错误信息
Ctrl-c Ctrl-c compilation-goto-error 访问对应于当前出错信息的源代码
SPACE scroll-down 下卷屏幕显示内容
DEL scroll-up 上卷屏幕显示内容
————————————————————————————————————————
基本命令
C-x C-c : 退出Emacs

C-x C-f : 打开一个文件,如果文件不存在,则创建一个文件

C-g : 取消未完成的命令
编辑
C-z (redefined): Undo;原来C-z是挂起Emacs(然后用fg命令调出);C-x u 是默认的命令; 移动一下光标,再C-z就可以redo

M-d : 删除光标后的词语
移动光标
C-v : 向前翻页

M-v : 向后翻页

M-r : 将光标移动到屏幕中间那行

C-a : 移到行首

M-a : 移到句首,从行首到句首之间可能有空格

C-e : 移到行尾

M-e : 移到句尾

M-{ : 向上移动一段

M-} : 向下移动一段

C-right : 向前移动一个单词

C-left : 向后移动一个单词

C-up : 向前移动一段

C-down : 向后移动一段

M-< : 移到整个文本开头

M-> : 移到整个文本末尾

C-u 数字 命令 : 执行多次(数字表示次数)该命令;“M-数字 命令” 也可以

M-x goto-line : 移动到某一行

C-l : 重绘屏幕,效果就是当前编辑行移动窗口中央
Buffer 相关
C-x k : 关闭当前buffer

C-x b : 切换到前一个编辑的buffer

C-x C-b : 列出当前所有buffer

C-x C-s : 保存当前buffer

C-x s : 保存所有未保存的buffer,会提示你是否需要保存

C-x C-w : 文件另存为
拷贝与粘贴
M-space (redefined): 设置mark; C-@ 是默认命令

C-w (redefined) : 剪切一块区域;如果没有设置mark,则是剪切一行

M-w (redefined) : 拷贝一块区域;如果没有设置mark, 则是拷贝一行

C-k : 从当前位置剪切到行尾

C-y : 粘贴

M-y : 用C-y拉回最近被除去的文本后,换成 M-y可以拉回以前被除去的文本。键入多次的M-y可以拉回更早以前被除去的文本。

C-x r k : 执行矩形区域的剪切

C-x r y : 执行矩形区域的粘贴
窗口操作
C-x 0 : 关闭当前窗口

C-x 1 : 将当前窗口最大化

C-x 2 : 垂直分割窗口

C-x 3 : 水平分割窗口

M-o (redefined) : 在窗口之间切换; C-x o 是默认命令

C-x 5 1/2/3/0 : 对frame类似的操作

C-x < : 窗口内容右卷

C-x > : 窗口内容左卷(这两个命令在垂直分割窗口后比较有用)

(C-u) C-x ^ : 加高当前窗口,如果有C-u,则每次加高4行

(C-u) C-x } : 加宽当前窗口

(C-u) C-x { : 压窄当前窗口

ESC C-v : 在其它窗口进行卷屏操作
搜索和替换
C-s : 向前搜索(增量式搜索);连续C-s,跳到下一个搜索到的目标

C-s RET : 普通搜索

C-r : 向前搜索

C-s RET C-w : 按单词查询

M-% : 查询替换,也就是替换前会询问一下

M-x replace-string : 普通替换
Tags
M-! etags .c .h : 创建TAGS文件

M-. : 跳到tag所在位置

M-x list-tags : 列出tags
Bookmark
C-x r m : 设置书签bookmark

C-x r b : 跳到bookmark处
帮助
C-h ? : 查看帮助信息

C-h f : 查看一个函数

C-h v : 查看一个变量

C-h k : 查看一个键绑定 (C-h c 也是查看键绑定,但是信息较简略)

C-h C-f : 查看一个函数的Info,非常有用

C-h i : 看Info
其它
C-M-\ : 对选中区域,按照某种格式(比如C程序)进行格式化

C-x h : 全部选中

M-! : 执行外部shell命令

M-x shell : 模拟shell的buffer

M-x term : 模拟terminal, C-c k 关闭terminal

C-x C-q : 修改buffer的只读属性

一些扩展

显示行号
1, 下载wb-line-number.el, 放到合适的目录. (我一般放在~/.emacs.d中)

2, 在~/.emacs中添加:

(set-scroll-bar-mode nil) ;; no scroll bar, even in x-window system (recommended)
(require 'wb-line-number)
(wb-line-number-toggle)

注意: 这里假设你已设置了加载目录: (add-to-list 'load-path "~/.emacs.d")

【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实战手记】到此就全部结束了。我希望这短短的五篇文章能起到点作用,这样也不妄费我痛苦的敲键盘。感谢大家的阅读。:)

/////////////////////////
1. C-h

任何命令都可以忘掉,C-h不能忘,因为通过它你可以找到其他所有的命令,不知道C-h怎么用?C-h C-h 这里第二个C-h是个help option,常用的option还有:

* a 列出包含给定字符串的所有命令。这里的命令实际上是函数名,因为emacs中的所用功能都是通过函数来实现的,把这些功能(函数)绑定到键盘上,就叫做key binding,这种设计使我们可以很容易地把某项功能绑定到我们喜好的按键上。
* b 显示所有的key bindings
* C 显示指定编码的信息,如果不带参数则显示当前和编码有关的设置
* r info形式的emacs guide,最好的参考资料

2. user option和变量

两者都是perl变量,用来定制emacs环境,区别在于M-x set-variable只能设置user option变量,要设置任何变量,在*scratch*buffer输入(setq variable-name value),用C-j执行;用C-h v VAR则可以查看任何变量的值
3. buffer

* 查看buffer列表 C-x C-b
* 切换buffer C-x b
* 关闭buffer C-x k
* 保存当前的buffer到它关联的文件 C-x C-s

4. 编码相关

emacs使用language environment来进行编码相关的设置。一个language environment为emcas中编码相关的变量设置默认值,比较重要的设置项有:

* 优先编码列表 当读入一个文件时,以该列表的顺序来识别文件的编码,用prefer-coding-system在该列表首插入一个编码
* default-buffer-file-coding-system 新建文件的默认编码


C-h L来查看当前或其他language environment的信息,使用M-x set-lanaguage-environment来修改。 如果没有指定language enviroment,emacs将会根据locale中设置的编码来选择一个language environment,比如在我的en_US.UTF-8下,language environment设置的是UTF-8。不过这里似乎有个问题,按理说这时相关的编码变量应该也被设置为UTF-8 language environment设置的默认值,不过在我的环境下这些变量的值似乎和UTF-8 language environment无关,于是不得不在.emacs下明确设置一下:

(if (equal current-language-environment "UTF-8") (prefer-coding-system 'gb2312) (prefer-coding-system 'Utf-8) ) ) ) (add-hook 'set-language-environment-hook 'utf8gbk) (set-lanaguage-environment 'UTF-8)

在UTF-8这个language environment下,emacs并不能自动识别gbk编码的文件,因为其缺省设置的优先编码列表没有gbk,上面的lisp对UTF-8 language environment做了定制,之所以又加了一次utf-8编码是因为希望在UTF-8这个language environment下首选的编码是utf-8。

5. registers

emacs用来存放文本、矩形、位置或其他内容的地方,供以后使用。每个register都有一个名字,为一个英文字母。 C-x r s R 保存region的文本到register R C-x r i R 从register R中插入文本

1. deleting, killing and yanking killing会把删掉的文本放到kill ring中,随后可以用yanking来把它copy到别处,类似win下的copy/paste,deleting则不把删掉的文本放到kill ring中,因此也无法copy删掉的文本。
* C-k killing从当前光标到行尾的文本,如果是空行则包括其换行符,在行首两次C-k就删掉该行
* C-w Killing region
* C-y yanking上次killing的文本

6. undo and redo

用C-x u进行undo,用什么来redo呢?不幸的是,emacs没有redo的命令,它是用undo来实现redo的:任意一个非undo的命令将会打断 undo命令的顺序,从那时起,以前的undo命令就成为了普通的改变文本的命令,这样当再使用undo命令时将会undo以前undo命令的改变,于是 就redo了
7. region

很多emacs命令操作buffer中任意一段连续的区域,怎么指定这段区域呢?在这个区域的一端设置一个mark,再移动光标到另一端,位于光标和mark之间的内容就是选择的区域。用C-<SPC>来设置mark。

* Kill region C-w
* save region到一个register C-x r s
* 设置整个buffer为region C-x h

8. indentation

在多数mode下,Tab键是被绑定到indent相关的命令上的,要插入tab字符,需要用C-q tab转义一下。

* 对region中的每一行indent C-M-\
* <RET>并<TAB> C-j

9. 字体

emacs是针对charset来配置字体的,对要显示的coding system中的字符,emacs把它们归到这些charset中,然后使用在这些charset上指定的字体来显示它们。这样的一个字体配置在emacs里叫做fontset,如:

Emacs.Fontset-0:-*-courier-medium-r-normal-*-18-*-*-*-*-*-fontset-courier,\ chinese-gb2312:-*-simsun-medium-r-*-*-18-*-*-*-p-*-iso10646-1,\ chinese-cns11643-5:-*-simsun-medium-r-*-*-18-*-*-*-p-*-iso10646-1,\ chinese-cns11643-6:-*-simsun-medium-r-*-*-18-*-*-*-p-*-iso10646-1,\ chinese-cns11643-7:-*-simsun-medium-r-*-*-18-*-*-*-p-*-iso10646-1,\ Emacs.font:fontset-courier


10. Move

* 以word为单位的前移/后移 M-b/M-f
* 以word为单位的前删/后删 M-Delback/M-d
* 移到行首/行尾 C-a/C-e
* 移到页首/页尾 M-a/M-e
* 移动到buffer首/尾 M-</M->

11. 常用命令

* 列出某个主题的帮助 C-h a
* 删除从当前光标到行尾/行首 C-k/C-u
* Undo/Redo C-x u/
* 在window间切换 C-x o(other)
* 翻页 C-v/M-v
* 退出 C-x C-c
* 启动emacs时不加载~/.emacs:-q
* 配合sudo打开文件 C-x C-f /sudo::/etc/emacs/
* 把一个文件的内容插入到当前位置 C-x i
* 在当前光标处插入一行 C-o
* 使光标所在文本滚动到离窗口顶部n行处 C-u n C-l

12. 插件/扩展

emacs 是用lisp扩展的,M-x load-file用来执行任意一段lisp脚本,M-x load-library则从变量load-path定义的一个目录列表中寻找指定的文件并执行它,autoload函数把一个函数和一个lisp脚本相 关联,当执行这个函数时,加载对应的脚本文件并执行,如: (autoload 'javascript-mode "javascript" nil t) 当执行javascript-mode函数时,load-library javacript,nil是该函数的描述,t表示该函数是interactive的,当以后用C-h f来查看该函数时,这些信息将得到体现。

1. 如何在buffer中输入回车和换行 C-q C-m 输入回车(\r),这里C-q代表转义,C-m代表ascii的控制字符\r C-q C-j 输入换行(\n),C-j代表ascii的控制字符\n

13. key binding

(global-set-key [?\C-2] 'set-mark-command)

方括号中的是key sequence,后面的是要绑定到的command。对key sequence中的字符元素,用lisp的字符常量来表示:问号后跟该字符,用\C-表示控制字符;对key sequence中的symbo元素,直接写其名称,如f7
14. lisp

注释 以;;开头的行为注释


/////////////////////
本文件列出了在Emacs C mode下面常見的指令及所謂的C mode就是在Emacs下面撰寫C語言程式的模式。在這個模式下面Emacs會提供一些針對C語言所增加的特性及功能。對於C的程式設計師而言是相當好 用的。雖然這篇文章著重在C mode之下,但是大部分的指令對於其他的模式依舊適用。
避免被其他的設定所影響
Emacs本身是一個非常有彈性的編輯器,因此經過相當的設定之後,原本預設的設定可能會被修改掉了。為了讓您的Emacs能夠符合本文件所列出的熱鍵及弁遄C建議您在home directory的.emacs檔案中加入下面的設定。


(setq inhibit-default-init t) ; 避免被系統預設的設定所影響
(keyboard-translate ?C-h ?C-?) ; 可以避免backspace變成help hot-key的問題
(keyboard-translate ?C- ?C-h) ; 將help hot-key由Ctrl-h轉成Ctrl-
;; 以下的設定是讓C mode具有 K&R 所建議的樣式
(setq c-mode-hook '(lambda () (auto-fill-mode 1)))
(setq c-indent-level 5)
(setq c-continued-statement-offset 5)
(setq c-argdecl-indent 0)
(setq c-brace-offset -5)
(setq c-label-offset -5)

進入及離開Emacs

如果您的系統上面已經安裝好emacs,只要在shell下面執行emacs xxx.c就可以以C mode進入emacs中。如果您要離開emacs,則需要在emacs中鍵入:Ctrl-x-c。


檔案控制及存取
Ctrl-x Ctrl-s 儲存目前正在編輯視窗內的檔案
Ctrl-x s 儲存所有目前在編輯的檔案
Ctrl-x k 關閉目前正在編輯視窗的檔案,但是不存檔
Ctrl-x Ctrl-c 跳出emacs
Ctrl-x Ctrl-w 另存新檔
Ctrl-x Ctrl-f 開啟檔案
Ctrl-x Ctrl-r 以唯讀模式開啟檔案
Ctrl-x Ctrl-q 將原本是唯讀的檔案變成可寫入

游標的移動
Ctrl-b 往回移一個字元
Ctrl-f 往後移一個字元
Ctrl-p 往上移動一行
Ctrl-n 往下移動一行
Ctrl-a 移到行首
Ctrl-e 移到行末
Esc b 往前移一個英文字
Esc f 往後移一個英文字
Esc v 往上移一頁
Ctrl-v 往下移一頁
Esc < 移到檔案最前面
Esc > 移到檔案最後面
Esc a 移到敘述(statement)最前面
Esc e 移到敘述最後面
Esc Ctrl-a 移到Function最前面
Esc Ctrl-e 移到Function最後面
Ctrl-u 重複前一個指令四次

刪除與回復
DEL 刪除游標左邊的字元
Ctrl-d 刪除游標所在位置的字元
ESC DEL 刪除游標左邊的英文字
ESC d 刪除游標右邊的英文字
Ctrl-k 刪除所有在游標右邊的字元
ESC Shift-2 設定Region的Mark
Ctrl-w 從設定Region Mark到目前游標之間的字元全部刪除
Ctrl-y 將被Ctrl-w指令所刪除的字元回復
ESC y 將被Ctrl-y所回復的字元再刪除
Ctrl-u 重複前一個命令四次
Ctrl-x u 回復前一個命令所造成的影響(Undo)

搜尋與置換
Ctrl-r 向上搜尋
ESC 在搜尋模式中按ESC可以離開搜尋模式
ESC % 啟動置換模式。在置換模式中,首先要輸入將被置換掉的字串,然後輸入新字串。接下來游標會移到需要被置換的地方。你需要用下面的key來指定動作:

* y:置換目前游標所在的字串,並且移到下一個可被置換的字串。
* n:跳過目前游標所在的字串。移到下一個可被置換的字串。
* !:將整個檔案一次置換完畢,不進行任何詢問。
* ESC:結束置換模式。
* .:將目前的字串置換後,即離開置換模式。
* ^:回到前一個符合置換的地方。


拷貝與搬移
Ctrl-@ 設定標記起始點
Ctrl-w 剪下標記起始點至目前游標所在位置的文字。
Alt-w 複製標記起始點至目前游標所在位置的文字。
Ctrl-y 貼上之前所剪下或複製的文字至目前游標所在的位置。

多重視窗控制
Ctrl-x 0 刪除目前的視窗(不會關閉正在編輯的檔案)
Ctrl-x 1 刪除其他的視窗(不會關閉正在編輯的檔案)
Ctrl-x 2 水平分割視窗
Ctrl-x 3 垂直分割視窗
Ctrl-x b 將目前視窗內的檔案切換成其他的檔案
Ctrl-x o 將游標移動到其他視窗之內

加入註解
ESC ; 在Emacs的C mode中按下'ESC ;'就會出現註解符號/* 及*/。並且在編輯時會自動幫你換行。

編譯程式
ESC x compile 在C mode中輸入ESC x compile就可以在不離開Emacs的狀況下進行程式的編譯。此時,emacs會顯示預設的編譯命令是make -k。compile之後,所有訊息都會出現在另一個視窗。
Ctrl-x ` 編譯完成後,如果有錯誤發生,按下Ctrl-x `就可以跳到下一個有錯誤的地方,修改完成後,再按一次就可以繼續修改下一個錯誤,一直到沒有其他的錯誤為止。

SHELL
ESC x shell 進入Shell mode。可以讓你在emacs的視窗中使用shell。
Ctrl-c Ctrl-c 將正在執行的程式中斷
Ctrl-c Ctrl-z 暫停目前的工作
Ctrl-c Ctrl-r 將游標移動到最後一個命令
Ctrl-c Ctrl-y 重複執行前一個命令。

Tags
tags 是一個很有用的工具,他可以幫助您將source檔案中所有function定義,及 typedef的定義,全部收集成為一個資料庫,讓你可以很輕易的跳到您要的函數定義。在使用emacs的tags機制之前,您需要先將有關的tag的資 料庫建構出來。建構的方法如下:

% etags -tlist_of_source_file

list_of_source_file就是您要做紀錄的原始程式檔案。您可以指定很多個檔案。例如:

% etags -t *.[ch]

其中,-t的參數主要是要求etags將typedef的宣告一併放入資料中。

在Emacs中,如果要使用tags的機制,可以使用下表的命令:

ESC . 尋找函數的定義。你可以透過這個命令來找尋你要的函數。輸入此命令後,emacs會提示訊息,要求你輸入要找尋的函數名稱。或是typedef的定義。
Ctrl-x 4 . 功能同ESC .。但是會把找到的函數定義顯示在另外一個視窗。
ESC x visit-tags-table 使用其他的TAGS檔案
ESC x tags-search 以regular expression的方式來找尋函數名稱。
ESC , 輸入ESC x tags-search之後,可以用這個來進行尋找下一個的動作。
ESC x tags-query-replace 以regular expression的方式來置換函數名稱。

其他
Ctrl-x Ctrl-b 目前正在處理的檔案列表
Ctrl-x b 將目前視窗內的檔案切換成其他的檔案
Ctrl-x d 會在目前的視窗中顯示目錄列表
Ctrl-x 4 d 在其他視窗顯示目錄列表
///////////////////////////
Emacs Lisp 功能扩展集锦

Emacs 具有超强的扩展性。这是当今没有任何其它编辑器可以比拟的强大特点。这里介绍一些很方便的 Emacs Lisp 扩展。

有链接的文件可能不是 Emacs 自带的,你需要下载el文件到你的 load-path 中的一个目录里。

所有文件可以点击链接下载,你也可以点击这里一次性下载所有 el 文件,但是不包括大型的 elisp 包,比如 dictionary. [下载]。

这里提供的下载是我正在用的版本。我没有列出我找到它们的地址, 因为我记不住那么多。如果你需要最新的版本,请查看文件里的网址 到作者的主页。

每个标题后面的lisp代码是需要写到配置文件里的东西。
session.el

(require 'session)
(add-hook 'after-init-hook 'session-initialize)

使用了这个扩展之后,你上次离开 Emacs 时的全局变量 (kill-ring,命令记录……),局部变量,寄存器,打开的文件,修改过的文件和最后修改的位置,…… 全部都会被记录下来。

加载了 session 之后菜单上会多两项:最近访问过的文件和最近修改过的文件。看这个图 。
desktop.el

(load "desktop")
(desktop-load-default)
(desktop-read)

如果你想保存上次打开的文件记录,那么可以使用 desktop。这是 Emacs 自带的。你只需要加入以上设置,然后 M-x desktop-save。以后 Emacs 启动时就会打开你上次离开时的所有 buffer.

M-x desktop-clear 可以删除记住的内容,你闲现在记住的 buffer 太多就可以采用这个办法。不过我还是建议用 ibuffer(见下) 来管理这些buffer,因为有时你会发现,如果删掉全部记住的buffer,以后你需要一定的时间来打开你经常编辑的文件!

如果session跟desktop配合,下次启动Emacs 的时候,就像根本没有关闭 Emacs 一样!多爽!
ibuffer.el

把这几行加入 .emacs 就可以把 C-x C-b 那个普通的 buffer menu 换成非常方便的 ibuffer 啦!

(require 'ibuffer)
(global-set-key (kbd "C-x C-b") 'ibuffer)

使用了 desktop 之后有可能使你同时有几十个 buffer 同时打开着。有时你想把其中一些关闭,有时你想在某些 buffer 里寻找某个 regexp。这个时候你可以用 ibuffer,它有跟 dired 相似的界面。可以对 buffer 进行各种标记,排序,隐藏,查找,替换。非常好用。看看这个抓图就是我限定显示 emacs-lisp-mode 和 c-mode 的 buffer,按 major mode 名称排序,并做上一些记号的情况。

我常用的一个功能是,用 %-n 标记符合某种名字的 buffer,然后按 "O" 在这些buffer里寻找我需要的字串。比如在所有打开的后缀为 html 的 buffer 里寻找 "Emacs" 字样,得到如下结果。
browse-kill-ring.el

(require 'browse-kill-ring)
(global-set-key [(control c)(k)] 'browse-kill-ring)
(browse-kill-ring-default-keybindings)

方便的在 kill-ring 里寻找需要的东西。

你是不是经常按 C-y 放进一个 kill-ring 里的单元。然后 M-y,M-y,…… 来寻找你需要的很久以前剪切下来的东西?很费事吧?用了 browse-kill-ring 就好了。你只需要把它绑定到一个热键,比如 C-c k: 就能出现这样一个buffer。[查看图形]

kill-ring 里的内容都可以方便的浏览,粘贴。具体操作请在这个 buffer 里 C-h m 或者 ?.
ido.el

你可能用过 iswitchb。但是当有很多buffer时,iswitchb 还是很慢。你可以使用ido。这是我见过的最方便的切换buffer,寻找文件的扩展了。在你的 .emacs 文件里加入:

(require 'ido)
(ido-mode t)

ido 主要有两个界面:打开文件和切换buffer,它们之间可以随便切换。它的原始的键设定不是很方便直观,所以我把它另外设置了一下。看这个列表。其实你从这个列表就可以看出 ido 的功能。我这里只叙述一下基本的操作。

1. 打开文件 (C-x C-f)

启动 ido-mode 以后,你可以在 C-x C-f 打开文件时得到一个如下的界面:

你开始输入文件名,前缀匹配的文件和目录都会列在光标后面的表里。目录是红色的。

你可以使用 C-s,C-r 或者左右光标键在匹配的文件之间来回旋转,按上下光标可以在匹配的目录名之间旋转。你可以按 TAB 补全名字,方括号里的内容是你按 TAB 将会补全的字符。按 backspace 遇到目录名时,一次会吃掉整个目录名,并且到达上一级目录。C-k 可以删除一个文件。别担心,当删除文件时,你会被要求做出明确的回答。

如果你按 C-p 就会启动部分匹配,而不是严格前缀匹配。这时只要文件名的一部分与你的输入匹配就会列在表中。

按 C-t 就会切换到正则表达式匹配方式,你输入的文字将被作为正则表达式对文件进行匹配。比如我输入 ".*el$" 就可以得到所有以 "el" 结尾的 文件列表。

另外,C-c 和 C-a 分别切换大小写匹配和忽略某些文件。

你访问过的目录都会被 ido 记住,你可以按 M-up 和 M-down切换以前访问过的目录,按 M-left 和 M-right 可以提出以前使用过的文件名。

按 C-b 就会切换到选择buffer模式。按 C-d 就会进入Dired.

注意,你如果要创建一个新的文件叫 "ab",而你的目录里有匹配前缀的文件或目录,RET 就会打开部分匹配的文件。所以这个时候你必须按 C-j 来创建这样一个文件。如果没有匹配的文件,那么RET也会创建一个新的文件。

由于方向键,backspace 和 C-f, C-b 都被作为其它用途了,所以如果你想把光标移动到行首修改一些东西,你必须按 C-e 进入编辑模式。
2. 寻找文件

Emacs 打开文件的函数叫 find-file。这是很多人不理解的问题。下面我们就能看到,有了 ido 之后,这个函数就名副其实了。当你输入了一个文件名或者正则表达式,而在当前目录没有这样的文件,你就可以利用ido的查找功能了。我举一个例子好了。

我经常同时编辑不同种类的文件,它们在系统里不同的目录中。它们的目录名会被ido记住。这样我打开一个文件时,可以不管它在哪个目录。我只需要输入它的名字。比如,我刚才已经打开了

~/html/emacs_elisp.html
/usr/local/texlive/texmf-local/tex/latex/CJK/GB/c19fzhc.fd
~/.emacs.d/site-lisp/folding.el
....

现在我想打开另一些

/usr/local/texlive/texmf-local/tex/latex/CJK/GB/

目录下的 .cap 文件。我就在 C-x C-f 的界面按输入 "cap$",然后打开正则匹配和部分匹配,出现以下界面:

因为当前目录(PWD)下没有后缀是 fd 的文件,所以我按了一下 M-up,这下成了这个样子:

显然它找到一个结尾是 "cap" 的文件,但是这不是我想要的,于是我继续按一下 M-up 到再上面一个目录里去找。就成了这样:

这就是我需要的文件!想一想,你的当前目录不在那个地方,用别的办法打开如此深一个目录里的文件需要花多少时间?

其实我们还有一个窍门,刚才如果在不能匹配的时候按 M-s,ido 就会把所路径合并,找到匹配文件,然后给出一个列表:
3. 切换buffer(C-x b)

切换 buffer 的界面也跟打开文件功能类似。不过少了一些文件特有的功能,多了一些buffer特有的的功能。

打开文件时 C-k 是删除文件,现在 C-k 变成了关闭 buffer。如果你按 C-a 就会显示通常被忽略的 buffer。

如果不存在这样的的buffer,你可以直接回车新建一个buffer,也可以使用 C-f 切换到打开文件界面。

这个扩展功能实在太多,你看了我的叙述能够体会到它的方便了吧。但是实际使用时,你很少能记住所有这些功能。最好是自己绑定键。在需要的时候可以查询这个键绑定。就像我的这个键绑定。

最新的 ido 可以逐步筛选你需要的文件 (ido-restrict-to-matches),你可以把这段代码加入你的 .emacs.
# swbuff

(require 'swbuff)
(global-set-key (kbd "") 'swbuff-switch-to-previous-buffer)
(global-set-key (kbd "") 'swbuff-switch-to-next-buffer)
(setq swbuff-exclude-buffer-regexps
'("^ " "\\*.*\\*"))

(setq swbuff-status-window-layout 'scroll)
(setq swbuff-clear-delay 1)
(setq swbuff-separator "|")
(setq swbuff-window-min-text-height 1)

使用这个,你就可以方便的在最近编辑的 buffer 之间切换了。切换的时候会出现一个小窗口显示附近的buffer,就像翻页一样。看看抓图。

我把它绑定到了 C-prior 和 C-next,按起来很方便。而且你可以用变量 swbuff-exclude-buffer-regexps 设定你不想看到的 buffer。它们不会出现在列表里。这个例子中我把所有名称开头是空格的 buffer 和名字前后都是 "*" 的都排除在轮训以外,这样就可以在不同的文件之间切换而不被恼人的临时 buffer 扰乱了。

一个很重要的变量是 swbuff-status-window-layout, 改变它的值可以改变 swbuff 下面那个窗口的显示方式。

如果你的 buffer 很多,这个窗口可以长得很大。如果你把 swbuff-status-window-layout设为 'adjust,则不论什么时候都会出现这样的大窗口,设为 'default 则只有单窗口时才出现大窗口。虽然这个窗口只显示几秒钟,但是 我很讨厌一个那么大的窗口在我面前一闪。现在如果你把它设为 'scroll,不论什么时候都只占用一行。这样buffer太多时,那个窗口不会占用太多空间扰乱视线。

原来的 swbuff 有一个小小的 bug, 无论 swbuff-status-window-layout 是什么值,都会显示一个很大的窗口显示所有的 buffer,这个文件是我修改过的版本。

swbuff-clear-delay 可以控制小窗口消失的延迟。

swbuff-window-min-text-height 可以控制小窗口的大小。如果设为 0, 就不会打开小窗口了。
tabbar.el

(require 'tabbar)
(tabbar-mode)
(global-set-key (kbd "") 'tabbar-backward-group)
(global-set-key (kbd "") 'tabbar-forward-group)
(global-set-key (kbd "") 'tabbar-backward)
(global-set-key (kbd "") 'tabbar-forward)

你曾经觉得 Windows 样式的编辑器上面的 tab 很好用吧?其实 Emacs 的更好,它不但可以把所有 buffer 列在 tab 上,而且根据 major mode 对 tab 进行分组。你可以用 customize-group RET tabbar RET 来设置它的选项。

我把Windows键盘上的 "Win" 键绑定到了这个功能,因为 tabbar 很像Windows 的风格。按 Win-left 和 Win-right 就会在同组 tab 之间切换,Win-up 和 Win-down 可以在分组之间切换。

看看下面几个图你就知道它如何好用啦!

显示 html mode 的分组:

分组列表

在不同的窗口里可以有独立的 tab。图片太大,要看的话点击这里

tabbar 有一个小小的 Hack, 可以使你更方便。
speedbar

这个是 Emacs 自带的。M-x speedbar 就可以启动它。它可以让你 方便的浏览文件,你还可以显示文件里的标题,函数,变量……

在你编辑不同的文件时,它可以显示当前文件所在目录里的相关文 件和它们的信息,比如文件是否需要重新编译,elisp文件是否已 经编译,…… 等等。

你可以看看我的抓图。
table.el

(autoload 'table-insert "table" "WYGIWYS table editor")

非常酷的一个扩展。可以“所见即所得”的编辑一个文本模式的表格。就跟很多字处理程序那样操作,可以识别文本文件里本来就存在的表格,而且可以把表格输出为 HTML 和 TeX。看看我的抓图吧。
recentf.el

这个扩展可以帮你保存一个“最近打开的文件”列表。在 .emacs 文件里加入:

(require 'recentf)
(recentf-mode 1)

你可以把不常用的C-x C-r 绑定到这样一个函数:

(defun recentf-open-files-compl ()
(interactive)
(let* ((all-files recentf-list)
(tocpl (mapcar (function
(lambda (x) (cons (file-name-nondirectory x) x))) all-files))
(prompt (append '("File name: ") tocpl))
(fname (completing-read (car prompt) (cdr prompt) nil nil)))
(find-file (cdr (assoc-ignore-representation fname tocpl)))))

(global-set-key [(control x)(control r)] 'recentf-open-files-compl)

这样你就可以 C-x C-r 然后 TAB 列出最近打开文件列表了。
rect-mark.el

你是不是觉得 Emacs 的“矩形区域操作”不太直观?使用这个包之后矩形 region会被真正显示成一个矩形。[查看图形]这可以使你的矩形操作大大方便。

如果你已经有了一个 region。你可以使用 C-x r C-x 把它显示为一个矩形。如果你刚开始设定一个矩形区域,你可以使用 C-x r 作为你的 set-mark-command 的前缀,比如 C-x r C-SPC。那么区域会被显示为矩形。
hippie-expand

这个是 Emacs 自带的功能,可是知道它的人不多。很多人用的是M-/ (dabbrev-expand) 这样的东西。 hippie-expand 要强大的多。因为它可以使用扩展函数任意扩充!你可以把你的 M-/ 绑定到 hippie-expand,马上就可以体会到它的方便。

(global-set-key [(meta ?/)] 'hippie-expand)

你可以设置以下 hippie-expand 的补全方式。它是一个优先列表, hippie-expand 会优先使用表最前面的函数来补全。通常我的设置是:

(setq hippie-expand-try-functions-list
'(try-expand-dabbrev
try-expand-dabbrev-visible
try-expand-dabbrev-all-buffers
try-expand-dabbrev-from-kill
try-complete-file-name-partially
try-complete-file-name
try-expand-all-abbrevs
try-expand-list
try-expand-line
try-complete-lisp-symbol-partially
try-complete-lisp-symbol))

这是说,首先使用当前的buffer补全,如果找不到,就到别的可见的窗口里寻找,如果还找不到,那么到所有打开的buffer去找,如果还……那么到kill-ring里,到文件名,到简称列表里,到list,…… 当前使用的匹配方式会在 echo 区域显示。

特别有意思的是 try-expand-line,它可以帮你补全整整一行文字。我很多时后有两行文字大致相同,只有几个字不一样,但是我懒得去拷贝粘贴以下。那么我就输入这行文字的前面几个字。然后多按几下 M-/ 就能得到那一行。
括号匹配

这是一个很小的函数。你是不是觉得 Emacs 在匹配的括号之间来回跳转的时候按 C-M-f 和 C-M-b 太麻烦了?vi的 % 就很方便,我们可以把 % 设置为匹配括号。可是你想输入 % 怎么办呢?

一个很巧妙的解决方案就是,当 % 在括号上按下时,那么匹配括号,否则输入一个 %。你只需要在 .emacs 文件里加入这些东西就可以达到目的:

(global-set-key "%" 'match-paren)

(defun match-paren (arg)
"Go to the matching paren if on a paren; otherwise insert %."
(interactive "p")
(cond ((looking-at "\\s\(") (forward-list 1) (backward-char 1))
((looking-at "\\s\)") (forward-char 1) (backward-list 1))
(t (self-insert-command (or arg 1)))))

临时记号

有时你需要跳到另一个文件进行一些操作,然后很快的跳回来。你当然可以使用 bookmark 或者寄存器。但是这些实在是太慢了。你多想拥有vi那样的 ma, mb, 'a, 'b 的操作。现在你可以用几行 elisp 达到类似的目的:

(global-set-key [(control ?\.)] 'ska-point-to-register)
(global-set-key [(control ?\,)] 'ska-jump-to-register)
(defun ska-point-to-register()
"Store cursorposition _fast_ in a register.
Use ska-jump-to-register to jump back to the stored
position."
(interactive)
(setq zmacs-region-stays t)
(point-to-register 8))

(defun ska-jump-to-register()
"Switches between current cursorposition and position
that was stored with ska-point-to-register."
(interactive)
(setq zmacs-region-stays t)
(let ((tmp (point-marker)))
(jump-to-register 8)
(set-register 8 tmp)))

当你按 C-. 时就做了一个记号。然后你可以到别处,按 C-, 就可以在这两点之间来回跳转了。这虽然没有 vi 的 26 个 mark 多,但是你仔细想想,vi的26个 mark,你通常能用到几个?
go-to-char

(defun wy-go-to-char (n char)
"Move forward to Nth occurence of CHAR.
Typing `wy-go-to-char-key' again will move forwad to the next Nth
occurence of CHAR."
(interactive "p\ncGo to char: ")
(search-forward (string char) nil nil n)
(while (char-equal (read-char)
char)
(search-forward (string char) nil nil n))
(setq unread-command-events (list last-input-event)))

(define-key global-map (kbd "C-c a") 'wy-go-to-char)

非常感谢 Oliver Scholz 提供这个函数给我。

这个函数是一个 vi 的 "f" 命令的替代品。vi的用户知道,vi有一个特别好的命令 "f"。当你按 "fx", x 是任意一个字符时,光标就会移动到下一个 "x" 处。这之后只要按 ";"(分号),光标就到再下一个 "x"。

举个例子说明这个命令的用途。比如我们有这样一行字,光标在行首。

(setq unread-command-events (list last-input-event)))
^^^^^

我们希望迅速的到达最后那个 event 处,于是我在 vi 里按 "fe"。结果光标到了 "setq" 的那个 e 上面,这时候我接着按 ";", 不一会儿就到了我们想要的地方。很方便吧?可能起初不觉得,后来你发现这真的非常好!

我一直觉得 Emacs 没有这样一个方便的命令,但是 Oliver 给了我一个完美的答案:

有了这段代码之后,当你按 C-c a x (x 是任意一个字符) 时,光标就会到下一个 x 处。再次按 x,光标就到下一个 x。比如 C-c a w w w w ..., C-c a b b b b b b ...

我觉得这个方式比 vi 的 "f" 要快。
setnu和setnu-plus

这两个包可以用来显示文件的行号。并且根据是否空行和文件行的语法加亮显示不同的数字颜色。

看看我的抓图。
hide-region.el 和 hide-lines.el

这两个函数可以分别把一个区域和匹配某个regexp的行都藏起来,就跟不存在一样……这样你就可以对某些内容进行任意的操作而不会影响到其它的部分。

hide-lines 在操作某些行的时候用起来特别方便。加一个前缀参数可以把不匹配的行都藏起来,只看到匹配的!看看我只显示这个文件里含有global-set-key 的行:

;;hide region
(require 'hide-region)
(global-set-key (kbd "C-c r") 'hide-region-hide)
(global-set-key (kbd "C-c R") 'hide-region-unhide)


;; hide lines
(require 'hide-lines)
(global-set-key (kbd "C-c l") 'hide-lines)
(global-set-key (kbd "C-c L") 'show-all-invisible)

folding.el

我的 folding 配置很长,要看请点击这里。

我编辑了这么长一个 HTML 文件,你觉得一定很费力,不容易定位吧?其实我的屏幕看起来就是这个样子。所有小节都被我折叠了起来,我很容易就可以调换小节的位置。我刚才把folding的大段的配置代码移动到了另一个文件,就像移动了一行。

folding 根据不同的文档有不同的标记,它都是基于注释的。本网页就是这样一个例子。
htmlize.el

把语法加亮的文件输出成彩色 HTML 文件。看看这个例子。
dictionary

[本地下载][来源地]

(autoload 'dictionary-search "dictionary"
"Ask for a word and search it in all dictionaries" t)
(autoload 'dictionary-match-words "dictionary"
"Ask for a word and search all matching words in the dictionaries" t)
(autoload 'dictionary-lookup-definition "dictionary"
"Unconditionally lookup the word at point." t)
(autoload 'dictionary "dictionary"
"Create a new dictionary buffer" t)
(autoload 'dictionary-mouse-popup-matching-words "dictionary"
"Display entries matching the word at the cursor" t)
(autoload 'dictionary-popup-matching-words "dictionary"
"Display entries matching the word at the point" t)
(autoload 'dictionary-tooltip-mode "dictionary"
"Display tooltips for the current word" t)
(autoload 'global-dictionary-tooltip-mode "dictionary"
"Enable/disable dictionary-tooltip-mode for all buffers" t)

(global-set-key [mouse-3] 'dictionary-mouse-popup-matching-words)
(global-set-key [(control c)(d)] 'dictionary-lookup-definition)
(global-set-key [(control c)(s)] 'dictionary-search)
(global-set-key [(control c)(m)] 'dictionary-match-words)

;; choose a dictionary server
(setq dictionary-server "localhost")

;; for dictionary tooltip mode
;; choose the dictionary: "wn" for WordNet
;; "web1913" for Webster's Revised Unabridged Dictionary(1913)
;; so on
(setq dictionary-tooltip-dictionary "wn")
(global-dictionary-tooltip-mode t)
;(dictionary-tooltip-mode t)

连接到 dict 协议服务器,并且查询单词含义。按 C-c d 查询道当 前单词,按 C-c m 在字典里查找一个匹配的单词,鼠标邮件点击单词 会弹出菜单。还有 tooltip 功能!非常好用!你可以看看我的屏幕截图。

你可以在自己机器上安装一个 dictd。这样就不需要连到很远的服 务器查字典了。
color theme

Emacs 提供给你所有的配色机制,可是由于你的艺术细胞不够,经常为找不到好的配色方案而烦恼。使用这个包就可以方便的改变你的 Emacs 的配色方案啦!看看我的屏幕抓图 [1] [2] [3]

它提供了50种以上的配色方案。你只需要把:

(require 'color-theme)

加入到 .emacs 文件。使用 M-x color-theme-select 就会出现一个配色方案选择窗口,在配色方案上按 l 就可以改变当前 frame 的配色,按 i 就可以改变所有 frame 的配色。

如果你想选定一个配色方案后就一直用它,而避免每次都加载大量用不着的 lisp代码,按 p 就可以把当前配色方案的 lisp 打印出来,你可以把它加到你的 .emacs 文件。而不使用 (require 'color-theme) 这样可以加快启动速度。
thumbs

这个扩展可以把 Emacs 变成一个图片浏览器。看看抓图吧。
mmm

(autoload 'mmm-mode "mmm-mode" "Multiple Major Modes" t)
(autoload 'mmm-parse-buffer "mmm-mode" "Automatic MMM-ification" t)

你想过一个 buffer 里同时存在很多个 major mode 吗?现在用 MMM 就可以办到了。在不同的区域拥有对应键绑定,变量,缩进 ……

看看我的抓图,HTML, Emacs Lisp, Perl, C 和 LaTeX 全都都在同一个 buffer 里被正确的语法加亮了!而且TAB在不同的区域都可以进行正确缩进。在 LaTeX 的区域还可以使用 AUC TeX 来处理某个部分。

当然我现在是在滥用这个模式。如果你有嵌入 HTML 的 JavaScript 或 CSS2, PL/SQL,……这个就有用了。

我可以使用这个扩展来处理 CWEB 程序。最外面的 major mode 用 cweb-mode, 里面的 TeX 和 C 的区域就使用它们各自的TeX-mode 和 c-mode。看起来就像这个样子 。
AUCTeX

看到这个名字你还以为是一个 TeX 发行吧?它不是一个 TeX 发行,而是一个专门用来帮助作者写 TeX/LaTeX 文档的工具。它大大加强了 LaTeX 用户的能力。你写文档时能够只 TeX 一个你觉得需要看到效果的 region 的内容,而不必等待漫长的编译过程啦!
preview-latex

可以把 LaTeX 文档的效果插入到文档里,形成一个预览,与你的原文件一一对照。非常方便。你可以看看我的抓图:

文档里的公式

文档里的图片

注意要用这个包,你必须安装 TeX 系统和 AUCTeX.
ctypes.el

(require 'ctypes)
(ctypes-auto-parse-mode 1)

ctypes 可以识别你的 C 文件里的类型定义 (typedef)。自动对它们进行语法加亮。
ECB

ECB(Emacs Code Browser) 是一个代码浏览器,它依赖于Semantic 和Eieio。

它们组合可以实现很好的文法分析的代码浏览。ECB 在 Semantic 和 Eieio 的支持下,可以识别许许多多种计算机语言,C, C++, Java, Elisp, ...

看看这个抓图。
Emacs Wiki

(require 'emacs-wiki)

(add-hook 'emacs-wiki-mode-hook
(lambda ()
(define-key emacs-wiki-mode-map (kbd "C-c C-h") 'emacs-wiki-preview-html)
(define-key emacs-wiki-mode-map (kbd "C-c C-c") 'emacs-wiki-preview-source)
(define-key emacs-wiki-mode-map (kbd "C-c C-v") 'emacs-wiki-change-project)

))

;; (setq emacs-wiki-grep-command "glimpse -nyi \"%W\"")

(setq emacs-wiki-publishing-directory "publish")

(setq emacs-wiki-directories '("~/WiKi"))
(setq emacs-wiki-meta-charset "gb2312")
(setq emacs-wiki-style-sheet
"")

(setq emacs-wiki-inline-relative-to 'emacs-wiki-publishing-directory)

(defun emacs-wiki-preview-source ()
(interactive)
(emacs-wiki-publish-this-page)
(find-file (emacs-wiki-published-file)))

(defun emacs-wiki-preview-html ()
(interactive)
(emacs-wiki-publish-this-page)
(browse-url (emacs-wiki-published-file)))

(setq emacs-wiki-projects
`(("default" . ((emacs-wiki-directories . ("~/WiKi"))))
("work" . ((fill-column . 65)
(emacs-wiki-directories . ("~/workwiki/"))))))


用来制作 WiKi 的包。非常方便。看看我的抓图。

这上面的只是我自己的设定,你要根据自己的情况修改。

我写了一个简要的 WiKi 说明在 这里。

更多的信息请参考 http://repose.cx/emacs/wiki/


附件:
elisp.zip [1.7 MiB]

posted on 2011-05-25 20:15 艾斯维亚 阅读(4414) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理