Отметка
Каждый буфер имеет специальную отметку, которая обозначается как отметка. Когда буфер только что создан, эта отметка существует, но не указывает на какой-либо элемент; это означает, что отметка ещё не существует в этом буфере. Последующие команды могут установить отметку.
Отметка определяет позицию для ограничения области текста для многих команд, таких как kill-region и indent-rigidly. Эти команды обычно действуют на текст между текущей позицией и отметкой, что называется областью. Если вы пишете команду, которая работает с областью, не проверяйте отметку напрямую; вместо этого используйте interactive со спецификацией ‘r’. Это предоставляет значения текущей позиции и отметки в качестве аргументов команде при интерактивном вызове, но позволяет другим программам Lisp явно задавать аргументы. См. Интерактивные коды.
Некоторые команды устанавливают отметку как побочный эффект. Команды должны делать это только в случае, если это потенциально полезно для пользователя, и никогда не для своих внутренних целей. Например, команда replace-regexp устанавливает отметку в значение текущей позиции перед выполнением каких-либо замен, поскольку это позволяет пользователю удобно вернуться туда после завершения замены.
После того, как отметка существует в буфере, она обычно никогда не перестаёт существовать. Однако она может стать неактивной, если включен режим Временной отметки. Переменная буфера mark-active, если она не nil, означает, что отметка активна. Команда может вызвать функцию deactivate-mark для отключения отметки напрямую, или она может запросить отключение отметки при возвращении в цикл команд редактора, установив переменную deactivate-mark в значение, отличное от nil.
Если режим Временной отметки включён, определённые команды редактирования, которые обычно применяются к тексту рядом с текущей позицией, вместо этого применяются к области, когда отметка активна. Это основная причина использования режима Временной отметки. (Ещё одной причиной является возможность выделения области, когда отметка активна. См. Отображение.)
Помимо отметки, каждый буфер имеет кольцо отметок, которое представляет собой список маркеров, содержащих предыдущие значения отметки. Когда команды редактирования изменяют отметку, они обычно должны сохранять старое значение отметки в кольце отметок. Переменная mark-ring-max задаёт максимальное количество элементов в кольце отметок; как только список становится таким длинным, добавление нового элемента удаляет последний элемент.
Существует также отдельное глобальное кольцо отметок, но оно используется только в нескольких особых командах уровня пользователя и не имеет отношения к программированию на Lisp. Поэтому мы его здесь не описываем.
- Функция: mark &optional force
-
Эта функция возвращает позицию отметки текущего буфера в виде целого числа или
nil, если в этом буфере никогда не была установлена отметка.Если режим Временной отметки включён, и
mark-even-if-inactiveравноnil,markсигнализирует об ошибке, если отметка неактивна. Однако, если force неnil, тоmarkигнорирует неактивность отметки и возвращает позицию отметки (илиnil) в любом случае.
- Функция: mark-marker
-
Эта функция возвращает маркер, представляющий текущую отметку буфера. Это не копия, это маркер, используемый во внутренней работе. Поэтому изменение позиции этого маркера напрямую повлияет на отметку буфера. Не делайте этого, если это не тот эффект, который вы хотите получить.
(setq m (mark-marker)) ⇒ #<marker at 3420 in markers.texi>(set-marker m 100) ⇒ #<marker at 100 in markers.texi>(mark-marker) ⇒ #<marker at 100 in markers.texi>Как и любой маркер, этот маркер можно установить на любую позицию в любом буфере. Если вы установите его на любой буфер, кроме того, в котором он является отметкой, это даст вполне согласованные, но довольно странные результаты. Мы рекомендуем вам этого не делать!
- Функция: set-mark position
-
Эта функция устанавливает отметку в position и активирует отметку. Старое значение отметки не добавляется в кольцо отметок.
Обратите внимание: Используйте эту функцию только если вы хотите, чтобы пользователь видел, что отметка переместилась, и вы хотите, чтобы предыдущая позиция отметки была утеряна. Обычно, когда устанавливается новая отметка, старая должна попасть в
mark-ring. По этой причине большинство приложений должны использоватьpush-markиpop-mark, а неset-mark.Новички в программировании на Emacs Lisp часто пытаются использовать отметку не по назначению. Отметка сохраняет расположение для удобства пользователя. Команда редактирования не должна изменять отметку, если изменение отметки не входит в функциональность команды уровня пользователя. (И в этом случае этот эффект должен быть задокументирован.) Чтобы запомнить расположение для внутреннего использования в программе Lisp, сохраните его в переменной Lisp. Например:
(let ((beg (point))) (forward-line 1) (delete-region beg (point))).
- Функция: push-mark &optional position nomsg activate
-
Эта функция устанавливает отметку текущего буфера в position и помещает копию предыдущей отметки в
mark-ring. Если position равноnil, используется значение текущей позиции.Функция
push-markобычно не активирует отметку. Чтобы сделать это, укажитеtв качестве аргумента activate.Сообщение «Отметка установлена» отображается, если nomsg не равно
nil.
- Функция: pop-mark
Эта функция извлекает верхний элемент из
mark-ringи делает эту отметку текущей отметкой буфера. Это не перемещает текущую позицию в буфере, и ничего не делает, еслиmark-ringпуст. Она отключает отметку.
- Опция пользователя: transient-mark-mode
-
Эта переменная, если не
nil, включает режим Временной отметки. В режиме Временной отметки каждый примитив модификации буфера устанавливаетdeactivate-mark. Вследствие этого большинство команд, которые изменяют буфер, также отключают отметку.Когда режим Временной отметки включён и отметка активна, многие команды, которые обычно применяются к тексту рядом с текущей позицией, вместо этого применяются к области. Такие команды должны использовать функцию
use-region-pдля проверки, должны ли они выполнять операции с областью. См. Область.Программы Lisp могут установить
transient-mark-modeв значения, отличные отnil,t, чтобы временно включить режим Временной отметки. Если значение равноlambda, режим Временной отметки автоматически отключается после любого действия, такого как изменение буфера, которое обычно отключает отметку. Если значение равно(only . oldval),transient-mark-modeустанавливается в значение oldval после любой последующей команды, которая перемещает текущую позицию и не является переключением (см. переключение), или после любого другого действия, которое обычно отключает отметку. (Маркировка области мышкой временно включаетtransient-mark-modeтаким образом.)
- Опция пользователя: mark-even-if-inactive
Если это значение не
nil, программы Lisp и пользователь Emacs могут использовать отметку даже когда она неактивна. Эта опция влияет на поведение режима Временной отметки. Когда опция неnil, отключение отметки отключает выделение области, но команды, использующие отметку, ведут себя так, как если бы отметка была всё ещё активной.
- Переменная: deactivate-mark
-
Если команда редактора устанавливает эту переменную в значение, отличное от
nil, тогда цикл команд редактора отключает отметку после возвращения команды (если включён режим Временной отметки). Все примитивы, которые изменяют буфер, устанавливаютdeactivate-mark, чтобы отключить отметку по завершении команды. Установка этой переменной делает её локальной для буфера.Чтобы написать код Lisp, который изменяет буфер без вызова отключения отметки в конце команды, привяжите
deactivate-markкnilвокруг кода, который выполняет модификацию. Например:(let (deactivate-mark) (insert " "))
- Функция: deactivate-mark &optional force
Если режим Временной отметки включён или force не равно
nil, эта функция отключает отметку и выполняет обычный обработчикdeactivate-mark-hook. В противном случае ничего не делает.
- Переменная: mark-active
Отметка активна, когда эта переменная не
nil. Эта переменная всегда локальна для каждого буфера. Не используйте значение этой переменной для определения, должна ли команда, которая обычно действует на текст рядом с текущей позицией, действовать на область вместо этого. Используйте функциюuse-region-pдля этого (см. Область).
- Переменная: activate-mark-hook
- Переменная: deactivate-mark-hook
Эти обычные обработчики вызываются соответственно, когда отметка становится активной и когда она становится неактивной. Обработчик
activate-mark-hookтакже вызывается, когда область активируется заново, например, после использования команды, которая возвращает обратно в буфер с активной отметкой.
- Функция: handle-shift-selection
-
Эта функция реализует поведение с нажатой клавишей Shift при перемещении текущей позиции. См. Выбор с нажатой клавишей Shift в Руководстве по GNU Emacs. Она вызывается автоматически циклом команд Emacs всякий раз, когда вызывается команда с символом ‘^’ в её
interactiveспецификации, до выполнения самой команды (см. ^).Если
shift-select-modeнеnilи текущая команда была вызвана с нажатой клавишей Shift (см. переключение с нажатой клавишей Shift), эта функция устанавливает отметку и временно активирует область, если область не была уже активирована временно таким образом. В противном случае, если область была активирована временно, она отключает отметку и восстанавливает переменнуюtransient-mark-modeдо её предыдущего значения.
- Переменная: mark-ring
-
Значение этой переменной, локальной для буфера, представляет собой список сохранённых предыдущих отметок текущего буфера, от самых последних к более ранним.
mark-ring ⇒ (#<marker at 11050 in markers.texi> #<marker at 10832 in markers.texi> …)
- Опция пользователя: mark-ring-max
Значение этой переменной — максимальный размер
mark-ring. Если вmark-ringпомещается больше отметок, чем это значение,push-markотбрасывает старую отметку при добавлении новой.
При включенном режиме удаления выделения (см. Удаление выделения в Руководстве GNU Emacs) команды, работающие с активной областью (также известной как «выделение»), ведут себя немного по-другому. Это достигается путем добавления функции delete-selection-pre-hook к pre-command-hook (см. Обзор команд). Эта функция вызывает delete-selection-helper для удаления выделения соответствующим образом для команды. Если вы хотите адаптировать команду к режиму удаления выделения, установите свойство delete-selection на символ функции (см. Списки символов); команды, у которых нет этого свойства на их символе, не будут удалять выделение. Это свойство может иметь одно из нескольких значений для настройки поведения в соответствии с тем, что команда должна делать; см. строки документации delete-selection-pre-hook и delete-selection-helper для получения подробностей.
Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/The-Mark.html