Emacs 编辑环境,第 6 部分: 自定义您的 Emacs 环境

使用这个著名的开放源代码编辑器

本教程是系列文章的第 6 部分,将向您介绍一些有价值的方法,您可以使用它们来自定义和配置 Emacs 环境。了解如何对 Emacs 环境中的各个方面(从次要模式的行为到缺省的键绑定)按照您的喜好进行更改。在本文的介绍过程中,说明了如何设置变量,如何通过启动文件使您的所有自定义工作自动完成,如何保存并再次查看对窗口和框架的自定义,以及如何使用 Emacs 中内置的简单自定义工具。

开始之前

了解本教程中包含的内容以及如何最好地利用本教程。

关于本系列

Emacs 编辑环境深受 UNIX® 开发人员的喜爱。它是世界公认的编辑器之王,但许多用户发现它学起来需要一定的过程。Emacs 环境初看起来并不是很直观,而且和其他编辑器和字处理器的工作方式不大一样。但 Emacs 的学习并不困难。一旦您熟悉了它,就会发现它有多么直观,而且越用越顺手。这个系列教程(请参见参考资料)将为您提供指导,带您了解 Emacs 的基本知识,如它的功能、原理、按键命令布局和编辑文本的方法,然后深入它众多的强大编辑功能。

在完成本系列文章(请参见参考资料)的学习后,您可以通过 Emacs 很方便地进行日常编辑工作,能越来越熟练地使用 Emacs,并对 Emacs 的许多高级功能有一个良好的认识。

关于本教程

本文是学习 Emacs 的系列教程中的第 6 部分。本系列文章中前面的几个教程向您介绍了 Emacs 的一些基础知识;这篇中级水平的实践教程基于您在前面的教程中所学习的基础知识,并向那些已经熟练掌握 Emacs 的基本控制方法的读者介绍如何根据他们特定的需求来自定义和使用该系统。

在本教程中,您将了解如何采用各种方法对系统进行自定义、更改其行为、并使其按照您所希望的方式进行工作。您还将了解如何设置和检查 Emacs 变量,它们可以更改应用程序行为、更改键和模式的工作方式、在 init 文件中编写 Emacs Lisp 代码使得您的自定义工作能够自动地完成、记住您的窗口和框架的更改,并使用内置的自定义缓冲区实用工具作为更改和管理各种 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 --version
GNU Emacs 22.0.91.1
Copyright (C) 2006 Free Software Foundation, Inc.
GNU Emacs comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of Emacs
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING.
$

因为本教程中的部分内容研究了对 X 窗口系统环境中 Emacs 图形元素的操作,所以您应该拥有一台正常运行的 X 服务器。


设置 Emacs 变量

要对您的 Emacs 环境中的某些方面进行自定义,最快捷且最简单的方式就是设置 Emacs 变量。变量 可以影响 Emacs 中各个方面的工作方式;它们是 Emacs Lisp 符号,通过名称对其进行引用,并且通常具有一个缺省值。有些变量可以包含数值或者字符串,而其他的变量则是“真”或者“假”:如果将一个变量的值设置为 nil,那么它的值是“假”,值 t 表示“真”。

在 Emacs 会话中,您可以在任何时间更改任何变量的值。进行这种操作,可以为特定的缓冲区设置局部变量,可以更改仅应用于当前会话的全局变量,或者测试不同值的行为。

例如,在本系列文章的第 2 部分教程(请参见参考资料)中,您学习了 fill-paragraph 函数(绑定于 M-q),该函数在光标处填充段落。fill-column 变量中包含了这个函数将要填充的宽度,和其他的 Emacs 变量一样,您可以显示其内容并对其进行更改。

首先,使用一个新文件的缓冲区启动 Emacs:

$ emacs bee

现在,在您的新缓冲区中插入一行文本:

The busy bee has no time for sorrow.

通过键入 M-q 运行 fill-paragraph 函数,以便填充当前段落(即您刚刚插入的行)。

当您键入这个内容的时候,看起来似乎没有出现什么变化,这是因为 Emacs 用于在缓冲区中填充文本的缺省宽度(以字符为单位),比您刚刚键入的段落要长。您可以通过观察 fill-width 变量的内容来进行证实。

显示变量的值

使用 describe-variable 函数以得到变量的值。当您运行这个函数的时候,Emacs 将打开一个新窗口,该窗口中包含该变量的给定当前值。如果有的话,还将提供关于该变量的描述。这个函数与 C-h v 按键进行了绑定。

通过键入 C-h v fill-width,可以尝试获得 fill-width 变量的值。

在完成了这个操作之后,您将在 Emacs 会话(包含清单 1 的文本)中看到一个新的窗口。

清单 1. 显示 fill-width 变量值的 Emacs describe-variable 函数的输出
fill-column's value is 70

Documentation:
*Column beyond which automatic line-wrapping should happen.
Automatically becomes buffer-local when set in any fashion.

You can customize this variable.

从这个输出中您可以看到,直到到达第 70 个字符,fill-paragraph 函数才划分出一个新的行,所以您所键入的简短段落的长度并不足以进行自动换行。

设置变量

与任何 Emacs 变量一样,您可以更改 fill-column 的值。可以使用 set-variable 函数来完成这个任务,当您运行该函数的时候,它会请求输入变量的名称和您希望给它赋的值。

