Избегайте блокировок шрифтов, мешающих внутри комментариев
В моем font-lock-defaults
Я имею:
("\\(^\\| \\|\t\\)\\(![^\n]+\\)\n" 2 'factor-font-lock-comment)
Символ комментария !
и это делает так, чтобы комментарии получили правильное лицо. Это работает в основном, за исключением случаев, когда внутри комментария присутствует конкурирующая сущность с блокировкой шрифта, например строка (ограниченная двойными кавычками):
! this line is font-locked fine
! this one is "not" because "strings"
Как вы получаете блокировку шрифта, чтобы понять, что комментарий уже отлично заблокирован шрифтом, и ему не нужно пытаться блокировать шрифты внутри него каких-либо строк? Очевидным способом является добавление !
к начальному классу комментария в таблице синтаксиса:
(modify-syntax-entry ?! "< 2b" table)
Это решение невозможно, поскольку имена функций и другие символы, содержащие !
законны, такие как map!
filter!
а также foo!bar
, И добавление !
приведет к неправильному выделению кода, содержащего такие имена.
1 ответ
Как правило, плохая идея выделять комментарии, используя ключевое слово font-lock. Для этого лучше использовать синтаксическую фазу.
Даже несмотря на то, что таблица синтаксиса недостаточно мощна, чтобы описать синтаксис вашего языка, все же возможно выделить комментарии, используя на этапе синтаксической блокировки шрифтов. Решение состоит в том, чтобы предоставить пользовательскую функцию для назначения синтаксических свойств !
символы, которые должны начинать комментарий. Это делается с помощью переменной syntax-propertize-function
,
Смотрите руководство elisp для деталей. Кроме того, этот урок описывает это очень подробно.
Обновление: ниже приведен простой пример, который определяет !
быть начальным символом комментария, но не внутри идентификаторов. В реальном примере может потребоваться более изощренный способ проверить, является ли что-то идентификатором.
(defun exmark-syntax-propertize (start end)
(funcall (syntax-propertize-rules
("[[:alnum:]_]\\(!\\)"
(1 "_")))
start
end))
(defvar exmark-mode-syntax-table
(let ((table (make-syntax-table)))
(modify-syntax-entry ?\n "> " table)
(modify-syntax-entry ?! "< " table)
table))
(define-derived-mode exmark-mode prog-mode "!-Mark"
"Major mode for !-mark."
(set (make-local-variable 'syntax-propertize-function)
'exmark-syntax-propertize))