又有人给emacs开发了一个lsp客户端

你这个问题我以前也提到过。

我现在配置文件基本是这样的:

;; misc.el
(definitfun foo
  :pre
  (progn ...)
  :post
  (progn ...))

解析的时侯原地展开为:

;; misc.el
(defun misc--pre-init-foo ()
  (progn ...))

(defun misc--post-init-foo ()
  (progn ...))

这两个函数仍然在 misc.el 文件中,所以 describe-function 可以跳到 misc.el 文件头。如果我再实现一个跨行匹配 (definitfun pkg\n :pre 的方法,就能准确跳到 :pre 的位置。

然而实际上我并没有实现那个跳转方法(暂时没这个需求),而是给 imenu regex 加了一条规则用来定位整个 (definitfun pkg ...)

1 个赞

比如cquery的lsp-cquery-enable, 用describe-function可以打开cquery.el文件, 光标在文件开头, 具体定义还要自己找, 甚至看很多代码

对, 试了一下lsp-cquery-enable, 是跳到cquery.el文件开头, 但这还不够啊, 还要看很多代码才行

看了一下, 就是这个情况, 就是感觉这个不方便. 特别是跟踪调试的时候, 想起以前有一个c语言用宏实现的hash table, 虽然可能效率很高, 但是调试太麻烦了, 也很难看懂, 要么就展开再调试, 感觉麻烦

lsp-mode 的做法是更进一步,它把整个函数的实现都放在另一个宏里面,无数个 lsp-<language>-enable 都对应这同一块代码。我上边的例子,函数的主体其实还在声明的这一端,比较有存在感。

然而 eglot 项目也不是为了解决这个问题而成立的。作者只是想用一个统一的 eglot 函数作为入口,而非每一种语言对应一个 eglot-<language>。把整个函数的实现放在另一个宏里面,目前的代码里已经有了,以后随着项目越来越完善,这种情况只会更多:

其实调试不必纠结 lsp-<language>-enable 能不能定位到,直接看它后边的函数 lsp--enable-stdio-client。把它看作跟 eglot 一样,是统一的入口。lsp-<language>-enablelsp--enable-stdio-client 之间几乎只是参数传递。

那么问题来了,那个更好呢?

现在貌似lsp-mode比较流行 一 点

eglot 绝对比 lsp-mode 好用

lsp-mode 一旦 Kill buffer 就会导致各种报错, eglot 可以保持后台重新连接, 没有各种奇怪的报错.

eglot 的作者写出的代码开箱即用, 插件要看实际运行的效果, 而不是只看代码本身, 如果代码写的再好, 但是用户体验和质量做的一团糟, 我想没人想敲几个字符就 backtrace 吧?

既然大神如此推荐,我也去试试eglot,哈哈

lsp-mode 有imenu,find-references之类的功能。imenu index的支持对js开发者简直是福音。不过希望大神提出的这些问题lsp-mode能够早日解决吧。

https://github.com/emacs-lsp/lsp-mode/blob/master/lsp-methods.el#L877

(add-hook 'kill-buffer-hook #'lsp--text-document-did-close nil t)

kill-buffer會發送當前document的textDocument/didClose notification,solargraph (Ruby language server)在這種情況下會斷線?

还没有深入研究, kill-buffer 会导致 solargraph 的端口被占用, 因为 lsp-ruby 是写死端口号的.

應該用 stdin/stdout,stdin/stdout用fifo (emacs)

都不怎么滴,没nvim好用。我全都测过。同一份代码。nvim瞬间补全,而且我看过cquery cpu,触发补全时,cpu非常低。用emacs时,cpu就会非常高,而且持续好几秒,最终的表现就是补全速度非常慢。估计是发消息太太太频繁了。不如nvim客户端优化的好。

lcn cpu最低10%,eglot其次30%。lsp mode最高,能达到70%。 所以补全速度的体验也是天壤之别。有空我👆个图,让大家看看

来上图看看了

最新版的 lsp-ruby 已经修复了这个问题, 不会因为 kill-buffer 导致端口被占用的问题

最好做成一键执行的脚本,让任何人都可以重现,然后提给 lsp-mode。

1 个赞

cquery有个参数,可以指定log文件,把客户端的请求记录到log里。可以打开这个参数,然后比较几个客户端发的请求

預設移動會觸發textDocument/documentHighlight textDocument/hover。ccls/cquery中修改textDocument/didChange)會觸發textDocument/publishDiagnostics

ccls可以設置diagnostics.onChange: false

(setq ccls-extra-init-params '(:diagnostics (:onChange :json-false)))關掉change 時diagnostics

另外https://github.com/emacs-lsp/lsp-mode/issues/210報告native json parser使用體驗也行。