尝试将 fill-column 的值设置为 10,如清单 2 中所示。

清单 2. 使用 Emacs set-variable 函数更改 fill-column 变量的值
M-x set-variable Enter
Set variable: fill-column Enter
Set fill-column to value: 10 Enter

现在,再次填充该段落:确保光标位于您刚刚键入的行的末尾处,然后键入 M-q 以运行 fill-paragraph 函数。

请注意,如何填充该段落以使得其中所有的行都不超过 10 个字符,如清单 3 中所示。

清单 3. 在将 fill-width 变量设置为 10 之后进行自动换行的示例段落
The busy
bee has no
time for
sorrow.

在将 fill-column 的值设置为 4 之后,再次尝试这个操作,使用清单 2 中给定的过程。

在使用另一个 M-q 填充该段落之后,您将看到这些单词进行了不同的自动换行,如清单 4 中所示。

清单 4. 在将 fill-width 变量设置为 4 之后进行自动换行的示例段落
The
busy
bee
has
no
time
for
sorrow.

因为 fill-column 是一个局部 变量,所以您对它做的任何更改都仅应用于当前缓冲区。在一个 Emacs 会话中,每个缓冲区都有它自己的 fill-column 变量;这些变量中的任何一个都可以设置为不同的值。

尝试选择您所插入的所有文本,并将其粘贴到一个新的缓冲区:

C-space M-< M-w C-x b cee Enter C-y

在键入了该内容之后,您应该拥有一个刚填充的段落的副本(从 bee 缓冲区复制到新的、名为 cee 的缓冲区,并且尚未进行保存)。

键入 M-q 以填充它。填充的内容仅占用一行,看起来与您在开始时键入的单行内容相同。

通过请求 Emacs 显示变量的内容,您还可以验证在两个缓冲区中 fill-column 的值是不同的。

键入 C-h v fill-column Enter 以显示这个缓冲区的 fill-column 变量的值,它应该为 70。

在完成了这个操作之后,请求 Emacs 显示 bee 缓冲区的 fill-column 变量的值:键入 C-x b Enter C-h v fill-column Enter 以验证它仍然设置为 4。如图 1 中所示,其中所显示的 *Help* 缓冲区同样可以告诉您这个变量的局部值与全局值是不同的。

图 1. 在缓冲区内对 Emacs 的 fill-column 变量进行了局部更改之后,显示它的值
在缓冲区内对 Emacs 的 fill-column 变量进行了局部更改之后,显示它的值

使用并了解一些常见的 Emacs 变量

Emacs 提供了许多影响并改变其行为的变量。表 1 列出了一些经常进行修改的变量,并描述了它们的功能。

表 1. 常见 Emacs 变量汇总
变量描述
auto-mode-alist如果设置为 nil,那么将关闭根据文件名扩展自动选择主要模式的功能。它的缺省值是一些文件名扩展和相应模式的列表。
auto-save-default如果没有将其设置为 nil,那么 Emacs 则根据预设的时间间隔,自动地将经过更改的缓冲区保存到相应的文件。它的缺省值是 t
auto-save-interval包含调用 Auto-save 模式(如果它被设置为“真”)之后经过更改的字符的数目,其缺省值是 300。
calendar-latitude包含用户工作站位置的纬度值,采用度数表示;其缺省值是 nil
calendar-longitude包含用户工作站位置的经度值,采用度数表示;其缺省值是 nil
calendar-location-name包含用户工作站所在位置的位置名(如城市、州或省、国家/地区)的值,其缺省值是 nil
colon-double-space如果没有将其设置为 nil,那么填充文本的命令将在冒号后面插入两个 空格而不是一个。其缺省值是 nil
command-line-args包含在当前 Emacs 会话中所执行的命令行中使用的参数列表。
command-line-default-directory包含执行当前 Emacs 会话的目录的路径名。
compare-ignore-case如果没有将其设置为 nil,那么在运行 compare-windows 函数的时候,Emacs 将忽略大写字母和小写字母的区别,如在本系列文章的第 5 部分教程中所描述的(请参见参考资料)。其缺省值是 nil
confirm-kill-emacs如果设置为 nil,那么 Emacs 在退出的时候不请求确认;否则,可能自定义 Emacs Lisp 函数以完成退出验证工作,如 y-or-n-p(请参见使得简短的回答成为可能部分)。其缺省值是 nil
default-justification设置缺省的对齐风格。该值可能是 leftrightcenterfull 或者 none 中的一个。其缺省值是 left
default-major-mode为新的文件或者缓冲区选择缺省主要模式。其缺省值是 fundamental-mode
display-time-24hr-format如果设置为 t,那么 Emacs 将采用 24 小时军用格式来显示时间,而不是采用带有 AM 或者 PM 后缀的标准 12 小时格式。其缺省值是 nil
display-time-day-and-date如果没有将其设置为 nil,那么 Emacs 以当前星期几、当前月份和日期的格式来显示时间,而不仅仅显示小时和分钟。其缺省值是 nil
fill-column包含各行中的列数(从此处开始填充文本到下一行)。其缺省值是 70。
initial-major-mode指定启动时用于 *scratch* 缓冲区的主要模式。其缺省值是 lisp-interaction-mode
inverse-video如果没有将其设置为 nil,那么 Emacs 将对显示的颜色取反(如果可能的话)。其缺省值是 nil
kill-ring包含 Emacs 剪切环的内容,如本系列文章的第 3 部分教程中所描述的(请参见参考资料)。
kill-ring-max设置剪切环中所允许的条目数。其缺省值是 60。
kill-whole-line如果没有将其设置为 nil,那么 kill-line 函数(绑定于 C-k)将剪切当前行以及 其尾部的换行符(如果是在该行的开头处执行这个函数)。其缺省值是 nil
make-backup-files如果没有将其设置为 nil,Emacs 将进行任何更改之前保存缓冲区的备份(使用相同的文件名,但在文件名后追加了波浪符 (~))。
mark-ring包含该缓冲区的当前标记环的内容,如本系列文章的第 3 部分教程中所描述的(请参见参考资料)。
mark-ring-max包含标记环中所允许的条目数。其缺省值是 16。
mouse-avoidance-mode包含描述 mouse-avoidance 模式类型的值,如本系列文章第 5 部分教程中所描述的(请参见参考资料)。其缺省值是 nil
next-line-add-newline如果没有将其设置为 nil,那么只要按下向下箭头键,Emacs 就会在该缓冲区的末尾添加一个新行。其缺省值是 nil(在更新的 Emac 版本中)。
scroll-bar-mode包含 Emacs 框架侧边缘(放置滚动条的位置)的值:rightleft。如果设置为 nil,则关闭滚动条。其缺省值是 left
scroll-step 包含使用 scroll-downscroll-up 函数(在缺省情况下,分别绑定于 PgDn 和 PgUp 键)在缓冲区中移动的行数。如果设置为 0,那么在滚动的时候,Emacs 使光标位于窗口的中心位置。
show-trailing-whitespace如果没有将其设置为 nil,那么 Emacs 将显示当前缓冲区中的行尾处的任何空白字符。其缺省值是 nil
visible-bell如果没有将其设置为 nil,那么 Emacs 将使得该框架闪烁,而不是鸣响系统警铃。其缺省值是 nil
x-cut-buffer-max设置剪切环的字符的最大数目,该剪切环同样存储于 X Window System 的剪切缓冲区中。其缺省值是 20000。

