22.2.5 选择命令备选实现

有时定义一个充当「通用调度器」的命令会很有用, 它能够根据用户需求调用一组命令中的某一个。 例如,你可能想定义一个名为 ‘open’ 的命令, 用于「打开」并显示多种不同类型的对象。 或者你可以有一个名为 ‘mua’(邮件用户代理 Mail User Agent 的缩写)的命令, 它可以通过多种邮件后端(如 Rmail、Gnus 或 MH-E)读取和发送邮件。 宏 define-alternatives 可用于定义此类 通用命令(generic commands)。 通用命令是一种交互式函数,其具体实现可根据用户偏好从多个备选方案中选择。

Macro: define-alternatives command &rest customizations

该宏定义新的通用命令 command,该命令可拥有多个备选实现。 参数 command 应为未加引号的符号。

调用该宏时,会创建一个交互式 Lisp 闭包(see 闭包)。 当用户首次运行 M-x command RET 时, Emacs 会要求用户从 command 的多个备选实现中选择一个, 并为这些备选方案的名称提供补全功能。 这些名称来自宏创建的用户选项 command-alternatives(如果该选项不存在)。 为保证可用性,该变量的值应为一个关联列表(alist), 其元素格式为 (alt-name . alt-func), 其中 alt-name 是备选方案的名称, alt-func 是选中该备选方案时要调用的交互式函数。 当用户选择某个备选方案后,Emacs 会记住该选择; 此后用户再次调用 M-x command 时, 会自动调用该选中的备选方案,无需再次提示。 若要选择不同的备选方案,可键入 C-u M-x command RET—— 此时 Emacs 会再次提示选择备选方案,且新选择会覆盖之前的设置。

变量 command-alternatives 可在调用 define-alternatives 之前创建并设置合适的值; 若未提前创建,该宏会创建值为 nil 的该变量, 之后需填充描述备选方案的关联项。 希望为已有通用命令提供自定义实现的包, 可使用 autoload 标记(see 自动加载)向该关联列表中添加内容,例如:

;;;###autoload (push '("My name" . my-foo-symbol) foo-alternatives

若可选参数 customizationsnil, 则应由交替出现的 defcustom 关键字(通常为 :group:version) 以及要添加到 defcustom command-alternatives 定义中的值组成。

以下是一个简单的通用调度器命令示例, 命令名为 open,包含 3 个备选实现:

(define-alternatives open
  :group 'files
  :version "42.1")
(setq open-alternatives
      '(("file" . find-file)
	("directory" . dired)
	("hexl" . hexl-find-file)))

emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike