标记用于指定一个缓冲区以及该缓冲区中的位置。在需要位置参数的函数中,标记可以像整数一样用来表示位置。这种情况下,标记所属的缓冲区通常会被忽略。当然,以这种方式使用的标记一般指向函数所操作缓冲区中的位置,但这完全由程序员负责。See 位置,查看关于位置的完整说明。
标记包含三个属性:标记位置、标记所属缓冲区,以及插入类型。标记位置是一个整数,在给定时刻等价于该标记在缓冲区中的位置。但标记的位置值在其生命周期内可以改变,并且经常改变。缓冲区中文本的插入与删除会使标记重定位。其设计思想是:无论缓冲区其他位置如何插入或删除,位于两个字符之间的标记始终保持在这两个字符之间。重定位会改变标记对应的整数值。
删除标记位置周围的文本后,标记会留在被删文本前后紧邻的字符之间。在标记位置插入文本时,标记通常会留在新文本的前方或后方,具体取决于标记的插入类型(insertion type)(see 标记插入类型)—除非插入操作使用 insert-before-markers(see 插入文本)。
缓冲区中的插入与删除操作必须检查所有标记并在必要时重定位它们。这会减慢拥有大量标记的缓冲区的处理速度。因此,如果你确定不再需要某个标记,最好让它不再指向任何位置。无法再被访问的标记最终会被回收(see 垃圾回收)。
由于经常需要对标记位置进行算术运算,大多数此类运算(包括 + 和 -)都接受标记作为参数。在这种情况下,标记代表其当前位置。
以下是创建标记、设置标记以及将光标移至标记位置的示例:
;; 创建一个初始不指向任何位置的新标记:
(setq m1 (make-marker))
⇒ #<marker in no buffer>
;; 将 m1 指向当前缓冲区中第 99 与第 100 个字符之间:
(set-marker m1 100)
⇒ #<marker at 100 in markers.texi>
;; 现在在缓冲区开头插入一个字符:
(goto-char (point-min))
⇒ 1
(insert "Q")
⇒ nil
;; m1 会被自动更新。
m1
⇒ #<marker at 101 in markers.texi>
;; 指向同一位置的两个标记并非 eq,但 equal。
(setq m2 (copy-marker m1))
⇒ #<marker at 101 in markers.texi>
(eq m1 m2)
⇒ nil
(equal m1 m2)
⇒ t
;; 使用完毕后,让标记不再指向任何位置。
(set-marker m1 nil)
⇒ #<marker in no buffer>