次: Buffer Names, 前: Buffer Basics, 上: Buffers
一般に、Emacsセッションには多くのバッファがあります。 いつの時点でも、それらの1つをカレントバッファ (current buffer)として区別します。 バッファ内のテキストを検査したり変更する基本関数は 暗黙のうちにカレントバッファに作用するため、 ほとんどの編集はカレントバッファに対して行われます (see Text)。 通常、スクリーン上で選択されたウィンドウに表示されているバッファが カレントバッファですが、つねにそうとは限りません。 Lispプログラムでは、スクリーン上の表示は変えずに、 任意のバッファの内容を操作するために 一時的に当該バッファをカレントバッファにできます。
Lispプログラムでカレントバッファを指定するには、
set-buffer
を呼び出します。
新たに指定し直すまで指定したバッファがカレントバッファであり続けます。
編集コマンドがエディタコマンドループへ戻ると、
コマンドループは、混乱を避けるために、選択されているウィンドウに
表示されているバッファをカレントバッファとします。
つまり、Emacsがコマンドを読むときにカーソルがあるバッファが
コマンドが適用されるバッファです。
(See Command Loop。)
したがって、set-buffer
は、
ユーザーが編集できるように別のバッファへ切り替える方法にはなりません。
これには、Displaying Buffersで述べている関数を使う必要があります。
しかし、別のカレントバッファに替えるLisp関数では、
コマンドループがカレントバッファを
あとで戻すということに依存してはいけません。
Emacs Lispで書かれた編集コマンドは、コマンドループに加えて
別のプログラムからも呼ばれます。
サブルーティンがカレントバッファを替えないほうが
(それがサブルーティンの目的でなければ)、
呼び出し側にとっては便利です。
したがって、関数の実行が終るともとのカレントバッファに戻す
フォームsave-current-buffer
や
save-excursion
(see Excursions)の内側で、
普通はset-buffer
を使います。
例として、(説明文字列を簡略にして)コマンドappend-to-buffer
のコードを示します。
(defun append-to-buffer (buffer start end) "Append to specified buffer the text of the region. ..." (interactive "BAppend to buffer: \nr") (let ((oldbuf (current-buffer))) (save-current-buffer (set-buffer (get-buffer-create buffer)) (insert-buffer-substring oldbuf start end))))
この関数では、ローカル変数を束縛してカレントバッファを記録し、
save-current-buffer
でそれがカレントバッファに戻るようにしています。
つぎに、set-buffer
で指定したバッファをカレントバッファにします。
最後に、insert-buffer-substring
でもとのカレントバッファから
指定された(いまはカレント)バッファに文字列をコピーします。
内容を付加したバッファがどれかのウィンドウに表示されていると、 つぎに表示を更新したときに変更されたテキストが表示されます。 それ以外では、スクリーン上でただちには変更を見ることはできません。 コマンドの実行中にはバッファが一時的にカレントバッファになりますが、 それによりそのバッファが表示されるわけではありません。
バッファローカルな束縛を持つ変数を(let
や関数の引数で)
ローカルに束縛する場合には、ローカルな束縛の有効範囲の開始時と終了時には、
同じバッファが必ずカレントバッファであるようにします。
さもないと、あるバッファでは変数を束縛し、
別のバッファではその束縛を解除してしまうことがあります。
これには2つの方法があります。
単純な場合には、束縛の有効範囲内で
カレントバッファが替わらないを確認します。
さもなければ、save-current-buffer
やsave-excursion
を使って、
始めにカレントバッファであったバッファが、
変数束縛が解除されるときにはつねにカレントバッファであるようにします。
set-buffer
でもとのカレントバッファに戻すのでは信頼性がありません。
正しくないバッファがカレントバッファであるときに
中断が起きると戻せないからです。
してはいけないことをつぎに示します。
(let (buffer-read-only (obuf (current-buffer))) (set-buffer ...) ... (set-buffer obuf))
つぎのようにsave-current-buffer
を使えば、
通常の評価に加えて、中断、エラー、throw
も扱えます。
(let (buffer-read-only) (save-current-buffer (set-buffer ...) ...))
この関数は、buffer-or-nameをカレントバッファにする。 この関数は現在選択されているウィンドウやその他のウィンドウに 当該バッファを表示しないので、ユーザーが当該バッファを見られるとは限らない。 しかし、Lispプログラムはいずれにしても当該バッファを操作できる。
この関数はbuffer-or-nameで指定されるバッファを返す。 buffer-or-nameが既存のバッファを指定しなければ、エラーを通知する。
マクロ
save-current-buffer
は、 カレントバッファの識別子を保存し、フォームbodyを評価し、 最後にもとのカレントバッファに戻す。 戻り値は、bodyの最後のフォームの値である。throw
やエラー(see Nonlocal Exits)による異常終了であっても カレントバッファは戻される。
save-current-buffer
から抜けるときに、 もとのカレントバッファとして使われていたバッファが削除されていると、 もちろん、カレントバッファにはならない。 そのかわりに、抜けるまえにカレントバッファであったバッファが カレントバッファであり続ける。
マクロ
with-current-buffer
は、 カレントバッファの識別子を保存し、 bufferをカレントバッファにし、フォームbodyを評価し、 最後にもとのカレントバッファに戻す。 戻り値は、bodyの最後のフォームの値である。throw
やエラー(see Nonlocal Exits)による異常終了であっても カレントバッファは戻される。
マクロ
with-temp-buffer
は、 一時的なバッファをカレントバッファとして フォームbodyを評価する。 カレントバッファの識別子を保存し、 一時的なバッファを作成してそれをカレントバッファにし、 フォームbodyを評価し、 最後にもとのカレントバッファに戻すとともに一時的なバッファを削除する。戻り値は、bodyの最後のフォームの値である。 最後のフォームとして
(buffer-string)
を使えば、 一時的なバッファの内容を返せる。
throw
やエラー(see Nonlocal Exits)による異常終了であっても カレントバッファは戻される。
Writing to Filesのwith-temp-file
も参照してください。