5.1 The Definition of copy-to-buffer

After understanding how append-to-buffer works, it is easy to understand copy-to-buffer. This function copies text into a buffer, but instead of adding to the second buffer, it replaces all the previous text in the second buffer.

The body of copy-to-buffer looks like this,

…
(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)))))

The copy-to-buffer function has a simpler interactive expression than append-to-buffer.

The definition then says

(with-current-buffer (get-buffer-create buffer) …

First, look at the earliest inner expression; that is evaluated first. That expression starts with get-buffer-create buffer. The function tells the computer to use the buffer with the name specified as the one to which you are copying, or if such a buffer does not exist, to create it. Then, the with-current-buffer function evaluates its body with that buffer temporarily current, after which it will switch back to the buffer we are at now12.

(This demonstrates another way to shift the computer’s attention but not the user’s. The append-to-buffer function showed how to do the same with save-excursion and set-buffer. with-current-buffer is a newer, and arguably easier, mechanism.)

The barf-if-buffer-read-only function sends you an error message saying the buffer is read-only if you cannot modify it.

The next line has the erase-buffer function as its sole contents. That function erases the buffer.

Finally, the last two lines contain the save-excursion expression with insert-buffer-substring as its body. The insert-buffer-substring expression copies the text from the buffer you are in (and you have not seen the computer shift its attention, so you don’t know that that buffer is now called oldbuf).

Incidentally, this is what is meant by “replacement”. To replace text, Emacs erases the previous text and then inserts new text.

In outline, the body of copy-to-buffer looks like this:

(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)))

Footnotes

(12)

It is like calling (save-excursion (set-buffer …) …) in one go, though it is defined slightly differently which interested reader can find out using describe-function.