Next: Generic Commands, Previous: Interactive Examples, Up: Defining Commands [Contents][Index]
Emacsのコマンドの多くは汎用であり、特定のモードに関連付けられていません。たとえばM-x kill-regionは編集可能テキストをもつほとんどのモード、(M-x list-buffersのような)情報表示コマンドはほとんどのコンテキストで使用できます。
しかしそれ以外の多くのコマンドはモードに具体的に関連付けられており、そのコンテキスト外部では意味をなしません。たとえばDiredバッファーの外部でM-x
dired-diff
を使用すると、単にエラーをシグナルするでしょう。
したがってEmacsにはコマンドが“所属する”モードが何かを指定するためのメカニズムがあります:
(defun dired-diff (...) ... (interactive "p" dired-mode) ...)
これはそのコマンドをdired-mode
(やdired-mode
から派生したモード)だけに適用されるようにマークします。interactive
フォームには任意個数のモードを追加できます。
モードの指定は、M-S-x
(execute-extended-command-for-buffer
)でのコマンド補完に影響を与えます(Interactive Callを参照)。read-extended-command-predicate
の値に応じて、モード指定がM-xでの補完にも影響を与えるかもしれません。
たとえばread-extended-command-predicate
の値としてcommand-completion-default-include-p
述語を使用する際には、特定モードに適用されるとマークされたコマンドはM-xでリストされないでしょう(もちろんそのモードを使用するバッファーにいない場合)。これはメジャーモードとマイナーモードの両方に言えることです(対照的にM-S-xは適用されないコマンドを補完候補から常に省略する)。
read-extended-command-predicate
はデフォルトではnil
であり、M-xでの補完ではカレントバッファーのモードに適用されるとマークされているか否かに関わらず、ユーザーがタイプしたものにマッチするすべてのコマンドがリストされます。
あるモードにたいして適用されるものとしてコマンドをマークすると、(何らかのキーにバインドされていなければ)それらはC-h mでもリストされるようになります。
(拡張interactive
フォームをサポートしない古いバージョンのEmacsでは動作すると思われるコードがある等で)この拡張interactive
フォームの使用が不便なら、かわりに等価な以下の宣言(Declare Formを参照)を使用できます:
(declare (modes dired-mode))
コマンドのモードへのタグ付けはある意味好みの問題ですが、そのモードの外部では動作しないことが明確なコマンドはタグ付けするべきです。これにはどこか別の場所で呼び出すとエラーをシグナルするだけではなく、期待しないモードからの呼び出しが破壊的なコマンドも含まれます(これは通常はスペシャルモード、すなわち編集不可なモード用に記述されたコマンドのほとんどが含まれる)。
別モードから呼び出した際にも害がなく、“機能する”コマンドもありますが、それでも別の場所使用することが実際に無意味なコマンドには、依然としてタグ付けする必要があります。たとえば多くのスペシャルモードはバッファーのexitコマンドにqをバインドしており、これは"Goodbye
from this
mode"のようなメッセージを発行してkill-buffer
を呼び出す以外は何も行わないかもしれません。このコマンドは別のモードでも“機能する”でしょうが、そのスペシャルモードのコンテキスト外部でこのコマンドを実際に使いたいと思う人が居るようには思えません。
多くのモードには、そのモードを異なる方法で開始するために、一連の異なるコマンドがあります (例:
eww-open-in-new-buffer
とeww-open-file
)。このようなコマンドはユーザーがさまざまなコンテキストから発行し得るので、モード固有とタグ付けするべきでは決してありません。
Emacs
28.1ではコマンドモードの指定はネイティブコンパイルされた関数ではサポートされていないことに注意してください(Emacsの将来のバージョンでは修整される)。これはネイティブコンパイル付きで構築されたEmacsではread-extended-command-predicate
もサポートされていないことを意味します。