Previous: , Up: Text   [Contents][Index]


31.28 フックの変更

以下のフック変数によりバッファー(これらをバッファーローカルにした場合には特定のバッファー)での変更にたいして、通知を受け取るようにアレンジすることができます。テキストの特定部分にたいする変更の検出方法についてはSpecial Propertiesも参照してください。

これらのフック内で使用する関数は、もしそれらが正規表現を使用して何かを行う場合にはマッチしたデータの保存とリストアを行うべきです。さもないとそれらが呼び出す編集処理に奇妙な方法で干渉するでしょう。

Variable: before-change-functions

この変数はEmacsがバッファー変更を行おうとする際に呼び出す関数のリストを保持する。各関数は変更されようとするリージョンの先頭と終端を整数で表す2つの引数を受け取る。変更されようとするバッファーは関数の呼び出しの際には常にカレントバッファーである。

Variable: after-change-functions

この変数はEmacsがバッファー変更を行った後に呼び出す関数のリストを保持する。各関数は正に変更されたリージョンの先頭と終端、およびその変更前に存在したテキストの長さという3つの引数を受け取る。これら3つの変数は、すべて整数。変更されたバッファーは関数の呼び出しの際には常にカレントバッファーである。

古いテキストの長さは、変更される前のテキストでのテキストの前後のバッファー位置の差で与えられる。変更されたテキストでは、その長さは単に最初の2つの引数の差で与えられる。

これらの関数は*Messages*バッファーへのメッセージの出力では呼び出されず、特定の処理用にEmacsが作成する内部的なバッファーのようなLispプログラムからは可視であるべきではないバッファーへの変更でも呼び出されません。

バッファーへのそれぞれの変更の周辺で、before-changeフックとafter-changeフックが釣り合いの取れたペアであることを期待しないでください。またEmacsが削除しようとするテキスト塊(chunk of text)ごとにbefore-changeフックが呼び出されることも期待してはなりません。これらのフックはLispプログラムがbefore-changeかafter-changeの両方ではなく、いずれかを使用するという想定で提供されており、その変更が発生したリージョン境界には実際に変更があったテキストだけではなく、少量にたいして行われた変更を複数集めて一塊とした変更さえ含まれるかもしれません。

Macro: combine-after-change-calls body…

このマクロは普通にbodyを実行するが、もしそれが安全なように見えるなら一連の複数の変更にたいして正に一度、after-change関数を呼び出すようにアレンジする。

そのバッファーの同じ領域内でプログラムが複数のテキスト変更を行う場合には、その部分のプログラムの周囲でマクロcombine-after-change-callsを使用することにより、after-changeフック使用中の実行がかなり高速になり得る。after-changeフックが最終的に呼び出される際には、その引数はcombine-after-change-callsのbody内で行われたすべての変更にたいして含むバッファーの範囲を指定する。

警告: フォームcombine-after-change-callsのbody内でafter-change-functionsの値を変更してはならない。

警告: 組み合わされた変更がバッファーの広い範囲に点在してに出現する場合でも、これは依然として機能するが推奨できない。なぜならこれは、ある変更フック関数を非効率的な挙動へと導くかもしれないからである。

Variable: first-change-hook

この変数は以前は未変更の状態だったバッファーが変更された際は常に実行されるノーマルフック。

Variable: inhibit-modification-hooks

この変数が非nilならすべての変更フックは無効。それらは何も実行されない。これはこのセクションで説明したすべてのフック変数、同様に特定のスペシャルテキストプロパティ(Special Propertiesを参照)とオーバーレイプロパティ(Overlay Propertiesを参照)にアタッチされたフックに影響を与える。

これらの同一フック変数上の関数の実行の間、バッファー変更によるデフォルトの変更フックが他の変更フック実行中に実行されないように、この変数は非nilにバインドされる。それ自体が変更フックから実行される特定のコード断片内で変更フックを実行したければ、inhibit-modification-hooksnilにローカルに再バインドすること。