Come rilevare se il punto si trova all'interno di un'area di commento?


15

Come rilevare se il punto si trova all'interno di un'area di commento?

Risposte:


19

Controlla il quarto * valore nell'elenco restituito da syntax-ppss:

(nth 4 (syntax-ppss))

È nilse il punto è esterno a qualsiasi commento, tse all'interno di un commento non annidabile o un numero intero (la profondità di annidamento) se all'interno di un commento annidabile. Vedi la documentazione parse-partial-sexpper ulteriori dettagli.

* Basato su zero.

Nota che questo non funziona con la modalità Org, dovresti usare questo:

(defun in-comment-p ()
  "Testy if cursor/point in a commented line?"
  (save-excursion
        (if (derived-mode-p 'org-mode)
                (save-match-data (beginning-of-line) (looking-at "^[ \t]*#"))
          (nth 4 (syntax-ppss)))))

Perfetto, esiste una documentazione per tutte le altre informazioni che syntax-ppssfornisce?
Nome

2
Sì, è nella documentazione per parse-partial-sexp.
Legoscia,

2
@Nome: il docstring per syntax-ppssti indicherà parse-partial-sexp, quest'ultimo ti fornirà una descrizione di tutto il materiale restituito da queste funzioni. Spero che questo aiuti per iniziare.
Dan

1
Vedere anche la sezione 34.6 "Espressioni di analisi" nel manuale Emacs Lisp.
Sue D. Nymme,

7

usa il font-face, questo è il trucco che ho imparato da flyspell.

Ho provato syntax-ppssdue anni fa, non funziona per due motivi:

  • non funziona sul bordo del commento (limite del commento), ad esempio, per un commento come // this is commentin modalità c ++, se si posiziona il cursore sul /carattere, il risultato (nth 4 (syntax-ppss))è zero.

  • non funziona affatto in modalità principale come la modalità web

Ecco il codice che ho copiato da flyspell:

(defun evilnc--in-comment-p (&optional pos)
  "Test if character at POS is comment.  If POS is nil, character at `(point)' is tested"
  (interactive)
  (unless pos (setq pos (point)))
  (let* ((fontfaces (get-text-property pos 'face)))
    (when (not (listp fontfaces))
      (setf fontfaces (list fontfaces)))
    (delq nil
          (mapcar #'(lambda (f)
                      ;; learn this trick from flyspell
                      (or (eq f 'font-lock-comment-face)
                          (eq f 'font-lock-comment-delimiter-face)))
                  fontfaces))))

Si noti che il codice potrebbe essere esteso per supportare le nuove modalità principali mediante la corrispondenza del carattere fuzz corrispondente.

Ho usato questo trucco per circa tre anni senza fallimenti. Inoltre, considerando che flyspell è ampiamente utilizzato per così tanto tempo, potrei affermare che questo metodo è affidabile.

Vedi Quale scorciatoia da tastiera usare per navigare fuori da una stringa per domande simili.


1
Una modifica ha proposto un'altra versione che non accetta POSarg e utilizza point. Meglio che avere due di queste versioni è rendere arg POSopzionale e impostarlo su (point)quando nil.
Ha
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.