Эти переменные хуков позволяют вам отслеживать изменения в буферах (или в определенном буфере, если вы делаете их локальными для буфера). См. также Свойства со специальным значением, как обнаруживать изменения в определенных частях текста.
Функции, которые вы используете в этих хуках, должны сохранять и восстанавливать данные совпадения, если они используют регулярные выражения; в противном случае они могут некорректно вмешаться в операции редактирования, которые их вызывают. Кроме того, функции в этих хуках должны избегать изменения текста буфера, цветовых схем, свойств, наложений и других аспектов состояния, специфичного для буфера, за исключением тех, которые сами создают и управляют функции хука, потому что другие части Emacs могут запутаться из-за таких изменений.
Эта переменная содержит список функций, которые вызываются, когда Emacs собирается изменить буфер. Каждая функция получает два аргумента: начало и конец области, которая собирается измениться, представленные в виде целых чисел. Буфер, который собирается измениться, всегда является текущим буфером, когда вызывается функция.
Эта переменная содержит список функций, которые вызываются после того, как Emacs изменил буфер. Каждая функция принимает три аргумента: начало и конец измененной области, а также длину текста, который существовал до изменения. Все три аргумента — целые числа. Буфер, который был изменен, всегда является текущим буфером, когда вызывается функция.
Длина старого текста — это разница между позициями в буфере до и после того, как этот текст был изменен. Что касается измененного текста, его длина — это просто разница между первыми двумя аргументами.
Вывод сообщений в буфер *Messages* не вызывает эти функции, и некоторые внутренние изменения буфера, такие как изменения в буферах, созданных Emacs внутренне для определенных задач, которые не должны быть видны программам Lisp, также не вызывают их.
Подавляющее большинство примитивов изменения буфера вызывают
before-change-functions и after-change-functions
в сбалансированных парах, один раз для каждого изменения, где аргументы этих
хуков точно определяют вносимое изменение. Тем не менее, функции хуков
не должны полагаться на то, что это всегда так, потому что некоторые сложные
примитивы вызывают before-change-functions один раз до
внесения изменений, а затем вызывают after-change-functions
ноль или более раз, в зависимости от того, сколько отдельных изменений
вносит примитив. Когда это происходит, аргументы для
before-change-functions будут охватывать область, в которой
вносятся отдельные изменения, но это не обязательно будет минимальная такая
область, а аргументы для каждого последующего вызова
after-change-functions затем точно определят измененную часть
текста. В общем, мы советуем использовать либо хук перед изменением,
либо хук после изменения, но не оба.
Макрос выполняет body нормально, но организует вызов функций после изменения только один раз для серии нескольких изменений — если это безопасно.
Если программа вносит несколько изменений текста в одной и той же области
буфера, использование макроса combine-after-change-calls
вокруг этой части программы может значительно ускорить ее работу при
использовании хуков после изменения. Когда хуки после изменения вызываются,
аргументы указывают на часть буфера, включающую все изменения, внесенные
внутри тела combine-after-change-calls.
Предупреждение: Вы не должны изменять значения
after-change-functions внутри тела формы
combine-after-change-calls.
Предупреждение: Если изменения, которые вы объединяете, происходят в широко разбросанных частях буфера, это все же сработает, но это не рекомендуется, потому что это может привести к неэффективному поведению для некоторых функций хука изменения.
Это выполняет body нормально, за исключением того, что
любые изменения буфера, которые он вносит, не вызывают вызовов
before-change-functions и after-change-functions.
Вместо этого происходит один вызов каждого из этих хуков для области,
ограниченной beg и end, при этом
параметры, переданные в after-change-functions, отражают
изменения, внесенные в размер области body.
Результатом этого макроса является результат, возвращаемый body.
Этот макрос полезен, когда функция вносит возможно большое количество
повторяющихся изменений в буфер, и хуки изменения в противном случае
занимали бы много времени, если бы они вызывались для каждой отдельной
модификации буфера. Сам Emacs использует этот макрос, например, в
командах comment-region и uncomment-region.
Предупреждение: Вы не должны изменять значения
before-change-functions или after-change-functions
внутри body.
Предупреждение: Вы не должны вносить никаких изменений буфера вне области, указанной beg и end.
Эта переменная — обычный хук, который выполняется всякий раз, когда буфер изменяется, который ранее находился в неизмененном состоянии.
Если эта переменная не равна nil, все хуки изменения
отключаются; ни один из них не выполняется. Это относится ко всем хукам,
описанным выше в этом разделе, а также к хукам, прикрепленным к
определенным специальным свойствам текста (см. Свойства со специальным значением)
и свойствам наложений (см. Свойства наложений).
Кроме того, эта переменная привязывается к не-nil во время
выполнения тех же хуков, чтобы по умолчанию модификация буфера из
хука модификации не вызывала выполнение других хуков модификации.
Если вы хотите, чтобы хуки модификации выполнялись в определенном
фрагменте кода, который сам выполняется из хука модификации, то
локально перепривяжите inhibit-modification-hooks к
nil. Однако это может вызвать рекурсивные вызовы
хуков модификации, поэтому будьте готовы к этому (например,
привязав какую-либо переменную, которая указывает вашему хуку
ничего не делать).
Мы рекомендуем привязывать эту переменную только для модификаций, которые
не приводят к постоянным изменениям содержимого буфера (например,
изменения цвета или временные модификации). Если вам необходимо
приостановить хуки изменения во время серии изменений (обычно по
причинам производительности), используйте вместо этого
combine-change-calls или combine-after-change-calls.