Wie erkenne ich, ob sich der Punkt innerhalb eines Kommentarbereichs befindet?

15

Wie erkenne ich, ob sich der Punkt innerhalb eines Kommentarbereichs befindet?

Name
quelle

Antworten:

19

Überprüfen Sie den vierten * Wert in der Liste, die zurückgegeben wird von syntax-ppss:

(nth 4 (syntax-ppss))

Es ist, nilwenn point außerhalb eines Kommentars liegt, twenn es sich innerhalb eines nicht verschachtelbaren Kommentars befindet, oder eine Ganzzahl (die Verschachtelungstiefe), wenn es sich innerhalb eines verschachtelbaren Kommentars befindet. Weitere Informationen finden Sie in der Dokumentation parse-partial-sexp.

* Auf Null basierend.

Beachten Sie, dass dies im Org-Modus nicht funktioniert. Sie sollten dies verwenden:

(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)))))
Legoscia
quelle
Perfekt, gibt es eine Dokumentation für alle anderen Informationen, die syntax-ppssbereitstellen?
Name
2
Ja, es steht in der Dokumentation für parse-partial-sexp.
Legoscia
2
@Name: Der docstring für verweist syntax-ppssauf parse-partial-sexp, der eine Beschreibung aller von diesen Funktionen zurückgegebenen Elemente enthält . Hoffentlich hilft das erstmal.
Dan
1
Siehe auch Abschnitt 34.6 "Analysieren von Ausdrücken" im Emacs Lisp-Handbuch.
Sue D. Nymme
8

benutze die Schriftart, das ist der Trick, den ich von flyspell gelernt habe.

Ich habe es vor syntax-ppsszwei Jahren versucht , es funktioniert aus zwei Gründen nicht:

  • Arbeiten Sie nicht an der Kante des Kommentars (Kommentar-Limit), zum Beispiel für Kommentare wie // this is commentim C ++ - Modus. Wenn Sie den Cursor über das /Zeichen setzen, ist das Ergebnis von (nth 4 (syntax-ppss))Null.

  • Funktioniert im Hauptmodus überhaupt nicht wie im Webmodus

Hier ist der Code, den ich aus flyspell kopiert habe:

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

Bitte beachten Sie, dass der Code erweitert werden kann, um neue Hauptmodi durch Fuzz Matching Font Face zu unterstützen.

Ich habe diesen Trick ungefähr drei Jahre lang ohne Fehler angewendet. Abgesehen davon, dass Flyspell so lange weit verbreitet ist, könnte ich behaupten, diese Methode ist zuverlässig.

Eine ähnliche Frage finden Sie unter Welche Tastenkombination zum Navigieren aus einer Zeichenfolge verwendet werden soll .

chen bin
quelle
1
Eine Änderung schlug eine andere Version vor, die kein POSArgument benötigt und verwendet point. Besser als zwei solcher Versionen ist es, arg POSoptional zu machen und auf (point)when zu setzen nil.
Drew