Jak dodać złożone wyróżnianie składni w trybie pomocniczym?

10

Chciałbym wyróżnić kod różnymi twarzami w trybie pomocniczym.

Oto zrzut ekranu, który jest blisko tego, czego chcę:

Python-syntax-highlight

Jedną rzeczą, która mi brakuje to posiadające znaki komentarz #w font-lock-comment-face. Chodzi o to, aby komentarze „należące” do konspektu były wyróżnione jako zwykły tekst, dzięki czemu łatwiej jest je czytać. Podczas regularnych komentarzy z ich zwykle mniej widoczną twarzą.

Oto kod, którego użyłem:

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

Chodzi o to, że nie mam pojęcia o interfejsie, na którym font-lock-syntactic-face-functiondziała, poza tym, że otrzymuje złożoną strukturę danych state, ma inny stan punktu i zwraca twarz.

Czy ktoś mógłby wyjaśnić ten interfejs? Czy może jest lepszy?

abo-abo
źródło

Odpowiedzi:

6

font-lock-syntactic-face-functionjest regularną zmienną z Font Lock, a dokładniej z fazy Syntactic Font Lock (wyróżnienie moje):

Jeśli ta zmienna jest różna od zera, powinna być funkcją określającą, której powierzchni należy użyć dla danego elementu składniowego (łańcucha lub komentarza). Wartość jest zwykle ustawiana za pomocą elementu other-vars w ustawieniach domyślnych font-lock-default.

Funkcja jest wywoływana z jednym argumentem, stanem parsowania w punkcie zwracanym przez parse-partial-sexpi powinna zwrócić twarz . Wartość domyślna zwraca font-lock-comment-face dla komentarzy i font-lock-string-face dla łańcuchów (patrz Twarze dla Font Lock).

parse-partial-sexpz kolei zwraca listę opisującą aktualny stan składni Emacsa, który jest zasadniczo wynikiem zastosowania tabeli składni do bieżącego bufora. Lista jest raczej złożona, dlatego oszczędzę ją tutaj; możesz zobaczyć pełne odniesienie w dokumentacji parse-partial-sexp. Celem tej funkcji jest zmiana twarzy zastosowanej do elementu składniowego zgodnie z pewnymi zasadami. Początek twojej funkcji pokazuje to: Jeśli bieżący ciąg znaków jest dokumentem, użyj dla niego innej twarzy.

Jednak twarz zawsze odnosi się do całego elementu składniowego, tj. Całego ciągu lub komentarza. Za pomocą tej funkcji nie można wyróżnić poszczególnych części i należy w statetym celu spojrzeć tylko na dane - podobnie jak (python-info-docstring-p state)w kodzie. Czy nie używać punkt w tym miejscu; Nie jestem nawet pewien, czy wartość parametru pointjest poprawnie zdefiniowana na tym etapie blokowania czcionek.


Łącząc elementy, używasz niewłaściwej funkcji do swoich celów, dlatego nie możesz jej uruchomić.

Nie próbowałem zaimplementować pożądanego podświetlenia, ale myślę, że wykopałeś sposób, zbyt głęboki dla twojego celu. Jeśli dobrze rozumiem, po prostu chcesz wyróżnić kontury w komentarzu.

Jeśli mam rację, potrzebujesz tylko font-lock-keywordsw specjalny sposób, a mianowicie:

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

gdzie outline-facejest twarz, którą chcesz zastosować do nagłówka, toznacza zastąpienie wcześniejszego blokowania czcionek w tym miejscu i my/find-outline-in-commentjest funkcją dopasowywania (patrz dokumentacja font-lock-defaults), która zajmuje pozycję i szuka pierwszego konturu w komentarzu pomiędzy (point)i tą pozycją, zwracając zakres konturu, który zostanie podświetlony w danych dopasowania.

Aby znaleźć konspekt, możesz przeskanować do przodu w poszukiwaniu komentarzy (za pomocą font-lock-comment-facelub w stanie składniowym), a następnie użyć, looking-ataby sprawdzić, czy komentarz ma konspekt.

księżycowy
źródło
1

Rozważ font-lock-syntactic-face-functiontakie zdefiniowanie :

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

Testowano to z python-mode.el, pozostawiając sekcję zaczynającą się od „# *” bez komentarza:

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

Podczas gdy jest administrowany w trybie:

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

Zamiast tego nilkażda ważna twarz powinna działać.

Andreas Röhler
źródło