Lsp-Copilot:Rust 版本的 lsp-bridge

一个学习Rust的项目,找了个感兴趣的方向才有学习的动力。整个思路都是学的 lsp-bridge ,只是换成了 jsonrpc.el 和 Rust ,使用 capf 补全,没能力写补全前端所以就尽量在Server端来优化响应速度了。

设计上就是 Emacs 尽管发请求,Server 端会起个队列比较新旧请求,如果可以复用,则取消对顶等待的请求,注册最新的请求,等待第一个请求处理完毕后复用结果直接返回,并缓存响应结果,如果继续有新的请求进来,且命中缓存则直接返回。

针对Lsp的返回结果,Server 会根据前缀进行过滤,实现上参考的 vscode-fuzzy ,返回前20条(当前是写死的20),并内部集成了 emacs-lsp-booster 对结果进行编码,最大可能的减少 Emacs 的负担。

目前只在 Mac 上使用过,以前端开发(vtsls、eslint、tailwindcss)为主,日常使用没有问题,配置上都是照着 helix 的实现来的,一般情况下可以照搬它的配置。

14 个赞

考慮用 dynamic module, 然後去掉 jsonrpc.el 嗎?

看过一些 rust dynamic module 的实现,不太用会就选了一种简单的方式,也研究过lspce, 那样和 lspce 是不是一样了, 不清楚 dynamic module 如果卡住会不会影响 Emacs ,目前这种分离的方式是对Emacs影响最小的了

哈哈哈, Emacs牛逼哇, 已经有5个 LSP Client 啦。

1 个赞

dynamic module 裏面應該可以用 tokio 起一個常駐的進程 (听說)

用dynamic module,如果是同步处理请求的方式,可能跟eglot差别不大(我是说性能方面,不考虑用emacs lsp booster的话);如果是异步的方式,估计就跟lspce差别不大了。但是异步方式有个问题是,因为server请求是在独立的线程里接收的,这个线程拿不到合法的env(反正我是没找到方法),所以没法直接调用elisp,就导致不好处理server的请求和通知。

我其实想过要不要把lspce改成类似你这种实现方式,但是没啥动力了,哈哈。

我现在期待mps垃圾回收分支能合到主分支,同时效果还不错,到时我觉得eglot在大多数情况下就足够用了。

对了,当时之所以开发lspce,一个原因是如果有大量的diagnostics(上百条甚至更多的时候),Emacs就会被卡的很慢。lspce目前是默认只返回30条诊断给Emacs,基本不会再卡Emacs。

1 个赞

还没试过大量的 diagnostics 的情况,有时候遇到多的时候 flycheck 会自动禁用,回头注意下看看

dynamic module 的核心的收益是啥呢,节省 jsonrpc 的通信开销么? 目前控制了补全的返回数,感觉在这个场景下 jsonrpc 倒不是问题,另外 lspce 大佬没解决的问题我估计也白给 :joy:

看到名字我以为和 ai 补全有关 :dog:

我覺得是可以降低延遲,還可以進一步減少對象數量。

有时间研究一下看看