中级 Emacs 黑客技术

作者:Charles Curley

自定义 Emacs 对于充分利用它非常重要。您可以更改其运行方式以反映您的做事方式,从而提高您的效率。正如定制靴子比工厂靴子更合脚一样,定制的 Emacs 比标准的、现成的 Emacs 更适合您。

Emacs 的更改可以是会话特定的或永久性的。您可以通过在迷你缓冲区中执行命令或使用 set-variable 命令修改变量来直接自定义 Emacs。这些更改是易失性的,这意味着当您结束会话时,您会丢失它们。要进行永久性更改,您可以创建或修改初始化文件。Emacs 在加载时会检查多个初始化文件。可能最简单的自定义方法是编辑存储在您主目录中的 .emacs。在加载您的 .emacs 文件之前,Emacs 会从您的库路径加载 default.el。Emacs 还在其加载路径中查找 site-start.el,系统管理员可以使用它来提供站点范围的自定义。或者,您可以通过“自定义”菜单(在 21.1 及更高版本中为“选项”→“自定义 Emacs”)进行永久性的 Emacs 更改。这为您提供了一个基于 GUI 的前端,用于修改您的 .emacs 文件。

使用自定义

像大多数 GUI 前端一样,“自定义”不如黑客攻击文本配置文件那样强大,但它更容易使用。启动“自定义”组,您会注意到 Emacs 会动态构建菜单。这样它始终是最新的(图 1)。

Intermediate Emacs Hacking

图 1. 顶层自定义菜单

要导航“自定义”的树状结构,请指向按钮并按“回车”键或单击按钮。“自定义”缓冲区中也支持完整的 Emacs 搜索。树中的每个级别都表示在一个缓冲区中,您可以像往常一样操作“自定义”缓冲区。例如,当您完成一个级别后,杀死缓冲区。

例如,我想在进入 PHP 模式时(例如,当我访问 PHP 文件时)打开 PHP 速查栏。为此,我按照菜单树导航到 PHP 模式自定义(图 2)。正如您所见,我已经切换了状态,但尚未保存更改。我可以仅为此会话设置它,也可以保存更改以供将来会话使用。当我执行后者时,Emacs 会编辑我的 .emacs 文件。您可以通过在 .emacs 中搜索变量名来验证更改。

Intermediate Emacs Hacking

图 2. 设置速查栏在 PHP 模式下打开

如果您不确定变量的名称或在“自定义”的庞大树中在哪里找到它,您可以使用正则表达式搜索变量名及其内容。如果您想更改 Emacs 的打印方式,您可以搜索正则表达式“print”,Emacs 将为您构建一个自定义的“自定义”菜单。有关这些和其他选项,请参阅“选项”→“自定义 Emacs”下的菜单。

编辑您的 .emacs 文件

您还可以通过直接编辑 ~/.emacs 来修改 Emacs 的行为。这是添加功能和插入您可能从其他人那里了解到的批量自定义的好方法。例如,可以通过设置影响 C 模式运行方式的变量来修改 C 模式。

许多模式是在每个缓冲区的基础上自定义的。这意味着您编写一个简短的函数来设置变量,并将该函数设置为在 Emacs 进入该模式时执行。其轮廓是

(defun rays_c_mode ()
  "ray's c/c++ mode hook"
  (message "Loading Ray's C mode...")
  ...
  (message "Loading Ray's C mode... Done")
  )
(add-hook 'c-mode-common-hook 'rays_c_mode)

Lisp 函数 defun 定义了一个函数,在本例中为 rays_C_mode。该函数不带参数;它仅出于用户利益而打印消息。最后一行将函数 rays_c_mode 添加到 C 模式的模式钩子,即 Emacs 进入 C 模式时执行的函数列表。您可以在我的个人 .emacs 文件(请参阅“资源”)中看到更多 Ray 的 C 模式。

习惯上通过在模式名称前加上模式名称来命名特定模式的变量。要查看与特定模式关联的变量,请使用 M-X 对变量名进行正则表达式搜索apropos-variable。对于 C 模式,我们使用正则表达式“^c-”消除了许多误报。当 Emacs 返回结果列表时,移动到该缓冲区并在您感兴趣的任何变量上按“回车”键以获取更多信息。

