42.9.1 管理覆盖层

本节介绍用于创建、删除、移动覆盖层以及查看其内容的函数。对覆盖层的修改不会记录在缓冲区的撤销列表中,因为覆盖层不被视为缓冲区内容的一部分。

Function: overlayp object

如果 object 是一个覆盖层,该函数返回 t

Function: make-overlay start end &optional buffer front-advance rear-advance

该函数创建并返回一个隶属于 buffer、范围从 startend 的覆盖层。startend 都必须指定缓冲区位置,可以是整数或标记。若省略 buffer,则在当前缓冲区中创建覆盖层。

若覆盖层的 startend 指向同一缓冲区位置,则称为 空覆盖层(empty)。若非空覆盖层的起止之间文本被删除,它会变为空。发生这种情况时,覆盖层默认不会被删除,但你可以为其设置 ‘evaporate’ 属性使其自动删除(see evaporate property)。

参数 front-advancerear-advance 分别指定在覆盖层起始位置(start 之前)与结束位置插入文本时的行为。默认情况下二者均为 nil,此时在起始位置插入的文本会被纳入覆盖层,而在结束位置插入的文本则不会。若 front-advancenil,在覆盖层起始处插入的文本会被排除在覆盖层之外。若 rear-advancenil,在覆盖层结束处插入的文本会被纳入覆盖层。

Function: overlay-start overlay

该函数以整数形式返回 overlay 的起始位置。

Function: overlay-end overlay

该函数以整数形式返回 overlay 的结束位置。

Function: overlay-buffer overlay

该函数返回 overlay 所属的缓冲区。若覆盖层已被删除,则返回 nil

Function: delete-overlay overlay

该函数删除指定的 overlay。该覆盖层作为 Lisp 对象仍然存在,其属性列表不变,但不再依附于原缓冲区,也不再对显示产生任何效果。

被删除的覆盖层并非永久断开关联。你可以通过调用 move-overlay 重新为其指定缓冲区中的位置。

Function: move-overlay overlay start end &optional buffer

该函数将 overlay 移动到 buffer 中,并将其范围设为该缓冲区的 startendstartend 均需指定缓冲区位置,可以是整数或标记。

若省略 buffer,覆盖层保留在原关联缓冲区;若覆盖层此前已被删除(因此不关联任何缓冲区),则进入当前缓冲区。

返回值为 overlay

该函数是修改覆盖层端点的唯一合法方式。

Function: remove-overlays &optional start end name value

该函数清除 startend 区域内所有满足条件的覆盖层,即其名为 name 的属性值等于 value 的覆盖层,使这类覆盖层不再影响该区域文本。实现方式包括移除区域内覆盖层、移动其端点、分割覆盖层或组合使用这些方式。具体规则如下:

  • 起始于或晚于 start 且结束于 end 之前的覆盖层会被完全移除。
  • 起始于 start 之前、结束于 start 之后但在 end 之前的覆盖层,会被修改为结束于 start
  • 起始于或晚于 start 且结束于 end 之后的覆盖层,会被修改为起始于 end
  • 起始于 start 之前且结束于 end 之后的覆盖层,会被分割为两个覆盖层:一个结束于 start,另一个起始于 end

name 被省略或为 nil,表示删除/修改所有影响指定区域文本的覆盖层。若 start 和/或 end 被省略或为 nil,则分别默认为缓冲区的开头和结尾。因此,(remove-overlays) 会移除当前缓冲区中的所有覆盖层。

覆盖层属性的命名值使用 eq 进行比较,若值不是符号或定长整数这一点尤为重要(see 相等性谓词)。这意味着传入函数的值必须与设置覆盖层属性时使用的是同一个对象,而非副本;即使内容完全相同,不同对象也不会被判为相等。

可选参数 namevalue 应同时传入且非 nil,或同时省略或为 nil

Function: copy-overlay overlay

该函数返回 overlay 的一个副本。副本拥有与原覆盖层相同的端点与属性。但覆盖层起始与结束位置的文本插入类型会被设为默认值。

以下是一些示例:

;; 创建一个覆盖层。
(setq foo (make-overlay 1 10))
     ⇒ #<overlay from 1 to 10 in display.texi>
(overlay-start foo)
     ⇒ 1
(overlay-end foo)
     ⇒ 10
(overlay-buffer foo)
     ⇒ #<buffer display.texi>
;; 为其设置一个后续可检查的属性。
(overlay-put foo 'happy t)
     ⇒ t
;; 验证属性已存在。
(overlay-get foo 'happy)
     ⇒ t
;; 移动覆盖层。
(move-overlay foo 5 20)
     ⇒ #<overlay from 5 to 20 in display.texi>
(overlay-start foo)
     ⇒ 5
(overlay-end foo)
     ⇒ 20
;; 删除覆盖层。
(delete-overlay foo)
     ⇒ nil
;; 验证已删除。
foo
     ⇒ #<overlay in no buffer>
;; 已删除的覆盖层没有位置。
(overlay-start foo)
     ⇒ nil
(overlay-end foo)
     ⇒ nil
(overlay-buffer foo)
     ⇒ nil
;; 恢复覆盖层。
(move-overlay foo 1 20)
     ⇒ #<overlay from 1 to 20 in display.texi>
;; 验证结果。
(overlay-start foo)
     ⇒ 1
(overlay-end foo)
     ⇒ 20
(overlay-buffer foo)
     ⇒ #<buffer display.texi>
;; 移动与删除覆盖层不会改变其属性。
(overlay-get foo 'happy)
     ⇒ t