プログラム中の限定された部分でポイントを一時的に移動するのが便利なことが時折あります。これはエクスカーション(excursion:
遠足、小旅行)と呼ばれるもので、スペシャルフォームsave-excursionにより行われます。この構文は初期のカレントバッファー自体とポイントの値を記憶して、そのエクスカーション完了時にそれらをリストアします。これはプログラムのある部分においてプログラムの他の部分に影響を与えることなくポイントを移動する標準的な手段であり、EmacsのLispソース内では何度も使用されています。
カレントバッファー自体のみの保存やリストアが必要なら、かわりにsave-current-bufferやwith-current-bufferを使用してください(Current Bufferを参照)。ウィンドウ構成の保存やリストアが必要なら、Window ConfigurationsとFrame Configurationsで説明されているフォームを参照してください。
このスペシャルフォームはカレントバッファー自体とポイント値を保存、bodyを評価してから最後にバッファーと保存したポイントとマークの値をリストアする。throwやエラーを通じたアブノーマルexit(Nonlocal Exitsを参照)の場合にも、保存されたいずれの値もリストアされる。
save-excursionがリターンする値はbody内の最後のフォームの結果、またはbodyフォームが与えられなければnilをリターンする。
save-excursionはエクスカーション開始時にカレントだったバッファーのポイントだけを保存するために、そのエクスカーション中に変更された他のバッファーのポインはその後も効果が残るでしょう。これはしばしば予期せぬ結果を招くので、エクスカーション中にset-bufferを呼び出すとバイトコンパイラーは警告を発します:
Warning: Use ‘with-current-buffer’ rather than
save-excursion+set-buffer
このような問題を回避するためには、以下の例のように望むカレントバッファーをセット後にのみsave-excursionを呼び出すべきです:
(defun append-string-to-buffer (string buffer)
"BUFFER末尾にSTRINGを追加"
(with-current-buffer buffer
(save-excursion
(goto-char (point-max))
(insert string))))
同様にsave-excursionはswitch-to-bufferのような関数が変更したウィンドウ/バッファーの対応をリストアしません。
警告:
保存されたポイント値に隣接する通常のテキスト挿入は、それがすべてのマーカーを再配置するのと同じように、保存されたポイントカーを再配置します。より正確には保存される値は挿入タイプnilのマーカーです。Marker Insertion Typesを参照してください。したがって保存されたポイント値は、リストア時には通常は挿入されたテキストの直前になります。
このマクロはsave-excursionと同様だが、マークの位置とmark-activeの保存とリストアも行う点が異なる。このマクロはEmacsのバージョン25.1以前にsave-excursionが行っていたことを行う。