要了解您还可以搜索什么,请尝试 M-Xapropos-command RET apropos RET。“apropos-zippy”?我让您检查一下。

一个函数当然可以调用其他函数。这种可能性是使编辑您的 .emacs 文件和使用 Emacs Lisp 进行编程比使用“自定义”更强大的几个原因之一。

打印

Emacs 像往常一样,为您提供了很大的打印灵活性。您可以通过将缓冲区的原始内容发送到打印机来打印。这既快速又容易,但它可能无法完全满足您的需求。您可以更好地控制 PostScript 打印,因此这可能是最佳选择。首先,字体锁定的(彩色)缓冲区在彩色打印机上以彩色打印,在单色打印机上以灰度打印,前提是 Ghostscript 支持这些功能。

Emacs 打印区域中最常见的更改可能是更改 Emacs 默认打印机的名称。这可以是 nil,它告诉 Emacs 使用默认打印机,在 Linux 或 UNIX 中为 lp。或者,它可以是打印机名称,以使 lp 守护程序将其识别为打印机名称。如果您有 Red Hat 的 printtool 或类似的工具,您可以从中获取打印机名称。如果失败,请在 /var/spool/lpd/ 中查找打印机名称。Emacs 可以使用您可以为其定义本地队列的任何打印机,包括远程打印机。

设置了两个变量来指示打印机,一个用于 PostScript 打印,另一个用于非 PostScript 打印。下面的代码显示了我在 Linux 和 Windows 下如何设置 Emacs。Windows 定义使用计算机 charlesc 上的远程打印机。将两台打印机设置为同一台计算机仅在服务器是 Linux 机器时才有效。printcap 检测 PostScript 并通过 Ghostscript 运行它,然后再打印它