自定义您的 Emacs 键绑定

正如您所知道的,Emacs 函数绑定于各种称为键绑定 的按键组合;标准的 Emacs 绑定易于使用和记忆(绑定中所使用的键,通常存在与记忆相关的提示),而且使用起来速度很快(因为在设置它们的时候,考虑到您仅需要最少的手动工作,就可以迅速地键入任何给定的按键组合)。

但是如果您不喜欢这些绑定,您也可以对它们进行更改。您可以自定义 Emacs 的所有键绑定:如果您需要的话,您可以使 A 键入字符 Z,或者使得 C-f 向后移动光标,使得 C-b 向前移动光标。尽管这些更改对于大多数用户来说或许并没有多大用处,但是存在一些重新配置,您个人可能会认为是非常便捷的。而且,与提供了缺省绑定的函数相比,Emacs 中包含更多的函数,许多可能的键盘按键组合还没有绑定于任何函数。

如果您频繁地使用一个特定的函数或者函数组,并且它们没有绑定于任何按键(或者如果它们所绑定的按键使用起来没有其他的按键方便),那么您可以重新定义它们。或者如果有一个函数您并不使用,那么您可以删除它的绑定,释放该按键,使其可以为其他函数所用。

global-set-key 函数将给定的函数绑定于给定的按键,并使得它在所有的模式和缓冲区中都有效。接下来将使用它进行大量的自定义和修复。

修复 Home 和 End 键

在 Emacs 中,通常按两种方式对 Home 和 End 键进行配置:要么,它们将光标移动到当前行的开头和结尾;要么,它们将光标移动到当前缓冲区的开头和结尾。

查看您绑定到这两种方式中的哪一种:在您的 bee 缓冲区中,按 HomeEnd 各几次。

现在您知道了这两种键绑定的方式,请尝试更改它们的绑定:

  • 如果您的 Home 和 End 绑定于移动光标到当前 的开头和结尾,那么键入:

    M-x global-set-key Enter
    Set key globally: Home
    Set key <home> to command: beginning-of-bufferM-x global-set-key
    Set key globally: End
    Set key <home> to command: end-of-buffer
  • 如果您的 Home 和 End 绑定于移动光标到当前缓冲区 的开头和结尾,那么键入:

    M-x global-set-key
    Set key globally: Home
    Set key <home> to command: beginning-of-lineM-x global-set-key
    Set key globally: End
    Set key <home> to command: end-of-line

在这个缓冲区中,测试 Home 和 End 几次,然后在 cee 缓冲区中尝试它们以证实您刚刚所做的更改是全局范围的:

HomeEndHomeEnd C-x b cee EnterHomeEndHomeEnd

修复 Del 键

在 Emacs 的某些配置中,Del 键与 Backspace 键绑定于相同的函数,delete-backward-char。这并不是大多数人所想要的和期望的值;对于大多数软件,Del 键都用于删除光标后面的 字符,而不是前面的字符。

