フック(hook)とは、既存のプログラムから特定の場面で 呼び出される(1つか一連の)関数を収めた変数です。 Emacsは、カスタマイズのためにフックを用意しています。 ほとんどの場合、フックはファイル.emacsで設定しますが、 Lispプログラムが行ってもかまいません。 標準のフック関数一覧については、See Standard Hooks。
Emacsの多くのフックはノーマルフック(normal hook)です。 これらの変数は、引数なしで呼び出される関数のリストを保持しています。 フック名が‘-hook’で終っていると、ノーマルフックを意味します。 読者がそれらを単一の方法で使えるように、 可能な限りノーマルフックにするように心掛けています。
各メジャーモード関数は、
その初期化の最終段階でモードフック(mode hook)と呼ばれる
ノーマルフックを実行すると期待されます。
これにより、モードがすでに設定したバッファローカルな変数を上書きすることで、
ユーザーがモードのふるまいをカスタマイズしやすくしています。
しかし、フックは別の場面でも使われています。
たとえば、フックsuspend-hook
は、
Emacsが自身を一時休止する直前に実行されます。
(see Suspending Emacs)。
ノーマルフックにフック関数を追加する推奨方法は、
add-hook
(下記参照)を呼ぶことです。
フック関数は、funcall
(see What Is a Function)が
受け付けるならばどんな種類の関数でもかまいません。
ほとんどのノーマルフック変数は最初は空ですが、
add-hook
はその扱い方を知っています。
フック変数の名前が‘-hook’で終らない場合、 それがアブノーマルフック(abnormal hook)であることを表します。 読者は、そのようなフックの正しい使い方を説明書で調べるべきです。
変数名が‘-functions’や‘-hooks’で終っていると、
その値は関数のリストですが、
それらの関数を引数ありで呼び出したり、
関数の戻り値をどこかで使うという意味でアブノーマル(異常)なのです。
リストに関数を追加するにはadd-hook
を使えますが、
関数を書くときには注意する必要があります。
(これらの変数のうち、実際にはノーマルフックであるものもある。
ノーマルフックには‘-hook’を使うという慣習を
確立するまえに命名したものである。)
変数名が‘-function’で終っていると、 その値は、関数のリストではなく、1つの関数です。
lisp対話モードで自動詰め込み(auto-fill)モードをオンにするために モードフックを使った例を示します。
(add-hook 'lisp-interaction-mode-hook 'turn-on-auto-fill)
適当な時期に、Emacsは関数run-hooks
を使って
特定のフックを実行します。
この関数は、add-hook
で追加されたフック関数を呼び出します。
この関数は複数個のフック変数名を引数にとり、各フックを順に実行する。 各引数hookvarは、フック変数のシンボルであること。 これらの引数は、指定された順に処理される。
フック変数が
nil
以外の値であると、 その値は、関数か関数のリストである。 値が関数(ラムダ式や関数定義を持つシンボル)であると、それを呼び出す。 値がリストであると、順番にその要素を呼び出す。 フック関数は、引数なしで呼び出される。 現在、フック変数に1つの関数を入れることは廃れかけている。 つねに関数のリストを使うべきである。例として、
emacs-lisp-mode
がそのモードフックをどのように 実行するかを示す。(run-hooks 'emacs-lisp-mode-hook)
この関数は、フック関数に引数を渡すアブノーマルフックを実行する方法である。 各フック関数に引数argsを渡して呼び出す。
この関数は、フック関数に引数を渡すアブノーマルフックを実行するが、 フック関数が失敗するとただちに止める方法である。 フック関数が
nil
を返すまで、 各フック関数に引数argsを渡して呼び出す。nil
が返ってくるとnil
で戻る。 さもなければ、nil
以外の値を返す。
この関数は、フック関数に引数を渡すアブノーマルフックを実行するが、 フック関数が成功するとただちに止める方法である。 フック関数が
nil
以外を返すまで、 各フック関数に引数argsを渡して呼び出す。nil
以外が返ってくると 最後に呼び出したフック関数の戻り値を返す。
この関数はフック変数hookに関数functionを追加する 手軽な方法である。 引数functionは、正しい個数の引数をとる任意の正しいLisp関数であること。 たとえば、
(add-hook 'text-mode-hook 'my-text-hook-function)は、
text-mode-hook
というフックにmy-text-hook-function
を追加する。
add-hook
は、ノーマルフックに加えてアブノーマルフックにも使える。フック関数は実行順序に依存しないように設計するのが最良である。 実行順序に依存すると『トラブルを呼び込む』ようなものである。 しかし、順序は予測できる。 通常、functionはフックリストの先頭に置かれるので、 (ほかに
add-hook
の呼び出しがなければ)最初に実行される。 省略可能な引数appendがnil
以外であると、 新たなフック関数はフックリストの末尾に置かれ、 最後に実行される。localが
nil
以外であると、 新たなフック関数をカレントバッファにバッファローカルにすることを意味する。 これを行うまえに、(make-local-variable
ではなく)make-local-hook
を呼んで フック自身をバッファローカルにしておく必要がある。 フック自身がバッファローカルでないと、localの値は意味を持たない。 フック関数はつねにグローバルである。
この関数は、フック変数hookからfunctionを取り除く。
localが
nil
以外であると、 グローバルなフックリストではなくバッファローカルなフックリストから functionを削除することを指定する。 フック変数自身がバッファローカルでないと、localの値は意味を持たない。
この関数は、フック変数
hook
をカレントバッファにバッファローカルにする。 フック変数がバッファローカルであると、 バッファローカルなフック関数とグローバルなフック関数を持つことができ、run-hooks
はそれらすべてを実行する。この関数は、バッファローカルな値の要素を
t
にすることで動作する。 これは、バッファローカルな値に加えてフック変数のデフォルト値にある フック関数を使うことを表すフラグである。run-hooks
はこのフラグを理解し、make-local-hook
はすべてのノーマルフックを処理できる。 アブノーマルフックに関しては、t
の意味を理解するように更新したものだけが処理できる。フック変数に対して
make-local-variable
を直接使わないこと。 それだけでは不十分である。