treesit 已经合并进 master 分支了

我最近也在折腾配色方案,但是不知道为什么,我默认的配色方案似乎就有些问题,不知道能否指导一下,如何排查?

举个例子,go-ts-mode 中是这样配置的:

(defvar go-ts-mode--font-lock-settings
  (treesit-font-lock-rules
   :language 'go
   :feature 'function
   ‘((call_expression
      function: (selector_expression
                 field: (field_identifier) @font-lock-function-name-face))
     (call_expression
      function: (identifier) @font-lock-function-name-face)
     (function_declaration
      name: (identifier) @font-lock-function-name-face)
     (method_declaration
      name: (field_identifier) @font-lock-function-name-face))))

实际使用过程中,只有 foo() 这样的函数能高亮,foo.bar() 这样的函数就不会高亮

我看过 explore-mode 里面,定义里的 field: (field_identifier) 也是能对于到 foo.bar() 里面的 bar 的,但是就是无法高亮 bar

(call_expression
      function: (selector_expression
                 field: (field_identifier) @font-lock-function-name-face))
  (setq-local treesit-font-lock-level 4)
  (treesit-font-lock-recompute-features '(command string variable function operator bracket keyword)))

这两个 设置很重要的

1 个赞

这样设置对性能有影响吗?看说明渲染会多不少东西。

反正我是没感觉到卡顿,以前使用 emacs-tree-sitter.el 的时候,也是这样配色的。也没遇到性能上的问题。

@casouri 最近发了篇 Blog 介绍 Emacs 29 中的 tree-sitter 使用和未来的计划。还不了解用法的可以看看。

https://archive.casouri.cc/note/2023/tree-sitter-in-emacs-29/index.html

6 个赞

感谢分享。设置 treesit-language-source-alist 这个变量后,就可以直接在 Emacs 里安装相关的 parser 了

(setq treesit-language-source-alist
      '((bash       . ("https://github.com/tree-sitter/tree-sitter-bash.git"))
        (c          . ("https://github.com/tree-sitter/tree-sitter-c.git"))
        (cmake      . ("https://github.com/uyha/tree-sitter-cmake.git"))
        (cpp        . ("https://github.com/tree-sitter/tree-sitter-cpp.git"))
        (csharp     . ("https://github.com/tree-sitter/tree-sitter-c-sharp.git"))
        (css        . ("https://github.com/tree-sitter/tree-sitter-css.git"))
        (dockerfile . ("https://github.com/camdencheek/tree-sitter-dockerfile.git"))
        (go         . ("https://github.com/tree-sitter/tree-sitter-go.git"))
        (gomod      . ("https://github.com/camdencheek/tree-sitter-go-mod.git"))
        (html       . ("https://github.com/tree-sitter/tree-sitter-html.git"))
        (java       . ("https://github.com/tree-sitter/tree-sitter-java.git"))
        (javascript . ("https://github.com/tree-sitter/tree-sitter-javascript.git"))
        (json       . ("https://github.com/tree-sitter/tree-sitter-json.git"))
        (python     . ("https://github.com/tree-sitter/tree-sitter-python.git"))
        (ruby       . ("https://github.com/tree-sitter/tree-sitter-ruby.git"))
        (rust       . ("https://github.com/tree-sitter/tree-sitter-rust.git"))
        (toml       . ("https://github.com/tree-sitter/tree-sitter-toml.git"))
        (tsx        . ("https://github.com/tree-sitter/tree-sitter-typescript.git" nil "tsx/src"))
        (typescript . ("https://github.com/tree-sitter/tree-sitter-typescript.git" nil "typescript/src"))
        (yaml       . ("https://github.com/ikatyang/tree-sitter-yaml.git"))))

这样直接在 Emacs 里 M-x treesit-install-language-grammar 就可以了,不用每次都要到 admin/notes/xxx 里去手动安装了,这样默认会装在 (user-emacs-directory)/tree-sitter 下面

不过现在 Emacs 更新后,auto-mode-alist 里没了 xxx-ts-mode,还得自己手动加, 以 go-ts-mode 为例

虽然 mode 文件里有写这么一行,但这不应该是调用了 go-ts-mode 后才会生效的吗?除了提前在自己的配置文件里加上 (add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode)),还有啥好的解决办法么


随手糊了一个,但治标不治本,现在将就用

