32.1 Обзор маркеров

Маркер указывает на буфер и позицию в этом буфере. Маркер может использоваться для представления позиции в функциях, требующих ее, подобно тому, как использовалось бы целое число. В этом случае буфер маркера обычно игнорируется. Разумеется, маркер, используемый таким образом, обычно указывает на позицию в буфере, с которой работает функция, но это полностью ответственность программиста. См. Позиции для полного описания позиций.

Маркер имеет три атрибута: позиция маркера, буфер маркера и тип вставки. Позиция маркера — это целое число, которое в данный момент эквивалентно маркеру как позиции в этом буфере. Но значение позиции маркера может меняться в течение жизни маркера, и часто меняется. Вставка и удаление текста в буфере перемещают маркер. Идея в том, что маркер, расположенный между двумя символами, остается между этими двумя символами, несмотря на вставку и удаление в другом месте буфера. Перемещение изменяет целое числовое эквивалентное значение маркера.

Удаление текста вокруг позиции маркера оставляет маркер между символами, непосредственно предшествующими и следующих за удаленным текстом. Вставка текста в позиции маркера обычно оставляет маркер либо перед, либо после нового текста, в зависимости от типа вставки маркера (см. Типы вставки маркеров) — если только вставка не выполняется с помощью insert-before-markers (см. Вставка текста).

Вставка и удаление в буфере должны проверять все маркеры и перемещать их при необходимости. Это замедляет обработку в буфере с большим количеством маркеров. По этой причине хорошей идеей является установка маркера в состояние "нигде", если вы уверены, что больше не нуждаетесь в нем. Маркеры, к которым больше нельзя получить доступ, в конечном итоге удаляются (см. Сборка мусора).

Поскольку часто выполняются арифметические операции над позицией маркера, большинство этих операций (включая + и -) принимают маркеры в качестве аргументов. В таких случаях маркер представляет свою текущую позицию.

Ниже приведены примеры создания маркеров, установки маркеров и перемещения курсора к маркерам:

;; Создание нового маркера, который изначально нигде не указывает:
(setq m1 (make-marker))
     ⇒ #<маркер в пустом буфере>

;; Установка m1 для указания между 99-м и 100-м символами
;;   в текущем буфере:
(set-marker m1 100)
     ⇒ #<маркер на позиции 100 в markers.texi>

;; Теперь вставляем один символ в начало буфера:
(goto-char (point-min))
     ⇒ 1
(insert "Q")
     ⇒ nil

;; m1 соответствующим образом обновляется.
m1
     ⇒ #<маркер на позиции 101 в markers.texi>

;; Два маркера, указывающие на одну и ту же позицию
;;   не являются eq, но они equal.
(setq m2 (copy-marker m1))
     ⇒ #<маркер на позиции 101 в markers.texi>
(eq m1 m2)
     ⇒ nil
(equal m1 m2)
     ⇒ t

;; Когда вы закончили использовать маркер, установите его в состояние "нигде".
(set-marker m1 nil)
     ⇒ #<маркер в пустом буфере>