Previous: Transposition, Up: Text


31.23 変更フック

これらのフックにより、すべてのバッファ (それらをバッファローカルにしておけば特定のバッファ)における すべての変更を知るようにできます。 テキストの特定部分の変更を検出する方法については、 Special Propertiesも参照してください。

これらのフックに使う関数において正規表現を使う場合には、 マッチデータを保存し復元する必要があります。 さもないと、それらを呼び出す編集操作と奇妙な干渉を引き起こします。

— Variable: before-change-functions

この変数は、バッファを変更するまえに呼び出すべき関数のリストを保持する。 各関数は2つの引数、つまり、整数で表した変更対象の領域の先頭と末尾を受け取る。 変更対象のバッファはつねにカレントバッファである。

— Variable: after-change-functions

この変数は、バッファを変更したあとに呼び出すべき関数のリストを保持する。 各関数は3つの引数、つまり、変更されたばかりの領域の先頭と末尾、 変更前に存在していたテキストの長さを受け取る。 3つの引数はすべて整数である。 変更対象のバッファはつねにカレントバッファである。

古いテキストの長さは、変更前のそのテキストの先頭と末尾の バッファ内位置の差である。 変更済みのテキストの長さは、単純に始めの2つの引数の差である。

— Macro: combine-after-change-calls body...

このマクロは通常どおりbodyを実行するが、 一連の変更に対して安全と思えるときには、 after-change-functionsの関数を一度だけ呼び出す。

プログラムからバッファの同じ部分でテキスト変更を複数回行う場合、 プログラムの当該部分の周りでマクロcombine-after-change-callsを使うと、 フックafter-change-functionsを使用してるときには 動作がかなり速くなりうる。 最終的にフックafter-change-functionsが呼ばれると、 combine-after-change-callsの本体で行った変更すべてを含むような バッファ部分が引数に指定される。

警告: フォームcombine-after-change-callsの本体の内側では after-change-functionsafter-change-functionの値を 変更しないこと。

注意: 変更がバッファの広く分散した部分に行われるときにもこれは動作するが、 推奨できない。 非効率なふるまいをするようなフック関数があるからである。

— Variable: before-change-function

この廃れた変数は、任意のバッファの変更を行うまえに 呼ばれる1つの関数を保持する (nilならばそのような関数はなし)。 before-change-functionsの関数と同様に呼ばれる。

— Variable: after-change-function

この廃れた変数は、任意のバッファの変更を行ったあとに 呼ばれる1つの関数を保持する (nilならばそのような関数はなし)。 after-change-functionsの関数と同様に呼ばれる。

上の4つの変数は、これらの関数が実行中には一時的にnilに束縛されます。 つまり、これらの関数の1つがバッファを変更しても、 その変更ではこれらの関数を呼び出しません。 フック関数においてこれらの関数を実行するような変更を行いたい場合には、 フック関数でこれらの変数をそれらの通常の値に束縛し直します。

この保護的な機構の1つの不便な帰結は、 after-change-functionsbefore-change-functionsには、 その変数の値を変更する関数を持てないことです。 しかし、これは本当の制限ではありません。 それらの関数で実行すべき関数のリストを変更したければ、 単純に1つの定まった関数をフックに追加し、 その関数では呼び出すべき別の関数を指定する別の変数を調べます。 つぎのようにします。

     (setq my-own-after-change-functions nil)
     (defun indirect-after-change-function (beg end len)
       (let ((list my-own-after-change-functions))
         (while list
           (funcall (car list) beg end len)
           (setq list (cdr list)))))
     
     (add-hooks 'after-change-functions
                'indirect-after-change-function)
— Variable: first-change-hook

この変数は、未変更状態のバッファを変更するたびに実行される ノーマルフックである。