Как определить, находится ли точка в области комментариев?

15

Как определить, находится ли точка в области комментариев?

имя
источник

Ответы:

19

Проверьте четвертое значение * в списке, возвращаемом syntax-ppss:

(nth 4 (syntax-ppss))

Это nilесли точка находится за пределами любого комментария, tесли он находится внутри нестабильного комментария, или целое число (глубина вложения), если он находится внутри нестабильного комментария. Смотрите документацию parse-partial-sexpдля более подробной информации.

* На основе нуля.

Обратите внимание, что это не работает с Org-режимом, вы должны использовать это:

(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
источник
Отлично, есть ли документация для всей другой информации, которая syntax-ppssпредоставляет?
Имя
2
Да, это в документации parse-partial-sexp.
Legoscia
2
@Name: строка документации для syntax-ppssвас укажет parse-partial-sexp, последняя из которых даст вам описание всего, что возвращается этими функциями. Надеюсь, это поможет для начала.
Дан
1
Смотрите также раздел 34.6 «Анализ выражений» в Руководстве по Emacs Lisp.
Сью Д. Нимм
7

используйте font-face, это трюк, который я узнал из flyspell.

Я пробовал syntax-ppssдва года назад, это не работает по двум причинам:

  • не работает с краем комментария (предел комментария), например, для комментария, как // this is commentв режиме c ++ - если вы поместите курсор на /символ, результат будет (nth 4 (syntax-ppss))равен нулю.

  • вообще не работает в мажорном режиме, как в веб-режиме

Вот код, который я скопировал с 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))))

Обратите внимание, что код может быть расширен для поддержки новых основных режимов путем нечеткого соответствия шрифта.

Я использовал этот трюк около трех лет без сбоев. Кроме того, учитывая, что flyspell широко используется так долго, я могу утверждать, что этот метод является надежным.

Посмотрите, какое сочетание клавиш использовать для перехода из строки для аналогичного вопроса.

чен бен
источник
1
Редакция предложила другую версию, которая не требует POSаргументов и использует point. Лучше, чем две такие версии, сделать arg POSнеобязательным и установить его (point)когда nil.
Дрю