lsp-bridge -- 速度最快的语法补全插件

我的不是clang,我是java的jdtls

你别急啊,我这是个hack,真实原因要等大佬确认一下 :joy_cat: 。万一别的地方崩了就不好了,只是想给大佬更多信息 @manateelazycat 大佬麻烦看一下,应该是 insertText 的逻辑 python 和 lisp 没配合好,相当于 java 和 clang 都复现了现在

我一直都在用 corfu-complete, 而不是 corfu-insert, 我现在正在看社区大佬的PR。

每个语言服务器的返回值都不一样, 现在补全插入的优先级顺序是: textEdit → insertText → label

现在的逻辑是 textEdit 和 insertText 逻辑混用了。

感谢。btw,我 company 和 corfu 都复现了

分享一下和 lsp-mode 配合的情况:目前体验是95分,有一些小小问题不太影响工作流(我也没时间排查),company可以直接用,corfu要简单hack一些细节。

我的做法是: advice 函数 lsp 让本项目在 lsp 返回后自动调用 (lsp-bridge-mode 1)

这样就可以提升 lsp-mode 的补全体验,还保留原来的其它功能。

附图:

你这样不行的, lsp-bridge 是 push 机制, 不管是 company 还是 corfu , lsp-bridge 都是调用他们手动补全的功能, lsp-mode 默认是自动补全的,这样混用会导致 company 一直在用缓存的补全(也就是你弹出菜单那一瞬间),你的补全信息是不完全的。

不会啊,我理解调用 (lsp-bridge-mode 1) 时,因为我设置的在 lsp 后调用,所以本项目的 completion-at-point-functions 就覆盖了 lsp-mode 的,并且因为有 (setq-local company-idle-delay nil)lsp-mode 的 company 基本可以认为已经阵亡了?(我理解错了?)

我 corfu 版的用得应该就更好了,因为我直接buffer local地disable了 lsp-mode 的补全功能以及 company-mode 本身。

其实如果 company 我理解的是错的,至少简单 advice 一下补全用 corfu 的方案应该还不错吧?


edit:

又想了一下,是不是无脑 disable 掉 lsp-mode 的补全功能就肯定不会有问题了?

对呀,如果你要混合用,你应该完全禁用 lsp-mode 的补全功能,而不是写 advice

不不不,你理解错了,我的advice就是打开文件执行一次,淦掉 lsp-mode 的补全,不是 advice 它的补全。当然不 advice 用 hook 也行了,我只是刚开始试这个项目时,advice 了 lsp 的黑名单,后来发现是多余的,但后来就懒得改成hook了。

总之,配合 lsp-mode 我这边体验挺好的就是了

混用的缺点是会启动两个服务器,一个 lsp-bridge 的, 一个lsp-mode 的,内存双倍

我的 rust-analyzer completion 一直返回 null,其他通信看起来又是正常的,换 rls 补全也是正常的。

--- Send (42797): textDocument/completion
{
   "id": 42797,
   "method": "textDocument/completion",
   "params": {
      "position": {
         "line": 3,
         "character": 5
      },
      "context": {
         "triggerKind": 1
      },
      "textDocument": {
         "uri": "file:///x%3A/Projects/Rust/hello_world.rs"
      }
   },
   "jsonrpc": "2.0"
}

--- Recv response (42797): textDocument/completion
{
   "jsonrpc": "2.0",
   "id": 42797,
   "result": null
}

通信里面, initilize->initilized->didChangeConfiguration->didOpen 都是正常的,我看 eglot 和 vscode, 好像服务器会发个 registCapabality 还是什么的,我这没看见,有人有能补全的 rust-analyzer, 看下 log 么。

1 个赞

可以看看 lsp-mode 或者 elogt 的 init 参数是什么? 我怀疑 lsp-bridge 里 rust 的服务器配置不对

特别特别长一串。。。 但是全部放在 initilize 里面。didChangeConfiguration 请求的 settings 也是空。我晚上有空抄过去试试。

这个补丁已经修复了,我分别在 Java、Python、 Vue 里面测试了,应该修复好了。

更新最新版即可。

Exception in thread Thread-2:
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.8/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "/home/zy/.emacs.d/repo/lsp-bridge/lsp-bridge.py", line 104, in event_dispatcher
    getattr(self, func_name)(*func_args)
  File "/home/zy/.emacs.d/repo/lsp-bridge/lsp-bridge.py", line 177, in _do
    self._open_file(filepath)  # _do is called inside event_loop, so we can block here.
  File "/home/zy/.emacs.d/repo/lsp-bridge/lsp-bridge.py", line 153, in _open_file
    lsp_server.attach(file_action)
  File "/home/zy/.emacs.d/repo/lsp-bridge/core/lspserver.py", line 214, in attach
    if is_in_path_dict(self.files, fa.filepath):
AttributeError: 'LspServer' object has no attribute 'files'

不知道哪个版本开始,没安装对应的服务器又会崩了

最近重构底层,这个防御被重构掉了,等我再看看。

启动参数是上图这个吗,没特别配置。 我说的补全情况如下图,本来有Apache Common 的StringUtils的,但是列表里只有jdk的信息。

  1. (setq lsp-bridge-enable-log t) 打开日志。
  2. (require 'lsp-bridge-jdtls) 确认一下有没有加载这个
  3. 查看一下 ~/.cache/lsp-bridge-jdtls/${projectname-hash}/jdtls.json 配置。
  4. 打开 *lsp-bridge* buffer 看一下项目导入是否成功。

正常应该会输出:

--- Recv notification: language/status
{
   "jsonrpc": "2.0",
   "method": "language/status",
   "params": {
      "type": "Starting",
      "message": "100% Starting Java Language Server - Refreshing '/project-name'."
   }
}
--- Recv notification: textDocument/publishDiagnostics
....
...
{
   "jsonrpc": "2.0",
   "method": "language/status",
   "params": {
      "type": "ServiceReady",
      "message": "ServiceReady"
   }
}

我这边是可以的,补个图

1 个赞

更新后重新配置了一下,已经可以了,谢谢。 前面用的版本还没lsp-bridge-jdtls,是启动失败了,lsp-bridgebuffer有报错,应该是没指定data参数导致的?

Invalid project description. Contains: OK Contains: /Users/freedomsky/Documents/Code/java/parser overlaps the workspace location: /Users/freedomsky/Documents/Code/java/parser/src/main/java/com/example/parser/util/workspace

是的, -data 必须要指定。 不然默认生成的workspace刚好在项目中的话,会导致项目导入失败。猜测是因为workspace里面生成的java文件导致的。