ただし、save-excursionについて解説する前に、まずはGNU
Emacsにおけるポイントとマークとは何かを確認しておくと役立つでしょう。ポイントとは、カーソルの現在位置のことです。カーソルがある場所こそがポイントとなります。より正確には、カーソルが文字の上に表示されている端末では、ポイントはその文字の直前になります。Emacs
Lispにおいて、ポイントは整数です。バッファ内の最初の文字が1、2番目が2、という具合になります。関数pointは、カーソルの現在位置を数値として返します。各バッファには、それぞれ固有のポイント値があります。
マークはバッファ内の別の位置であり、その値は C-SPC (set-mark-command)
などのコマンドで設定できます。マークが設定されている場合、C-x C-x (exchange-point-and-mark)
コマンドを使用してカーソルをマーク位置にジャンプさせ、マークをポイントの直前の位置に設定できます。さらに、別のマークを設定すると、直前のマークの位置がマークリングに保存されます。この方法で、多くのマーク位置を保存できます。C-u C-SPC
を1回以上入力することで、保存されたマークにカーソルをジャンプさせることができます。
ポイントとマークの間にあるバッファ領域をリージョンと呼びます。center-region、count-words-region、kill-region、print-regionなど、数多くのコマンドがこのリージョンに対して動作します。
save-excursion 特殊形式は、point の位置を保存し、特殊形式の本体内のコードが
Lisp インタプリタによって評価された後にその位置を復元します。したがって、point がテキストの先頭にあり、何らかのコードによって point
がバッファの末尾に移動した場合、save-excursion
は関数本体内の式が評価された後、point を元の位置に戻します。
Emacsでは、ユーザーが想定していない場合であっても、内部処理の一環としてポイントを移動させる関数がよくあります。例えば、count-words-regionはポイントを移動させます。予期せぬ、かつ(ユーザーの視点からは)不要なジャンプによってユーザーが煩わされないように、save-excursionがよく用いられ、ポイントをユーザーが想定する位置に保持します。save-excursionの使用は、適切な管理と言えます。
家を清潔に保つため、save-excursionは内部のコードに不具合が生じた場合でも(より正確に、適切な専門用語を用いれば「異常終了時」であっても)、pointの値を復元します。この機能は非常に有用です。
save-excursion
はポイントの値を記録するだけでなく、現在のバッファを追跡し、それを復元もします。つまり、バッファを変更するコードを書き、save-excursion によって元のバッファに戻してもらうことができます。append-to-buffer ではこのように save-excursion が使用されています。(append-to-buffer の定義 を参照してください。)