ユーザーのニーズに応じて一連のコマンドのいずれかを呼び出せる「汎用ディスパッチャ」として機能するコマンドを定義することが有用な場合があります。例えば、数種類の異なるオブジェクトを「開いて」表示できる「open」という名前のコマンドを定義したい場合を考えてみましょう。あるいは、Rmail、Gnus、MH-Eといった複数のメールバックエンドのいずれかを使用してメールの送受信ができる「mua」(Mail User Agentの略)というコマンドを用意することもできます。このような汎用コマンドを定義するには、マクロ 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は再び代替案の中から1つを選択するよう求め、その選択が前回の選択を上書きします。
変数 command-alternatives
は、適切な値を用いて define-alternatives
を呼び出す前に作成できます。そうでない場合、マクロは nil
の値で変数を作成し、その後、代替案を記述する関連付けをその変数に格納します。既存のジェネリックコマンドの独自実装を提供したいパッケージは、autoload クッキー(Autoload を参照)を使用してアリストに追加できます。例えば以下の通りです:
;;;###autoload (push '("My name" . my-foo-symbol) foo-alternatives
オプション引数 customizations が nil 以外の場合、それは defcustom command-alternatives の定義に追加する
defcustom キーワード(通常は :group と :version)と値を交互に並べたものである必要があります。
以下に、3つの代替実装を持つ open
という名前のシンプルな汎用ディスパッチャコマンドの例を示します。
(define-alternatives open :group 'files :version "42.1")
(setq open-alternatives
'(("file" . find-file)
("directory" . dired)
("hexl" . hexl-find-file)))