Previous: Keymaps and Minor Modes, Up: Minor Modes [Contents][Index]
マクロdefine-minor-mode
は、自己完結した単一定義内にモードを実装する便利な方法を提供します。
このマクロは名前がmode(シンボル)の新たなマイナーモードを定義する。これはドキュメント文字列としてdocをもつマイナーモードをトグルするためにmodeという名前のコマンドを定義する。
トグルコマンドは1つのオプション(プレフィクス)引数を受け取る。引数なしでinteractiveに呼び出されると、そのモードのオンとオフをトグルする。正のプレフィクス引数はモードを有効にして、それ以外のプレフィクス引数はモードを無効にする。Lispから呼び出すと引数がtoggle
ならモードをトグルして、引数が省略かnil
ならモードを有効にする。これはたとえばメジャーモードフック内でマイナーモードを有効にするのを簡便にする。docがnil
なら、このマクロは上記を記述したデフォルトのドキュメント文字列を提供する。
デフォルトではこれはモードを有効にするとt
、無効にするとnil
にセットされる、modeという名前の変数も定義する。この変数はinit-valueに初期化される。通常(以下参照)はこの値はnil
でなければならない。
文字列lighterはモード有効時にモードライン内に何を表示するか指定する。これがnil
ならこのモードはモードライン内に表示されない。
オプション引数keymapはそのマイナーモードにたいするキーマップを指定する。非nil
なら、それは(値がキーマップであるような)変数の名前かキーマップ、または以下の形式のalistであること
(key-sequence . definition)
ここでkey-sequenceとdefinitionはdefine-key
に渡すのに適した引数である(Changing Key Bindingsを参照)。keymapはキーマップかalistであり、これは変数mode-map
も定義する。
上記の3つの引数init-value、lighter、keymapはkeyword-argsが使用されたときは(部分的に)省略できる。keyword-argsはキーワードとその後の対応する値により構成され、いくつかのキーワードは特別な意味をもつ:
:group group
生成されるすべてのdefcustom
フォームで使用されるカスタムグループ名。mode
(後に‘-mode’がある場合はそれを除く)にたいするデフォルトである。警告:
そのグループを定義するためdefgroup
を正しく記述していなければ、このデフォルトグループ名を使用してはならない。Group Definitionsを参照のこと。
:global global
非nil
ならそのマイナーモードがバッファーローカルでなくグローバルであることを指定する。デフォルトはnil
。
マイナーモードをグローバルにしたときの効果の1つは、mode変数がカスタマイズ変数になることである。Customizeインターフェイスを通じてこの変数をトグルするとモードがオンやオフになり、変数の値は将来のEmacsセッション用に保存できるようになる(Saving
Customizations in The GNU Emacs
Manualを参照)。保存された変数が機能するためにはEmacsが開始されるたびにdefine-minor-mode
フォームが確実に評価されるようにすること。Emacsの一部ではないパッケージにたいしては、:require
キーワードを指定するのがこれを行う一番簡単な方法である。
:init-value init-value
これはinit-value引数を指定するのと等しい。
:lighter lighter
これはlighter引数を指定するのと等しい。
:keymap keymap
これはkeymap引数を指定するのと等しい。
:variable place
これはそのモードの状態を格納するために使用されるデフォルトの変数modeを置き換える。これを指定するとmode変数は定義されず、すべてのinit-value引数は使用されない。placeは異なる名前の変数(あなた自身が定義しなければならない)、またはsetf
関数とともに使用され得るすべてのもの(Generalized Variablesを参照)。placeにはコンス(get
.
set)
も指定できる。ここでgetはカレント状態をリターンする式であり、setはそれをセットする1つの引数(状態)をとる関数である。
:after-hook after-hook
これはモードフック実行後に評価される単一のLispフォームを定義する。これをクォートしないこと。
その他のすべてのキーワード引数は変数modeにたいして生成されたdefcustom
に直接渡される。
modeという名前のコマンドは最初にmodeという名前の変数をセットする等の標準的な動作を処理した後に、もしあればbodyフォームを実行する。それからモードフック変数mode-hook
を実行してから:after-hook
内のフォームを評価して終了する。
init-valueの値はnil
でなければなりません。ただし、(1)Emacsによりそのモードが事前ロードされている、または(2)たとえユーザーが要求しなくともモードを有効にするためにロードするのが容易な場合を除きます。たとえば他の何かが有効でなければそのモードの効果がなく、常にそのタイミングでロードされるような場合には、デフォルトでそのモードを有効にすることに害はありません。しかしこの状況は通常はあり得ません。通常はinit-valueの値はnil
でなければなりません。
easy-mmode-define-minor-mode
という名前はこのマクロにたいするエイリアスです。
以下はdefine-minor-mode
の使い方の例です:
(define-minor-mode hungry-mode "Hungryモードをトグルする 引数なしでinteractiveに呼び出すとモードをトグルする 正のプレフィクス引数でモードを有効に、その他のプレフィクス引数で 無効にする。Lispから呼び出す場合、引数を省略、またはnilなら モードを有効に、`toggle'なら状態をトグルする Hungryモードが有効なときは、C-DELキーは、 最後を除く先行するすべての空白を飲み込む コマンド \\[hungry-electric-delete] を参照" ;; 初期値 nil ;; モードラインの標示 " Hungry" ;; マイナーモードのバインディング '(([C-backspace] . hungry-electric-delete)) :group 'hunger)
これは“Hungry
mode”という名前のマイナーモード、モードをトグルするhungry-mode
という名前のコマンド、モードが有効かどうかを示すhungry-mode
という名前の変数、モードが有効なときそのキーマップを保持するhungry-mode-map
という名前の変数を定義します。これはC-DELにたいするキーバインディングでキーマップを初期化します。また変数hungry-mode
をカスタムグループhunger
に配置します。bodyフォームはありません
— 多くのマイナーモードはそれを必要としません。
以下はこれを記述する等価な方法です:
(define-minor-mode hungry-mode "Hungryモードをトグルする ...省略..." ;; 初期値 :init-value nil ;; モードラインへのインジケーター :lighter " Hungry" ;; マイナーモードのバインディング :keymap '(([C-backspace] . hungry-electric-delete) ([C-M-backspace] . (lambda () (interactive) (hungry-electric-delete t)))) :group 'hunger)
これはglobal-modeという名前をグローバルにトグルする。これはmodeという名前のバッファーローカルなマイナーモードをすべてのバッファーで有効か無効にするということを意味する。あるバッファー内でそのマイナーモードをオンにするには関数turn-onを使用する。マイナーモードをオフにするには-1を引数としてmodeを呼び出す。
モードをグローバルに有効にすると、それ以降ファイルをvisitすることによって作成されるバッファーやFundamental以外のメジャーモードを使用するバッファーにも影響がある。しかしFundamentalで作成される新たなバッファーは検知しない。
これはCustomizeインターフェイス内でそのマイナーモードのオン/オフを切り替えるカスタムオプションglobal-mode
(Customization)を定義する。define-minor-mode
と同様に、たとえば:require
を与える等によってEmacs開始時に毎回確実にdefine-globalized-minor-mode
フォームが評価されるようにすること。
グローバルマイナーモードのモード変数にたいしてカスタムグループを指定するにはkeyword-args内で:group
group
を使用する。
一般的にはグローバル化されたマイナーモードを定義するときは、ユーザーがバッファーごとにモードを使用(または無効に)できるように非グローバル版も定義すること。これにより特定のメジャーモード内でそのモードのフックを使用すればグローバルに有効化されたマイナーモードを無効にすることができるようになる。