Як додати складне підсвічування синтаксису в незначному режимі?

Я хотів би виділити код з різними обличчями в незначному режимі.

Ось знімок, який близький до того, що я хочу:

python-syntax-highlight

Одна річ, яку мені не вистачає - це наявність символів символів # у форматі font-lock-comment-face . Ідея полягає в тому, щоб мати коментарі, які "належать" на контур, виділений як звичайний текст, тому його легше читати. Поки маючи регулярні коментарі зі своїм звичним менш помітним обличчям.

Ось код, який я використав:

(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 працює, окрім як отримує Структура складних даних стан , має різний стан точок і повертає обличчя.

Чи може хтось пояснити цей інтерфейс? Чи може бути кращий?

9

2 Відповіді

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

Якщо ця змінна не є нульовою, вона повинна бути функцією для визначення того, яке обличчя використовувати для даного синтаксичного елемента (рядка або коментаря). Значення, як правило, встановлюється за допомогою елемента 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 означає перевизначити будь-яке попереднє блокування шрифтів у цьому місці, а мій/find-outline-in-comment - функція збігу (див. розділ font-lock-defaults ), який приймає позицію і шукає перший контур у коментарі між (point) і ця позиція, повертаючи экстенти контуру, які підсвічуються в даних збігу.

Щоб знайти контур, потрібно сканувати коментарі (за допомогою 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
додано