Я пытаюсь обернуть голову вокруг формата font-lock-keywords Keywords , в частности варианта MATCH-ANCHORED , но я не вижу, как бы я использовал повторы , сгенерированные из одного регулярного выражения. Ниже моя установка для иллюстрации:

(defvar fmt-font-lock-keywords
  ;; no-args
  `(("~\\(@:?\\|:@?\\)?[]>()}aswvcp;_]"
     (0 font-lock-keyword-face))
    ;; numeric-arg
    ("~\\([0-9]*\\|#,?\\)\\(@:?\\|:@?\\)?[i*%&|~{[]"
     (0 font-lock-keyword-face))
    ;; decimal
    ("~\\([0-9]*\\|#\\(,[0-9]*\\|#\\)\\{0,3\\}\\)?\\(@:?\\|:@?\\)?[rdbox]"
     (0 font-lock-keyword-face))
    ;; floating-point f
    (,(concat
       "~\\(\\(\\([0-9]*\\|#\\)\\(,\\([0-9]*\\|#\\)\\)\\{3\\}\\(,'\\w\\)\\{1,2\\}\\)\\|"
       "\\(\\([0-9]*\\|#\\)\\(,\\([0-9]*\\|#\\)\\)\\{0,3\\}\\)\\)"
       "?\\(@:?\\|:@?\\)?f")
     (0 font-lock-keyword-face))
    ;; floating-point e, g
    (,(concat
       "~\\(\\(\\([0-9]*\\|#\\)\\(,\\([0-9]*\\|#\\)\\)\\{3\\}\\(,'\\w\\)\\{1,3\\}\\)\\|"
       "\\(\\([0-9]*\\|#\\)\\(,\\([0-9]*\\|#\\)\\)\\{0,3\\}\\)\\)"
       "?\\(@:?\\|:@?\\)?[eg]")
     (0 font-lock-keyword-face))
    ;; currency
    (,(concat
       "~\\(\\(\\([0-9]*\\|#\\)\\(,\\([0-9]*\\|#\\)\\)\\{2\\}\\(,'\\w\\)\\)\\|"
       "\\(\\([0-9]*\\|#\\)\\(,\\([0-9]*\\|#\\)\\)\\{0,2\\}\\)\\)"
       "?\\(@:?\\|:@?\\)?[$]")
     (0 font-lock-keyword-face))
    ;; tabulation
    ("~\\(\\([0-9]*\\|#\\)\\(,\\([0-9]*\\|#\\)\\)?\\)?\\(@:?\\|:@?\\)?t"
     (0 font-lock-keyword-face))
    ;; escape
    ("~\\(\\([0-9]*\\|#\\)\\(,\\([0-9]*\\|#\\)\\)\\{0,2\\}\\)?\\(@:?\\|:@?\\)?^"
     (0 font-lock-keyword-face))
    ;; logical block
    ("~\\(\\([0-9]*\\|#\\)\\(,\\([0-9]*\\|#\\)\\)\\{0,3\\}\\)?\\(@:?\\|:@?\\)?<"
     (0 font-lock-keyword-face))
    ;; custom function
    (,(concat
       "~\\(\\([0-9]+\\|'\\w\\|#\\)\\(,\\([0-9]+\\|'\\w\\|#\\)+\\)*\\)?"
       "\\(@:?\\|:@?\\)?\\/[^\\s\\n,#@]+\\/")
     (0 font-lock-keyword-face))))

И при инициализации этого режима:

(define-derived-mode fmt-mode fundamental-mode
  . . .
  (set (make-local-variable 'font-lock-defaults)
      '(fmt-font-lock-keywords)) . . .)

Извините, я знаю, что это похоже на клинопись, но на самом деле это очень просто ... это анализ мини-языка формата Common Lisp.

Что он делает сейчас: он окрашивает все специальные подстроки, используя ключевое слово face, но я бы хотел по-разному раскрасить определенные части (числовые аргументы будут окрашены по-разному, вызов пользовательской функции будет окрашен по-разному, at и colon - может по другому, символьные данные - может и по другому тоже).

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


Я понимаю, что анализ может быть решен гораздо проще, если не использовать регулярные выражения, но я не знаю, как совместить его с режимом блокировки шрифтов. Но если вам случится знать, как это сделать без регулярных выражений, и в то же время использовать механику блокировки шрифтов для раскраски, это был бы отличный ответ!

1 ответ1

1

Быстрый частичный ответ, не глядя на ваш код (извините) - так что он вполне может пропустить лодку.

  1. Если часть того, о чем вы спрашиваете, это как оставить что-то выделенным в записи f-l-k даже если это также соответствует более поздней записи f-l-k , ответом на это будет использование keep. (Смотрите также, что делает t , что в значительной степени противоположно.)

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

Если вы этого еще не сделали, обратитесь к руководству по Elisp , узел Search-based Fontification - найдите keep и FUNCTION .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .