これらのフック変数を使用すると、バッファ(あるいはバッファローカルに設定した場合は特定のバッファ)の変更を検知するように設定できます。テキストの特定部分の変更を検知する方法については、特殊な意味を持つプロパティも参照してください。
これらのフックで使用する関数は、正規表現を用いる処理を行う場合は、マッチデータを保存および復元する必要があります。そうしないと、それらを呼び出す編集操作に予期せぬ形で干渉することになります。さらに、これらのフック内の関数は、バッファ固有の状態のうち、フック関数自身が作成・管理する要素以外のバッファテキスト、フェイス、プロパティ、オーバーレイ、およびその他の項目を変更することを避けるべきです。というのも、Emacsの他の部分が、こうした変更に気づかぬまま影響を受ける可能性があるためです。
この変数には、Emacsがバッファを変更しようとする際に呼び出される関数のリストが格納されています。各関数には、変更対象となるリージョンの開始位置と終了位置を表す2つの引数(整数)が渡されます。変更対象となるバッファは、関数が呼び出された時点でのカレントバッファとなります。
この変数には、Emacsがバッファを変更した後に呼び出す関数のリストが格納されています。各関数には、変更されたばかりのリージョンの開始位置と終了位置、および変更前に存在していたテキストの長さという3つの引数が渡されます。これら3つの引数はいずれも整数です。変更されたバッファは、関数が呼び出された時点のカレントバッファとなります。
元のテキストの長さは、変更前のそのテキストにおける前後のバッファ位置の差となります。変更後のテキストについては、その長さは単に最初の2つの引数の差となります。
*Messages* バッファへのメッセージ出力ではこれらの関数は呼び出されず、また、Lisp プログラムからは参照できないはずの特定の内部バッファの変更(特定のジョブ向けに Emacs が内部的に作成したバッファの変更など)においても同様です。
バッファ変更プリミティブの大部分は、変更ごとに before-change-functions と
after-change-functions
をバランスの取れたペアで呼び出し、これらのフックへの引数がまさに行われる変更範囲を画定します。しかし、一部の複雑なプリミティブでは、変更を行う前に一度
before-change-functions
を呼び出し、その後、プリミティブが行う個々の変更回数に応じて after-change-functions を 0
回以上呼び出すため、フック関数は常にこの挙動になると想定すべきではありません。その場合、before-change-functions
への引数は個々の変更が行われる領域を囲みますが、それが必ずしも最小の領域になるとは限らず、続く after-change-functions
の各呼び出しにおける引数が、変更されるテキスト部分を正確に画定することになります。一般的に、before-change または after-change
のいずれか一方のフックを使用し、両方を併用しないことを推奨します。
このマクロは通常 body を実行しますが、一連の複数回の変更に対して、変更後の関数を一度だけ呼び出すように構成されています—それが安全であると思われる場合に限ります。
プログラムがバッファの同一領域で複数回のテキスト変更を行う場合、その部分をマクロ combine-after-change-calls
で囲むことで、変更後フックが使用されている際に実行速度を大幅に向上させることができます。最終的に変更後フックが呼び出される際、引数には combine-after-change-calls
本体内で行われたすべての変更を含むバッファの一部が指定されます。
警告: combine-after-change-calls フォームの本文内で after-change-functions の値を変更してはいけません。
警告: 組み合わせる変更がバッファ内の広範囲に分散している場合でも、動作はしますが、一部の変更フック関数において非効率な挙動を招く可能性があるため、推奨されません。
これは body を通常通り実行しますが、その際に行われるバッファの変更によって before-change-functions および after-change-functions の呼び出しがトリガーされることはありません。代わりに、beg と end
で囲まれた領域に対してこれらのフックがそれぞれ1回ずつ呼び出され、after-change-functions に渡されるパラメータには body によって行われた領域サイズの変更が反映されます。
このマクロの結果は、body が返す結果となります。
このマクロは、関数がバッファに対して(場合によっては)大量の反復的な変更を行い、個々のバッファ変更ごとに変更フックを実行すると実行に時間がかかってしまう場合に有用です。Emacs自体も、例えば
comment-region や uncomment-region といったコマンドでこのマクロを使用しています。
警告: body 内の before-change-functions または after-change-function の値を変更してはなりません。
警告: beg および end で指定された領域外では、バッファに変更を加えてはなりません。
この変数は、以前は未変更状態であったバッファが変更されるたびに実行される通常のフックです。
この変数が nil
以外の場合、すべての変更フックが無効になり、いずれも実行されません。これは、本セクションで前述したすべてのフック変数に加え、特定の特殊なテキストプロパティ(特殊な意味を持つプロパティ
を参照)やオーバーレイプロパティ(オーバーレイプロパティ を参照)に紐付けられたフックにも影響します。
また、この変数は、同じフック変数を実行する際に non-nil
にバインドされるため、デフォルトでは修正フックからバッファを変更しても、他の修正フックが実行されることはありません。もし、修正フックから実行される特定のコード内で修正フックを実行させたい場合は、ローカルで
inhibit-modification-hooks を nil
に再バインドしてください。ただし、これを行うと修正フックへの再帰呼び出しが発生する可能性があるため、その対策を必ず講じてください(例えば、フックに何もさせないよう指示する変数をバインドするなど)。
この変数のバインドは、バッファテキストの内容に永続的な変更を伴わない修正(例えばフェイスの変更や一時的な修正など)にのみ行うことを推奨します。一連の変更において変更フックを遅延させる必要がある場合(通常はパフォーマンス上の理由から)は、代わりに
combine-change-calls または combine-after-change-calls を使用してください。