(dolist (list `((cmake      . (,(rx (or "CMakeLists.txt" ".cmake") eos) . cmake-ts-mode))
                (dockerfile . (,(rx (or (seq "Dockerfile" (opt "." (zero-or-more nonl))) (seq "." (any "Dd") "ockerfile")) eos) . dockerfile-ts-mode))
                (go         . (,(rx ".go" eos) . go-ts-mode))
                (gomod      . (,(rx "/go.mod" eos) . go-mod-ts-mode))
                (rust       . (,(rx ".rs" eos) . rust-ts-mode))
                (tsx        . (,(rx ".tsx" eos) . tsx-ts-mode))
                (typescript . (,(rx ".ts" eos) . typescript-ts-mode))
                (yaml       . (,(rx ".y" (opt "a") "ml" eos) . yaml-ts-mode))))
  (let ((parser (car list))
        (alist (cdr list)))
    (when (treesit-ready-p parser)
      (add-to-list 'auto-mode-alist alist))))
3 个赞

另一种方法是 (add-to-list 'major-mode-remap-alist '(go-mode . go-ts-mode)),这样在激活 go-mode 时调用 go-ts-mode.

但 Emacs 没有内置的 go-mode ,除非装了 go-mode 这个包,这样 remap 的时候才有用

今天有大佬根据 casouri 的starter guide 写了个treesit-auto, 包含了各种语言的source-alist, 以及各个mode的 fallback,如果想偷懒的话可以直接装这个。

文章中包的地址多了个后缀.el打不开,用这个地址:GitHub - renzmann/treesit-auto: Automatically pick between Tree-sitter and default major modes in Emacs 29+

edit: typo

2 个赞

我个人不大需要这样的包,自己常用的也就那几个 mode,放到个人配置就好了。而且 tree-sitter 还在不断改动。等 emacs-29 发布时应该会有一个官方推荐设置。

上面提到的 treesit-language-source-alist变量不是应该提供一个默认值更好吗?还要让用户去设置这一大串。

不过我还是更加喜欢用脚本。

嗯,我个人也只用python, js, clojure,但也是脚本一次性全build了。除了其中 clojure 的source link 要自己找,整体上工作量不大。

不过一开始设置的时候还是比较蒙圈的,直到starter guide出来后,思路算是清晰了。

看描述,是不是官方没有提供 ts-mode的语言,也可以使用? 我看到列表里面有R语言的tree-sitter 安装,但Emacs 官方目前还没有r-ts-mode.

没有 *-ts-mode 的, 如果有编译相应的tree-sitter模块,应该可以使用treesit-explore-mode查看结构。但高亮和indent 需要 *-ts-mode的支持。我之前试过elisp-tree-sitter,有点儿忘了具体细节了。

ok,多谢!

下面这个 commit 后应该就不用手动设置路径了。
https://git.savannah.gnu.org/cgit/emacs.git/commit/?h=emacs-29&id=abb3becb9fb925a4fc3c13da677cc55823423cb3

2 个赞

喜大普奔,紫薯布丁

emacs-29 分支下的编译语言定义的脚本也可以用在 Windows 上了。需要在 mingw 下用。喜欢自动一次编译的可以用这个脚本 admin/notes/tree-sitter/build-module/batch.sh

https://git.savannah.gnu.org/cgit/emacs.git/commit/?h=emacs-29&id=00675aa724a6e18d03c2ccc63269ef03c67086ec

Emacs 内置的 treesit 叕更新了。现在所有支持的 mojor mode 都不会默认开启 tree-sitter 了,要用得用户自己设置。比如 yaml-mode 不是 Emacs 内置的,内置的只用 yaml-ts-mode,但用户要设置 auto-mode-alist 来默认对 yaml 文件启用 yaml-ts-mode

参考 News: https://git.savannah.gnu.org/cgit/emacs.git/tree/etc/NEWS?h=emacs-29#n3235

这是我目前的设置:

我现在偷懒,继续使用tree-sitter mode,基本不需要自己配置。

我现在的做法是这一楼的最下面

遇到的一个问题是:在调用了 (treesit-ready-p xxx) 之后,Emacs 就会把加载的动态库文件锁定,如果之后想在 Emacs 里调用 (treesit-install-xxx) 更新相关的 parser 时会报错。必须关掉 Emacs 后再替换相关的动态库。

1 个赞