次: , 前: Buffer Basics, 上: Buffers


26.2 カレントバッファ

一般に、Emacsセッションには多くのバッファがあります。 いつの時点でも、それらの1つをカレントバッファ (current buffer)として区別します。 バッファ内のテキストを検査したり変更する基本関数は 暗黙のうちにカレントバッファに作用するため、 ほとんどの編集はカレントバッファに対して行われます (see Text)。 通常、スクリーン上で選択されたウィンドウに表示されているバッファが カレントバッファですが、つねにそうとは限りません。 Lispプログラムでは、スクリーン上の表示は変えずに、 任意のバッファの内容を操作するために 一時的に当該バッファをカレントバッファにできます。

Lispプログラムでカレントバッファを指定するには、 set-bufferを呼び出します。 新たに指定し直すまで指定したバッファがカレントバッファであり続けます。

編集コマンドがエディタコマンドループへ戻ると、 コマンドループは、混乱を避けるために、選択されているウィンドウに 表示されているバッファをカレントバッファとします。 つまり、Emacsがコマンドを読むときにカーソルがあるバッファが コマンドが適用されるバッファです。 (See Command Loop。) したがって、set-bufferは、 ユーザーが編集できるように別のバッファへ切り替える方法にはなりません。 これには、Displaying Buffersで述べている関数を使う必要があります。

しかし、別のカレントバッファに替えるLisp関数では、 コマンドループがカレントバッファを あとで戻すということに依存してはいけません。 Emacs Lispで書かれた編集コマンドは、コマンドループに加えて 別のプログラムからも呼ばれます。 サブルーティンがカレントバッファを替えないほうが (それがサブルーティンの目的でなければ)、 呼び出し側にとっては便利です。 したがって、関数の実行が終るともとのカレントバッファに戻す フォームsave-current-buffersave-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-buffersave-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 ...)
         ...))
— 機能: current-buffer

この関数はカレントバッファを返す。

          (current-buffer)
               => #<buffer buffers.texi>
     
— 機能: set-buffer buffer-or-name

この関数は、buffer-or-nameをカレントバッファにする。 この関数は現在選択されているウィンドウやその他のウィンドウに 当該バッファを表示しないので、ユーザーが当該バッファを見られるとは限らない。 しかし、Lispプログラムはいずれにしても当該バッファを操作できる。

この関数はbuffer-or-nameで指定されるバッファを返す。 buffer-or-nameが既存のバッファを指定しなければ、エラーを通知する。

— 特殊型: save-current-buffer body...

マクロsave-current-bufferは、 カレントバッファの識別子を保存し、フォームbodyを評価し、 最後にもとのカレントバッファに戻す。 戻り値は、bodyの最後のフォームの値である。 throwやエラー(see Nonlocal Exits)による異常終了であっても カレントバッファは戻される。

save-current-bufferから抜けるときに、 もとのカレントバッファとして使われていたバッファが削除されていると、 もちろん、カレントバッファにはならない。 そのかわりに、抜けるまえにカレントバッファであったバッファが カレントバッファであり続ける。

— マクロ: with-current-buffer buffer body...

マクロwith-current-bufferは、 カレントバッファの識別子を保存し、 bufferをカレントバッファにし、フォームbodyを評価し、 最後にもとのカレントバッファに戻す。 戻り値は、bodyの最後のフォームの値である。 throwやエラー(see Nonlocal Exits)による異常終了であっても カレントバッファは戻される。

— マクロ: with-temp-buffer body...

マクロwith-temp-bufferは、 一時的なバッファをカレントバッファとして フォームbodyを評価する。 カレントバッファの識別子を保存し、 一時的なバッファを作成してそれをカレントバッファにし、 フォームbodyを評価し、 最後にもとのカレントバッファに戻すとともに一時的なバッファを削除する。

戻り値は、bodyの最後のフォームの値である。 最後のフォームとして(buffer-string)を使えば、 一時的なバッファの内容を返せる。

throwやエラー(see Nonlocal Exits)による異常終了であっても カレントバッファは戻される。

Writing to Fileswith-temp-fileも参照してください。