Come aggiungere l'evidenziazione della sintassi complessa in una modalità minore?


10

Vorrei evidenziare il codice con vari volti in una modalità minore.

Ecco uno screenshot vicino a quello che voglio:

python-syntax-highlight

Una cosa che mi manca è avere i caratteri di commento #in font-lock-comment-face. L'idea è di avere commenti che "appartengono" a una struttura evidenziata come testo semplice, quindi è più facile da leggere. Pur avendo commenti regolari con la loro solita faccia meno prominente.

Ecco il codice che ho usato:

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

Il fatto è che non ho idea dell'interfaccia su cui font-lock-syntactic-face-functionopera, a parte il fatto che riceve una struttura di dati complessa state, ha uno stato di punto diverso e restituisce una faccia.

Qualcuno potrebbe spiegare questa interfaccia? Ce n'è forse uno migliore?

Risposte:


6

font-lock-syntactic-face-functionè una variabile regolare da Blocco caratteri, in particolare dalla fase Blocco caratteri sintattici (enfasi mia):

Se questa variabile è nulla, dovrebbe essere una funzione per determinare quale faccia utilizzare per un dato elemento sintattico (una stringa o un commento). Il valore viene normalmente impostato tramite un elemento other-vars in default di font-lock-default.

La funzione viene chiamata con un argomento, lo stato di analisi al punto restituito da parse-partial-sexpe dovrebbe restituire una faccia . Il valore predefinito restituisce font-lock-comment-face per i commenti e font-lock-string-face per le stringhe (vedere Facce per Blocco caratteri).

parse-partial-sexpa sua volta restituisce un elenco che descrive l'attuale stato sintattico di Emacs, che è essenzialmente il risultato dell'applicazione della tabella di sintassi al buffer corrente. L'elenco è piuttosto complesso, quindi lo risparmierò qui; puoi vedere il riferimento completo nella documentazione di parse-partial-sexp. Lo scopo di questa funzione è cambiare la faccia applicata a un elemento sintattico in base a determinate regole. L'inizio della tua funzione lo dimostra: se la stringa corrente è una stringa, usa una faccia diversa per essa.

Tuttavia, la faccia si applica sempre all'intero elemento sintattico, cioè all'intera stringa o commento. Non puoi evidenziare singole parti con questa funzione e dovresti solo guardare il dato stateper questo scopo, come (python-info-docstring-p state)nel tuo codice. Do Non utilizzare punto in questo luogo; Non sono nemmeno sicuro che il valore di pointsia definito correttamente in questa fase del blocco dei caratteri.


Mettendo insieme i pezzi, stai usando la funzione sbagliata per il tuo scopo, motivo per cui non riesci a farlo funzionare.

Non ho cercato di implementare l'evidenziazione desiderata, ma penso che tu abbia scavato molto, troppo in profondità per il tuo scopo. Se capisco bene le cose, ti piacerebbe solo evidenziare i contorni in un commento.

Se ho ragione, allora hai solo bisogno font-lock-keywordsdi un modo speciale, vale a dire:

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

dove si outline-facetrova la faccia che si desidera applicare al titolo, tsignifica sovrascrivere qualsiasi blocco del carattere precedente in questo punto ed my/find-outline-in-commentè una funzione di corrispondenza (vedere il documento di font-lock-defaults) che prende posizione e cerca il primo contorno in un commento tra (point)e quella posizione, restituendo le estensioni del contorno da evidenziare nei dati della partita.

Per trovare la struttura, esegui la scansione in avanti per i commenti (usando font-lock-comment-faceo lo stato sintattico) e quindi usi looking-atper verificare se il commento ha una struttura.


1

Considera di definire in font-lock-syntactic-face-functionquesto modo:

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

Questo è stato testato con python-mode.el, lasciando una sezione che inizia con "# *" senza commento:

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

Mentre è amministrato con la modalità:

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

Invece nil, qualsiasi faccia valida dovrebbe funzionare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.