Emacs编辑器概览
Emacs和vi应该是unix中最负盛名的编辑器了。编辑器之神Vi自然名不虚传,vi用户能做到眼球扫到哪光标就同步到哪的境界,vi有模式且使用大量单字母快捷键,可以飞快地录入。不过,vi的用法与现在流行的GUI编辑器差别太大,初用时往往搞不清处于什么模式,还有就是必须记住一些快捷键才能用。相比之下,emacs的学习曲线比较平缓,你击键的速度可能不及用vi时,但Emacs的一个键往往可完成更复杂的工作。emacs最为强大的地方在于可扩展性,通过Emacs lisp脚本几乎可定制Emacs的的每个方面,现在已经很多现成的包可用。
基本概念
界面
Emacs既可作终端程序,也可作GUI程序。把被Emacs占用的屏幕部分称为窗口。
Emacs窗口的构成由上而下为:
- 菜单栏:可通过菜单执行一些命令(除鼠标外,可用F10打开菜单,用方向键移动,用RET选中,用ESC关闭)
- 工具栏(仅见于GUI):按图标会执行相应命令
- 窗格(可以有多个,但同一时间只有一个被选中,选中者通常有闪动的光标):显示缓冲区的内容
- 每个窗格有一个光标,光标虽然在画一个字符上,但概念上在该字符与前一字符之间。
- 每个窗格下方有模式行,以格式
字符集 换行符(:表示LF、/表示CRLF、(Mac)表示CR) 状态(--表示与文件同、**表示已修改、%*表示文件只读但已修改、%%表示其它) 文件属性(-表示本机、@表示远程) 窗口(只见于终端) 缓冲区 位置(Top或Bot或一个百分比) 行号 (主模式 次模式)
- 回显区:显示或输入少量信息,如
- 在输入多字符命令过程中若停顿超过一秒会开始回显已输入部分
- 显示错误信息、进度等等,也保存于缓冲区
*Messages*
(可能只保存最近若干条) - 临时成为提示输入命令参数的小缓冲区(视为当前缓冲区,其中可用大多数不需小缓冲区的命令,通常可用TAB补全,用方向键遍历历史,用
C-r
或C-s
搜索历史,用RET提交)
按键
按键盘的各字符键通常会使相应字符插入到光标前位置。至于各控制键则有特殊含义,它们常如下使用:
- C-
表示当输入字符 时按住 CONTROL 键。因此 C-f 就表示:按住 CONTROL 键再输入 f。 - M-
表示当输入字符 时按住 META(或 EDIT 或 ALT)键。如果你的键盘上没有 META 、EDIT 或 ALT 键(又或你无法同时按两个键),用下述方法也等效:先按一下 ESC 键然后放开,再输入 。我们用 来表示ESC 键。
Emacs的命令名一般由被-
分隔的英文单词组成(如next-line
),每个命令被调用时会执行对应的Lisp过程。要调用命令,可以先按M-x,然后输入命令名(可以按TAB自动补全)后按Enter键。不过,Emacs默认情况下提供了很多快捷键对应各种命令。快捷键可能涉及多个组合键,例如要退出 Emacs,请用 C-x C-c(先按C-x再按C-c);要退出一个正在输入中的命令,请用 C-g。
内置快捷键
移动
快捷键 | 用途 |
---|---|
C-v或PageDown | 移动到下一屏。(中间会有两行的重复) |
M-v或PageUp | 移动到上一屏。(中间会有两行的重复) |
C-l | 按第一次会将光标所在行置于屏幕的中央,再次输入会移动到屏幕的顶端,再次输入会文字将移动到底端,如此循环。 |
C-f或方向键 | 向右移动一个字符 |
C-b或方向键 | 向左移动一个字符 |
M-f或C-方向键 | 向右移动一个词(对中文是移动到下一个标点符号) |
M-b或C-方向键 | 向左移动一个词(对中文是移动到上一个标点符号) |
C-n或方向键 | 移动到下一显示行 |
C-p或方向键 | 移动到上一显示行 |
C-a或Home | 移动到行首 |
C-e或END | 移动到行尾 |
M-a | 移动到句首 |
M-e | 移动到句尾 |
M-m | 移动到当前行首个非空白字符 |
C-M-a | 移动到函数定义首 |
C-M-e | 移动到函数定义尾 |
C-M-f | 移动到下一配对表达式 |
C-M-b | 移动到上一配对表达式 |
M-> | 移动到所有文字的最末尾 |
M-< | 移动到所有文字的最开始 |
M-r | 移动到屏幕中央 |
M-g c | 移动到指定位置(1表示缓冲区首个字符)的字符 |
M-g g | 移动到指定行号(1表示缓冲区首个字符)的行的开始 |
M-g TAB | 移动到指定位置(1表示缓冲区当前行首个字符)的字符 |
C-x C-n | 把当前光标在行中的位置设为目标列,即上下移动光标时会尽可能移到行中的这个位置 |
C-u C-x C-n | 取消设置目标列 |
M-x imenu | 移动到函数定义 |
快捷键 | 用途 |
---|---|
M-x what-line | 显示行号 |
M-= | 显示区域中行、单词和字符个数 |
M-x count-words | 显示缓冲区或活动区域中行、单词和字符个数 |
C-x = | 显示光标后字符的代码点、位置和列号(加前缀参数更详细) |
区域
区域是缓冲区中连续的字符序列,或说标记位置和当前光标之间部分,通常会突出显示。区域可以用拖动鼠标设置,也可用键盘设置。输入会使区域失效。
快捷键 | 用途 |
---|---|
C-@ | 把标记设置在当前光标位置并激活它 |
在输入光标移动命令时同时按着Shift | 把当前光标位置设为标记(若标记非活动),然后移动光标 |
C-x C-x | 交换光标和标记的位置 |
M-@ | 把标记设为下一个单词末位置 |
C-M-@ | 把标记设为下一个配对表达式的结束位置 |
M-h | 把光标移到当前段首而把标记设为段末 |
C-M-h | 把光标移到当前函数定义首而把标记设为定义末 |
C-x C-p | 把光标移到当前页首而把标记设为页末 |
C-x h | 把光标移到当前缓冲区首而把标记设为缓冲区末 |
插入与删除
插入
插入文字很简单,直接敲键盘就可以了。普通的字符,比如 A、7、* 等等,会随着你的输入而插入到光标位置。要插入一个换行符,输入
要插入特殊字符,可用C-x 8 RET <Unicode名字> RET
或C-x 8 RET <Unicode代码点> RET
,其中代码点默认用十六进制表示。也可用C-q <控制字符>
输入字面的控制字符如TAB、DEL等等。
快捷键|用途 :—|:— TAB|插入空白,或者缩进当前行或区域中所有行,取决于模式 C-M-o|在光标处换行并缩进(不移动光标) M-i|缩进到下一制表位 M-x indent-relative|缩进到与上一行首个非空白字符的列(已经超过则到下一制表位) C-M-|缩进区域中每行(加数值参数则缩进指定列) C-x TAB|交互式地缩进区域中所有行 C-M-q|重新缩进括号组中所有行 C-u TAB|移动括号组使首行缩进正确 M-x indent-code-rigidly|自动缩进区域中所有行 M-;|插入或对齐当前行注释(有前缀参数则移除注释),又或开关区域注释 C-x ;|设置注释列 M-x comment-region|注释区域 C-x a g|为区域(有前缀参数则指定前若干个单词)定义缩写 C-x a l|为区域(有前缀参数则指定前若干个单词)定义主模式特定缩写 C-x a i g|为区域(有前缀参数则指定前若干个单词)定义扩展 C-x a i l|为区域(有前缀参数则指定前若干个单词)定义主模式特定扩展 M-x define-global-abbrev RET abbrev RET exp RET|定义缩写 M-x define-mode-abbrev RET abbrev RET exp RET|定义模式特定缩写 M-x kill-all-abbrevs|取消所有缩写定义 M-‘|把前缀与后面的缩写分开 C-x a e|展开缩写 M-x expand-region-abbrevs|展开区域中所有缩写 M-x list-abbrevs|列出缩写 M-x|编辑缩写列表 M-x write-abbrev-file RET file RET|把缩写描述写到指定文件 M-x read-abbrev-file RET file RET|读入缩写描述 M-x define-abbrevs|用当前缓冲定义缩写 M-x insert-abbrevs|把所有缩写定义插入到当前缓冲区 M-/|展开动态缩写(在缓冲区向前找首个可用的) C-M-/|完成动态缩写
删除
你可以用 来删除光标左边的字符,这个键通常被标注为“Backspace”――跟你在 Emacs 之外的用法应该一样,删除光标前的最后一个的字符。标注着
另外emacs有很多移除或删除命令,移除与删除的区别在于被移除的内容会记录在一个环中,稍后可召回。在GUI中,被移除内容也会放到系统剪贴板,召回也可从系统剪贴板获取内容。
快捷键 | 用途 |
---|---|
DEL或BACKSPACE | 删除光标左边的字符或活动的区域 |
Delete | 删除光标后边的字符或活动的区域 |
C-d | 删除光标后边的字符 |
M-\ | 删除光标附近的空格和制表符 |
M-SPC | 删除光标附近的空格和制表符,只留一个空白 |
C-x C-o | 删除当前行附近的空行 |
M-^ | 与上一行连接 |
C-k | 移除从光标位置到行末的文字(已经在行末则移除换行) |
C-S-backspace | 移除当前行 |
M-d | 移除从光标位置到当前单词末的文字 |
M-DEL | 移除从当前单词开始到光标位置的文字 |
C-x DEL | 往回移除到句子开始 |
M-k | 移除到句子末 |
C-M-k | 移除下一配对的表达式 |
M-z 字符 | 移除到指定字符出现 |
C-w | 移除区域(剪切) |
M-w | 复制区域 |
C-y | 把上次被移除的内容召回到光标位置 |
M-y | 把刚召回的内容换成更早被移除的文字 |
C-M-w | 若下一命令为移除,被移除内容会附加到上次被移除的内容 |
以下这些较少用的快捷键操作矩形区域(由光标与标记分别在对角来确定),对多栏文本有用。
快捷键 | 用途 |
---|---|
C-x r k | 移除矩形区域 |
C-x r M-w | 复制矩形区域 |
C-x r d | 删除矩形区域 |
C-x r y | 以光标位置为左上角召回矩形区域 |
C-x r o | 用空格填充矩形区域,把原来内容右移 |
C-x r N | 在矩形区域左侧插入行号,把原来内容右移 |
C-x r c | 用空格填充矩形区域,代替原来内容 |
M-x delete-whitespace-rectangle | 删除矩形区域中各行左侧的空白 |
C-x r t 字符串 RET | 用指定字符串填充矩形区域各行内容,代替原来内容 |
C-x SPC | 开关突出显示矩形区域模式 |
寄存器
Emacs的寄存器用单个字母或数字命名,可用于保存各种东西。
快捷键 | 用途 |
---|---|
M-x view-register RET r | 显示寄存器r的内容 |
C-x r SPC r | 把光标位置保持在寄存器r中 |
C-x r j r | 跳到寄存器r对应的缓冲区和位置或者执行键盘宏 |
C-x r s r | 把区域复制到寄存器 r |
C-x r i r | 插入寄存器r中的文字 |
M-x append-to-register RET r | 把区域附加到寄存器r后 |
M-x prepend-to-register RET r | 把区域附加到寄存器r前 |
C-x r r r | 把矩形区域复制(有数值参数则剪切)到寄存器 r |
C-x r i r | 插入寄存器r保存的矩形区域 |
C-x r w r | 把当前窗口的窗格状态保存到寄存器r |
C-x r f r | 把所有窗口的窗格状态保存到寄存器r |
C-u number C-x r n r | 把指定数值保存到寄存器r |
C-u number C-x r + r | 把指定数值保存加到寄存器r |
C-x r i r | 插入寄存器r中的数值 |
C-x C-k x r | 把上一个键盘宏保存到寄存器r |
C-x r m RET | 在光标位置设置书签 |
C-x r m bookmark RET | 在光标位置设置指定名称的书签 |
C-x r b bookmark RET | 跳到指定书签 |
C-x r l | 列出所有书签 |
M-x bookmark-save | 保存当前所有书签到默认的书签文件 |
M-x bookmark-load RET filename RET | 加载书签文件 |
M-x bookmark-write RET filename RET | 保存当前所有书签 |
M-x bookmark-delete RET bookmark RET | 删除指定书签 |
M-x bookmark-insert-location RET bookmark RET | 插入指定书签指向的文件名 |
M-x bookmark-insert RET bookmark RET | 插入指定书签指向的文件内容 |
撤销
通常 C-/或C-_会消除一个命令所造成的所有改变;如果你在一行中连续多次地使用,你会把以前的命令也依次撤销。
- 没有改变文字的命令不算(包括光标移动命令和滚动命令)
- 从键盘输入的字符以组为单位――每组最多 20 个字符――来进行处理。(这是为了减少你在撤销“插入文字”动作时需要输入的次数)
重复命令
要重复上一命令一次,可用C-x z
。
大部分的 Emacs 命令接受数字参数,并且对于多数命令而言,这些数字参数的作用是指定命令的重复次数。为一个命令指定数字参数(也就是重复次数)的方法有:
- 输入 C-u,然后输入若干个数字作为参数(零个表示4),最后再输入命令
- 按住 META 键不放,然后输入一个或以上数字,最后再输入命令
举例来说, C-u 8 C-f
会向前移动 8 个字符。
虽然大部分命令把数字参数解释为其重复次数,但是也有些命令例外,它们将数字参数另做它用。比如有些命令(我们目前还没学到)仅仅将前缀参数作为一个标志――只要给出有一个前缀参数,不管其值为何,它都会改变命令的功能。而 C-v 和 M-v 则属于另一种类型的例外。当给定一个参数时,它们将滚动你指定的行数,而不是屏数。举例来说,C-u 8 C-v
将文本向下滚动 8 行。
如果要重复一系列命令,则可用键盘宏:
快捷键 | 用途 |
---|---|
F3或C-x ( | 开始宏定义(已经在宏定义则插入键盘宏相关的计数器) |
F4或C-x ) | 结束宏定义或执行上一键盘宏 |
C-x e | 执行上一键盘宏,再按e会重复执行 |
C-u F3 | 执行上一键盘宏,然后把后续按键加到上一键盘宏 |
C-u C-u F3 | 把后续按键加到上一键盘宏 |
C-x C-k r | 对区域中开始的每行执行上一键盘宏 |
C-x C-k C-k | 执行在键盘环头的键盘宏 |
C-x C-k C-n | 旋转键盘环(使头为更早定义的) |
C-x C-k C-p | 旋转键盘环(使头为更晚定义的) |
C-x C-k C-i | 插入键盘宏相关的计数器 |
C-x C-k C-c | 设置键盘宏相关的计数器 |
C-x C-k C-a | 把前缀参数加到键盘宏相关的计数器 |
C-x C-k C-f | 指定键盘宏相关的计数器的格式 |
C-x C-k n | 把最近定义的键盘宏绑定到指定的命令名(只在当前会话有效) |
C-x C-k b | 把最近定义的键盘宏绑定到指定的按键序列(只在当前会话有效) |
C-x C-k C-e | 编辑上一键盘宏 |
C-x C-k e name RET | 编辑给定名字的键盘宏 |
C-x C-k l | 编辑最后300次按键作为键盘宏 |
M-x insert-kbd-macro | 插入键盘宏的定义(Lisp代码) |
搜索和替换
Emacs 可以向前或向后搜索字符串(“字符串”指的是一组连续的字符)。搜索命令是一个移动光标的命令:搜索成功后,光标会停留在搜索目标出现的地方。
快捷键 | 用途 |
---|---|
C-s | 开始向下增量搜索 |
C-r | 开始向上增量搜索 |
C-s RET string RET | 向下搜索指定字符串 |
C-r RET string RET | 向上搜索指定字符串 |
M-s w | 若正在增量搜索,则开关词搜索模式,否则开始向下增量词搜索 |
M-s w RET words RET | 向下搜索指定词 |
M-s w C-r RET words RET | 向上搜索指定词 |
M-s _ | 若正在增量搜索,则开关符号搜索模式,否则开始向下增量符号搜索 |
M-s _ | 开始向下增量符号搜索,初始搜索接近的符号 |
M-s _ RET words RET | 向下搜索指定符号 |
M-s _ C-r RET words RET | 向上搜索指定符号 |
C-M-s | 开始向下正则表达式增量搜索 |
C-M-r | 开始向上正则表达式增量搜索 |
C-M-s RET string RET | 向下搜索指定正则表达式 |
C-M-r RET string RET | 向上搜索指定正则表达式 |
M-x multi-isearch-buffers | 开始多缓冲区增量搜索(有前缀参数则用正则表达式指定缓冲区) |
M-x multi-isearch-buffers-regexp | 开始多缓冲区增量正则表达式搜索(有前缀参数则用正则表达式指定缓冲区) |
M-x occur | 显示给定正则表达式在缓冲区各匹配所在的行(可用前缀参数指定多显示多少行上下文),其中可用RET移到匹配位置、o或C-o可在另一窗格显示、C-x ‘转到下一匹配、e可切换为编辑模式、C-c C-c退出Occur模式 |
M-s o | 用上次(或当前)增量搜索的字符串运行occur |
M-x multi-occur | 类似occur,但对多个指定缓冲区进行 |
M-x multi-occur-in-matching-buffers | 类似multi-occur,用正则表达式指定文件名(有前缀参数则指定缓冲区名) |
M-x how-many | 显示光标后或区域中所有与给定正则表达式匹配次数 |
默认情况下,若没有大字字母,则搜索是大小写不敏感的。
快捷键 | 用途 |
---|---|
M-x replace-string RET string RET newstring RET | 把光标后的所有string 替换为newstring |
M-x replace-regexp RET regexp RET newstring RET | 把光标后的所有匹配正则表达式string 的文本替换为newstring ,其中newstring 可用\& 引用匹配的文本、用\数字 引用捕获组、用\# 引用已经替换的次数、用\,表达式 引用Lisp表达式的值 |
M-% string RET newstring RET | 交互式文本替换 |
C-M-% regexp RET newstring RET | 交互式正则表达式替换 |
C-x ESC ESC RET | 重启上一替换 |
M-x flush-lines | 删去光标后或区域中所有与匹配给定正则表达式的文本相交的行 |
M-x keep-lines | 删去光标后或区域中所有没有与匹配给定正则表达式的文本相交的行 |
默认情况下,若没有大字字母,则搜索是大小写不敏感的,这时替换字符串中小写的字符会尝试迫近原来的大小写模式。在交互式替换过程中,可用以下命令:
快捷键 | 用途 |
---|---|
SPC或y | 替换当前匹配 |
DEL或n | 不替换当前匹配 |
, | 替换当前匹配并显示结果,然后按DEL或SPC继续,用C-r修改或用C-x u撤销 |
RET或q | 退出搜索 |
. | 替换当前匹配后结束搜索 |
! | 替换当前缓冲区所有余下的匹配 |
Y | 替换所有余下缓冲区的所有匹配 |
N | 跳过当前缓冲区的所有余下的匹配 |
^ | 回到上个匹配 |
C-r | 进入递归编辑换成什么,用 C-M-c 继续 |
C-w | 删除当前匹配并进入递归编辑换成什么,用 C-M-c 继续 |
e | 编辑替换字符串 |
C-l | 重绘屏幕 |
C-h | 显示选项 |
窗格与窗口
快捷键|用途
:—|:—
C-x 0|关掉当前窗格
C-x 1|只保留当前窗格,关掉其它所有窗格
C-x 2|将当前窗格划分成上下两个窗格,显示同一缓冲区
C-x 3|将当前窗格划分成左右两个窗格,显示同一缓冲区
C-x 4 C-f|在新窗格打开文件并让它成为当前窗格
C-M-v|向下滚动另一的窗格一屏
C-M-S-v|向上滚动另一的窗格一屏
C-x o|切换当前窗格,连续使用可以遍历所有窗格
C-x 4 b bufname RET|在另一窗格显示指定缓冲区并选取它
C-x 4 C-o bufname RET|在另一窗格显示指定缓冲区
C-x 4 f filename RET|在另一窗格显示指定文件并选取它
C-x 4 d directory RET在另一窗格显示指定目录并选取它
C-x 4 m|在另一窗格开始写邮件
C-x 4 .|在当前标签表找
C-x 4 r filename RET|在另一窗格显示指定只读文件并选取它
C-x 4 0|关掉当前窗格并移除相应缓冲区
C-x ^|使当前窗格更高
C-x }|使当前窗格更宽
C-x {|使当前窗格更窄
C-x -|使当前窗格更矮
C-x +|使所有窗格等宽
M-x make-frame