Emacsのコマンドの多くは汎用的であり、特定のモードに限定されません。例えば、M-x kill-regionは編集可能なテキストがあるほぼあらゆるモードで使用でき、情報を表示するコマンド(M-x list-buffersなど)もほぼあらゆるコンテキストで使用可能です。
しかし、他の多くのコマンドは特定のモードに紐付いており、その文脈以外では意味をなしません。例えば、M-x
dired-diff を Dired バッファ外で使用すると、単にエラーが返されます。
したがって、Emacsには、コマンドがどのモード(または複数のモード)に「属する」かを指定する仕組みが備わっています:
(defun dired-diff (...) ... (interactive "p" dired-mode) ...)
これにより、このコマンドはdired-mode(またはdired-modeから派生した任意のモード)にのみ適用されることになります。interactive形式には、任意の数のモードを追加できます。
モードを指定すると、M-S-x(execute-extended-command-for-buffer、インタラクティブ呼び出しを参照)におけるコマンド補完に影響します。また、read-extended-command-predicateの値によっては、M-xにおける補完にも影響する場合があります。
例えば、command-completion-default-include-p 述語を read-extended-command-predicate の値として使用する場合、M-x
は特定のモードに適用可能としてマークされたコマンドを一覧に表示しません(もちろん、そのモードを使用しているバッファ内にいる場合は除きます)。これはメジャーモードとマイナーモードの両方に当てはまります。(対照的に、M-S-x は適用不可能なコマンドを常に補完候補から除外します。)
デフォルトでは read-extended-command-predicate は nil であり、M-x
での補完では、現在のバッファのモードに適用可能としてマークされているか否かにかかわらず、ユーザーが入力した内容に一致するすべてのコマンドが一覧表示されます。
モードに適用可能なコマンドを指定すると、C-h m にもこれらのコマンドがリストされます(いずれかのキーに割り当てられていない場合)。
この拡張形式 interactive の使用が不便な場合(拡張形式 interactive をサポートしていない旧バージョンの Emacs
でも動作させる必要がある場合など)は、代わりに以下の同等の宣言(declare 形式
を参照)を使用できます:
(declare (modes dired-mode))
どのコマンドにモードタグを付けるかはある程度好みの問題ですが、明らかにそのモード以外では動作しないコマンドにはタグを付けるべきです。これには、別の場所から呼び出された場合にエラーを通知するコマンドだけでなく、予期しないモードから呼び出された際に破壊的な動作をするコマンドも含まれます。(通常、これには特殊な(すなわち編集用ではない)モード向けに記述されたコマンドの大部分が該当します。)
一部のコマンドは無害であり、他のモードから呼び出された際に「動作」することもありますが、他の場所で実際に使用する意味がほとんどない場合は、それでもモードをタグ付けしておくべきです。例えば、多くの特殊モードには
q にバインドされたバッファを抜けるコマンドがあり、「Goodbye from this
mode」といったメッセージを出力して kill-buffer
を呼び出す以外に何も行わない場合があります。このコマンドはどのモードからでも「動作」しますが、この特殊モードのコンテキスト外で実際にこのコマンドを使いたいと思う人は、まずいないでしょう。
多くのモードには、それぞれ異なる方法でモードを起動する一連のコマンド(例:eww-open-in-new-buffer や eww-open-file)が用意されています。こうしたコマンドは、ユーザーがほぼどのようなコンテキストからでも発行できるため、モード固有のものとしてタグ付けすべきではありません。