copy-to-buffer ¶の定義append-to-bufferの仕組みを理解すれば、copy-to-bufferを理解するのは簡単です。この関数はテキストをバッファにコピーしますが、2つ目のバッファに追加するのではなく、2つ目のバッファにあるそれまでのすべてのテキストを置き換えます。
copy-to-bufferの本体はこんな感じで、
...
(interactive "BCopy to buffer: \nr")
(let ((oldbuf (current-buffer)))
(with-current-buffer (get-buffer-create buffer)
(barf-if-buffer-read-only)
(erase-buffer)
(save-excursion
(insert-buffer-substring oldbuf start end)))))
copy-to-buffer 関数は、append-to-buffer よりもシンプルな interactive 式を持っています。
すると、定義には次のようにあります。
(with-current-buffer (get-buffer-create buffer) ...
まず、最も内側にある式を確認してください。それが最初に評価されます。その式は get-buffer-create
buffer
で始まっています。この関数は、コピー先として指定された名前のバッファを使用するか、そのようなバッファが存在しない場合は新たに作成するようにコンピュータに指示します。次に、with-current-buffer
関数はそのバッファを一時的に有効にした状態で本体を評価し、その後、現在使用しているバッファに戻ります12。
(これは、ユーザーではなくコンピュータの注意をそらす別の方法を示すものです。append-to-buffer 関数では、save-excursion や set-buffer
を用いて同様の処理を行う方法を示しました。with-current-buffer
はより新しく、おそらくより簡便な仕組みです。)
barf-if-buffer-read-only
関数は、バッファを変更できない場合に、バッファが読み取り専用である旨のエラーメッセージを返します。
次の行は、erase-buffer 関数のみを記述しています。この関数はバッファを消去します。
最後に、最後の2行には insert-buffer-substring をボディとする save-excursion 式が含まれています。insert-buffer-substring
式は、現在いるバッファからテキストをコピーします(コンピュータが注意を別のところへ移したのをまだ見ていないため、そのバッファが現在は oldbuf と呼ばれていることは分かりません)。
ちなみに、これが「置換」ということです。テキストを置換する場合、Emacsは元のテキストを削除してから新しいテキストを挿入します。
概略として、copy-to-bufferの本体は次のようになっています。
(let (bind-oldbuf-to-value-of-current-buffer) (with-the-buffer-you-are-copying-to (but-do-not-erase-or-copy-to-a-read-only-buffer) (erase-buffer) (save-excursion insert-substring-from-oldbuf-into-buffer)))
いわば(save-excursion (set-buffer …) …)を一度に呼び出すようなものですが、定義がわずかに異なるため、興味のある方はdescribe-functionを使って確認してみてください。