Как добавить сложную подсветку синтаксиса в малый режим?

Я хотел бы выделить код с различными лицами в второстепенном режиме.

Вот скриншот, который близок к тому, что я хочу:

python-syntax-highlight

Одна вещь, которую мне не хватает, - это символы комментариев # в <Код> шрифт блокировки-комментарий-лицо . Идея состоит в том, чтобы иметь комментарии, которые "принадлежат" к контуру, выделенному как обычный текст, поэтому его легче читать. В то время как регулярно комментируя свое обычное менее заметное лицо.

Вот код, который я использовал:

(setq-local font-lock-defaults
            '(python-font-lock-keywords
              nil nil nil nil
              (font-lock-syntactic-face-function
               . lpy-font-lock-syntactic-face-function)))

(defun lpy-font-lock-syntactic-face-function (state)
  "Return syntactic face given STATE.
Returns 'defalt face for comments that belong to an outline."
  (cond ((nth 3 state)
         (if (python-info-docstring-p state)
             font-lock-doc-face
           font-lock-string-face))
        ((save-excursion
           (while (and (> (point) (point-min))
                       (progn (move-beginning-of-line 0)
                              (eq (char-after) ?\#))))
           (forward-line 1)
           (looking-at "#\\*+ "))
         'default)
        (t
         font-lock-comment-face)))

Дело в том, что я понятия не имею о интерфейсе, на котором font-lock-syntactic-face-function , кроме того, что он получает сложная структура данных state , имеет другое состояние точки и возвращает лицо.

Может кто-нибудь объяснить этот интерфейс? Может быть, лучше?

9

2 ответы

font-lock-syntactic-face-function is a regular variable from Font Lock, more specifically from the Syntactic Font Lock phase (emphasis mine):

Если эта переменная не равна nil, она должна быть функцией для определения того, какую грань использовать для данного синтаксического элемента (строки или комментария). Значение обычно устанавливается через элемент other-vars в значениях font-lock-defaults.

     

Функция вызывается с одним аргументом, состоянием разбора в точке, возвращаемой parse-partial-sexp , и должна возвращать лицо . Значение по умолчанию возвращает font-lock-comment-face для комментариев и font-lock-string-face для строк (см. Faces for Font Lock).

parse-partial-sexp in turn returns a list which describes Emacs' current syntactic state, which is essentially the result of the application of the syntax table to the current buffer. The list is rather complex, hence I'll spare it here; you can see the complete reference in the docstring of parse-partial-sexp. The purpose of this function is to change the face applied to a syntactic element under certain rules. The beginning of your function demonstrates this: If the current string is a docstring, use a different face for it.

Однако лицо всегда применяется к синтаксическому элементу целиком , т. Е. Целая строка или комментарий. Вы не можете выделить отдельные части этой функцией, и вы должны смотреть только на это состояние для этой цели, например (состояние python-info-docstring-p) в вашем коде. Используйте не точку использования в этом месте; Я даже не уверен, правильно ли определено значение point на этом этапе блокировки шрифтов.


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

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

Если я прав, вам просто нужен font-lock-keywords особым образом, а именно:

(my/find-outline-in-comment-p 0 'outline-face t)

где outline-face - это лицо, которое вы хотите применить к заголовку, t означает отмену любой предыдущей блокировки шрифта в этом месте и my/find-outline-in-comment - это функция сопряжения (см. docstring font-lock-defaults ), которая занимает позицию и ищет первый контур в комментарии между (точка) и эта позиция, возвращая экстенты контура, которые будут выделены в данных соответствия.

Чтобы найти контур, вы сканируете вперед комментарии (используя font-lock-comment-face или синтаксическое состояние), а затем используйте look-at , чтобы проверить, комментарий имеет набросок.

6
добавлено

Попробуйте определить font-lock-syntactic-face-function , как это:

(setq font-lock-syntactic-face-function
      (lambda (state)
    (cond ((nth 3 state)
           font-lock-string-face)
          ((and (nth 4 state)(nth 8 state))
            MY-COMMENT-FACE
          (t  font-lock-comment-face))))

Это было протестировано с python-mode.el, оставив раздел, начинающийся с «# *» без комментария:

(setq py--font-lock-syntactic-face-function
      (lambda (state)
    (cond ((nth 3 state)
           font-lock-string-face)
          ((and (nth 4 state)(nth 8 state)
            (progn (save-excursion
                 (goto-char (nth 8 state))
                 (looking-at (concat comment-start (regexp-quote "*"))))))
           nil)
          (t font-lock-comment-face))))

Пока он управляется с режимом:

(font-lock-syntactic-face-function
                    . py--font-lock-syntactic-face-function)

Вместо nil любое действующее лицо должно работать.

0
добавлено