;; Begin setup for printing on Win32
(if (and  (>= sams-Gnu-Emacs-p 20)
	   (memq window-system '(win32 w32)))
    (progn (setq printer-name "//charlesc/lp")
	   (setq ps-printer-name "//charlesc/lp"))
  )
;; End setup for printing on Win32

;; Begin setup for printing on Linux
(if (and  (>= sams-Gnu-Emacs-p 20)
	  (string-equal system-name "charlesc.localdomain"))
    (progn (setq printer-name "lp")
	   (setq ps-printer-name "lp"))
  )
;; End setup for printing on Linux

Emacs 的 PostScript 打印非常强大。默认情况下,它在每页顶部打印一个灰色框,其中包含缓冲区的名称、数据、页码和计数。

您可以在每页或选定页面上设置水印的文本字符串和其他特征。例如,对于代码审查,初步或草稿的水印是一个好主意;请参阅变量 ps-print-background-text。您还可以使用 EPS 图像,例如 Tux 的图片或自由软件基金会的 GNU 徽标作为水印。

我们这些不喜欢 8.5 磅字体的老年人可以更改 ps-font-size 的值。该值包含两个数字,第一个用于横向打印,第二个用于纵向打印。是否打印横向或纵向由变量 ps-landscape-mode 控制。

您可以修改默认的 PostScript 标头并添加页脚。对于双面打印,您可以指定左右页眉和页脚。如果您想节省纸张,请查看 ps-n-up-printing。它允许您在一张纸上打印多页。

字体选择

Emacs 支持多个框架或窗口。您可以使用 Ctrl-X 5 2 启动另一个框架,或使用 Ctrl-X 5 0 删除一个框架。启动 Emacs 时创建的初始框架具有由变量 initial-frame-alist 定义的许多图形特征。后续框架由 default-frame-alist 管理。完全相同地使用这两个变量。每个变量都是子变量及其值的列表,有点像 Perl 中的哈希。例如,要设置屏幕上第一个框架的初始位置,请使用

(setq initial-frame-alist
    '((top . 40) (left . -15)
      (width . 96) (height . 40)
      (background-color . "Gray94")
      (foreground-color . "Black")
      (cursor-color	. "red3")
      (user-position t)
      ))

此定义将 Emacs 初始框架设置为距屏幕顶部 40 像素,距右侧 15 像素(因此左侧为负数),宽度为 96 个字符,高度为 40 行。它设置了默认的背景和前景色文本颜色,然后设置了光标颜色。

如果您不喜欢默认字体,此定义也是您设置字体的位置。程序 xfontsel 随 XFree86 一起提供,您可以使用它来查找合适的字体(图 3)。选择“选择”作为选项,xfontsel 会将其放入剪贴板。在 initial-frame-alist 的定义中添加另一对括号,插入短语font .并插入一对引号。然后使用 Ctrl-Y 恢复引号之间的字体定义,就像任何其他剪贴板条目一样

(font . "-adobe-courier-*-r-*-*-*-140-*-*-*-*-*-*")
Intermediate Emacs Hacking

图 3. 使用 X 的实用程序 xfontsel 选择字体

如果您想知道我是如何在屏幕截图中获得颜色的,这就是我的方法。

如果您在这些设置方面遇到问题,请在您的 .Xresources 文件中查找任何 Emacs 设置。.Xresources 中的任何设置都会覆盖这些定义。要摆脱覆盖,请注释掉 .Xresources 文件中的它们并重新启动 X。

直到最近,Emacs 还不支持可变宽度字体,并且固定宽度字体对于大多数用途来说已经足够好了。但是,由于最新版本中包含了对比例字体和非英语字符集的支持,您现在可以在 Emacs 中定义自己的字体集。字体集允许像文字处理器一样轻松控制字体。例如,查看 Emacs Info 和“自定义”菜单中的标题;另请参阅 Emacs 关于字体集的 info 节点。

有关 X 下字体的更多信息,请参阅 Emacs 关于字体规范选项的 info 节点。

速查栏

我在讨论“自定义 Emacs”系统时解释了如何自动打开速查栏。速查栏是一个单独的框架(窗口),允许在 Emacs 缓冲区之间进行鼠标单击导航。从图中可以看出,速查栏允许树状结构,例如 Emacs 的 Info 系统。单击 + 打开子节点,单击 – 关闭它们(图 4)。

Intermediate Emacs Hacking

图 4. Emacs 的速查栏点击浏览界面

当您在某些模式下(例如 Rmail、Info 和 GUD)进行编辑时,速查栏会显示要在该模式下编辑的其他选择。例如,当您处于 Info 模式时,速查栏会显示节点。否则,它会显示当前缓冲区中文件所在目录中的文件。

如果您在 Emacs 中打开了很多文件,速查栏是一个有用的工具。我经常同时打开 30 多个文件,速查栏可以帮助我管理和在它们之间切换。

Emacs 用于电子邮件

在文章“Emacs 入门”,LJ,2003 年 3 月中,我演示了如何将 Emacs 用作服务器,让 crontab 和 mutt 等程序使用 Emacs 进行文件编辑。为了进一步发展,您可以将 Emacs 用作任何可以调用外部编辑器的应用程序的编辑器,包括邮件阅读器。但是,Emacs 至少有两种邮件模式和一个名为 GNUS 的强大新闻阅读器。

要发送消息,Ctrl-X M(或 M-Xmail)使您进入邮件模式。只需编辑消息并发送即可(图 5)。正如屏幕截图所示,您会看到一个电子邮件的骨架,等待您填写空白。您可以使用控制字符序列移动到(并在必要时创建)其他标头,例如 FCC。您可以在标头中使用制表符补全。在那里,它会查看本地系统用户以及您在 .emacs 中定义的任何电子邮件别名的内容。

Intermediate Emacs Hacking

图 5. Emacs 邮件模式下的电子邮件骨架

您可以使用 Ctrl-C Ctrl-W 插入您的签名,或者您可以让 Emacs 为您执行此操作,方法是将 mail-signature 设置为t在您的 .emacs 文件中。如果您想变得花哨并编写一个 Lisp 程序来根据您可以编写 Lisp 代码来检测的任何内容为您选择签名。

您可以对您的消息运行拼写检查器。输入 M-Xispell-message仅检查消息的正文,跳过任何引用的材料。

阅读邮件

在 Emacs 中,使用 rmail 模式(M-Xrmail)(图 6)阅读和回复您的收件箱邮件。您可能希望做的第一件事是创建摘要缓冲区或通过修改 rmail 模式钩子来自动化它。这将创建一个大多数用户熟悉的缓冲区:每条消息一行,该行包含日期、源电子邮件地址、数据大小和主题。正如您在图 7 中看到的那样,rmail 缓冲区中的消息以绿色突出显示。正常的 Emacs 导航键在摘要缓冲区中有效。

Intermediate Emacs Hacking

图 6. rmail 模式下的电子邮件消息

Intermediate Emacs Hacking

图 7. 带有摘要的 rmail 模式

Emacs 邮件以某种复杂的方式运行,以便适应多个操作系统。当您启动 rmail 缓冲区时,它会将邮件从您的收件箱文件(通常在 Linux 中的 /var/spool/mail 中)移动到一个文件 ~/RMAIL 中。这是您通常编辑的文件。您可以随时使用 G 键将电子邮件放入 ~/RMAIL 中。如果您有 POP 或 IMAP 帐户,请尝试使用 fetchmail 将您的邮件放入收件箱中。

Emacs 使用 Babyl 邮件文件格式。您可以将单个消息导出为文本文件;整个 rmail 文件可以以邮箱格式导出。

大多数邮件阅读器使用多个邮件文件(目录,如果它们使用 maildir 邮件格式)。Emacs 可以在不同的 rmail 文件之间切换,但您可能不需要这样做。相反,您可以使用正则表达式和其他搜索模式创建自定义摘要。您可以根据收件人、主题或标签中的正则表达式搜索来指定摘要。

您可以拥有多个 rmail 文件,并将每个文件与一个或多个收件箱关联。这意味着已经运行或使用 procmail 配方将其电子邮件传递到单独文件的垃圾邮件过滤器(如 SpamAssassin)的人们无需放弃该投资。每次您访问 rmail 文件时,Emacs 都会从关联的输入文件中获取任何新邮件。

您可以在 rmail 模式下回复和转发电子邮件。两者都会打开一个邮件模式缓冲区,其中电子邮件标头已完成。您可以使用 Ctrl-C Ctrl-Y 拖入您要回复的消息。如果您想回复多封电子邮件,请切换到 rmail 缓冲区,选择不同的消息,切换回并拖入新的当前消息。为了符合 RFC,您必须通过自定义 mail-yank-prefix 以使用字符串 > 来设置引用字符。

资源

作者的 .emacs:www.charlescurley.com/~ccurley/emacs.init.html

Emacs 初学者 HOWTO:www.tldp.org/HOWTO/Emacs-Beginner-HOWTO.html,或者可能已在您的计算机上,与其他 LDP 文档一起。

Emacs 的内置帮助系统:Ctrl-H

Emacs for Vi 用户:grok2.tripod.com

“Emacs:自由软件 IDE”,作者:Charles Curley,LJ 2002 年 6 月:/article/5765

Emacs Wiki:www.emacswiki.org/cgi-bin/wiki.pl

fetchmail:www.catb.org/~esr/fetchmail

“Emacs 入门”,作者:Charles Curley,LJ,2003 年 3 月

GNU Emacs 主页:www.fsf.org/software/emacs/emacs.html

GNU Emacs Lisp 参考手册:www.gnu.org/manual/elisp-manual-20-2.5/elisp.html

GNU Emacs 教程(旧版,但仍然有用):www.futureone.com/~sponge/tutorial/emacs/index.html

如何对我的 Gnu Emacs .emacs 文件进行常见修改?www.yak.net/fqa/124.html

Procmail:www.procmail.org

Emacs Lisp 编程入门,作者:Robert J. Chassell:www.gnu.org/manual/emacs-lisp-intro/emacs-lisp-intro.html

SpamAssassin:spamassassin.org

技巧 - emacs “在 /编辑器/ 中完成工作的绝妙方法”:www.portico.org/index.php3?catList=28

“非常非官方的 .emacs 主页”,作者:Ingo Koch:www.dotemacs.de

Charles Curley (www.charlescurley.com) 在怀俄明州的两所大学教授 Linux。他还使用 Emacs 等开源软件工具编写软件、文章和书籍。他的桌面已经“Microsoft Free Zone”超过三年,并且他为 Sams 的 24 小时自学 Emacs (ISBN: 0-672-31594-7) 做出了贡献。

加载 Disqus 评论