测试您的 Del 键:

  1. 键入 C-x b *scratch* Enter,以移动到临时缓冲区。

  2. 键入一些文本:

    Delete me
  3. 键入 M-b 使得光标位于字符 m 上。

  4. 按下 Del

如果您的 Del 键绑定正确,那么将删除 m。如果您删除的是这两个单词之间的空格,那么可以使用下面的操作修复您的 Del 键:

M-x global-set-key
Set key globally: Del
Set key C-d to command: delete-char

创建自定义键

要为当前没有定义的按键定义一个新的绑定,可以运行 global-set-key 函数,给出新的按键,然后给出要运行的命令。

例如,在缺省情况下,M-F1 按键是未定义的。通过按住 Alt(或者您键盘中的任何 Meta 键),再按 F1 键,然后同时释放这两个键,就可以键入这个按键。尝试这个操作,当您在进行这个操作的时候,唯一应该发生的事情是 Emacs 发出警示声,指出这个按键还没有定义任何函数。

您可以定义这个按键,以运行 phases-of-moon 函数,该函数将打开一个显示当前月亮盈亏的新缓冲区窗口。

尝试下面的操作:

M-x global-set-key
Set key globally: M-F1
Set key <M-F1> to command: phases-of-moon

尝试您新定义的键绑定:键入 M-F1。在完成这个操作之后,您应该看到打开了一个新的缓冲区窗口,并显示了当前月亮的盈亏。


自定义您的 Emacs 界面

可以通过大量的 Emacs 模式和函数来控制 Emacs 界面自身,并且您还可以对它们进行自定义。

删除菜单条

Emacs 菜单条对于初学者来说是很有帮助的,但是一旦您熟练掌握了 Emacs,就可能想要删除它。您将使用键盘而不是菜单,并且删除菜单条将在屏幕中为您的缓冲区增加额外的一行空间。

使用 menu-bar-mode 函数打开和关闭菜单条,该函数可以进行切换。

尝试关闭它,然后再打开它:

M-x menu-bar-mode
M-x menu-bar-mode

有些类似的函数同样也值得我们深入地研究。tool-bar-mode 函数可以切换 Emacs 工具条的显示,工具条显示于 Emacs 框架(在 X 中)的顶部,并且包含大量的图形图标(各种常见 Emacs 命令的鼠标快捷方式)。scroll-bar-mode 函数(请参见表 1)可以控制是否在 Emacs 框架的左侧或者右侧绘制滚动条,或者完全将其省略。

在模式行中放置一个时钟

另一个简单的 Emacs 自定义是 display-time 函数,该函数可以在模式行中显示当前时间(以及其他有价值的当前状态信息)。

现在,通过键入 M-x display-time 来打开它。

在缺省情况下,这个函数在该缓冲区名的右边采用小时和分钟的形式显示当前时间,其后紧跟当前系统的负载级别,以及单词 Mail(如果您有尚未阅读邮件的话)。每分钟都会对这些值进行更新。

您可以更进一步对其进行自定义,以便在所有状态信息之前显示当前星期几、以及当前月份(这两者都采用三字母的缩写),其后紧跟该日期。要完成这项操作,您必须设置 display-time-day-and-date 变量,在表 1 中对该变量进行了描述。现在尝试对其进行设置:

M-x set-variable Enter
Set variable: display-time-day-and-date Enter
Set display-time-day-and-date to value: 1 Enter

显示并不会立即更新,您必须等待几分钟才能看到更改,或者再次运行 display-time 函数(通过键入 M-x display-time)。此时,如果您已经遵循本文中的示例进行了相应的操作,那么您的 Emacs 会话应该与图 2 所示类似。当前缓冲区的模式行(在这个示例中,即 *scratch*)包含星期几、月份的名称、日期和时间(采用标准的 12 小时格式)。您也可以采用 24 小时军用计时格式来显示时间,要实现这一点,可以使用 display-time-24hr-format 变量(请参见表 1)。

图 2. 自定义模式行中当前时间的显示
自定义模式行中当前时间的显示

要返回到原始风格,可以将 display-time-day-and-date 设置为 nil:

M-x set-variable Enter
Set variable: display-time-day-and-date Enter
Set display-time-day-and-date to value: nil

当分钟发生了更改、或者如果您再次运行 display-time 函数的时候,当前时间将出现在模式行中,但没有显示星期几、月份名称和日期。

自定义您的位置

Emacs 可以根据您所处的地理位置完成一些有价值的操作,比如给出日出和日落的时间。要启用这个功能,需要为您的位置设置 calendar-latitudecalendar-longitudecalendar-location-name 变量的值。

尝试将这些变量设置为一个示例位置,如清单 5 中所示。

清单 5. 在 Emacs 中配置地理位置数据
M-x set-variable Enter
Set variable: calendar-latitude Enter
Set calendar-latitude to value: 26.37 EnterM-x set-variable Enter
Set variable: calendar-longitude Enter
Set calendar-longitude to value: -80.09 EnterM-x set-variable Enter
Set variable: calendar-location-name Enter
Set calendar-location-name to value: "Boca Raton, FL (USA)" Enter

现在,运行 sunrise-sunset 函数:

