一連のコマンドセットのうちからユーザーのニーズに応じていずれか1つを呼び出すことができるような、“ジェネリックディスパッチャー(generic
dispatcher)”としてコマンドを定義すると便利なときがあるかもしれません。たとえば複数の異なるオブジェクトを“オープン”して表示できる‘open’というコマンドを定義したいときを想像してください。あるいは‘mua’
(Mail User Agent:
電子メールクライアント)というコマンドを使ってRmail、Gnus、MH-Eのような複数の電子メールバックエンドのいずれか1つを用いることにより電子メールを読んだり送信ができるかもしれません。そのようなジェネリックコマンド(generic
commands)を定義するために、マクロdefine-alternatives
を使用することができます。ジェネリックコマンドとは複数ある選択肢からユーザーが好みに応じて実装を選択できるインタラクティブな関数のことです。
このマクロは実装の候補を複数もつジェネリックなcommandを新たに定義する。引数commandはクォートされていないシンボルであること。
呼び出されると、このマクロはインタラクティブなLispクロージャ(クロージャーを参照)を作成する。ユーザーがM-x command RETを最初に実行した際に、Emacsはcommandの実装候補から1つを選択するよう尋ねる(候補の名前にたいする補完が提供される)。候補の名前はこのマクロが作成したcommand-alternatives
という名前のユーザーオプション(以前に存在していなければ)に由来する。利便性のためにこの変数の値は(alt-name . alt-func)
という形式の要素をもつalistであること。ここでalt-nameは候補の名前、alt-funcはその候補が選択された際に呼び出されるインタラクティブ関数。ユーザーがある候補を選択するとEmacsがその選択を記憶して、次回以降ユーザーがM-x
commandを呼び出した際には入力を求めることなく前に選択した候補を自動的に呼び出す。別の候補を選択するにはC-u M-x command RETとタイプすれば、Emacsは再び候補のいずれかを選択するよう求めてその選択が以前選択された候補をオーバーライドする。
define-alternatives
を呼び出す前に、適切な値で変数command-alternatives
を作成することも可能。作成しない場合にはマクロがnil
値でこの変数を作成するので、候補を記述する連想値を設定する必要がある。既存のジェネリックコマンドにたいして独自の実装を提供したいパッケージは、たとえば以下のようにautoload
クッキー(autoloadを参照)を用いて、alistに追加することができる:
;;;###autoload (push '("My name" . my-foo-symbol) foo-alternatives
オプション引数customizationsが非nil
なら、defcustom
キーワード(典型的には:group
と:version
)、およびdefcustom
command-alternatives
の定義に追加する値により構成される選択肢。
以下は3つn実装候補をもつopen
という名前のシンプルなジェネリックディスパッチャーコマンドの例:
(define-alternatives open :group 'files :version "42.1")
(setq open-alternatives '(("file" . find-file) ("directory" . dired) ("hexl" . hexl-find-file)))