萌新求问关于tree-sitter的安装问题

最近摸索了一下tree-sitter这个东西,现在有两个问题。

  1. 我是emacs29.1 在melpa上面下载的tree-sitter是最终的吗,我看到有人说这个是emacs-tree-sitter/elisp-tree-sitter 不好用。我现在就是melpa安装,然后稍微配置一下:
    (require 'tree-sitter)
    (require 'tree-sitter-langs)

也发现很多染色问题,例如函数内部的局部变量显示就不好,根本没渲染成功。一些全局变量也没渲染,白色的。如下图:

  1. 如果现在tree-sitter官网这个才好用,那么这个怎么安装配置呀,需要重新编译emacs29吗?而且我看见有个tree-sitter-module的网站,里面要编译出一些动态链接文件。具体是怎么安装使用的呢?
1 个赞

应该没有,emacs自定义语法高亮的办法,我用过的有hi-lock-mode,不过这个是用正则,现在流行的应该是用tree-sitter

兄弟你好,最近摸索了一下tree-sitter这个东西,现在有两个问题,在主题上。帮忙看看啦。

Emacs 从 29开始自带了一个 tree-sitter 名为 treesit,作者之前也在本论坛,不需要另行安装,melpa 上的那个是另一个作者开发的……以后 Emacs 上treesitter 的未来大概率是自带的treesit,也推荐使用这个……

教程的话,可以试试我这个……

tree-sitter 的安装与使用 这个段落开始看

How to Get Started with Tree-Sitter - Mastering Emacs 这篇文章可能对你有帮助。
第一个问题: Emacs 29.1 自带 treesit 模块(如果编译的时候带 --with-tree-sitter 这个参数,当然包管理器安装的 Emacs 应该都带 treesit 模块吧)。所以你不要从 melpa 上使用 tree-sitter 这个库。
第二个问题: 运行 (info "(elisp) Language Grammar") 这条 elisp 代码,查看文档开头,知道编译出的动态链接文件应该放哪里。我是 ~/.emacs.d/tree-sitter 目录。我一般是克隆 tree-sitter-moduletree-sitter 目录下, 然后进入 tree-sitter-module,运行 ./batch 然后 cp ./dist/* ../ (把编译出来的 动态链接文件 复制到 tree-sitter 目录下。 这是我的 tree-sitter 目录结构

# pwd: ~/.emacs.d/tree-sitter
.
使用的 .so 文件
├── exclude
       一些不用的 .so 文件
└── tree-sitter-module
    └── dist
        编译出来的 .so 文件

此外的一些参考:

;; @ Automatically install and use tree-sitter major modes in Emacs 29+.
(use-package treesit-auto
	:hook (after-init . global-treesit-auto-mode)
  :config
  (setq treesit-auto-install nil))
(add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-ts-mode))

兄弟,我配置好了。

(treesit-language-available-p 'c)运行也是t了。

后续我的 C语言工程文件 怎么配置高亮之类的操作呀。

我看了下官网的Creating Parsers,好复杂。。。。

兄弟,我配置好了。

(treesit-language-available-p 'c)运行也是t了。

后续我的 C语言工程文件 怎么配置高亮之类的操作呀。

我看了下官网的Creating Parsers,好复杂。。。。

https://manateelazycat.github.io/2023/09/02/treesit/

看最下面的内容

:fearful:难道要自己根据规则写高亮语法吗。有没有开箱即用的。给个工程根目录,自己去识别。然后写一下配置文件,添加第三方库,宏定义等等,类似ccls这种。

又或者基于ctags?因为我现在看工程文件是用citre+ctags。

后面只要将 c-mode 替换成 c-ts-mode 就可以了……

(setq major-mode-remap-alist
	      '((c-mode . c-ts-mode)))

请仔细看文章底部配置内容,仅仅是下载,设置mode就好了

我的配置如下,但是结果还是白茫茫一片,么得效果呀。(按道理tree-sitter应该需要一个根目录吧)

也尝试 用treesit-install-language-grammar 安装了C语言,发现他生成一个.so文件覆盖了我别的地方生成的动态库。

(add-to-list 'treesit-extra-load-path "~/.emacs.d/tree-sitter/tree-sitter-module")

;;(add-to-list 'load-path "~/.emacs.d/tree-sitter/my-tree-sitter")
;;(require 'treesit-langs)

(setq major-mode-remap-alist
	  '((c-mode . c-ts-mode)))

(add-hook 'c-mode-hook #'(lambda () (treesit-parser-create 'c)))

(setq treesit-language-source-alist
      '((bash . ("https://github.com/tree-sitter/tree-sitter-bash"))
        (c . ("https://github.com/tree-sitter/tree-sitter-c"))
        (cpp . ("https://github.com/tree-sitter/tree-sitter-cpp"))))

:fearful:还是白茫茫一片么得效果,咋回事,配置如上面。

不过和原来相比,宏定义这里有颜色了。

试试这个包

(use-package treesit-auto
  :pin melpa
  :demand t
  :config
  (setq treesit-auto-install 'prompt)
  (global-treesit-auto-mode))

你可以开启比默认更多的高亮:

(setq treesit-font-lock-level 4)

虽然 Emacs 29 内置了 treesit,但你仍然可以使用第三方的 tree-sitter 包。

tree-sitter 的配置并不复杂。tree-sitter 甚至都不需要自己编译动态连接文件,只需要引入 tree-sitter-langs,它会从 Github 下载所有的预先编译好的动态链接文件。

如果预编译文件不兼容你现在的平台,可以通过 tree-sitter-langs-compiletree-sitter-langs-compile-changed-or-all 自行编译,跟内置的 treesit 一样方便。只要编译不出错就可以了,无须操心动态链接文件放在哪里。也用不到 tree-sitter-module,这个是配合 treesit 使用的。

如果你跟我一样还在使用旧的 Mac(例如 High Sierra),需要修改编译函数:

(advice-add 'tree-sitter-langs-install-grammars :override
 (lambda (&rest _) (warn "[@tree-sitter-langs-install-grammars] the prebuild binaries requires macOS 10.15 or newer.")))

(advice-add 'tree-sitter-langs--bundle-file :override
 (lambda (&rest _) (warn "[@tree-sitter-langs--bundle-file] the prebuild binaries requires macOS 10.15 or newer.")))

(psearch-patch tree-sitter-langs-compile
  (and
   ;; Build for old architacture
   (psearch-replace '`(setq target . ,_)
                    '`(setq target "x86_64-apple-darwin"))
   ;; Avoid the "tsc-lang-abi-too-new 14 (13 . 13)" issue
   (psearch-replace '`(tree-sitter-langs--call "tree-sitter" "generate")
                    '`(progn))))

另外附上我前几天为了测试 ts-fold 写的一份最小配置, 可以用它来检验是否正确:

;;; Usage: /path/to/emacs -Q -l /path/to/test-ts-fold.el
;;; Date: 2023-09-28_08.08.21
(toggle-debug-on-error)

;; ---------------------------------------------------------------------------
;; elpa

(require 'seq)

(setq user-emacs-directory
      (car (seq-filter
            #'file-exists-p
            (list (format "~/.emacs.d/%s/" emacs-version)
                  (format "~/.emacs.d/%s.%s/" emacs-major-version emacs-minor-version)
                  "~/.emacs.d/"))))

(setq package-user-dir (concat user-emacs-directory "elpa/"))

(package-initialize)

;; Add addtional local package here:
(add-to-list 'load-path "~/repos/emacs-ts-fold")
(add-to-list 'load-path "~/repos/emacs-fringe-helper")

;; ---------------------------------------------------------------------------

(require 'tree-sitter)
(require 'tree-sitter-langs)
(require 'ts-fold)
(require 'ts-fold-indicators)

(add-hook 'emacs-startup-hook
          (lambda ()
            (require 'yaml-mode)
            (find-file "~/Downloads/test-folding.yaml")
            (tree-sitter-mode 1)
            ;; (global-tree-sitter-mode 1)
            (ts-fold-indicators-mode 1)
            ;; (global-ts-fold-indicators-mode 1)
            ))

;;; test-ts-fold.el ends here

感谢,加上这句话解决了,(setq treesit-font-lock-level 4)

感谢,我用内置的解决了这个问题

问题解决了,最终我的配置如下:

;; 1. 编译emacs29.1  
;; 2. 添加动态模块
(add-to-list 'treesit-extra-load-path "~/.emacs.d/tree-sitter/tree-sitter-module")

;; 3. melpa 下载 tree-auto
(use-package treesit-auto
  :config
  (global-treesit-auto-mode)
  (add-hook 'tree-sitter-after-on-hook #'tree-sitter-hl-mode))
;; 这句话最管用,一下子从白茫茫一片变好了.
(setq treesit-font-lock-level 4)

;; 4. 添加模式链接
(setq major-mode-remap-alist
	  '((c-mode . c-ts-mode)))

最后这一句应该是不必要的,你这样一设置,反而覆盖了 treesit-auto 的设置:

去掉了,好像又变一片白茫茫了 :fearful: