33.33 グループのアトミックな変更

データベース用語においてのアトミック(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が使用する、より低レベルな関数を直接呼び出さなければなりません。

Function: prepare-change-group &optional buffer

この関数はbuffer (デフォルトはカレントバッファー)にたいする変更グループをセットアップする。これはその変更グループを表すhandleをリターンする。変更グループをactivateしたり、その後でそれを完了するためにはこのhandleを使用しなければならない。

変更グループを使用するためには、それをactivate(アクティブ化)しなければなりません。これはbufferのテキストを変更する前に行わなければなりません。

Function: activate-change-group handle

これはhandleが指定する変更グループをactiveにする。

変更グループをactivateした後には、そのバッファー内で行ったすべての変更は変更グループの一部となります。そのバッファー内で目論んでいたすべての変更を行ったら、変更グループをfinish(完了)しなければなりません。すべての変更を受け入れる(確定する)か、すべてをキャンセルするという2つの方法により、これを行うことができます。

Function: accept-change-group handle

この関数はhandleにより指定される変更グループ内のすべての変更にたいして、finalizeすることにより変更を受け入れる。

Function: cancel-change-group handle

この関数はhandleにより指定される変更グループ内のすべての変更をキャンセルしてundoする。

undo-amalgamate-change-groupを使用すれば、いくつか、あるいはすべての変更をundoコマンド(アンドゥを参照)の対象として単一の単位とみなせる変更グループにすることができます。

Function: undo-amalgamate-change-group

handleにより識別される状態以降にお子なわれた変更グループへの変更をすべてまとめる。この関数はhandleにより記述された状態以降の変更にたいするアンドゥレコード間のアンドゥ境界すべてを削除する。handleは通常はprepare-change-groupがリターンしたハンドルであり、この場合には変更先頭以降のすべての変更は、単一のアンドゥ単位にまとめられる。

グループが常に確実にfinishされるようにするために、コードではunwind-protectを使用するべきです。activate-change-groupの呼び出しは、実行直後にユーザーがC-gをタイプする場合に備えてunwind-protect内部にあるべきです(これがprepare-change-groupactivate-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-groupcancel-change-group呼び出しでそれをfinishしてください。

同一バッファーにたいするネストされた複数の変更グループ使用は、あなたが期待するであろう通りに機能します。同一バッファーにたいするネストされていない変更グループの使用によりEmacsが混乱した状態になるので、これが発生しないようにしてください。与えられた何らかのバッファーにたいして最初に開始した変更グループは最後にfinishする変更グループです。

Emacsはbuffer-undo-listのcdrそれぞれを辿ることにより、最終的にはprepare-change-groupの呼び出し時にセットされていたコンスに到達できると仮定して変更グループを追跡します。

buffer-undo-listにそのコンスが含まれていなければEmacsはすべての変更グループの追跡を失い、結果として変更グループのキャンセル時にエラーとなります。これを回避するためには、変更グループがアクティブなときに、そのような方法でundoリストを編集するかもしれない関数、特にundo-auto-amalgamateを呼び出すdelete-charのような“amalgamating(融合化)”なコマンドを呼び出さないでください。

This page has generated for branch:work/emacs-30_69b16e5c63840479270d32f58daea923fe725b90, commit:5e3f74b56ff47b5bcef2526c70f53f749bbd45f6 to check Japanese translation.