Jak wykryć, czy punkt znajduje się w obszarze komentarza?

15

Jak wykryć, czy punkt znajduje się w obszarze komentarza?

Nazwa
źródło

Odpowiedzi:

19

Sprawdź czwartą * wartość na liście zwróconą przez syntax-ppss:

(nth 4 (syntax-ppss))

Dzieje się tak, niljeśli punkt znajduje się poza komentarzem, tjeśli znajduje się wewnątrz komentarza, którego nie można zagnieździć, lub liczbą całkowitą (głębokość zagnieżdżenia), jeśli znajduje się w komentarzu zagnieżdżonym. Aby parse-partial-sexpuzyskać więcej informacji, zobacz dokumentację.

* Zero.

Pamiętaj, że to nie działa w trybie Org, powinieneś użyć tego:

(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
źródło
Idealnie, czy istnieje dokumentacja dla wszystkich innych informacji, które syntax-ppsszawiera?
Imię
2
Tak, jest w dokumentacji dla parse-partial-sexp.
legoscia
2
@Name: docstring syntax-ppsswskaże cię parse-partial-sexp, a ten ostatni da ci opis wszystkich rzeczy zwróconych przez te funkcje. Mam nadzieję, że to pomoże na początek.
Dan
1
Zobacz także rozdział 34.6 „Przetwarzanie wyrażeń” w Podręczniku Emacsa Lispa.
Sue D. Nymme,
7

użyj font-face, to jest sztuczka, której nauczyłem się od flyspell.

Próbowałem syntax-ppssdwa lata temu, to nie działa z dwóch powodów:

  • nie działa na krawędzi komentarza (limit komentarzy), na przykład dla komentarza jak // this is commentw trybie c ++ - jeśli umieścisz kursor nad /znakiem, wynik (nth 4 (syntax-ppss))jest równy zero.

  • w ogóle nie działa w trybie głównym, takim jak tryb internetowy

Oto kod, który skopiowałem z 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))))

Uwaga: kod można rozszerzyć o obsługę nowych głównych trybów poprzez dopasowanie czcionki fuzz.

Używam tej sztuczki od około trzech lat bez żadnych awarii. Poza tym, biorąc pod uwagę, że Flyspell jest szeroko stosowany przez tak długi czas, mogę stwierdzić, że ta metoda jest niezawodna.

Zobacz, którego skrótu klawiaturowego użyć do nawigowania poza ciągiem znaków w przypadku podobnego pytania.

Chen Bin
źródło
1
Edycja zaproponowała inną wersję, która nie wymaga POSarg i używa point. Lepszym rozwiązaniem niż posiadanie dwóch takich wersji jest uczynienie arg POSopcjonalnym i ustawienie go na (point)kiedy nil.
Drew