有没有办法区分当前光标的位置是docstring还是string呢?

(defun foo () "docstring" (message "string"))

有什么办法区分这两种情况吗?

根据语法高亮加的 text properties,简单高效,前提是有语法高亮了;另一个办法是判断这个 string 是不是处在 defun 之类的列表的第三位,算法简单,但频繁计算应该会卡。根据你的使用场景选择。

语法高亮并不太可靠,比方说判断face的话,docstring里面很容易出现face被覆盖的情况。 位置判断的话,不通用,不同语法的docstring在不同的位置。

什么情况?举个例子?

你写的是 Emacs Lisp 的 defun,第三个字符串是 docstring,还需要考虑什么情况?

存放宏的符号有个property doc-string-elt,记忆了这个宏的doc-string应该在的位置。

(get 'define-minor-mode 'doc-string-elt) ;=> 2
(get 'defvar 'doc-string-elt)           ;=> 3
(get 'defun 'doc-string-elt)            ;=> 3

然而这东西并不是万能的,有些corner case不能处理

比如defclass的doc-string-elt返回值为4,然而defclass允许你用:documentation "DOCSTRING"的keyword格式来指定docstring而非直接使用一个string,这种情况直接依赖这个判据的话会失效。

覆盖比如说 “\n”,这个转义可能就有自己的face。或 `hello’也可能应用自己的face。还有hl-line激活的情况下,我不知道怎么取到font-lock-string-face或font-loc-comment-face,如果有办法请指点一下。

多种语法指,比如clojure里面的docstring,python里面的docstring等等。我想能处理所有语言的情况。

最后给输入法用来区分是在文档中还是在字符串中。

这个方式可能适合不了多种语法,比如clojure和python用的方式就不同。

所以为什么不用text property?docstring本来就是font-lock按照正则刷上去的颜色,不然就只能把font-lock rules拿来自己匹配一次了。

(defun test ()
  (interactive)
  (let ((state (syntax-ppss)))
    (if (not (nth 3 state))
        (message "not string")
      (if (eq font-lock-doc-face (lisp-font-lock-syntactic-face-function state))
          (message "docstring")
        (message "normal string")))))

直接用现成的 code 啊(

这个方法的好处就是不管用户开没开 font-lock-mode 都能可靠地使用(

2 个赞

text property中我应该取哪个值来做判断呢?

(eq (plist-get (text-properties-at (point)) 'face) 'font-lock-doc-face)

可以先跳到docstring的引号上再做判断,这样比较保险

给力,这个好使。

嗯,我之前用face-at-point好像总是只能拿到最高的一个,这个方法看起来可以拿到全部的。

2 个赞