GNU Emacs 32.0.50 (9008bf64c3) のマニュアルを PLaMo 翻訳で機械翻訳したものです。誤訳を含むことがあります。原文: https://www.gnu.org/software/emacs/manual/html_node/emacs/Hooks.html ・ emacs-doc.conao3.com

51.2.2 フック

フックは、Emacsをカスタマイズするための重要な仕組みです。フックとは、明確に定義されたタイミングで呼び出される関数のリストを保持するLisp変数のことです。(これをフックを実行すると呼びます。)リストに含まれる個々の関数は、そのフックのフック関数と呼ばれます。例えば、フック kill-emacs-hook はEmacsを終了する直前に実行されます(Emacsの終了を参照)。

ほとんどのフックは通常のフックです。つまり、Emacsがフックを実行する際、各フック関数を引数なしで順に呼び出します。ほとんどのフックを通常のフックにすることで、統一的な方法で利用できるよう配慮しています。名前が‘-hook’で終わる変数はすべて通常のフックです。

一部のフックは異常フックです。その名称は、-hookではなく‘-functions’で終わります(古いコードの中には、非推奨の接尾辞‘-hooks’を使用しているものもあります)。これらのフックが異常とされる理由は、その関数の呼び出し方にあります。例えば、引数が渡されていたり、戻り値が何らかの形で利用されていたりする場合などです。具体例を挙げると、find-file-not-found-functionsが異常なのは、いずれか一つのフック関数がnil以外の値を返すと、残りの関数は一切呼び出されないためです(ファイルの参照を参照)。各異常フック変数のドキュメントには、その関数がどのように使用されるかが説明されています。

他のLisp変数と同様に、setq でフック変数を設定できますが、フック(通常または異常)に関数を追加する推奨方法は、以下の例に示すように add-hook を使用することです。詳細については、The Emacs Lisp Reference Manual の Hooks を参照してください。

ほとんどの主要なモードでは、初期化の最終ステップとして1つ以上のモードフックが実行されます。モードフックは、個々のモードの動作をカスタマイズするための便利な手段であり、常に通常モードで動作します。例えば、テキストモードおよびテキストモードをベースとしたその他のモードでオートフィルモードを有効にするフックを設定する方法は以下の通りです。

(add-hook 'text-mode-hook 'auto-fill-mode)

これは auto-fill-mode を呼び出すことで動作し、引数が指定されない場合にマイナーモードが有効になります(マイナーモード を参照)。次に、テキストモードに基づくモードの一つである LaTeX モードにおいて、オートフィルモードを有効にしたくない場合を考えてみましょう。これは、以下の行を追加することで実現できます:

(add-hook 'latex-mode-hook (lambda () (auto-fill-mode -1)))

ここでは、特殊なマクロ lambda を用いて無名関数(The Emacs Lisp Reference Manual の Lambda Expressions を参照)を構築しており、これが -1 を引数として auto-fill-mode を呼び出すことでマイナーモードを無効にします。LaTeX モードでは text-mode-hook の実行後に latex-mode-hook が実行されるため、結果として Auto Fill モードは無効なままとなります。

以下に、フックを使ってCコードのインデントをカスタマイズする方法を示す、より複雑な例を挙げます。

(setq my-c-style
  '((c-comment-only-line-offset . 4)
    (c-cleanup-list . (scope-operator
                       empty-defun-braces
                       defun-close-semi))))

(add-hook 'c-mode-common-hook
  (lambda () (c-add-style "my-style" my-c-style t)))

メジャーモードのフックは、元のモードから派生した他のメジャーモードにも適用されます(The Emacs Lisp Reference ManualのDerived Modesを参照)。例えば、HTMLモードはTextモードから派生しています(SGML and HTML Modesを参照)。HTMLモードが有効な場合、html-mode-hookを実行する前にtext-mode-hookが実行されます。これにより、単一のフックを用いて関連する複数のモードに影響を与えるという便利な方法が提供されます。特に、任意のプログラミング言語モードにフック関数を適用したい場合は、それをprog-mode-hookに追加してください。Progモードは、まさにこの目的のために、他のメジャーモードが自身を継承できるようにするだけのメジャーモードです。

フック関数は、実行順序に依存しないように設計するのが最善です。順序への依存はトラブルの元となります。ただし、順序は予測可能です。フック関数は、フック内に現れる順に実行されます。

add-hook を繰り返し呼び出してフック関数のさまざまなバージョンを追加していく場合、追加したすべてのバージョンがフック変数に一括して保持される点に注意してください。remove-hook を呼び出して個別の関数をクリアしたり、(setq hook-variable nil) を呼び出してすべてを削除したりできます。

hook変数がバッファローカルな場合、グローバル変数の代わりにバッファローカル変数が使用されます。ただし、バッファローカル変数に要素 t が含まれている場合は、グローバルのhook変数も実行されます。