あるファイルにたいして大きな変更を行った後、気が変わって元に戻したくなった場合は、revert-buffer
コマンドでそのファイルの以前のバージョンを読み込むことにより、それらの変更を取り消すことができます。詳細は、Reverting a Buffer in The GNU Emacs Manualを参照してください。
このコマンドはバッファーのテキストをディスク上のvisitされているファイルのテキストで置き換える。これによりファイルがvisitや保存された以降に行ったすべての変更はアンドゥ(undo: 取り消し)される。
デフォルトでは、最新のauto-saveファイルのほうがvisitされているファイルより新しく引数ignore-autoがnil
なら、revert-buffer
はユーザーにたいしてかわりにauto-saveファイルを使用するかどうか確認を求める。このコマンドをinteractiveに呼び出したときプレフィックス数引数が指定されていなければ、ignore-autoはt
となる。つまりinteractive呼び出しは、デフォルトではauto-saveファイルのチェックを行わない。
revert-buffer
は通常はバッファーを変更する前に確認を求める。しかし引数noconfirmが非nil
ならrevert-buffer
は確認を求めない。
このコマンドは通常はnormal-mode
を使用することにより、そのバッファーのメジャーモードとマイナーモードを再初期化する。しかしpreserve-modesが非nil
ならモードは変更されずに残る。
リバート(revert:
戻す、復元する)はinsert-file-contents
の置き換え機能を使用することにより、バッファー内のマーカー位置の保持を試みる。バッファーのコンテンツとファイルのコンテンツがリバート操作を行う前と等しければリバートはすべてのマーカーを保持する。等しくなければリバートによってバッファーは変更される。この場合は、(もしあれば)バッファーの最初と最後にある未変更のテキスト内にあるマーカーは保持される。他のマーカーを保持してもそれらは正しくないだろう。
ファイル以外のソースからリバートする際には、通常はマーカーは保持されないが、これはrevert-buffer-function
の個別の実装次第である。
revert-buffer
は処理を行っている間、この変数を非nil
値にバインドする。
このセクションの残りの部分で説明する変数をセットすることにより、revert-buffer
が処理方法をカスタマイズできます。
この変数は問い合わせなしでリバートされるファイルのリストを保持する。値は正規表現のリスト。visitされているファイルの名前がこれらの正規表現のいずれかにマッチし、かつバッファーが未変更だがディスク上のファイルは変更されていれば、revert-buffer
はユーザーに確認を求めることなくファイルをリバートする。
いくつかのメジャーモードは以下の変数をローカルにバインドすることによりrevert-buffer
をカスタマイズします:
この変数の値はそのバッファーをリバートするために使用する関数。これはリバート処理を行うために2つのオプション引数をとる関数であること。2つのオプション引数ignore-autoとnoconfirmはrevert-buffer
が受け取る引数である。
Diredモードのような編集されるテキストにファイルのコンテンツが含まれず他の方式によって再生成され得るモードは、この変数のバッファーローカル値にコンテンツを再生成する特別な関数を与えることができる。
この変数の値はそのバッファーをリバートする際に更新されたコンテンツの挿入に使用される関数を指定する。その関数は2つの引数を受け取る。1つ目は使用するファイル名で2つ目がt
なら、ユーザーはauto-saveファイルの読み込みにたいして確認を求められる。
revert-buffer-function
のかわりにこの変数をモードが変更する理由は、revert-buffer
が行残りの処理(ユーザーへの確認、アンドゥリストのクリアー、適切なメジャーモードの決定、以下のフックの実行)にたいする重複や置き換えを避けるためである。
このノーマルフックは変更されたコンテンツを挿入する前に、デフォルトのrevert-buffer-function
により実行される。カスタマイズしたrevert-buffer-function
は、このフックを実行するかどうか判らない。
このノーマルフックは変更されたコンテンツを挿入した後に、デフォルトのrevert-buffer-function
によって実行される。カスタマイズしたrevert-buffer-function
は、このフックを実行するかどうか判らない。
この変数の値にはバッファー状態を保存する関数のリストを指定する。revert操作の前には、このリストの関数が引数なしで呼び出される。これらの関数はそれぞれ何らかの特定状態(たとえばread-only状態など)を保持するラムダをリターンすること。revert操作の後にはリスト順にラムダが順番に呼び出される。これらのラムダはそれぞれrevertされるバッファーにたいして保存された状態をリストアすること。
Emacsはバッファーを自動的にリバートできます。これはファイルをvisitしているバッファーにはデフォルトで行われます。以下では新たなタイプのバッファーにたいして自動リバートのサポートを追加する方法を説明します。
そのようなバッファーはまず適切に定義されたrevert-buffer-function
とbuffer-stale-function
をもたなければなりません。
この変数の値はバッファーがリバートを要するかどうかをチェックするために呼び出される関数を指定する。デフォルト値では、修正時刻をチェックすることによりファイルをvisitするバッファーだけを処理する。ファイルをvisitしないバッファーにはオプション引数を1つ受け取るカスタム関数が必要になる。この関数はバッファーをリバートする必要があれば非nil
をリターンする。関数の呼び出し時にはそのバッファーがカレントになる。
この関数は主として自動リバートを意図しているが、他の用途にも使用できる。たとえば自動リバートが有効でなければ、ユーザーにバッファーのリバートが必要なバッファーを警告するために使用できる。noconfirm引数の背景にあるアイデアは、ユーザーへの確認なしでバッファーがリバートされるようならt
、関数がバッファーの期限切れをユーザーに警告する。特に自動リバートにおける使用ではnoconfirmはt
になる。関数が自動リバートにたいしてのみ使用されるようならnoconfirm引数は無視できる。
(Buffer Menuのように) auto-revert-interval
秒ごとに自動リバートをしたければバッファーのモード関数で:
(setq-local buffer-stale-function (lambda (&optional noconfirm) 'fast))
を使用する。
特別なリターン値‘fast’はリバートの必要性はチェックしていないがバッファーのリバートは高速であることを告げる。さらにauto-revert-verbose
が非nil
でもリバートメッセージを何もプリントしないようにAuto
Revertに指示する。auto-revert-interval
秒ごとのリバートメッセージが非常に煩雑になり得ることから、これは重要である。自動リバート以外の目的でこの関数が考慮される場合には、リターン値が提供する情報は有用になるかもしれない。
バッファーが適切なrevert-buffer-function
とbuffer-stale-function
をもった後にも、通常はいくつかの問題が残ります。
未変更とマークされた場合のみバッファーは自動リバートされます。したがって種々の関数はリバートにより失われるかもしれない情報をバッファーが含む場合や、ユーザーがバッファーにたいして作業を行っていて自動リバートがユーザーにとって不便だと確信できる理由がある場合にのみバッファーを変更済みとマークすることを保証する必要があるでしょう。バッファーの変更状態を手動で調整することによりユーザーは常にこれをオーバーライドできます。これをサポートするために、未変更とマークされたバッファーでのrevert-buffer-function
呼び出しでは、常にバッファーの未変更とマークされた状態を保つ必要があります。
自動リバートの結果としてその前後で連続してポイントがジャンプしないことを保証することが重要です。もちろんバッファーが根本的に変更されればポイントの移動は必然的かもしれません。
revert-buffer-function
がauto-revert-verbose
がt
の場合に表示されるAuto
Revert自身のメッセージを不必要に重複してプリントしないことと、auto-revert-verbose
にたいするnil
値を効果的にオーバーライドすることを保証する必要があります。したがって自動リバートにたいするモードの調整には、このようなメッセージを取り除くことを要する場合が多々あります。とりわけこれはauto-revert-interval
秒ごとに自動的にリバートされるバッファーにおいて重要です。
新しい自動リバートがEmacsの一部であるなら、global-auto-revert-non-file-buffers
のドキュメント文字列でそれに言及するべきです。
同様にEmacsマニュアル内に追加でドキュメントするべきです。