Next: Change Hooks, Previous: JSONRPC, Up: Text [Contents][Index]
データベース用語においてのアトミック(atomic: 原子的、不可分)な変更とは、全体として成功か失敗をすることはできるが、部分的にはできない個別の変更のことです。Lispプログラムは単一もしくは複数のバッファーにたいする一連の変更をアトミック変更グループ(atomic change group)にすることができます。これはその一連の変更全体がそれらのバッファーに適用されるか、またはエラーの場合は何も適用されないかの、いずれかであることを意味します。
すでにカレントであるような単一のバッファーにたいしてこれを行うには、以下のように単に変更を行うコードの周囲にatomic-change-group
の呼び出しを記述します:
(atomic-change-group (insert foo) (delete-region x y))
atomic-change-group
のbody内部でエラー(またはその他の非ローカルexit)が発生した場合には、そのbodyの実行の間にそのバッファーでのすべての変更が行われなかったことになります。この類の変更グループは他のバッファーには影響を与えず、それらのバッファーにたいする変更はそのまま残されます。
さまざまなバッファー内で行った変更から1つのアトミックグループを構成する等、より複雑な何かを必要とする場合には、atomic-change-group
が使用する、より低レベルな関数を直接呼び出さなければなりません。
この関数はbuffer (デフォルトはカレントバッファー)にたいする変更グループをセットアップする。これはその変更グループを表すhandleをリターンする。変更グループをactivateしたり、その後でそれを完了するためにはこのhandleを使用しなければならない。
変更グループを使用するためには、それをactivate(アクティブ化)しなければなりません。これはbufferのテキストを変更する前に行わなければなりません。
これはhandleが指定する変更グループをactiveにする。
変更グループをactivateした後には、そのバッファー内で行ったすべての変更は変更グループの一部となります。そのバッファー内で目論んでいたすべての変更を行ったら、変更グループをfinish(完了)しなければなりません。すべての変更を受け入れる(確定する)か、すべてをキャンセルするという2つの方法により、これを行うことができます。
この関数はhandleにより指定される変更グループ内のすべての変更にたいして、finalizeすることにより変更を受け入れる。
この関数はhandleにより指定される変更グループ内のすべての変更をキャンセルしてundoする。
グループが常に確実にfinishされるようにするために、コードではunwind-protect
を使用するべきです。activate-change-group
の呼び出しは、実行直後にユーザーがC-gをタイプする場合に備えてunwind-protect
内部にあるべきです(これがprepare-change-group
とactivate-change-group
が別関数となっている1つの理由。なぜなら通常はunwind-protect
開始前にprepare-change-group
を呼び出すであろうから)。グループを一度finishしたら、そのhandleを再度使用してはなりません。特に同じ変更グループを2回finishしないでください。
複数バッファー変更グループ(multibuffer change
group)を作成するためには、カバーしたいバッファーそれぞれでprepare-change-group
を一度呼び出してから、以下のようにリターン値を結合するためにnconc
を使用してください:
(nconc (prepare-change-group buffer-1) (prepare-change-group buffer-2))
その後は1回のactivate-change-group
呼び出しで複数変更グループをアクティブにして、1回のaccept-change-group
かcancel-change-group
呼び出しでそれをfinishしてください。
同一バッファーにたいするネストされた複数の変更グループ使用は、あなたが期待するであろう通りに機能します。同一バッファーにたいするネストされていない変更グループの使用によりEmacsが混乱した状態になるので、これが発生しないようにしてください。与えられた何らかのバッファーにたいして最初に開始した変更グループは最後にfinishする変更グループです。