28.12 在两个缓冲区之间交换文本

某些专用模式需要让用户在同一个缓冲区中 访问多种截然不同的文本内容。 例如,除了让用户编辑文本本身之外, 你可能还需要显示缓冲区文本的摘要信息。

这可以通过多个缓冲区实现(在用户编辑时保持同步), 或使用缩进功能(see 范围限制)。 但这些方案有时会过于繁琐或开销过大, 尤其是当每种文本都需要开销较大的缓冲区全局操作 才能提供正确的显示和编辑命令时。

Emacs为此类模式提供了另一种机制: 你可以使用 buffer-swap-text 在两个缓冲区之间快速交换文本内容。 该函数速度极快,因为它不移动任何文本, 仅修改缓冲区对象的内部数据结构, 使其指向另一块文本。 通过这种方式,你可以将两个或更多缓冲区模拟为 一个虚拟缓冲区,同时容纳所有单个缓冲区的内容。

Function: buffer-swap-text buffer

该函数交换当前缓冲区与参数 buffer 的文本内容。 如果两个缓冲区中有一个是间接缓冲区(see 间接缓冲区) 或是某个间接缓冲区的基础缓冲区,则会抛出错误。

所有与缓冲区文本相关的属性也会一并交换: 光标和标记位置、所有标记、覆盖层、 文本属性、撤销列表、 enable-multibyte-characters 标志的值(see enable-multibyte-characters)等。

警告:如果在 save-excursion 代码块中调用此函数, 退出代码块时当前缓冲区会被设为 buffer, 因为 save-excursion 用于保存位置和缓冲区的标记也会被一同交换。

如果你在访问文件的缓冲区上使用 buffer-swap-text, 应当设置钩子以保存缓冲区的原始文本,而非交换后的内容。 write-region-annotate-functions 可用于此目的。 你可能还需要在缓冲区中将 buffer-saved-size 设为 −2, 这样交换后的文本变化就不会干扰自动保存。