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


10

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

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

python-синтаксис-виділення

Одна річ , яку я пропускаю це має свій коментар символів #в 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працює, крім того, що він отримує складну структуру даних state, має інший стан точок і повертає обличчя.

Може хтось пояснить цей інтерфейс? Можливо, є кращий?

Відповіді:


6

font-lock-syntactic-face-function- це звичайна змінна від Font Lock, точніше із фази блокування синтаксичного шрифту (міна акценту):

Якщо ця змінна не є нульовою, слід визначити, яке обличчя використовувати для заданого синтаксичного елемента (рядок або коментар). Значення зазвичай встановлюється через інший елемент-vars у шрифтових блокуваннях за замовчуванням.

Функція викликається одним аргументом, стан розбору в точці, повернутий parse-partial-sexp, і повинен повернути обличчя . Значення за замовчуванням повертає шрифт-lock-comment-face для коментарів та font-lock-string-face для рядків (див. Обличчя для блокування шрифту).

parse-partial-sexpу свою чергу повертає список, який описує поточний синтаксичний стан Emacs, який по суті є результатом застосування таблиці синтаксису до поточного буфера. Список досить складний, тому я його пошкодую тут; ви можете побачити повне посилання в docstring parse-partial-sexp. Мета цієї функції - змінити обличчя, застосоване до синтаксичного елемента за певними правилами. Початок вашої функції демонструє це: Якщо поточний рядок є docstring, використовуйте для цього інше обличчя.

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


Збираючи шматки, ви використовуєте неправильну функцію для своїх цілей, тому ви не можете змусити її працювати.

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

Якщо я маю рацію, то вам просто потрібно font-lock-keywordsпо-особливому, а саме:

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

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

Щоб знайти контур, слід сканувати вперед коментарі (використовуючи font-lock-comment-faceабо синтаксичний стан), а потім використовувати, looking-atщоб перевірити, чи має коментар контур.


1

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.