本文介绍 Emacs 的基本概念。
屏幕组织
在图形显示器上,例如在使用 X 窗口系统的 GNU/Linux 上,Emacs 占用一个图形窗口。在文本终端上,Emacs 占用整个终端屏幕。我们将使用帧一词来指 Emacs 占用的图形窗口或终端屏幕。Emacs 在这两种帧上的表现非常相似。通常一开始只有一个帧,但也可以根据需要创建其他帧。
每个帧都由几个不同的区域组成。帧顶部是菜单栏,可以通过一系列菜单访问命令。在图形显示屏上,菜单栏的正下方是工具栏,这是一排图标,点击后可执行编辑命令。帧的最下方是回显区,这里显示信息,当 Emacs 要求输入信息时,你也可以在这里输入信息。
帧的主要区域,即工具栏(如果有的话)下方和回显区上方,称为窗口。因此,在本手册中,我们将在这个意义上使用“窗口“一词。图形显示系统通常使用含义不同的“窗口”一词,但如上所述,我们将这些图形窗口称为“帧”。
Emacs 窗口是显示缓冲区的地方,缓冲区就是你正在编辑或查看的文本或其他图形。在图形显示器上,窗口的一侧有一个滚动条,可以用来滚动缓冲区。窗口的最后一行是模式行。它显示缓冲区中的各种信息,如是否有未保存的更改、正在使用的编辑模式、当前行号等。
启动 Emacs 时,帧中通常只有一个窗口。不过,您可以水平或垂直细分这个窗口,创建多个窗口,每个窗口都可以独立显示一个缓冲区。
在任何时候,一个窗口都是选定窗口。在图形显示屏上,选定窗口显示一个较突出的光标(通常为实心和闪烁);其他窗口显示一个不太突出的光标(通常为空心方框)。在文本终端上,只有一个光标,显示在选定窗口中。选定窗口中显示的缓冲区称为当前缓冲区,编辑工作就在这里进行。大多数 Emacs 命令都隐式地应用于当前缓冲区;未选中窗口中显示的文本主要供参考。如果在图形显示屏上使用多个帧,则选择特定帧就会选择该帧中的窗口。
点
所选窗口中的光标显示大多数编辑命令生效的位置,称为点。许多 Emacs 命令会将点移动到缓冲区中的不同位置;例如,在所需位置单击鼠标键 1(通常是左键),就可以将点移动到该位置。
默认情况下,所选窗口中的光标绘制为实心块,似乎位于一个字符上,但您应该将 point 视为两个字符之间;它位于光标下的字符之前。例如,如果您的文本是 “Arch Linux 中社区
”,光标在“社
”上,那么点就在“中
”和“社
”之间。如果在该位置插入字符,结果就是“Arch Linux 中文社区
”,点位于“文
”和“社
”之间。因此,光标仍和以前一样位于“社
”之上。
回显区
帧最下方的一行是回显区。它用于显示各种用途的少量文字。
回显区之所以叫回显区,是因为它的作用之一就是回显,即在输入多字符命令时显示其中的字符。单字符命令不会有回显。多字符命令如果在输入过程中停顿超过一秒,就会产生回显。然后,Emacs 会回显显示该命令到目前为止的所有字符,以提示您输入其余字符。一旦开始回显,命令的其余部分就会在你输入时立即回显。这种行为旨在为自信的用户提供快速响应,同时为犹豫不决的用户提供最大程度的反馈。
当命令无法执行时,回显区还用于显示错误信息。错误信息可能伴有蜂鸣声或屏幕闪烁。
有些命令会在回显区显示提示信息,告诉您该命令执行了什么操作,或为您提供一些特定信息。这些信息与错误信息不同,不会伴有蜂鸣声或闪光。例如,C-x =
(按住 Ctrl 键并键入 x,然后放开 Ctrl 键并键入 =)会显示一条信息,说明点的字符、它在缓冲区中的位置以及它在窗口中的当前列。耗时较长的命令在运行过程中通常会显示以“...”结尾的信息(有时还会以百分比的形式显示运行进度),并在完成后添加 “done”(已完成)。
回显区的消息保存在一个名为 *Messages* 的特殊缓冲区中。如果错过了屏幕上短暂出现的信息,可以切换到 *Messages* 缓冲区再次查看。*Messages* 缓冲区有一定的行数限制,由变量 message-log-max
指定。(我们也没有解释变量;有关变量的更多信息,请参阅变量)。超过这个限制,每当在末尾添加一行新的信息时,就会从开头删除一行。
回显区还用于显示 minibuffer,这是一个特殊窗口,您可以在此输入命令参数,如要编辑的文件名。使用微型缓冲区时,回显 区显示的文本以提示字符串开头,活动光标显示在微型缓冲区内,minibuffer 暂时被视为选定窗口。您可以通过键入 C-g 退出 minibuffer。
模式行
每个窗口的底部都有一个模式行,用于描述当前缓冲区中正在发生的事情。当只有一个窗口时,模式行会出现在回显区的正上方;它是帧中倒数第二行。在图形显示屏上,模式行以 3D 方框的形式显示。Emacs 通常还会用不同于未选定窗口的颜色来绘制选定窗口的模式线,以使其更加突出。
模式线中显示的文本格式如下:
cs:ch-fr buf pos line (major minor)
在文本终端上,该文本后面会有一连串延伸至窗口右边缘的破折号。在图形显示屏上,这些破折号会被省略。
cs 字符串及其后的冒号字符描述了当前缓冲区使用的字符集和换行约定。通常,Emacs 会自动为您处理这些设置,但有时掌握这些信息也很有用。
cs 描述缓冲区中文本的字符集。如果是破折号('-'),则表示没有特殊的字符集处理(行结束约定可能除外,下一段将介绍)。= 表示不进行任何转换,通常用于包含非文本数据的文件。其他字符表示各种编码系统,例如'1'表示 ISO Latin-1。
在文本终端上,cs 前面还有两个字符,分别描述键盘输入和终端输出的编码系统。此外,如果使用的是输入法,cs 前面还会有一个字符串,用来标识输入法。
cs 后面的字符通常是冒号。如果显示的字符串不同,则表示文件编码的行尾约定不尽相同。通常,文件中的文本行以换行符分隔,但有时也使用其他两种约定。MS-DOS 惯例使用一个回车符,后面跟一个换行符;在编辑此类文件时,冒号会根据操作系统的不同变为反斜线('\')或'(DOS)'。旧版 Macintosh 系统采用的另一种习惯是使用回车符代替换行符;编辑此类文件时,冒号会变为正斜线('/')或'(Mac)'。在某些系统上,对于使用换行符作为行分隔符的文件,Emacs 会显示"(Unix)"而不是冒号。
在为 emacsclient 创建的帧中,下一个字符是"@"。对于作为守护进程运行的 Emacs 进程的帧来说,这种指示很典型。
如果窗口中显示的缓冲区与磁盘上相应文件的内容相同,即缓冲区未修改,则显示两个破折号('--')。如果缓冲区已修改,则显示两颗星('**')。对于只读缓冲区,如果缓冲区已修改,则显示"%*",否则显示"%%"。
ch 后面的字符通常是破折号('-')。但是,如果当前缓冲区的默认目录在远程计算机上,则会显示"@"。
fr 给出所选帧的名称。它只出现在文本终端上。初始帧名为 "F1"。
buf 是窗口中显示的缓冲区名称。通常与正在编辑的文件名相同。请参阅使用多个缓冲区。
pos 显示窗口顶部上方或底部下方是否有附加文本。如果缓冲区较小,窗口中可以看到全部缓冲区,则 pos 为"全部"。否则,如果您看到的是缓冲区的开头,则是 "Top";如果您看到的是缓冲区的结尾,则是 "Bot";或者是 "nn%",其中 nn 是窗口顶部以上缓冲区的百分比。使用 "Size Indication"(大小指示)模式,还可以显示缓冲区的大小。
行是字符 "L",后跟在点处的行号。(打开列号模式,也可以显示当前列号。请参阅可选模式行功能)。
major 是缓冲区中使用的主要模式名称。主要模式是缓冲区的主要编辑模式,如文本模式、Lisp 模式、C 模式等。请参阅主要模式。某些主要模式会在主要模式名称后显示附加信息。例如,编译缓冲区和 Shell 缓冲区会显示子进程的状态。
minor (次要)模式是一些已启用的 minor 模式的列表,它们是在主要模式基础上提供附加功能的可选编辑模式。
有些功能虽然不是真正的 minor 模式,但只要开启,就会与次要模式一起列出。Narrow 表示显示的缓冲区的编辑范围仅限于部分文本。Def 表示当前正在定义键盘宏(请参阅键盘宏)。
此外,如果 Emacs 处于递归编辑层内,模式周围的括号会出现方括号('[...]')。如果 Emacs 处于另一个递归编辑层中的一个递归编辑层,则会出现双方括号,依此类推。由于递归编辑级别会对 Emacs 产生全局影响,因此每个窗口的模式行中都会出现此类方括号。
您可以更改模式行的外观及其内容格式。请参阅可选模式行功能。此外,模式行对鼠标敏感;单击模式行的不同部分可执行各种命令。此外,将鼠标指针悬停在模式行的鼠标敏感区域上会显示工具提示,其中包含通过单击模式行可以调用的命令信息。
菜单栏
每个 Emacs 帧的顶部通常都有一个菜单栏,您可以用它来执行常用操作。无需在此一一列举,因为你可以更容易地看到它们。
在支持鼠标的显示器上,你可以用鼠标从菜单栏中选择命令。菜单项右边的箭头表示它指向一个辅助菜单或子菜单。菜单项末尾的"..."表示该命令在实际执行之前会提示你进一步输入。
菜单栏中的某些命令也有普通的按键绑定;如果有,按键绑定会显示在项目本身之后。要查看某个菜单项的完整命令名称和文档,请键入 C-h k,然后用鼠标以通常的方式选择菜单栏(请参阅 "按键文档")。
您也可以不使用鼠标,而是按 F10
键调用第一个菜单栏项目(运行命令 menu-bar-open
)。然后可以使用箭头键或 C-b
、C-f
(左/右)、C-p
和 C-n
(上/下)浏览菜单。要激活选定的菜单项,请按 RET
;要取消菜单导航,请按 C-g
或 ESC ESC ESC
。(不过请注意,如果 Emacs 是使用图形用户界面工具包创建的,那么菜单的绘制和控制都是由工具包完成的,取消菜单导航的按键顺序可能与上述描述不同)。
在文本终端上,可以选择访问回显区的菜单栏菜单。为此,请将变量 tty-menu-open-use-tmm
设置为非零值。然后键入 F10
将运行 tmm-menubar
命令,而不是下拉菜单。(您也可以键入 M-`
,它将始终调用 tmm-menubar。)tmm-menubar 可让您用键盘选择菜单项。回显区会出现一个临时选项。您可以使用上下箭头键在菜单中移动到不同的项目,然后键入 RET
来选择项目。每个菜单项也由一个字母或数字(通常是项目名称中某个单词的首字母)指定。该字母或数字与项目名称之间用"==>"隔开。您可以键入该项目的字母或数字来选择该项。
用户输入类型
GNU Emacs 主要是为使用键盘而设计的。虽然可以使用鼠标通过菜单栏和工具栏发出编辑命令,但效率通常不如键盘。
Emacs 中的键盘输入是基于 ASCII 的重度扩展版本。简单字符,如 "a"、"B"、"3"、"="和空格符(表示为 SPC),可通过键入相应的键来输入。控制字符,如 RET
、TAB
、DEL
、ESC
、F1
、Home
和 LEFT
,以及非英语键盘上的某些字符,也可以通过这种方式输入。
Emacs 还能识别使用修改键输入的控制字符。例如,按住 Ctrl
键的同时按 a,就可以输入 Control-a
;我们将其简称为 C-a
。同样,Meta-a
或简称 M-a
是按住 Alt
键并按 a
键输入的。修改键也可用于非字母数字字符,例如 C-F1
或 M-LEFT
。
您还可以使用以 ESC
开头的双字符序列输入 Meta
字符。因此,输入 ESC a
可以输入 M-a
。输入 ESC C-a
可以输入 C-M-a
(同时按住 Ctrl
和 Alt
,然后按 a
)。与 Meta
不同,ESC
是作为一个单独的字符输入的。输入下一个字符时不要按住 ESC
,而是按下 ESC
并松开,然后输入下一个字符。在某些 Meta
键无法正常工作的文本终端上,这一功能非常有用。
Emacs 还支持另外 3 个修改键,请参阅修改键。
Emacs 广泛支持使用鼠标按钮、鼠标滚轮和其他指向设备(如触摸板和触摸屏)。
在图形显示器上,窗口管理器可能会阻止某些键盘输入,包括 M-TAB
、M-SPC
、C-M-d
和 C-M-l
。如果遇到这种问题,可以自定义窗口管理器,使其不阻塞这些键,或者重新绑定受影响的 Emacs 命令。
简单字符和控制字符以及某些非键盘输入(如鼠标点击)统称为输入事件。
按键
有些 Emacs 命令只需一个输入事件即可调用,例如 C-f
在缓冲区中向前移动一个字符。其他命令需要两个或多个输入事件才能调用,例如 C-x C-f
和 C-x 4 C-f
。
按键序列(简称按键)是由一个或多个输入事件组成的序列,作为一个单元是有意义的。如果一个按键序列调用了一个命令,我们就称它为一个完整按键;例如,C-f
、C-x C-f
和 C-x 4 C-f
都是完整按键。如果一个键序的长度不足以调用命令,我们就称它为前缀键;从前面的例子中,我们可以看到 C-x
和 C-x 4
都是前缀键。每个按键序列要么是完整按键,要么是前缀按键。
前缀按键与后面的输入事件组合成一个更长的按键序列。例如,C-x
是一个前缀键,因此单独键入 C-x
并不会调用命令;相反,Emacs 会等待进一步的输入(如果暂停超过一秒,它就会回显 C-x
键以提示输入;参见回显区)。C-x
与下一个输入事件组合成一个双事件按键序列,它本身可以是一个前缀键(如 C-x 4
),也可以是一个完整的按键(如 C-x C-f
)。按键序列的长度没有限制,但在实际应用中很少超过三个或四个输入事件。
您不能在一个完整键上添加输入事件。例如,由于 C-f
是一个完整的键,所以 C-f C-k
这个双事件序列是两个键序列,而不是一个。
默认情况下,Emacs 的前缀键是C-c、C-h、C-x、C-x RET、C-x @、C-x a、C-x n、C-x r、C-x t、C-x v、C-x 4、C-x 5、C-x 6、ESC
和 M-g
(F1
和 F2
是 C-h
和 C-x 6
的别名)。例如,如果删除了 C-x 4
的前缀定义,那么 C-x 4 C-f
就会成为一个无效的键序。请参阅自定义按键绑定。
在前缀键后输入帮助字符(C-h
或 F1
),会显示以该前缀开头的命令列表。唯一的例外是 ESC
: ESC C-h
等同于 C-M-h
,后者的功能完全不同。不过,您可以使用 F1
显示以 ESC
开头的命令列表。
鼠标输入
默认情况下,Emacs 支持所有正常的鼠标操作,例如通过单击鼠标左键设置光标,以及通过拖动鼠标指针选择区域。所有鼠标操作都可以用来绑定命令,绑定方式与绑定键盘事件相同(请参阅#按键)。本节概述了如何在 Emacs 中使用鼠标。
单击鼠标左键时,Emacs 会收到一个 mouse-1 事件。要查看该事件绑定了什么命令,可以键入 C-h c
,然后按下鼠标左键。同样,鼠标中键是 mouse-2,鼠标右键是 mouse-3。如果你使用的是带滚轮的鼠标,滚轮事件通常会绑定到 wheel-down 或 wheel-up,或者 mouse-4 和 mouse-5,但这取决于操作系统的配置。
一般来说,传统 X 系统和终端会报告 mouse-4 和 mouse-5,而所有其他系统都会报告 wheel-down 和 wheel-up。
有些鼠标还有水平滚轮,触摸板通常也支持水平滚动。这些事件在所有系统中都会报告为 wheel-left 和 wheel-right,但终端和传统 X 系统除外,在这些系统中报告为 mouse-6 和 mouse-7。
您还可以将键盘修饰符与鼠标事件结合起来,例如,您可以绑定一个特殊命令,当您按住 Meta 键并使用鼠标中键时触发该命令。在这种情况下,事件名称将是 M-mouse-2。
在某些系统中,还可以绑定用于处理触摸屏事件的命令。在这种情况下,事件名称为触摸屏更新(touchscreen-update)和触摸屏结束(touchscreen-end)。
按键与命令
本文中有很多段落告诉你特定按键的作用。但 Emacs 并不直接为按键赋予含义。相反,Emacs 将含义分配给已命名的命令,然后通过将按键与命令绑定来赋予按键含义。
每个命令都有一个由程序员选择的名称。名称通常由几个英文单词组成,中间用破折号隔开,例如 next-line 或 forward-word。在内部,每个命令都是一种特殊的 Lisp 函数,与命令相关的操作通过运行函数来执行。请参阅《Emacs Lisp 参考手册》中的"什么是函数"。
键与命令之间的绑定记录在称为键映射的表中。
当我们说 "C-n 垂直向下移动一行" 时,我们忽略了一个微妙的区别,这个区别在普通使用中无关紧要,但对于 Emacs 的定制却至关重要。命令 next-line 是垂直向下移动一行。C-n
具有这种效果是因为它绑定了 next-line。如果将 C-n
与 forward-word 命令重新绑定,C-n
将向前移动一个字。
在本文中,我们经常把 C-n
等按键说成是命令,尽管严格来说,按键是与命令绑定的。通常情况下,我们在提到运行命令的按键后,会在括号内注明真正执行命令的命令名称。例如,我们会说 "命令 C-n(next-line)将点垂直向下移动",意思是命令 next-line 将点垂直向下移动,而按键 C-n
通常与之绑定。
既然是讨论自定义,我们就应该介绍一下变量。通常情况下,命令的说明中会说:"要改变这一点,请设置变量 mumble-foo"。变量是用来存储数值的名称。本文中记录的大多数变量都是用于自定义的:Emacs 的某些命令或其他部分会检查变量,并根据你设置的值做出不同的行为。在你对自定义变量感兴趣之前,可以忽略有关变量的信息。然后再阅读有关变量的基本信息,这样有关特定变量的信息就会变得有意义。