Як дадаць складаную падсвятленне сінтаксісу ў малым рэжыме?

Я хацеў бы падкрэсліць код з рознымі асобамі ў малым рэжыме.

Вось скрыншот, што блізка да таго, што я хачу:

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)))

Справа ў тым, што я паняцця не маю, аб інтэрфейсе, на якім <�Код> шрыфт блакіроўка-сінтаксічная-твар-функцыя працуе, акрамя таго, што атрымлівае складаная структура дадзеных стан , мае розныя пункты стану і вяртае твар.

Можа хто-небудзь растлумачыць гэты інтэрфейс? Ці ёсць лепш адзін можа быць?

9

2 адказы

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

<�Р> Калі гэтая пераменная не з'яўляецца нулявым, ён павінен быць функцыяй, каб вызначыць, з якой сутыкаюцца выкарыстоўваць для дадзенага сінтаксічнага элемента (радкі або каментара). Значэнне звычайна ўсталёўваецца праз іншы-Вары элемента ў Font-Lock-змаўчанні. </Р>      <�Р> <�моцны> Гэтая функцыя выклікаецца з адным аргументам, стан сінтаксічнага аналізу ў кропцы, вернутага сінтаксічны-частковай Sexp , і ён павінен вяртаць твар </моцны>. Значэнне па змаўчанні вяртае шрыфт замыканне каментара-твар для каментароў і шрыфт блакіроўка шнуроўкі асобы для радкоў (гл Faces для блакавання шрыфтоў).

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.

Тым не менш, твар заўсёды ставіцца да ўсім сінтаксічны элемент, гэта значыць уся радок або каментарыю. Вы не можаце вылучыць асобныя часткі з дапамогай гэтай функцыі, і вы павінны глядзець толькі на дадзеным стану для гэтага тыпу (пітон-інфа-р-радок дакументацыі стану) робіць ў вашым кодзе. У <�моцны> не выкарыстоўваць кропку ў гэтым месцы; Я нават не ўпэўнены, ці з'яўляецца значэнне кропка правільна вызначаны на дадзеным этапе шрыфта блакавання.


Ўвод кавалкі разам, вы карыстаецеся няправільную функцыю для вашай мэты, таму вы не можаце прымусіць яго працаваць.

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

Калі я маю рацыю, то вам проста неабходна шрыфты замак-ключавыя словы асаблівым чынам, а менавіта:

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

дзе абрыс-твар гэта асоба, якое вы хочаце ўжыць да загалоўка, т азначае перавызначыць любы папярэдні шрыфт блакаванне на гэтым месцы, і мае/знайсці контурную-в-каментар з'яўляецца функцыяй Сличителя (гл радкі дакументацыі па Font-Lock-змаўчанні ), які займае пазіцыю і шукае першы контур ў каментары паміж (кропка) і што становішча, вяртаючы экстенты контуру, якія будуць выдзелены ў дадзеным матчы.

Для таго, каб знайсці схему, вы б адсканаваць наперад для каментароў (выкарыстоўваючы шрыфт блакавання-каментар-слойного або сінтаксічнай стану), а затым выкарыстоўвае глядзіць-на , каб праверыць, ці з'яўляецца каментар мае контур.

6
дададзена

Разгледзім вызначэнне шрыфта блакавання сінтаксічны-твар-функцыі так:

(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))))

У гэтым выпадку тэстуюцца з пітона-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)

Замест нуль , любое сапраўднае асоба павінна працаваць.

0
дададзена