M-x sunrise-sunset

在迷你缓冲区中,您应该可以得到今天的日出和日落时间(对于您所给定的位置)。

但是这个函数还可以给出任何一天的日出和日落时间,而不仅仅是今天的。要获得特定日期的日出和日落时间,可以在调用这个函数之前加上 universal-argumentC-u。尝试这个操作,如清单 6 中所示。

清单 6. 针对特定的日期运行 sunrise-sunset 函数
C-u M-x sunrise-sunset

  Year (>0): 2007 Backspace 8 Enter
Month name: Mar Enter
Day (1-30): 4

在完成了这个操作之后,迷你缓冲区将向您报告下面的信息:

Tue, Mar 4, 2008: Sunrise 6:41am (EST), sunset 6:22pm (EST)
at Boca Raton, FL (USA) (11:41 hours daylight)

打开语法突出显示

Emacs 的 Font Lock 模式可以打开字体和颜色,对于包括语法突出显示 在内的许多内容来说,这是很有用的;在语法突出显示中,可以对特定类型文档的重要结构元素进行着色,或者在显示中采用某种方式对其进行格式化。例如,在 HTML 模式中,用某些颜色突出显示 HTML 文档中用括号括起来的各种标记。font-lock-mode 函数可以进行切换,以便为当前缓冲区打开或者关闭这个模式。

现在尝试设置它:

  1. 通过键入 C-x C-f,然后指定 ~/.emac 作为要查找的文件,来访问名为 .emac 的新缓冲区。

  2. 如果在您的 home 目录中有一个 .emac 文件,那么前面的步骤将在一个新的缓冲区中打开它;如果没有 .emac 文件,那么 Emacs 将生成一个使用该名称的新的空文件。无论在哪种情况下,插入清单 7 中给出的 Emacs Lisp 的内容行,以定义刚刚描述的三个位置变量(当然,除非先前存在的 .emac 文件已经包括,并且已定义了这些变量)。

    清单 7. 在 .emac 文件中指定地理位置
    ;; set the current location
    (setq calendar-latitude 26.37)
    (setq calendar-longitude -80.09)
    (setq calendar-location-name "Boca Raton, FL (USA)")
  3. 为这个缓冲区打开 Font Lock 模式:

    M-x font-lock-mode

使用应用于各种元素的突出显示方式,以相应的颜色显示 Emacs Lisp 代码,如图 3 中所示。

图 3. 在 Emacs Lisp 缓冲区中启用 Font Lock 模式
在 Emacs Lisp 缓冲区中启用 Font Lock 模式

您可以通过键入 C-x C-s 将该文件保存到磁盘。

常见 Emacs 界面函数汇总

表 2 列出并描述了影响 Emacs 界面的各种函数。

表 2. 常见 Emacs 界面函数汇总
函数描述
column-number-mode在模式行中,为光标所在的当前(前面有一个 C)切换显示。其缺省值是 nil
display-time在模式行中切换当前时间的显示。其缺省值是 nil
font-lock-mode如果没有将其设置为 nil,那么 Emacs 将为当前缓冲区自动地打开 Font Lock 模式。其缺省值是 nil
global-font-lock-mode如果没有将其设置为 nil,那么 Emacs 将为所有的 缓冲区自动地打开 Font Lock 模式。其缺省值是 nil
line-number-mode在模式行中,为光标所在的当前(前面有一个 L)切换显示,其缺省值是 t
menu-bar-mode切换 Emacs 菜单条的显示。其缺省值是 t
sunrise-sunset根据当前地理位置,显示今天日出和日落的时间。如果在它的前面加上 universal-argument,那么这个函数将提示输入一个特定的日期。
tool-bar-mode切换 Emacs 工具条的显示。其缺省值是 t

使用您的 Emacs 启动文件

每次 Emacs 启动的时候,它都会在您的 home 目录中查找一个隐藏文件 .emac,并执行该文件中包含的所有 Emacs Lisp。这就是您的 Emacs 启动文件或者初始化文件;可以使用它来设置变量或者进行其他更改(在 Emacs 启动时自动发生)。

使用圆括号将 Emacs Lisp 调用括起来;注释的内容以分号 (;)开头。随着 Emacs Lisp 的发展,产生了许多约定;例如,描述函数的注释通常以两个分号和一个空格字符开头。在 GNU Emacs Lisp 参考手册(请参见参考资料)中描述了这些约定。

在 .emac 文件中,您可以进行各种各样的自定义工作,包括设置变量、定义键绑定并设置各种模式,接下来将对这些内容进行描述。

(正如在本系列文章的第 4 部分教程中所描述的(请参见参考资料),您可以启动 Emacs,而无需通过给定 -q 选项首先加载这个初始化文件,并且您可以通过给出用户名作为 -u 选项的参数,以使得 Emacs 加载另一个用户的启动文件。)

在您的启动文件中设置变量

使用 .emac 初始化文件的最常见的目的可能是设置某些变量,以使得每次启动 Emacs 的时候,都能够自动地设置这些值。要在 .emac 文件中设置变量,可以使用 setq 函数,如下所示:

(setq VARIABLE VALUE)

