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-module
到 tree-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
,好复杂。。。。
难道要自己根据规则写高亮语法吗。有没有开箱即用的。给个工程根目录,自己去识别。然后写一下配置文件,添加第三方库,宏定义等等,类似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"))))
Elijah
14
试试这个包
(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-compile
和 tree-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
的设置:
emacs -Q + 最小配置才能说明问题。
你前面贴的看起来是从一个大配置中摘录了一小部分,无法判断这部分之外还有其他什么操作、会产生什么影响,例如以下这句用的变量来自第三方的 tree-sitter
包,但是却没有声明:
如果需要额外手动设置 major-mode-remap-alist
,说明 treesit-auto
根本没生效。
你可以观察 treesit-auto--ready-p
或 treesit-ready-p
的返回值,只有当它返回 t
的时候 treesit-auto
才会起作用。
以下是一份带调试输出的最小配置:(请酌情修改)
(setq user-emacs-directory "~/.emacs.d/")
(setq package-user-dir (format "~/.emacs.d/%s.%s/elpa/"
emacs-major-version emacs-minor-version))
(package-initialize)
(require 'use-package)
(advice-add 'treesit-auto--ready-p :around
(defun treesit-auto--ready-p@debug (orig-fn mode)
(let ((return (funcall orig-fn mode)))
(message "==> [treesit-auto--ready-p] mode: %s, return: (actual: %s, expected: t)" mode return)
return)))
(use-package treesit-auto
:config
(setq treesit-font-lock-level 4)
;; 为减少输出干扰, 去掉多余的定义
(setq treesit-auto-recipe-list
`(,(make-treesit-auto-recipe
:lang 'c
:ts-mode 'c-ts-mode
:remap 'c-mode
:url "https://github.com/tree-sitter/tree-sitter-c"
:ext "\\.c\\'")))
(global-treesit-auto-mode))
(add-hook 'emacs-startup-hook
(lambda ()
(view-echo-area-messages)
(find-file "/path/to/file.c")))
我试了一下, treesit-auto--ready-p
或 treesit-ready-p
的结果如下,是不是说明实际上treesit-auto
并未起作用,我把 treesit-auto
的配置删了,好像确实不影响。 这是为啥捏,我是通过melpa安装了呀。
目前有好几个问题,
- 我安装了
treesit-auto
为啥无效?看配置,好像就这几句话和 treesit-auto
相关。
- 按照你的意思,目前的语法渲染配色起效果 是
major-mode-remap-alist
起来的?也就是说把c-mode
转化成c-ts-mode
,tree-sitter
就起效果了?那我把 treesit-auto
删了,直接用这个就行。我只用C语言,这样会有问题吗?
- 基于1和2两点,
treesit-auto
不要行不行,后续我想变一下主题和语法,因为现在的颜色渲染太过单调了,局部变量,全局变量,宏定义,都是一个颜色。这个怎么配置。我看到别人的配置颜色好专业酷炫。
最后的我配置如下
;; 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))
;; 这句话最管用,一下子从白茫茫一片变好了.
(setq treesit-font-lock-level 4)
;; 4. 添加模式链接
(setq major-mode-remap-alist
'((c-mode . c-ts-mode)))
原因我在 #22 楼已经说了,也给了完整的验证代码。
不生效的直接原因是 treesit-auto--ready-p
何 treesit-ready-p
返回了 nil。返回 nil 的原因是无法找到 treesit 动态库文件。你应该把动态库文件放在 ~/.emacs.d/tree-sitter
,不要有下一级目录。