Spec-Zone.ru › Elisp

Обработка изменений

Эти переменные-хуки позволяют следить за изменениями в буферах (или в конкретном буфере, если вы сделаете их локальными для буфера). См. также Специальные свойства для обнаружения изменений в определённых частях текста.

Функции, используемые в этих хуках, должны сохранять и восстанавливать данные сопоставления, если они выполняют какие-либо действия с использованием регулярных выражений; в противном случае они будут странным образом мешать операциям редактирования, которые их вызывают.

Переменная: before-change-functions

Эта переменная содержит список функций, которые нужно вызывать, когда Emacs собирается изменить буфер. Каждая функция получает два аргумента: начало и конец области, которая собирается измениться, представленные целыми числами. Буфер, который собирается измениться, всегда является текущим буфером во время вызова функции.

Переменная: after-change-functions

Эта переменная содержит список функций, которые нужно вызывать после того, как Emacs изменит буфер. Каждая функция получает три аргумента: начало и конец только что изменённой области и длину текста, существовавшего до изменения. Все три аргумента являются целыми числами. Буфер, который был изменён, всегда является текущим буфером при вызове функции.

Длина старого текста представляет собой разницу между позициями буфера до и после изменения текста в виде, в котором он существовал до изменения. Что касается изменённого текста, его длина просто представляет собой разницу между первыми двумя аргументами.

Вывод сообщений в буфер *Messages* не вызывает эти функции, так же как и некоторые внутренние изменения в буферах, созданных Emacs внутри для определённых задач, которые не должны быть видны программам Lisp.

Большинство примитивов изменения буфера будут вызывать before-change-functions и after-change-functions в парных вызовах, по одному разу для каждого изменения, где аргументы этих хуков точно определяют выполняемое изменение. Тем не менее, функции хуков не должны полагаться на то, что это всегда происходит, так как некоторые сложные примитивы вызывают before-change-functions один раз перед выполнением изменений, а затем вызывают after-change-functions ноль или более раз, в зависимости от того, сколько отдельных изменений выполняет примитив. В этом случае аргументы before-change-functions будут охватывать область, в которой выполняются отдельные изменения, но необязательно будут минимальной такой областью, а аргументы каждого последующего вызова after-change-functions будут точно определять изменяемую часть текста. В общем случае рекомендуется использовать либо хук перед изменением, либо хук после изменения, но не оба одновременно.

Макрос: combine-after-change-calls body…

Макрос выполняет body обычно, но организует вызов функций after-change только один раз для серии из нескольких изменений — если это кажется безопасным.

Если программа выполняет несколько изменений текста в одной и той же области буфера, использование макроса combine-after-change-calls в этой части программы может значительно ускорить её работу при использовании хуков after-change. При конечном вызове хуков after-change аргументы указывают на часть буфера, включающую все изменения, выполненные внутри тела combine-after-change-calls.

Предупреждение: Не изменяйте значения after-change-functions внутри тела формы combine-after-change-calls.

Предупреждение: Если изменения, которые вы объединяете, происходят в широко разбросанных частях буфера, это всё равно будет работать, но это не рекомендуется, так как это может привести к неэффективному поведению для некоторых функций хуков изменения.

Макрос: combine-change-calls beg end body…

Этот макрос выполняет body обычно, но любые изменения в буфере, которые он делает, не вызывают вызовы before-change-functions и after-change-functions. Вместо этого происходит единственный вызов каждого из этих хуков для области, ограниченной beg и end, параметры, предоставленные after-change-functions, отражая изменения, внесённые в размер области телом body.

Результат этого макроса — результат, возвращаемый body.

Этот макрос полезен, когда функция выполняет возможно большое количество повторяющихся изменений в буфере, и хуки изменения в противном случае потребовали бы длительного времени выполнения, если бы они выполнялись для каждого отдельного изменения буфера. Emacs сам использует этот макрос, например, в командах comment-region и uncomment-region.

Предупреждение: Не изменяйте значения before-change-functions или after-change-function внутри body.

Предупреждение: Не выполняйте никаких изменений буфера за пределами области, указанной beg и end.

Переменная: first-change-hook

Эта переменная является обычным хуком, который выполняется всякий раз, когда буфер изменяется, ранее находившийся в неизменённом состоянии.

Переменная: inhibit-modification-hooks

Если эта переменная имеет ненулевое значение, все хуки изменения отключены; ни один из них не выполняется. Это влияет на все переменные хуков, описанные выше в этом разделе, а также на хуки, прикреплённые к определённым специальным свойствам текста (см. Специальные свойства) и свойствам наложений (см. Свойства наложений).

Кроме того, эта переменная привязана к ненулевому значению во время выполнения тех же переменных хуков, поэтому по умолчанию изменение буфера из хука изменения не вызывает выполнение других хуков изменения. Если вы хотите, чтобы хуки изменения выполнялись в определённом фрагменте кода, который сам выполняется из хука изменения, переопределите локально inhibit-modification-hooks на nil. Однако это может привести к рекурсивным вызовам хуков изменения, поэтому убедитесь, что вы к этому готовы (например, привязав какую-либо переменную, которая сообщит вашему хуку ничего не делать).

Рекомендуется привязывать эту переменную только к изменениям, которые не приводят к постоянным изменениям содержимого текста буфера (например, изменениям стиля отображения или временным изменениям). Если вам нужно отложить хуки изменения во время серии изменений (обычно для повышения производительности), используйте combine-change-calls или combine-after-change-calls вместо этого.

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/Change-Hooks.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API