基于tree-sitter的结构性编辑插件

grammatical-edit-jump-right这个函数,只能跳到本行尾就停止了,但是grammatical-edit-jump-left是可以一直向上跳的,这个是设计如此吗?为啥向后跳有这个限制呢?

找一个样本报issue吧,说不定是例外情况

发现在evil模式下,right的行为就是到本行尾就会停止,但切换到emacs模式后就正常,会向下一行跳转了; 奇怪的是left的行为就在evil模式下没问题;

这一个月的重构下来,tree-sitter 在一些复杂情况依然无法做到 100% 准确性,依然需要传统的parse-partial-sexp来分析当前光标处的类型。

比如:

  1. Golang语言中, `...` 风格的字符串内无法通过 tree-sitter cursor type 判定在字符串内
  2. Vue.js中,tree-sitter 认为 JavaScript 区域内所有字符串都属于 raw_text 类型,即使光标已经在字符串内

grammatical-edit 插件的编程实践看,必须结合 (tsc-node-type (tree-sitter-node-at-point))parse-partial-sexp 这两种技术才能100%应对各种编程语言的极端情况。

简单总结下来,tree-sitter 理论没问题,能很优雅的替换Emacs原来的regexp脏代码实现,但不是银弹。

2 个赞

语法层面(或者说结构化?)的处理都会面临这种特殊情况,最典型的应该是rust的宏。

为啥``风格的字符串不能判断呢? tree-sitter-go 的bug吗?

应该是吧,极限情况感觉还不是很准。

因为判断成字符串了? 很多时候其实是在 fields 后面加 tag

tree-sitter-langs 内置的 typescript.so 有问题,TypeScript语言的支持需要如下设置:

Make tree-sitter to support Typescript

1. git clone https://github.com/tree-sitter/tree-sitter-typescript.git
2. gcc ./tsx/src/parser.c ./tsx/src/scanner.cc -fPIC -I./ --shared -o typescript.so
3. cp ./typescript.so ~/.tree-sitter-langs/bin (~/.tree-sitter-langs/bin is path of your tree-sitter-langs repo)
(tree-sitter-load 'typescript "typescript")
(add-to-list 'tree-sitter-major-mode-language-alist '(typescript-mode . typescript))
1 个赞

今天修复了Wrap和Newline操作的一些小bug,建议大家更新一下。

3 个赞

这得看语言对应的 tree-sitter 实现的够不够细。细节总是要处理的,区别是放在 tree-sitter-lang 的代码里还是放在编辑器的代码里进行处理。
放在 tree-sitter-lang 做和 lsp 的情况差不多,一个通用的后端更有力于集中社区的精力。
所以某些功能适合直接向对应的 tree-sitter-lang 做贡献是最好的,仅仅在 emacs 里做没办法回馈整个语言社区。

1 个赞

语言细节直接写到代码中就行了,没必要分文件。

按道理这种语言细节应该越少越好,因为不会像原来正则那样差别那么大。

今天加了一个新的 向上跳到父节点的命令 grammatical-edit-jump-up

这个命令的应用场景是:

在一个非常大的Python class (比如上百行)中工作,正在编写里面的函数时,发现需要先跑到 class 的 init 函数去先声明一个属性才能继续编写函数,传统的做法是向上搜索 class 关键字或者瞄一下当前函数所属class名用 imenu 来跳转。

如果用 grammatical-edit-jump-up 命令就非常方便,不用看当前是什么class名,直接无脑的按这个命令,最多不超过3下就可以快速跳到 class 的定义位置。

这个命令最大的优点是心智负担非常低。

5 个赞

Emacs 29 内置的 treesit 的API名字和外面的 tree-sitter 还是非常不一样的, 而且能力更强。

所以, grammatical-edit 不再开发了, 相关代码已经移动到 GitHub - manateelazycat/fingertip: Fingertip is struct edit plugin that base on treesit , fingertip 是类似插件, 只不过基于 Emacs 内置的 treesit API.

5 个赞

猫大会迁移这个项目么:GitHub - manateelazycat/recursive-search-references: Find function references in directory

我所有关于 tree-sitter 的项目今天下午都迁移完成了:

grammatical-edit => fingertip , 这样保持兼容性, 两个包分别对应 tree-sitter 和 treesit

awesome-tray, find-orphan, recursive-search-references 全部都升级了。

tree-sitter 和 treesit 的每个API的名字都不一样, treesit 总体来说写代码简化了, 目前只是替换了名字, 功能应该都是一样的。

1 个赞

我前几天刚下来用了一下,发现是外部tree-sitter,刚翻进去看了一下,确实更新了,惊喜~

我一会儿去试下fingertip, 还没用过。

感谢 :grinning:

1 个赞

今天下午刚好有空, 研究了一下 treesit , 内置确实比较快, 而且 bug 少很多。

欢迎反馈升级后的问题。

2 个赞

我之前还尝试把recursive-search-references转成内部treesit,能力有限,半途而废了。 :crazy_face:

其实主要是 recursive-search-references-get-match-nodes, tree-sitter 的时候, 是我自己用 tsc-make-query、 tsc-root-node 和 tsc-query-captures 拼接来实现查找buffer中所有的规则节点。

treesit 中没有对应的等价API, 但是发现 treesit-query-range 配合 treesit-node-at 也可以, 更简单一点。

awesome-tray 和 find-orphan 也是同样的移植难点。