Многострочные конструкции Font Lock
Обычно элементы font-lock-keywords не должны совпадать через несколько строк; это ненадёжно работает, поскольку Font Lock обычно сканирует лишь часть буфера и может пропустить многострочную конструкцию, пересекающую границу строки, с которой начинается сканирование. (Обычно сканирование начинается в начале строки.)
Для корректной работы элементов, совпадающих с многострочными конструкциями, необходимы два аспекта: правильное определение и правильная повторная подсветка. Первое означает, что Font Lock находит все многострочные конструкции. Второе означает, что Font Lock корректно повторно подсвечивает весь соответствующий текст при изменении многострочной конструкции — например, если часть текста, ранее входившая в многострочную конструкцию, перестаёт быть её частью. Эти два аспекта тесно связаны, и часто работа над одним из них, по-видимому, приводит к тому, что работает и другой. Однако для надёжного результата необходимо уделить явное внимание обоим аспектам.
Есть три способа обеспечить правильное определение многострочных конструкций:
- Добавить функцию в
font-lock-extend-region-functions, которая выполняет определение и расширяет область сканирования так, чтобы сканируемый текст никогда не начинался и не заканчивался посреди многострочной конструкции. - Аналогичным образом использовать хук
font-lock-fontify-region-function, чтобы расширить область сканирования так, чтобы сканируемый текст никогда не начинался и не заканчивался посреди многострочной конструкции. - Каким-либо образом определить многострочную конструкцию сразу после её вставки в буфер (или в любой момент после этого, но до того, как font-lock попытается её подсветить) и пометить её свойством
font-lock-multiline, которое укажет font-lock не начинать и не заканчивать сканирование посреди конструкции.
Есть несколько способов повторно подсвечивать многострочные конструкции:
- Поместить на конструкцию свойство
font-lock-multiline. Это приведёт к повторной подсветке всей конструкции при изменении любой её части. В некоторых случаях это можно сделать автоматически, задав переменнуюfont-lock-multiline(см. её описание). - Убедиться, что задано
jit-lock-contextually, и полагаться на его работу. В этом случае повторно подсвечивается только часть конструкции, следующая за фактическим изменением, причём с небольшой задержкой. Этот способ работает, только если подсветка различных частей многострочной конструкции никогда не зависит от текста в последующих строках. Посколькуjit-lock-contextuallyвключён по умолчанию, этот вариант может быть привлекательным решением. - Поместить на конструкцию свойство
jit-lock-defer-multiline. Этот способ работает только при использованииjit-lock-contextuallyи также предусматривает небольшую задержку перед повторной подсветкой, но, как иfont-lock-multiline, он также обрабатывает случаи, когда подсветка зависит от последующих строк. - Если разбор синтаксиса конструкции зависит от того, разбирается ли она целиком, за один проход, можно добавить свойство текста
syntax-multilineдля рассматриваемой конструкции. Чаще всего это нужно, когда свойство синтаксиса, применяемое к «FOO», зависит от некоторого последующего текста «BAR»: разместив это свойство текста на всём фрагменте «FOO...BAR», вы гарантируете, что любое изменение «BAR» также приведёт к повторному вычислению свойства синтаксиса для «FOO». Примечание: чтобы это работало, режим должен добавитьsyntax-propertize-multilineвsyntax-propertize-extend-region-functions.
Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Multiline-Font-Lock.html