您在清单 7 中看到了一个示例,其中您创建了一个简单的 .emac 文件并将该缓冲区保存到您的 home 目录中。现在您可以对其进行演示:

  1. 键入 C-x C-c,以退出 Emacs;可能会丢失在任何未保存的缓冲区(本教程中您进行工作的缓冲区)中所做的更改,这没有什么关系。

  2. 重新启动 Emacs:

    $ emacs
  3. 获得今天的日出和日落时间:键入 M-x sunrise-sunset

您无需设置 Emacs 的纬度、经度、或者位置名称变量,因为当 Emacs 启动的时候,它会从您的 .emac 文件中读取它们。但是在 Emacs 会话中的任何位置,您都可以重新定义在您的 .emac 文件中设置的任何变量。

在您的启动文件中定义键绑定

当您使用在创建自定义键部分中所描述的方法来定义新的键绑定时,它仅仅在当前 Emacs 会话中是可用的(一旦退出,这些更改都将丢失)。但是您可以将自定义的绑定放在您的 .emac 文件中,以使得在您每次启动 Emacs 的时候它们都是可用的。

例如,如果您的 Del 键有问题,那么您可以在 .emac 文件中包括下面的内容:

;; Make Del delete the character at point.
(global-set-key [delete] 'delete-char)

并且您可以包括清单 8 中所描述的任何一对代码,以便自动地为每个 Emacs 会话重新定义您的 Home 和 End 键。

清单 8. 在 .emac 文件中重新定义 Home 和 End 键
;; Make Home and End move to the beginning and ending of the buffer
(global-set-key [home] 'beginning-of-buffer)
(global-set-key [end] 'end-of-buffer)

;; Make Home and End move to the beginning and ending of the line
(global-set-key [home] 'beginning-of-line)
(global-set-key [end] 'end-of-line)

;; Make Home and End move to the beginning and ending of the sentence
(global-set-key [home] 'backward-sentence)
(global-set-key [end] 'forward-sentence)

在您的启动文件中设置模式

还可以在您的 .emac 文件中打开或者关闭模式。

因为大多数模式都可以作为切换进行调用,所以在其后紧跟一个正参数可以打开它们,而紧跟一个负参数可以关闭它们。您还可以使用下面这种格式:

(MODE-NAME VALUE)

例如,您可以使用下面的操作自动地关闭菜单条:

;; turn off the Emacs menu bar
(menu-bar-mode -1)

通常,当给定一个正整数值或者 t(表示“真”)的时候,将打开模式;当给定一个负整数、零或者 nil 值的时候,将关闭模式。

下面所有的行都可以完成相同的任务:它们设置 global-font-lock-mode,该模式将自动地打开所有缓冲区的 Font Lock 模式:

(global-font-lock-mode)
(global-font-lock-mode 1)
(global-font-lock-mode t)

使得简短的回答成为可能

有时,当 Emacs 需要从您这里得到一个回答的时候,您不得不键入单词 yes 或者 no,并在其后使用 Enter 键。

当您很清楚自己所执行的操作时,这个操作就可能会和某些窗口应用程序要求您在弹出窗口中单击 OK 以验证您刚刚指定的命令一样令人讨厌。

为了简化这个过程,以便只需要按 Y 或者 N 键即可,可以将下面的内容添加到您的 .emac 文件:

;; eliminate long "yes" or "no" prompts
(fset 'yes-or-no-p 'y-or-n-p)

这种技术使用了 fset 函数,以重新定义给定的函数。要了解更多关于这个函数和类似的 Emacs Lisp 函数的信息,请参阅 GNU Emacs Lisp 手册(请参见参考资料)。

实际运用

清单 9 中包含一个示例 .emac 初始化文件,以及在这个部分中描述的许多自定义内容。它还包含使用表 1表 2 中所描述函数和变量进行附加自定义的内容。您可以编辑新的 .emac 文件,以包含这些条目,然后重新启动 Emacs 以观察这些更改如何产生作用。

清单 9. 示例 .emac 初始化文件
;; set the current location
(setq calendar-latitude 26.37)
(setq calendar-longitude -80.09)
(setq calendar-location-name "Boca Raton, FL (USA)")

;; eliminate long "yes" or "no" prompts
(fset 'yes-or-no-p 'y-or-n-p)


;; Custom mode configurations
;; 
;; turn off the menu bar
(menu-bar-mode -1)
;; 
;; turn off the tool bar
(tool-bar-mode -1)
;; 
;; turn on Font Lock mode globally
(global-font-lock-mode t)

;; Custom key bindings
;;  
;; Make Del delete the character at point.
(global-set-key [delete] 'delete-char)
;; 
;; Make Home and End move to the beginning and ending of the sentence
(global-set-key [home] 'backward-sentence)
(global-set-key [end] 'forward-sentence)

记住 Emacs 窗口和框架的自定义内容

在本系列文章的第 5 部分教程(请参见参考资料)中,您了解了如何操作 Emacs 框架,并将它们水平或者垂直地划分为多个窗口。您还可以保存对窗口所做的自定义工作,并稍后在您的会话中重新调用它们,甚至在对屏幕的布局做了许多更改之后重新调用它们;您可以使用 Winner 模式来完成这个任务。

Winner 模式是一个次要模式,它可以记录并记住您对窗口和框架所做的更改。您对窗口配置的每次更改,它都会记住;您可以撤消您的更改,以还原为最近的配置。您还可以重做您的更改,以返回到包含这些更改的情况。如果您正在尝试不同寻常的或者复杂的配置,或者如果您希望完成不同类型的任务(涉及到不同的窗口设置),那么使用它是非常方便的。

在 Winner 模式中工作的两个函数:C-x <-(通过按住 Ctrl,再按 X,同时释放这两个键,然后按向左箭头键,可以键入这个函数)将运行 winner-undo 函数,并撤销对窗口所做的最近一次更改。它的对等项是 C-x ->,它将运行 winner-redo,恢复对窗口所做的最近一次(您先前撤销的)更改。

启用 Winner 模式

要开始使用 Winner 模式,可以设置一个自定义 Emacs 框架:

  1. 退出 Emacs(如果当前它在运行的话),然后重新启动它(不使用任何参数):

    $ emacs
  2. 键入 C-x 2 以垂直地划分 Emacs 窗口,然后键入 C-x o C-x C-f .emacs Enter 以便在下面的窗口中打开您的 .emac 文件。

  3. 键入 M-x winner-mode 以打开 Winner 模式。

当您在进行这个操作时,请注意在两个可见缓冲区的模式行中,已将 Win 添加到括号中的模式清单。这意味着,已经打开了 Winner 模式,并且它在所有的缓冲区中都可以工作。(它甚至还可以在其他 Emacs 框架中工作,只要您创建了它们。)

您的 Emacs 会话应如 图 4 所示。请注意,Emacs 框架不再包含菜单条或者工具条,因为在 .emac 文件中关闭了这些内容。

图 4.在 Emacs 会话中启用 Winner 模式
在 Emacs 会话中启用 Winner 模式

遍历您的窗口配置

现在,进行一些新的窗口配置:

  1. 使用鼠标单击顶部窗口中的 B1,使得其变为活动窗口,然后键入 C-x 3 以水平地划分该窗口一次。

  2. 通过键入 C-x 2 垂直地划分左上方的窗口,然后通过键入 C-x 再次水平地划分新的、左上方的窗口。键入 C-x b .emacs Enter 以切换到新窗口中的 .emac 缓冲区。

您的 Emacs 框架应该与图 5 所示类似。请注意,在该框架的每个窗口的模式行中都出现了 Win

图 5. 启用 Winner 模式重新配置 Emacs 框架
启用 Winner 模式重新配置 Emacs 框架。

现在,您可以返回到过去的配置,并遍历它们,键入 C-x <- 以撤消您最近对窗口所做的更改。

再次键入 C-x <-,以撤消另一个更改。继续进行撤消操作,直到迷你缓冲区报告无法进行更进一步的撤销操作为止。此时,您的 Emacs 框架应该与图 4 所示类似,即您第一次启用 Winner 模式时的样子。

键入 C-x -> 以运行 winner-redo 函数,并撤消您最近的更改。您可以在 C-x <-C-x -> 之间循环,以遍历所做的所有窗口更改。

winner-mode 函数是一个切换:再次键入 M-x winner-mode,以将其关闭。当您在进行这个操作时,winner-redowinner-undo 函数将不再起作用,并且不再记住窗口的更改,但是一旦再次启用它,您可以撤消和重做您对窗口所做过的任何更改。


使用 Emacs 的 Customize 函数

Customize 是一个特殊的 Emacs 函数,该函数可以使得对编辑器行为各个方面的自定义变得更加容易。它允许您进行交互地选择、设置和保存相关的值,以及 Emacs 许多方面的设置,包括用于显示文本的各种字体、外观和颜色。其目的是在详细的 Emacs 自定义过程中进行简化和控制,使得对于非 Emacs Lisp 程序员的 Emacs 用户可以更加容易地自定义他们的设置。

对于设置文本颜色和外观,Customize 函数特别有价值,因为您可以观察并且交互地进行更改,您可以在您的当前会话中测试它们,而无需将它们应用到所有将来的会话中。当您为以后的会话保存您的更改时,可以自动地将它们写入您的 .emac 文件,因此它们将应用于当前以及所有将来的 Emacs 会话。

启动自定义缓冲区

要开始对您的 Emacs 进行自定义工作,可以通过键入 M-x customize 运行 customize 函数。

当您在进行这项操作时,在您的 Emacs 框架中将出现一个新的自定义缓冲区,如图 6 所示。请注意该缓冲区的名称:*Customize Group:Emacs*。

图 6. Emacs 自定义缓冲区
Emacs 自定义缓冲区

选择自定义组

将 Emacs 中可进行自定义的各个方面划分为不同的,每个组中包含一些类似的元素和编辑器的方面。所显示的组取决于您的系统设置。

要打开一个组并观察其中不同的成员,可以使用鼠标左键单击 Go to Group 文本按钮,或者使用键盘将光标移动到该按钮上并按 Enter。有时候,打开一个组可以得到新的子组的列表,在这种情况下,进行选择的过程是相同的。

现在,尝试选择 Editing 组。当您在进行这个操作时,Emacs 将打开一个名为 *Customize Group 的新缓冲区:Editing* 包含一个新的组清单,其中所有的内容都与 Emacs 的编辑函数相关。

在这个菜单中,选择 Fill 组,以便打开 *Customize Group:Fill* 缓冲区。这个缓冲区包含许多不同的选项和附加的子组,您必须向下滚动以查看所有的内容。您的 Emacs 会话应该与图 7 中所示类似。

图 7. Emacs Fill 自定义组缓冲区
Emacs Fill 自定义组缓冲区

更改自定义选项

这个组清单中的每个选项都有一个值,您可以对其进行更改。对于每个选项,包括 More 选项(提供关于该选项的更多信息),您都可以看到许多按钮。当您单击这个按钮的时候,它的标签变为 Hide;当您再次单击它的时候,则将扩展内容隐藏起来。

State 按钮描述该选项的当前状态:未对其标准设置进行过更改、隐藏、经过更改但未保存、或者经过更改且已保存。

尝试更改一个值:向下滚动到 Fill Column 条目,请注意该值设置为 70,您应该记得这恰好是该变量的缺省值。将光标移动到该值的框,并将其更改为 10。这个值的 State 按钮可以报告下面的信息:

you have edited the value as text, but you have not set the option.

向上移动到该缓冲区的顶部,并单击 Set for Current Session 按钮;这个操作将使您的更改生效,但是一旦您退出 Emacs 它们都将重新设置。(如果您希望进行一项影响本次会话和所有将来会话的更改,可以改为单击 Save for Future Sessions 按钮)。

单击 Finish 按钮,这个操作将删除该缓冲区,并单击所有其他 Customize 缓冲区中的 Finish 按钮。

现在,您可以测试您的自定义内容:

  1. 键入 C-x C-f .emacs Enter 以便在新的缓冲区中打开您的 .emac 初始化文件的一个副本。

  2. 将光标移动到每个命令行(它们以 ;; 开头,其后紧跟一行文本),并键入 M-q,对它们运行 fill-paragraph 函数。

这些段落将在每行的第十个字符处进行填充,因此您的 .emac 初始化文件应该与图 8 中所示类似。

图 8. 自定义填充列之后,在 .emac 文件中对注释文本进行自动换行
自定义填充列之后,在 .emac 文件中对注释文本进行自动换行

您可以验证,对缺省填充所做的更改仅作用于本次会话:保存经过重新格式化的 .emac 文件,使用 C-x C-c 退出 Emacs,然后使用您的 .emac 文件重新启动它:

$ emacs .emacs

现在,移动到包含文本的所有注释行,并在每行中键入 M-q,以观察它们变为之前的情况(在第 70 列处进行填充)。

自定义特定的属性

每次当您希望创建一项特殊的自定义内容时,并不需要遍历自定义缓冲区的整个系列。有一些命令可以直接将您带到特定的组,并且某些 Emacs 自定义菜单具有它们自己的特殊 Emacs 函数。

例如,customize-group 函数可以为给定的组打开自定义缓冲区。

尝试打开 Fill 组的一个新的 Emacs 自定义缓冲区:

M-x customize-group
Customize group: (default emacs) fill

与前面一样,您得到一个 *Customize Group:Fill* 缓冲区,如图 7 中所示。

了解 Emacs 自定义函数

表 3 列出并描述了各种 Emacs Customize 函数。

表 3. Emacs Customize 函数汇总
函数描述
customize-changed-options Enterversion为所有的外观、选项、或者自从通过 version 给定 Emacs 的版本之后经过更改的组,打开一个新的自定义缓冲区。
customize-customized为所有经过自定义但尚未保存到磁盘的选项和外观,打开一个新的自定义缓冲区。
customize-face Enter regexp为所有的外观、选项、或者与通过 regexp 给定的正则表达式相关的组,打开一个新的自定义缓冲区。
customize-face Enter face为通过 face 给定的外观名称,打开一个新的自定义缓冲区。
customize-group Enter group为通过 group 给定的组名称,打开一个新的自定义缓冲区。
customize-option Enter option为通过 option 给定的选项名称,打开一个新的自定义缓冲区。
customize-saved为所有使用 Customize 函数更改的外观和选项,打开一个新的自定义缓冲区。

总结

您已经了解了几种通过设置变量、更改缺省键绑定和以交互地方式操作模式来配置和自定义 Emacs 编辑环境的重要方式。您还了解了如何使用 Emacs 初始化文件为将来的会话保存您的自定义内容,如何使用 Winner 模式以保存并重新调用自定义 Emacs 窗口和框架,以及如何使用内置的 Emacs Customize 函数来自定义各种内容(从基本的字体和颜色,到执行特定的文本编辑函数的方式)。

Emacs 的各个方面都可以采用功能强大的方式进行更改或者扩展,并且您已经学习了如何完成这项任务。现在,您可以让 Emacs 按照您所希望的方式去工作了。

参考资料

学习

获得产品和技术

  • IBM 试用软件:从 developerWorks 可直接下载这些试用软件,您可以利用它们开发您的下一个项目。
  • GNU 项目网站:为您的操作系统和体系结构免费下载最新的 GNU Emacs 的免费副本。

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=AIX and UNIX, Open source
ArticleID=266183
ArticleTitle=Emacs 编辑环境,第 6 部分: 自定义您的 Emacs 环境
publish-date=11012007