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

跳不过去说不定是我上面这个漏消息的问题,等我更新后再测试一下吧, 说不定是马上就可以跳转了呢。

现在各个 LSP Server 返回的消息并不规范,这个补丁主要在解析当前消息的时候,顺便检查一下末尾有没有 Content-Length 的字样,避免错过下一条消息,修复了 rename 要刷两边才能生效的问题。

我在 tsserver.js 的源文件内打印了下错误的message,发现它接收到的消息是错位的:

--- Recv message
{
   "seq": 0,
   "type": "response",
   "command": "unknown",
   "request_seq": 0,
   "success": false,
   "message": "Error processing request. Unexpected token C in JSON at position 0\nContent-Length: 208"
}

{
   "seq": 0,
   "type": "response",
   "command": "unknown",
   "request_seq": 0,
   "success": false,
   "message": "Error processing request. Unexpected token C in JSON at position 291\n{\"jsonrpc\":\"2.0\",\"method\":\"textDocument/didChange\",\"params\":{\"textDocument\":{\"uri\":\"file:///media/psf/Home/Documents/JadeStrong/volar-starter/src/main.ts\",\"version\":5},\"contentChanges\":[{\"range\":{\"start\":{\"line\":1,\"character\":9},\"end\":{\"line\":1,\"character\":9}},\"rangeLength\":0,\"text\":\"l\"}]}}Content-Length: 293"
}

我摘了两条,它第一条只收到了 Content-Length ,然后后面的收到的是内容和下一条的 Content-Length

linux kernel源码也是 tab 缩进 :joy_cat:

附上我最喜欢的名人警句之一: :dog:

  1. Indentation

Tabs are 8 characters, and thus indentations are also 8 characters. There are heretic movements that try to make indentations 4 (or even 2!) characters deep, and that is akin to trying to define the value of PI to be 3.

先来张 lsp-bridge 的架构图,方便大家理解,稍后我会写一篇文章详细讲解 lsp-bridge 的实现细节。

36 个赞

ot一下,这个图看起来很漂亮,是用什么软件制作的? :grin:

Google Docs.

1 个赞

LSP-Brige架构设计与LSP协议解析

手把手教大家LSP的协议实现细节,欢迎各位大佬加入我们的开发。

lsp-bridge发布的短短几天,已经有15位开发者加入我们的团队,贡献16种编程语言的语法补全代码,包括Java、 C、 C++、 Python、 Golang、 Rust、 Ruby、 Haskell、 Elixir、 Dart、 SCala、TypeScript、 JavaScript、 OCaml、 Erlang、 LaTeX等语言。

目前已完成的功能包括代码语法补全、定义跳转、引用查看和重命名, 欢迎加入我们开发更多的高级功能。

持续给lsp-bridge做贡献的理由是我们可以保证永远不卡Emacs, 实现行云流水的编程体验, 哈哈哈哈。

6 个赞

大佬可以继续支持company吗?我的所有补全都是用的company,实在不愿意在corfu下再折腾一遍了。。。

关键 company 很难折腾呀,我也没时间呀。

懒猫之前说过,真正的高手编程都是不用补全的 :innocent:

你说的这个问题已经修复了 Rewrite the JSON message analysis code. · manateelazycat/lsp-bridge@a8a841b · GitHub

1 个赞

请问如果开启auto-save插件,在等待补全返回的过程中如果文件自动保存了。是不是补全消息就丢了?

我这边碰到个奇怪的问题,auto-save-idle使用默认的1, js文件补全会出现混乱,如果关闭或者我尝试设置auto-save-idle=3时,补全是正常的。

我一直在用我自己的 auto-save, 没有出现你说的问题呀,你用的 auto-save 是哪一个?

已经针对 vue3 添加了 volar 后端支持。

volar 这玩意返回补全参数几万行几万行的返回,我稍后去掉它发送文档的功能,看看能否提升性能?

volar 应该是最耗性能的后端,压力测试了一下 lsp-bridge, 后端暴慢的时候, lsp-bridge 不会有任何卡顿,最多弹出菜单的时间稍微久一点,性能和VSCode的表现是一样的。

4 个赞

迁移到 corfu 吧,你不会失望的,我之前也是 company , 迁移就花了半个小时。

corfu 基本上是开箱即用,没有 company 那么折腾。

最新版已经考虑major-mode、扩展名、项目根目录和操作系统平台四个维度的优先级:

  1. 第一优先级, 按项目根目录来判断选择哪个server或者自定义的JSON文件,注意需要自定义 lsp-bridge-get-lang-server-by-project 这个函数, 这个函数接受两个参数: 当前文件所属的项目根目录和文件路径,注意如果一个文件是单文件,没在git目录下,第一个参数也是文件路径

  2. 第二优先级, 按文件后缀来判断, 需要自定义 lsp-bridge-lang-server-extension-list 选项, 比如文件 a.vue 虽然是 web-mode, 但是 lsp-bridge-lang-server-extension-list 的优先级比 lsp-bridge-lang-server-mode-list 高,会使用 volar 后端,而不是 javascript 后端

  3. 第三优先级, 按照 lsp-bridge-lang-server-mode-list 的匹配规则来判定

对于大家的使用来说:

  1. 如果要根据项目的子路径来做自动化配置,请自定义 lsp-bridge-get-lang-server-by-project 函数
  2. 如果要针对相同 major-mode 但是不同扩展名的文件配置不同的 lsp server, 定制 lsp-bridge-lang-server-extension-list

贡献新 lsp server 分支的同学注意, langserver 做了不同平台的区分,比如Linux平台用 pyright.json , Windows平台用 pyright_nt.json, 这样各个平台的差异化都可以随意定制JSON文件即可。

修了(甚至照着 LSP 标准按 UTF-16 来算 offset

2 个赞

发现将typescript.serverPath改为tsserverlibrary.js(我本地的老的lsp-mode里的lsp-volar是这么干的,github上最新的已经是tsserver.js),volar on lsp-bridge就可以正常工作。

但是它返回的是如下的玩意,也没看到lsp-mode里是怎么处理targetUri的。是LocationLink

[Trace - 08:38:23 上午] Received response 'textDocument/definition - (19)' in 12ms.
Result: [
  {
    "targetUri": "file:///c%3A/Users/wsw/repos/emacs-application-framework/app/git/src/components/Main.vue",
    "targetRange": {
      "start": {
        "line": 59,
        "character": 1
      },
      "end": {
        "line": 210,
        "character": 2
      }
    },
    "targetSelectionRange": {
      "start": {
        "line": 59,
        "character": 1
      },
      "end": {
        "line": 210,
        "character": 2
      }
    },
    "originSelectionRange": {
      "start": {
        "line": 7,
        "character": 8
      },
      "end": {
        "line": 7,
        "character": 12
      }
    }
  }
]

大佬nb。

不知道要是有反过来操作,如find-def返回的row/column,lsp-bridge移动位置是不是也需要修改。