5.1 函数 copy-to-buffer 的定义

在理解了 append-to-buffer 的工作原理后,很容易理解 copy-to-buffer。这个函数将文本复制到一个缓冲区,但与其向第二个缓冲区添加文本不同,它替换了第二个缓冲区中的所有先前文本。

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

append-to-buffer 不同,copy-to-buffer 函数的交互表达式更简单。

接下来的定义如下

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

首先,看最内部的表达式;它首先被评估。该表达式以 get-buffer-create buffer 开头。该函数告诉计算机使用指定为要复制到的缓冲区的名称,或者如果不存在这样的缓冲区,则创建它。然后,with-current-buffer 函数使用该缓冲区临时作为当前缓冲区来评估其主体。

(这展示了另一种改变计算机注意力但不改变用户注意力的方法。append-to-buffer 函数展示了如何使用 save-excursionset-buffer 来实现相同的效果。with-current-buffer 是一种较新、可能更简单的机制。)

barf-if-buffer-read-only 函数在您无法修改缓冲区时发送错误消息,指示该缓冲区为只读。

接下来的一行只包含 erase-buffer 函数。该函数擦除缓冲区。

最后,最后两行包含 save-excursion 表达式,其主体是 insert-buffer-substringinsert-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)))