其实 typescript-language-server 没错,它返回的结果是完整结果,也就是 isIncomplete: false,即 this. 和 this.i 补全项相同。
可能目前大多数所用的 ls 返回结果都是 incomplete,所以 lsp-bridge 显示正常,因而鲜有人报 bug。而 lsp-mode/eglot 上有前端过滤,所以 isIncomplete 是啥也不影响用户。
我测试了几款 ls,情况如下:
| server | isIncomplete 值 | 实际结果集 | 结果符合预期 | lsp-bridge 显示 |
|---|---|---|---|---|
| pyright | True | incomplete | 符合✅ | 无多余的项 |
| pylsp | False | incomplete | 不符 | 无多余的项 |
| jedi | False | incomplete | 不符。可能传染给了 pylsp | 无多余的项 |
| gopls | True | incomplete | 符合✅ | 无多余的项 |
| rust-analyzer | True | complete | 不符 | 有多余的项🐞 |
| typescript-language-server | False | complete | 符合✅ | 有多余的项🐞 |
| solargraph | False | incomplete | 不符 | 无多余的项 |
所以我认为 lsp-bridge 也需要处理一下这个问题。
首先我试着在 completion.py 中过滤补全项,但是发现 lsp-bridge 会缓存上一次请求的结果,因此在 completion.py 中过滤会有漏网之虞:
- 输入
self.(所有补全项已缓存) - 按
C-g关闭补全菜单 - 按
i激活补全 此时lsp-bridge会先从缓存读取补全项(所有),然后再向 ls 发起请求,得到符合self.i的补全项。
所以改为在 acm/acm-backend-lsp.el:acm-backend-lsp-candidates 中过滤。
这是我的修改 (鉴于目前发现存在 language server 错误标识 isIncomplete 的情况,所以一律对补全项进行过滤): Filter lsp completion · twlz0ne/lsp-bridge@ac5b1ac · GitHub