1.
这篇中级水平的实践教程构建于您在本系列文章前面部分中所学习的知识的基础之上,并向您介绍了如何针对您的特定需求自定义和使用该系统。
在本教程中,您将了解如何管理和操作您的 Emacs 会话视口,即 Emacs X 客户端主窗口和其中显示缓冲区以及其他信息的空间。您将了解对这个区域进行分区的最好方法,包括通过使用水平的和垂直的分割来划分屏幕,为一个 Emacs 会话创建多个 X 客户端窗口,并在每个窗口中显示多个缓冲区。您还将研究如何使用鼠标对这些区域进行操作。
本教程演示了如何在 Emacs 中对您的视图进行操作:如何对一个 Emacs 窗口进行分区和划分,以及如何使得多个 Emacs 窗口附加到一个 Emacs 会话。
在完成本教程的学习之后,您将了解如何操作框架和它们所包含的窗口,包括使用一些鼠标技术来完成这项任务。
在开始学习本教程之前,您应该先完成本系列文章中前几部分教程的学习。它们为 Emacs 的学习打下了坚实的基础,并说明了您在本教程中将要使用到的许多 Emacs 概念(请参见参考资料)。
在本系列文章第一个教程(Emacs 编辑环境,第 1 部分:学习 Emacs 的基础知识,请参见参考资料)的介绍部分中,描述了用于表示键盘输入的特殊 Emacs 符号,在本教程和整个系列文章之中都将使用到这些特殊的符号。
尽管本教程面向所有不同级别的 UNIX 专业技术人员,但如果您至少对 UNIX 文件系统具有基本的了解,那么这将是很有帮助的:
文件
目录
权限
文件系统层次结构
本教程需要您在基于 UNIX 的系统中有一个用户帐户,且此系统中安装有最新版本的 Emacs。
Emacs 有几个版本;最原始,也是最流行的是 GNU Emacs,它是由 GNU 工程在线发布的(请参阅参考资料)。
您必须拥有较新版本的 GNU Emacs,即版本 20 或更高版本。版本 20 和 21 是最常见的,您也可以获得版本 22 的开发快照。本教程可与这些版本的 Emacs 中的任何一种配合使用。如果您的系统运行的是较早的版本,您应该进行升级。
为了了解您运行的是什么版本的 Emacs,请使用 GNU 风格的 –version 标志:
emacs–versionGNUEmacs22.0.91.1Copyright(C)2006FreeSoftwareFoundation,Inc.GNUEmacscomeswithABSOLUTELYNOWARRANTY.YoumayredistributecopiesofEmacsunderthetermsoftheGNUGeneralPublicLicense.Formoreinformationaboutthesematters,seethefilenamedCOPYING.
因为本教程专门研究对 X 窗口系统环境中 Emacs 图形元素的操作,所以您应该拥有一台正常运行的 X 服务器。
本教程使用了一个由两个文件组成的示例数据集,并在一个存档文件中提供了该数据集(请参见下载部分以获取相应的链接)。
2.
对您的 Emacs 会话进行划分和分区
您可以使用许多命令来控制 Emacs 窗口,它是您所看到的、以 Emacs X 客户端窗口为框架的一个缓冲区的视图,这个 X 客户端窗口中包含该缓冲区本身及其模式行(在它的下方)。这些命令通过各种方式对您的窗口进行分区,以允许您同时查看多个缓冲区。实际上,这些都是用于 Emacs 客户端窗口操作的所有命令中最常用的一些命令。
本教程中的示例使用了一个示例数据集,并在一个压缩的存档文件中提供了该数据集(请参见下载部分)。这个存档文件中包含一个 tar 存档文件,而 tar 存档文件包含了两个纯文本文件 innocence 和 experience,它们的内容分别是 William Blake 的 The Songs of Innocence 和 The Songs of Experience 的完整文本,其中您将看到来自以前的教程的一些文本。要开始学习本教程,首先将这两个文件解压缩到您自己的示例目录中。
对 Emacs 窗口进行分区的最常见的方式可能是从屏幕的中间将其分为两半。这一操作将生成两个新的窗口,其中每个窗口都具有它自己的模式行,并且每个窗口的高度都大约为原始高度的一半。您以水平方向对 Emacs 屏幕进行了切分,所以这两个新的窗口在一个垂直的列中相互堆叠;因而,我们称这种窗口操作为垂直 划分。
要进行这样的划分,可以运行 split-window-vertically 功能,它与 C-x 2 按键进行了绑定。
尝试使用示例文件进行这一操作:
通过在包含这两个示例文件副本的目录中键入 emacs,启动 Emacs。
打开这些文件:
C-x C-f innocence Enter C-x C-f experience Enter
对窗口进行划分:
C-x 2
请注意,在对窗口进行划分时,活动的缓冲区(名为 experience,是您最后打开的一个缓冲区)将出现在这两个窗口中。在顶部窗口中的缓冲区现在是活动缓冲区,并包含一个活动光标。在这个顶部窗口中切换到 innocence 缓冲区:
C-x b Enter
您的 Emacs 会话应该与图 1 中所示类似。
垂直地划分一个 Emacs 窗口
顺便提一下,当您使用两个文件作为参数启动 Emacs 时,将得到相同的两个垂直划分的缓冲区,这是由 Emacs 自动划分的,正如本系列文章第 4 部分教程“Emacs 选项、寄存器和书签”中所描述的。键入 C-x C-c 以退出 Emacs,然后针对示例文件尝试这一操作:
$ emacs innocence experience
请注意其中的一处区别:当您将两个文件指定作为命令行参数时,底部的窗口(其内容为第二个参数)将成为活动窗口。
您并不仅限于同时使用两个窗口,Emacs 可以根据屏幕的大小显示许多窗口。但请记住,当您进行一次划分时,Emacs 将对当前窗口进行划分,而不会涉及到所有其他窗口。
例如,在这两个窗口中,底部的窗口现在是活动的;键入 C-x 2,以便仅划分下面的这个窗口。
现在,将您的 Emacs 屏幕划分为了三个窗口,并且中间的窗口是活动的。键入 C-x 2,以便再次划分中间的窗口,在 Emacs 屏幕中一共生成了四个窗口,然后再次键入 C-x 2,以尝试对第二个、很小的那个窗口进行划分。根据 Emacs X 客户端主窗口的尺寸,对分割的窗口所进行的这种递归划分迟早将会中止,即当任何新的窗口太小,以至于不能够显示至少两行文本和模式行时;这时候,Emacs 将发出蜂鸣声,并在迷你缓冲区中报告,无法再继续对给定的窗口进行划分。您的会话应该与图 2 中所示类似。
多个 Emacs 垂直划分
您可以使用这些划分的窗口同时查看多个缓冲区,但是它同样有助于在多个窗口中查看相同的缓冲区,更确切的说,在不同的窗口中查看缓冲区的不同部分。在您查看缓冲区中另一个部分的同时,对缓冲区中的某个部分进行编辑,这是强大的编辑功能中最有用的技巧之一。它是非常有用的。
现在,请尝试下面的操作:
通过键入 C-x C-c 退出 Emacs,然后使用一个文件启动它:
$ emacs experience
键入 M->,以移动到缓冲区的末尾。
键入 C-x 2 以垂直地划分窗口,并且这两个窗口中显示了相同的缓冲区。
移动到活动窗口中的缓冲区的顶部:键入 M-<。
使用向下箭头键,将光标向下移动几十行。当该缓冲区出现在顶部的窗口中时,您可以在其中进行移动,但是 Emacs 总是在底部的窗口中显示相同的缓冲区的尾部。
当您在划分一个窗口时,Emacs 将自动地决定划分的尺寸,它通常从中间将缓冲区划分为两半,所以垂直划分所创建的两个新的缓冲区,其中每一个都恰好是原始窗口大小的一半。但是您也可以使用行数来指定其大小,即通过在划分命令之前使用一个数字,指定垂直划分的顶部窗口应该具有的行数(包括它的模式行)。
尝试将该缓冲区一分为二,并使顶部的缓冲区为九行内容的高度:
通过键入 C-x C-c 退出 Emacs,然后使用一个文件启动它:
$ emacs experience
键入 M-9 C-x 2 以划分该缓冲区,并使顶部的缓冲区为九行内容的高度。
要为底部的缓冲区而不是顶部的缓冲区指定行数,可以使用一个负数。
尝试将该缓冲区一分为二,并使底部的缓冲区为四行内容的高度:
通过键入 C-x C-c 退出 Emacs,然后使用一个文件启动它:
$ emacs experience
键入 M-- M-4 C-x 2 以划分该缓冲区,并使底部的缓冲区为四行内容的高度。
C-x 2 可以进行垂直划分,但是用于划分窗口的许多重要的键绑定都是使用 C-x 4 前缀作为开始的。
要在一个新的缓冲区中以及一个新的窗口中打开一个新的文件,可以使用 find-file-other-window 功能,它与 C-x 4 f 进行了绑定。然后,给出该文件的文件名。要打开只读文件,则可以使用 find-file-read-only-other-window,并给出其文件名。它与 C-x 4 r 进行了绑定。
尝试在其他窗口中的一个新的缓冲区中打开 innocence 文件:键入 C-x 4 f innocence Enter 。
尽管当您指定一个四行的窗口时,另一个窗口已经存在,但是请注意这个命令如何调整它的大小,以便活动窗口和新的窗口具有大致相同的尺寸。
switch-to-buffer-other-window 功能与 C-x 4 b 进行了绑定,它用于垂直地划分窗口,并允许您选择要在新的窗口中显示哪一个缓冲区,而该窗口也将成为活动窗口。
尝试使用这个命令,将另一个窗口中的缓冲区切换到 innocence 缓冲区:键入 C-x 4 b innocence Enter ,请注意,它不会对您输入该命令的窗口进行更改,现在,它也显示了 innocence 缓冲区。
要在另一个垂直的窗口中显示一个新的缓冲区,但保持活动光标仍然位于当前窗口中,可以运行 display-buffer 功能,它与 C-x 4 C-o 进行了绑定。它提示输入需要在另一个窗口中显示的缓冲区的名称,但是当前窗口仍然是活动的。如果该显示仅有一个窗口,那么这个功能将对其进行划分,并创建一个新的窗口,但是如果该显示已经有两个或者更多个窗口,那么不进行新的划分。
尝试使用这一命令,将底部窗口中的缓冲区切换到 experience 缓冲区:键入 C-x 4 C-o experience Enter 。
当您的 Emacs 会话中具有多个窗口时,不会影响光标的移动,您可以在当前活动窗口中正常地移动,就如同在您的会话中只有一个窗口一样。并且当您滚动这个窗口时(使用滚动条,或者使用各种用于滚动的键),其他的窗口都不会滚动,即使这些窗口显示了相同缓冲区的副本。
要滚动另一个 窗口,而不是光标所在的窗口,可以使用 scroll-other-window 功能,它与 C-M-v 进行了绑定。(Emacs 将您所有的窗口保存在一个排序的列表中,所以如果您打开了两个以上的窗口,这一命令将滚动列表中的下一个窗口。)
现在,尝试键入 C-M-v,以滚动下面的窗口(该窗口中包含 experience 缓冲区),直到看到标题“A Little Boy Lost”为止。
通过启用 scroll-all 模式,您可以同时滚动所有的打开了相同缓冲区的窗口。这一功能是可以进行切换的,当它处于活动状态时,模式行将显示 SL。它将相同缓冲区的所有窗口一同移动,即使这些窗口显示了缓冲区中完全不同的部分,即将您键入的滚动命令应用于包含该缓冲区的所有窗口。
现在,请尝试下面的操作:
键入 C-x b experience Enter ,以便在顶部窗口中切换到 experience 缓冲区。
通过键入 M-x scroll-all-mode 打开 scroll-all 模式。
当顶部的窗口仍然处于活动状态时,通过键入 PgDn,同时滚动两个窗口。
通过按向上箭头键,在两个窗口中向上移动光标;多次按向上箭头键,以便该缓冲区的顶部出现在顶部窗口中,继续按向上箭头键,这时可以观察到光标在底部窗口中移动,而不在顶部窗口中移动。
通过多次按向下箭头键,在两个窗口中向下移动光标。
要在两个窗口之间移动,可以运行 other-window 功能,C-x o,它将移动到下一个窗口。当您重复地运行该命令时,它循环地遍历所有的窗口。当您移动到另一个窗口时,将在该缓冲区的当前位置绘制光标。
通过使用 windmove 命令直接指定光标,您也可以将光标移动到其他窗口,如表 1 所述。
功能 描述
windmove-up 移动到正好位于当前窗口上方的窗口,如果该窗口存在的话。
windmove-down 移动到正好位于当前窗口下方的窗口,如果该窗口存在的话。
windmove-left 移动到正好位于当前窗口左边的窗口,如果该窗口存在的话。
windmove-right 移动到正好位于当前窗口右边的窗口,如果该窗口存在的话。
现在,请尝试下面的操作:
键入 C-x o,以移动到底部的窗口。
关闭 scroll-all 模式:键入 M-x scroll-all-mode,然后再次向下滚动到“A Little Boy Lost”,请注意顶部的窗口不再滚动。
通过键入 C-x o,移回到顶部的窗口。
使用 C-x 2,对这个窗口进行划分。
通过键入 M-x windmove-down,向下移动到您刚刚划分的窗口。
有几种方式可以删除 Emacs 窗口。
要删除当前 窗口(即活动光标当前所在的窗口),可以运行 delete-window 功能,它与 C-x 0 进行了绑定。
现在,尝试删除您刚刚创建的第三个窗口:键入 C-x 0。
要删除除了 当前窗口之外所有的窗口,可以运行 delete-other-windows 功能,它与 C-x 1 进行了绑定。
尝试下面的操作:键入 C-x 1。
当您删除一个窗口时,您并不会关闭它所显示的缓冲区,该缓冲区在 Emacs 中仍然保持打开。要删除当前窗口,并且 同时关闭其缓冲区,可以运行 kill-buffer-and-window 功能,它与 C-x 4 0 进行了绑定。
尝试下面的操作:
垂直地将窗口划分为两半:键入 C-x 2,以便在您的 Emacs 会话中得到两个窗口。
将光标移动到这首诗的标题中的 BOY 和 LOST 之间的空格处,并键入 M-t,以调换这两个单词。
将当前缓冲区 experience 写入到一个名为 new.experience 的新的文件:键入 C-x C-w new.experience。
使用 C-x 4 0 关闭该缓冲区和窗口。键入 y 以进行证实。
当您进行这一操作时,关闭了 new.experience 缓冲区,并且您的 Emacs 会话再次只包含一个窗口。
对应于刚刚描述的 split-window-vertically 功能的是 split-window-horizontally,它与 C-x 3 进行了绑定。这一功能将当前 Emacs 窗口从中间划分为两半,并将这两个新的窗口沿水平方向排成一行,因此它们相互紧靠在一起。对于并列地查看类似的缓冲区,这种方法是特别合适的。尝试下面的操作:
在一个新的缓冲区中打开 experience 文件:键入 C-x C-f experience Enter 。
键入 C-x 3,以水平方向将该窗口划分为两半。
键入 C-x b Enter ,以便将最左边窗口的内容更改为 innocence 缓冲区。
您的 Emacs 会话应如 图 3 所示。
在水平 Emacs 窗口中的示例文件
与垂直划分一样,您可以在这个功能的前面使用一个数值参数以指定左边 窗口应该具有的字符数目宽度;如果您给出了一个负数,那么它将指定右边 窗口的宽度。
尝试下面的操作:通过键入 C-u 11 C-x 3,以水平方向将当前窗口划分为两半,并使最左边的窗口具有 11 个字符宽度。
请注意,您给出的数值包括用于最左边窗口的滚动条的一个字符、用于滚动条和缓冲区的内容之间的空白列的一个字符、缓冲区本身的列、用于箭头图形(指示一行内容是否超出了它的显示宽度)的一列,以及该划分生成的第二个窗口的滚动条。在这一示例中,您刚刚创建的最左边的窗口具有可显示七个字符的宽度,如图 4 中所示。
Emacs 中的多个水平窗口
与相同缓冲区的垂直划分一样,可以分别地处理相同缓冲区的任何水平划分。在一个窗口中的滚动操作和光标移动不会影响其他窗口,所以当您在一个窗口中移动光标时,它不会影响任何包含相同缓冲区的其他窗口。但是您可以使用另一个技巧。如果您打开了follow-mode,那么您就可以根据相同缓冲区的多个窗口生成一个较大的“虚拟”窗口。
通过这种方式,当您对窗口进行水平划分时,这些窗口将显示该缓冲区中不同的、但又相连的部分,从而为该缓冲区生成一个较大的虚拟窗口。将光标移动到一个窗口的末尾,这样可以使其进入到一个窗口的开始处。
尝试下面的操作:
键入 C-x 1 以删除所有的窗口,并键入 C-x 3,以便水平地将单个窗口划分为两半。现在您的 Emacs 会话包含两个窗口,每个窗口都包含了 innocence 缓冲区,并且每个窗口的光标都位于缓冲区的顶部。
键入 M-x follow-mode 为该缓冲区启用这种模式。请注意,单词 Follow 出现在两个窗口的模式行中。第二个窗口的内容发生了更改:现在,它恰好接着左边窗口中的内容,以该窗口的下一行内容作为开始。
通过按向下箭头键,在左边的窗口中,将光标在缓冲区中向下移动,并观察当到达该窗口的底部时所发生的情况:光标将移动到右边窗口的顶部。
在右边的窗口中向下移动光标,并观察如何重绘这两个窗口。使用向上箭头键,在右边的窗口中向上移动光标,并观察当到达该窗口顶部时所发生的情况:光标移动到左边窗口的底部。
这个功能是可以进行切换的。再次运行它,就可以在这个缓冲区中关闭它:键入 M-x follow-mode,并注意 Follow 不再出现在模式行中。
尽管 follow-mode 同样可以工作于垂直划分的缓冲区中,但是在大多数情况下,使用这一模式没有任何优势。
到目前为止,您要么为窗口使用缺省大小,要么在创建它们时指定它们的大小。但是您可以在任何时候调整任何 Emacs 窗口的大小。
要使当前窗口变得更高些,可以运行 enlarge-window 功能,它与 C-x ^ 进行了绑定。要使它变得更矮些,可以在这一功能之前使用 M–。要按照特定的行数缩小或者增大窗口,可以给出具体的数值(使用通用的参数 C-u)。
您还可以更改窗口的宽度。要使当前窗口变得更窄,可以运行 shrink-window-horizontally 功能,它与 C-x { 进行了绑定。要使它变得更宽,可以运行 enlarge-window-horizontally 功能,它与 C-x } 进行了绑定。
尝试确定您的 Emacs 会话中某些窗口的形状:
键入 C-x 1 以关闭任何现有的窗口,并键入 C-x b innocence Enter ,以便在这一窗口中打开 innocence 缓冲区。
使用 C-x 3 水平地将这个窗口划分为两半。
通过键入 C-x 4 C-o experience Enter ,在最右边的窗口中切换缓冲区。
通过键入 C-x 2 C-x o C-x b experience Enter ,垂直地将最左边的窗口划分为两半,并使 experience 缓冲区处于底部的窗口中。
通过键入 C-s sunf 搜索标题,将光标移动到“Ah, Sunflower”诗的开头,然后键入 C-u 6 C-l 以重绘该窗口,并使这首诗呈现在眼前。
通过键入 M-- M-5 C-x ^ C-l,将这一窗口收缩五行,并重绘它。
因为窗口的宽度不足以显示它们,所以隐藏了一些行。通过键入 C-x } C-x } 使该窗口增加两个字符的宽度。
如果在调整大小时,您将该窗口设置得过小,以至于其中的行数不足以绘制窗口及其模式行,那么将关闭该窗口。尝试下面的操作:
移动到这个窗口上方的窗口:键入 windmove-up。
键入 C-u -5 C-x ^ 将该窗口收缩五行。
多次尝试这一操作:键入 C-u -5 C-x ^,并再次键入它以继续收缩这一窗口。继续进行这一操作直到该窗口消失。
您可以进行更多调整。要缩小该窗口的大小(如果可能的话),可以运行 shrink-window-if-larger-than-buffer 功能,它与C-x - 进行了绑定。通过运行 balance-windows 功能,您还可以平衡所有可见窗口的大小。它使得所有的窗口都具有大致相同的尺寸。它与 C-x + 进行了绑定。
尝试下面的操作:键入 C-x 2 C-x 2 以生成更多的窗口,并键入 C-x + C-x + 以平衡它们的高度。
除了使用这些命令之外,您还可以使用鼠标调整窗口大小,正如您将在“使用鼠标调整窗口大小”部分中学习到的。
通常,可以使用多个窗口以比较缓冲区的内容。compare-windows 功能允许您完成这项任务:它可以比较两个窗口中的文本,从两个窗口中光标处的字符开始,并将光标移动(在两个窗口中)到第一个不同的字符处。如果这两个文件是完全一样的,那么将光标移动到这两个缓冲区的末尾。
现在,尝试针对名为 experience 的示例文件和您以前编辑的 new.experience 文件运行它:
通过键入 C-x C-c 退出 Emacs,然后使用一个文件启动它:
$ emacs experience
键入 C-x f new.experience,以便在一个新的缓冲区中打开您编辑过的文件。
通过键入 C-x 3 C-x b Enter ,垂直地划分屏幕,并使得每个缓冲区都位于它自己的窗口中。
键入 M-x compare-windows 以运行比较操作。
两个窗口中的光标移动到文件中第一个不同的位置:这首诗的标题(您在前面对其进行了更改)。您的 Emacs 会话应该与图 5 中所示类似。
比较两个 Emacs 窗口的内容
表 2 中包含了用于操作窗口的常见 Emacs 命令的列表,给出了它们的键绑定(如果适用的话),并描述了它们的功能。
功能 绑定 描述
split-window-vertically C-x 2 从中间将当前窗口划分为两半,垂直地堆叠新的缓冲区。
switch-to-buffer-other-window C-x 4 b 垂直地将当前窗口划分为两半,提示输入缓冲区以使用底部的窗口,并将其作为活动窗口。
display-buffer C-x 4 C-o 在另一个窗口中显示一个缓冲区,提示输入缓冲区以使用另一个窗口,但保持当前窗口为活动窗口。(如果仅存在一个窗口,那么垂直地划分该窗口以显示另一个缓冲区。)
find-file-other-window C-x 4 f 在新的缓冲区中打开新的文件,在新的垂直窗口中绘制它。
find-file-read-only-other-window C-x 4 r 在一个新的只读缓冲区中打开新的文件,在新的垂直窗口中绘制它。
scroll-other-window C-M-v 滚动到下一个由 C-x o 切换到的窗口。
scroll-all 切换 scroll-all 次要模式。当它处于打开状态时,将同时滚动显示当前窗口中的缓冲区的所有窗口,并滚动均等的相应距离。
other-window C-x o 将光标移动到下一个窗口,并使其成为活动窗口。
windmove-up 移动到恰好位于当前窗口上方的窗口,如果它存在的话。
windmove-down 移动到恰好位于当前窗口下方的窗口,如果它存在的话。
windmove-left 移动到恰好位于当前窗口左边的窗口,如果它存在的话。
windmove-right 移动到恰好位于当前窗口右边的窗口,如果它存在的话。
delete-window C-x 0 删除当前窗口,并将光标移动到使用 C-x o 将切换到的下一个窗口。
delete-other-windows C-x 1 删除当前窗口之外的所有窗口。
kill-buffer-and-window C-x 4 0 删除当前窗口,并剪切它的缓冲区。
split-window-horizontally C-x 3 将当前窗口从中间划分为两半,水平地堆叠新的缓冲区。
follow-mode 切换 follow 次要模式。当它在缓冲区中处于打开状态时,将所有显示该缓冲区的窗口连接为一个较大的虚拟窗口。
enlarge-window C-x ^ 使当前窗口增加一行的高度;在其之前使用一个负数,将使得当前窗口减少一行的高度。
shrink-window-horizontally C-x } 使当前活动窗口减少一列的宽度。
enlarge-window-horizontally C-x { 使当前活动窗口增加一列的宽度。
shrink-window-if-larger-than-buffer C-x - 将当前活动窗口的大小缩小到对于它所包含的缓冲区来说可能的最小尺寸。
balance-windows C-x + 平衡所有窗口的尺寸,使它们的大小大致相等。
compare-windows 将当前窗口与下一个窗口进行比较,在两个窗口中从光标处开始比较,并在两个缓冲区中将光标移动到第一个不同的字符处,直到到达缓冲区的末尾为止。
3.
移动并操作 Emacs 框架
在 X 中,通常将一个在它自己的 X 客户端窗口中运行的应用程序称为一个窗口。但是因为 Emacs 对于单词窗口 有它自己的定义,正如在前面的部分中所描述的,Emacs 为整个 Emacs X 客户端窗口使用了另一个术语:称其为框架。
Emacs 支持为相同的 Emacs 会话打开多个框架。当您在多个框架中打开一个缓冲区时,更改将出现在所有框架的缓冲区中。关闭一个框架并不会影响到其他框架,但使用通常的 save-buffers-kill-emacs 功能(C-x C-c)退出一个框架,将保存所有框架的缓冲区,并退出所有的框架。
如果您处于一个控制台窗口中,那么这些命令仍然可以起作用,尽管一个控制台一次只能显示一个框架。在控制台中,通过给定的框架编号区分各个框架,该编号出现在模式行中(并且前面使用了一个 F 字符)以区分每个框架。
make-frame-command 功能,C-x 5 2,可以生成一个新的框架,并使其处于活动状态:
通过键入 C-x C-c 退出 Emacs,然后使用一个文件(您创建的新的文件)启动它:
$ emacs new.experience
键入 C-x 5 2 以生成一个新的框架。(它出现在您桌面上的确切位置,取决于您的窗口管理器。)它也包含了 new.experience 缓冲区的一个副本。
编辑一行:键入 C-u 381 C-n M-f M-f M-f M-t。对于两个框架中的这个缓冲区,将在模式行中出现星号。
C-x 4 命令用于 Emacs 窗口,C-x 5 命令用于 Emacs 框架。对于用于生成新窗口的所有 C-x 4 命令,正如在垂直地划分一个窗口部分中所描述的,都存在 C-x 5 等价操作:例如,switch-to-buffer-other-frame 功能是 C-x 5 b。
尝试下面的操作:
键入 C-x C-f experience Enter ,以便在一个新的缓冲区中打开 experience 文件的副本。
键入 C-x 5 b experience Enter ,以便在一个新的框架中打开这个缓冲区的副本。
find-file-other-frame 功能,它与 C-x 5 f 进行了绑定,提示输入一个文件名,并在新的框架中打开给定的文件。同样地,find-file-read-only-other-frame,它与 C-x 5 r 进行了绑定,在新的框架中打开给定的文件,并将其作为一个只读缓冲区。
尝试使用单步操作查找一个文件,并在一个新的框架中打开它,:键入 C-x 5 f innocence Enter 。
现在您的 Emacs 会话应该与图 6 所示类似,其中包括四个不同的 X 客户端窗口。
运行多个 Emacs 框架
使用 other-frame 功能,C-x 5 o,可以在框架之间进行移动。
与它的 Emacs 窗口等价操作 C-x o 一样,这个功能在所有的当前 Emacs 框架之间循环,提升 每个框架,以使其获得焦点并位于任何其他窗口之上,且选择其作为当前框架。
尝试在已经打开的四个框架之间循环: C-x 5 o C-x 5 o C-x 5 o C-x 5 o C-x 5 o。
如果您使用 X 控件以关闭一个框架,或者使用 C-x C-c 命令以退出 Emacs,那么您将退出所生成的所有框架。然而,用以销毁 一个框架的 X 控件,仅仅销毁特定的框架;它既不会关闭在该框架中打开的任何缓冲区,也不会销毁其他 Emacs 框架。
您还可以从 Emacs 删除框架。要删除当前框架,可以使用 delete-frame 功能,C-x 5 0。在删除了当前框架之后,将使下一个框架成为活动框架和当前框架。如果您尝试在会话中仅有的框架上运行这一操作,那么 Emacs 将发出蜂鸣声,并报告一个错误。现在尝试这一操作,以删除您所在的框架。
要删除除了 当前框架之外的所有框架,可以使用 delete-other-frames 功能,C-x 5 1。将删除当前框架之外的所有框架,如果它们存在的话。现在尝试这一操作以删除剩余的两个框架,以便回到一个 Emacs 框架。
请注意,这些命令并不会关闭缓冲区,在完成删除操作之后,在所删除框架的窗口中显示的任何缓冲区仍然可用于当前框架。
在控制台中,C-z 通常将 Emacs 挂起到后台;在 X 中,它将运行 iconify-or-deiconify-frame 功能。这一操作将图标化当前框架;但是如果已经图标化了当前框架,它将取消该框架的图标化。
尝试下面的操作:在您已经打开的当前框架中键入 C-z。根据您正在运行的 X 的版本和窗口管理器,以及您系统中的桌面软件,应该对 Emacs 窗口进行图标化。然后,对图标化的框架再次按 C-z,以取消它的图标化,并使得图标化的框架重新获得焦点。
表 3 中包含了用于操作框架的常见 Emacs 命令列表,给出了它们的功能名及其缺省的键绑定(如果适用的话),并描述了它们的功能。
功能 绑定 描述
make-frame-command C-x 5 2 生成一个新的 Emacs 框架,并使其成为活动框架。
switch-to-buffer-other-frame C-x 5 b 在另一个框架中打开指定的缓冲区。如果不存在其他框架,则创建一个新的框架。
find-file-other-frame C-x 5 f 在另一个框架中打开指定的文件。如果不存在其他框架,则创建一个新的框架。
find-file-read-only-other-frame C-x 5 r 在另一个框架中的只读缓冲区中打开指定的文件。如果不存在其他框架,则创建一个新的框架。
other-frame C-x 5 o 移动到下一个框架,并使其成为活动框架。
delete-frame C-x 5 0 删除当前框架,并使下一个框架成为活动框架。
delete-other-frames C-x 5 1 删除当前框架之外的所有框架。
iconify-or-deiconify-frame C-z 图标化当前框架。如果该框架已经图标化了,那么取消它的图标化。(在控制台中,这个绑定将挂起 Emacs。)
4.
Emacs 窗口和鼠标
在 Emacs 窗口中使用鼠标,有一些非常有价值的技术。
您可以使用鼠标执行在对您的 Emacs 会话进行划分和分区部分中所描述的许多功能。这些窗口操作可以在模式行中完成。
在 Emacs 的新版本中,模式行的特定区域具有它们自己的鼠标绑定。例如,如果您的模式行显示了您是否有邮件(它通过书写单词Mail 来完成这一任务),然后以某种方式使用鼠标在模式行中单击该单词,将为您的邮件启动一个新的缓冲区;单击模式行中该缓冲区的名称,会将该窗口中的缓冲区切换到缓冲区列表中的下一个缓冲区。当您将鼠标位于模式行中特定区域的上方时,将使用一个弹出框显示相应的内容,这些内容称为工具提示。除了这些特殊的工具提示之外,下面的命令也可以用于模式行中的任何位置。
在模式行上以 C-B2 组合方式进行单击,将在您单击的位置对窗口进行水平地 划分。如果您太靠近窗口的上下边缘,那么该划分是可能的最小尺寸。(通过按住 Ctrl 键,然后单击中间的鼠标按钮,就可以输入这个组合。)
在滚动条上输入 C-B2 组合,将在您单击鼠标的位置垂直地 划分窗口。如果您太靠近窗口的上下边缘,那么该划分是最小尺寸。(请注意,当前这一操作并不使用实现滚动条的某些 X 工具包。)
尝试使用鼠标划分窗口:
如果 Emacs 正在运行的话,通过 C-x C-c 退出它。使用示例文件之一,再次启动它:
$ emacs innocence
在一个新的垂直窗口中打开第二个示例文件:键入 C-x 4 f experience Enter 。
您的 Emacs 会话应该与图 1 中所示类似。尝试在顶部模式行的中间(即恰好位于单词 Top 之后的某处)使用 C-B2 鼠标组合,以便在该位置处水平地划分顶部的窗口。
在模式行上大约相同的位置使用 C-B2 鼠标组合,水平地划分底部的窗口,同样是在恰好位于单词 Top 之后的某处。
在您刚刚创建的两个新窗口的滚动条下面的小垂直条上单击并拖动 鼠标左键,以对其进行调整,使得所有四个窗口具有大致相同的大小。如果您的 Emacs 框架太小,而不能够显示所有四个窗口中的文本,那么您可以使用窗口管理器控件以调整 X 客户端框架的大小。
通过在您希望移动到的窗口的模式行的空白区域上单击 鼠标左键(第一个鼠标按钮),您可以使用鼠标移动到任何 Emacs 窗口。(在 Emacs 的新版本中,单击缓冲区名可以将该窗口中的可见缓冲区更改为缓冲区列表中的下一个缓冲区。)您单击其模式行的窗口将成为活动窗口,并且将活动光标移动到了该窗口中的当前位置。
您还可以使用鼠标移动到另一个窗口中可见部分的任何位置:要完成这一任务,在该窗口中单击 鼠标左键。光标将移动到您单击的位置。
尝试在您刚刚创建的四个窗口之间移动:
通过在其模式行的空白区域单击 鼠标左键,移动到右上方的窗口,然后键入 C-u 349 C-n 在该文件中向下移动。
通过在可见缓冲区窗口中的任何字符上单击 鼠标左键,移回到左上方的窗口,然后键入 C-s Till C-s C-s C-a,以便在缓冲区中的其他位置重新聚焦该显示。
暂停鼠标操作,并通过键入 C-x o C-x o 移动到左下方的窗口,正如您在移动到另一个窗口部分中所学习的。键入 C-u 286 C-n,以便在该缓冲区中向下移动。
在右下方窗口模式行中的缓冲区名称之后的某处,单击 鼠标左键,以使其成为活动窗口。键入 C-s jour C-l,以便将这个窗口中的视图移动到缓冲区中的其他位置。
您还可以在模式行上使用鼠标调整窗口大小。对于您先前在调整窗口大小部分中所学习的方法而言,这是一个替代方法。
要使窗口变得更高或者更矮,可以使用 鼠标左键 单击并拖动模式行。要使窗口变得更窄或者更宽,可以单击并拖动其滚动条下方的小垂直条。
尝试使用鼠标调整窗口大小:
单击并稍微拖动 鼠标左键 以及右上方窗口滚动条下面的小垂直条,从而使得右上方窗口的宽度缩小几个字符,并使左上方窗口变得足够大,以便能够在这两个缓冲区的窗口中显示每行所有的字符。(您可能还需要使用窗口管理器的控件,以增大 Emacs 框架。)
通过在模式行上单击并拖动 鼠标左键 使底部的两个窗口变得更小,从而使底部的窗口收缩几行。
如果您按照这一部分中的所有步骤进行了操作,那么您的 Emacs 会话应该与图 7 所示类似。
使用鼠标生成 Emacs 窗口并调整其大小
要删除一个窗口,可以在它的模式行上单击 鼠标右键。在模式行的空白区域上单击 鼠标中建,以关闭所有 其他窗口,并扩大该窗口,使其填满整个框架。
去掉一些窗口:
在左上方窗口的模式行上单击 鼠标右键,以删除该窗口。右上方的窗口向左边扩大以填满这个空间;现在这个窗口成为了活动窗口。
在它的模式行上单击 鼠标中建,以删除它下面的两个窗口,并使这个上面的窗口填满整个 Emacs 框架。
有时在 X 中,鼠标指针可能会妨碍您的 Emacs 会话,比如您选择了一个 Emacs 框架并开始进行编辑,并且鼠标指针悬停于某处文本的上方。
如果您觉得这种情况很讨厌,那么您可以使用 mouse-avoidance-mode 以更改鼠标指针的行为。这个模式提供了几种技术,如表 4中所述。
模式 描述
animate 只要光标靠近鼠标指针,就使得鼠标指针迅速地移动到该框架中的一个随机位置。
banish 一旦您开始键入,就将鼠标指针驱逐到该窗口的右上角。
cat-and-mouse 用作 animate 的同义词。
exile 仅当鼠标指针离光标太近时,将鼠标指针移动到该窗口的右上角(如同 banish)。一旦光标移开,将鼠标指针移回到它的原始位置。
jump 当光标靠近鼠标指针时,使鼠标指针立刻跳到该框架中的一个随机位置。
none 不提供鼠标躲避功能(缺省情况)。
proteus 与 animate 中一样移动鼠标指针,但是就像希腊神话中的海神普罗特斯,更改鼠标指针的形状(使用一个随机图像字符)。
最好使用一个实例加以说明。现在,请尝试下面的操作:
键入 M-x mouse-avoidance-mode Enter cat-and-mouse Enter 以打开鼠标躲避模式。
移动到临时缓冲区:键入 C-x b *scratch* Enter 。
移动鼠标指针,使其位于光标的左边,且与光标仅有几英寸的距离,并开始键入一行文本:“When the cat wants to play the mouse runs away”。一旦光标靠近鼠标指针,鼠标指针则应该迅速离开。
5.
总结
您已经了解了对 Emacs 会话形状进行操作的细节技术,即如何创建并控制多个框架、如何对任何框架进行划分和分区以得到多个窗口,以及如何遍历这些框架和窗口。您还了解了一些其他技巧,包括如何使用鼠标操作框架和窗口以及如何处理鼠标指针,并且通过这些优秀的、功能强大的技术,可以使得 Emacs 按照您所希望的方式进行工作,并具有您所希望的外观。