Bagaimana mendeteksi jika intinya ada di dalam area komentar?

15

Bagaimana mendeteksi jika intinya ada di dalam area komentar?

Nama
sumber

Jawaban:

19

Periksa nilai * keempat dalam daftar yang dikembalikan oleh syntax-ppss:

(nth 4 (syntax-ppss))

Itu niljika titik di luar komentar, tjika di dalam komentar non-nestable, atau integer (kedalaman bersarang) jika di dalam komentar nestable. Lihat docstring parse-partial-sexpuntuk lebih jelasnya.

* Berbasis nol.

Perhatikan bahwa ini tidak berfungsi dengan mode-Org, Anda harus menggunakan ini:

(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
sumber
Sempurna, apakah ada dokumentasi untuk semua informasi lain yang syntax-ppssmenyediakan?
Nama
2
Ya, ada di dokumen untuk parse-partial-sexp.
legoscia
2
@Name: docstring for syntax-ppssakan mengarahkan Anda ke parse-partial-sexp, yang terakhir akan memberi Anda deskripsi semua hal yang dikembalikan oleh fungsi-fungsi ini. Semoga itu membantu untuk memulai.
Dan
1
Lihat juga bagian 34.6 "Mengurai Ekspresi" di Manual Emacs Lisp.
Sue D. Nymme
7

gunakan font-face, ini trik yang saya pelajari dari flyspell.

Saya mencoba syntax-ppssdua tahun lalu, itu tidak berhasil karena dua alasan:

  • tidak bekerja di tepi komentar (batas komentar), misalnya, untuk komentar seperti // this is commentdalam mode c ++ -, jika Anda meletakkan kursor di atas /karakter, hasilnya (nth 4 (syntax-ppss))nihil.

  • tidak bekerja sama sekali dalam mode mayor seperti mode web

Berikut adalah kode yang saya salin dari 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))))

Harap dicatat kode dapat diperpanjang untuk mendukung mode utama baru dengan fuzz font yang cocok.

Saya telah menggunakan trik ini selama sekitar tiga tahun tanpa kegagalan. Selain itu, mengingat flyspell banyak digunakan begitu lama, saya bisa mengklaim metode ini dapat diandalkan.

Lihat Pintasan keyboard mana yang digunakan untuk menavigasi keluar dari string untuk pertanyaan serupa.

chen bin
sumber
1
Hasil edit mengusulkan versi lain yang tidak POSmenggunakan arg dan penggunaan point. Lebih baik daripada memiliki dua versi seperti itu untuk membuat arg POSopsional dan mengaturnya (point)kapan nil.
Drew