如何检测该点是否在注释区域内?


15

如何检测该点是否在注释区域内?

Answers:


19

检查返回的列表中的第四个*syntax-ppss

(nth 4 (syntax-ppss))

这是nil如果点任何评论之外,t如果一个非嵌套的注释中,或一个整数(嵌套深度)如果一个嵌套的注释中。有关parse-partial-sexp更多详细信息,请参见文档字符串。

*从零开始。

请注意,这不适用于组织模式,您应该使用以下命令:

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

完美,是否有提供所有其他信息的文档syntax-ppss
命名

2
是的,它在的文档字符串中parse-partial-sexp
legoscia

2
@Name:的docstring syntax-ppss将指向您parse-partial-sexp,后者将为您提供这些函数返回的所有内容的描述。希望这对开始有所帮助。

1
另请参见《 Emacs Lisp手册》中的第34.6节“解析表达式”。
Sue D. Nymme,2015年

7

使用字体,这是我从flyspell学到的技巧。

syntax-ppss两年前尝试过,但由于以下两个原因而无法使用:

  • 不适用于注释边缘(注释限制),例如,对于// this is commentc ++模式下的注释,如果将光标放在/字符上,则结果(nth 4 (syntax-ppss))为nil。

  • 在主要模式(例如网络模式)下根本无法工作

这是我从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))))

请注意,可以通过模糊匹配字体来扩展代码以支持新的主要模式。

我已经使用这个技巧大约三年了,没有失败。此外,考虑到复飞已被广泛使用了很长时间,我可以断言这种方法是可靠的。

有关类似问题,请参阅使用哪个键盘快捷键从字符串中导航出来


1
编辑提出了另一个版本,该版本不包含POSarg并使用point。比使用两个这样的版本更好的是将arg POS可选并将其设置为(point)when nil
提请
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.