怎样可以不用 org-element API 来知道是否在某种类型的代码块内?

我在做的事需要知道点是否在特定的 src-block 当中,比如 python block

因为是要用在 company backend 当中,因而不想使用 org-element API,因为效率太低,现在尝试了可以:

(get-char-property (point) 'src-block)

知道当前点在 block 内,但是不能知道是 Python block,有没有什么办法知道是 Python block 的?

(thing-at-point 'line) / (thing-at-point 'sentence)自行分析?

这里有些包也许能用:

光标在代码块中,返回 lang 的字符串

(when (get-char-property (point) 'src-block)
  (save-excursion
    (let ((case-fold-search t))
      (when (re-search-backward
             "^\\([ \t]*#\\(\\(\\+[a-zA-Z]+:?\\| \\|$\\)\\(_\\([a-zA-Z]+\\)\\)?\\)[ \t]*\\(\\([^ \t\n]*\\)[ \t]*\\(.*\\)\\)\\)"
             (point-min) t)
        (match-string 7)))))

参见 org-fontify-meta-lines-and-blocks-1 这个函数。

1 个赞

同样对 Org 的代码并不是很了解。不过貌似下面的代码可以实现:

(defun tom-org-in-python-src-block-p ()
  (and (org-in-src-block-p)
       (equal (plist-get (cadr (org-element-context)) :language)
              "python")))

这个使用了 org-element-context ,用在 company backend 中会导致拖慢。

这个靠谱,并且还给出了出处,赞!

刚才没认真审题,以为是猜测未知代码。如果已经是 block,#3 楼的方法可以,不过忽略了光标落在BEGIN_SRCEND_SRC的情况。

最后采取的解决办法是 hack org-fontify-meta-lines-and-block-1 这个函数,添加了一条新属性 lang,这样直接 get-char-property 就行了!

(string= (get-char-property (point) 'lang) "python")
--> t

这样连正则表达式都省了(正则表达式已经在 fontify 的时候匹配过了)