16.2 使用 defcustom 指定变量

您可以使用 defcustom 指定变量,以便您和其他人可以使用 Emacs 的 customize 功能来设置它们的值。 (您不能使用 customize 来编写函数定义;但是您可以在您的 .emacs 文件中编写 defuns。实际上,您可以在您的 .emacs 文件中写任何 Lisp 表达式。)

customize 功能依赖于 defcustom 宏。虽然您可以使用 defvarsetq 来定义用户设置的变量,但是 defcustom 宏是专门设计用于此任务的。

您可以使用对 defvar 的了解来编写 defcustom 的前三个参数。defcustom 的第一个参数是变量的名称。第二个参数是变量的初始值,如果有的话;并且仅当值尚未设置时才设置。第三个参数是文档。

defcustom 的第四个及以后的参数指定类型和选项;这在 defvar 中没有。 (这些参数是可选的。)

每个参数都由一个关键字和一个值组成。每个关键字以冒号字符 ‘:’ 开头。

例如,可定制的用户选项变量 text-mode-hook 如下所示:

(defcustom text-mode-hook nil
  "Normal hook run when entering Text mode and many related modes."
  :type 'hook
  :options '(turn-on-auto-fill flyspell-mode)
  :group 'wp)

变量的名称是 text-mode-hook;它没有默认值;其文档字符串告诉您其功能。

:type 关键字告诉 Emacs 应该将 text-mode-hook 设置为哪种数据类型,并且如何在自定义缓冲区中显示值。

:options 关键字指定变量的建议值列表。通常,:options 适用于钩子。列表只是一个建议;它不是排他的;设置变量的人可以将其设置为其他值;:options 关键字后面显示的列表旨在为用户提供方便的选择。

最后,:group 关键字告诉 Emacs 自定义命令该变量位于哪个组中。这告诉它在哪里找到它。

defcustom 宏识别超过十几个关键字。有关更多信息,请参见 Writing Customization Definitions in The GNU Emacs Lisp Reference Manual

text-mode-hook 为例。

有两种方法可以定制此变量。您可以使用定制命令,输入:

M-x customize

然后找到文本文件编辑组的名称为“Text”。进入该组。 Text Mode Hook 是第一个成员。您可以单击其各种选项,如 turn-on-auto-fill,以设置值。单击按钮

Save for Future Sessions

Emacs 将在您的 .emacs 文件中写入一个表达式。它看起来像这样:

(custom-set-variables
  ;; custom-set-variables was added by Custom.
  ;; If you edit it by hand, you could mess it up, so be careful.
  ;; Your init file should contain only one such instance.
  ;; If there is more than one, they won't work right.
 '(text-mode-hook '(turn-on-auto-fill text-mode-hook-identify)))

text-mode-hook-identify 函数告诉 toggle-text-mode-auto-fill 哪些缓冲区处于文本模式。它会自动启动。)

setq 不同,custom-set-variables 函数的工作方式有些不同。虽然我从未学习过其中的区别,但我手动修改 .emacs 文件中的 custom-set-variables 表达式:我以我认为合理的方式进行更改,并且没有遇到任何问题。其他人喜欢使用定制命令,让 Emacs 为他们完成工作。

另一个 custom-set-… 函数是 custom-set-faces。该函数设置各种字体样式。随着时间的推移,我已经设置了相当多的样式。有时候,我使用 customize 重新设置它们;其他时候,我只是编辑 .emacs 文件中的 custom-set-faces 表达式本身。

第二种自定义 text-mode-hook 的方法是在 .emacs 文件中使用与 custom-set-… 函数无关的代码自己设置它。

当您这样做,并稍后使用 customize 时,您会看到一个消息,上面写着

在 Customize 之外更改;在这里操作可能不可靠。

这只是一个警告。如果您单击按钮

Save for Future Sessions

Emacs 将在您的 .emacs 文件末尾附近写入一个 custom-set-… 表达式,该表达式将在您手写的表达式之后进行评估。因此,它将覆盖您手写的表达式。不会有任何问题。但是,请务必记住哪个表达式是活动的;如果您忘记了,可能会使自己困惑。

只要记得值是在哪里设置的,就不会有问题。无论如何,这些值总是在您的初始化文件中设置的,通常称为 .emacs

我个人几乎不使用 customize。大多数情况下,我自己编写表达式。

顺便说一下,为了更完整地了解定义:defsubst 定义内联函数。语法与 defun 相同。defconst 将符号定义为常量。意图是既不应该由程序也不应该由用户更改由 defconst 设置的值。 (您可以更改它;设置的值是一个变量;但请不要这样做。)