English | 简体中文
lsp-bridge 的目标是实现 Emacs 生态中性能最快的 LSP 客户端。
lsp-bridge 使用 Python 多线程技术在 Emacs 和 LSP 服务器之间构建高速缓存,在提供行云流水的代码补全体验的前提下,保证永远不会卡住 Emacs。
git clone
下载此仓库,并替换下面配置中的 load-path 路径(add-to-list 'load-path "<path-to-lsp-bridge>")
(require 'yasnippet)
(yas-global-mode 1)
(require 'lsp-bridge)
(global-lsp-bridge-mode)
lsp-bridge 开箱即用, 安装好语言对应的LSP 服务器和模式插件以后, 直接写代码即可, 不需要额外的设置。
需要注意的是 lsp-bridge 有三种扫描模式:
.git
目录时(通过命令 git rev-parse --is-inside-work-tree
来判断), lsp-bridge 会扫描整个目录文件来提供补全.git
目录时, lsp-bridge 只会对打开的文件提供单文件补全lsp-bridge-get-project-path-by-filepath
函数, 输入参数是打开文件的路径字符串, 输出参数是项目目录路径, lsp-bridge 会根据输出目录路径来提供补全按键 | 命令 | 备注 |
---|---|---|
Alt + n | acm-select-next | 选择下一个后选词 |
Down | acm-select-next | 选择下一个后选词 |
Alt + p | acm-select-prev | 选择上一个后选词 |
Up | acm-select-prev | 选择上一个后选词 |
Alt + . | acm-select-last | 选择最后一个后选词 |
Alt + , | acm-select-first | 选择第一个后选词 |
Ctrl + m | acm-complete | 完成补全 |
Return | acm-complete | 完成补全 |
Tab | acm-complete | 完成补全 |
Alt + h | acm-complete | 完成补全 |
Alt + H | acm-insert-common | 插入后选词共有部分 |
Alt + d | acm-doc-toggle | 开启或关闭后选词文档 |
Alt + j | acm-doc-scroll-up | 向下滚动后选词文档 |
Alt + k | acm-doc-scroll-down | 向上滚动后选词文档 |
Alt + l | acm-hide | 隐藏补全窗口 |
Ctrl + g | acm-hide | 隐藏补全窗口 |
数字键 | acm-complete-quick-access | 快速选择后选词, 需要开启 acm-enable-quick-access 选项 |
lsp-bridge-find-def
: 跳转到定义位置lsp-bridge-find-def-other-window
: 在其他窗口跳转到定义位置lsp-bridge-find-def-return
: 返回跳转之前的位置lsp-bridge-find-impl
: 跳转到接口实现位置lsp-bridge-find-impl-other-window
: 在其他窗口跳转到接口实现位置lsp-bridge-find-references
: 查看代码引用lsp-bridge-popup-documentation
: 查看光标处的文档lsp-bridge-popup-documentation-scroll-up
: 文档窗口向上滚动lsp-bridge-popup-documentation-scroll-down
: 文档窗口向下滚动lsp-bridge-rename
: 重命名lsp-bridge-diagnostic-jump-next
: 跳转到下一个诊断位置lsp-bridge-diagnostic-jump-prev
: 跳转到上一个诊断位置lsp-bridge-diagnostic-list
: 列出所有诊断信息lsp-bridge-diagnostic-ignore
: 插入注视忽略当前诊断lsp-bridge-workspace-list-symbols
: 列出工作区所有符号,并跳转到符号定义lsp-bridge-signature-help-fetch
: 在 minibuffer 显示参数信息lsp-bridge-popup-complete-menu
: 手动弹出补全菜单, 只有当打开 lsp-bridge-complete-manually
选项才需要使用这个命令lsp-bridge-restart-process
: 重启 lsp-bridge 进程 (一般只有开发者才需要这个功能)acm-insert-common
: 插入补全后选词的公共前缀acm-doc-scroll-up
: API 文档窗口向上滚动acm-doc-scroll-down
: API 文档窗口向下滚动lsp-bridge-python-command
: Python 命令的路径, 如果你用 conda
, 你也许会定制这个选项lsp-bridge-complete-manually
: 只有当用户手动调用 lsp-bridge-popup-complete-menu
命令的时候才弹出补全菜单, 默认关闭lsp-bridge-get-workspace-folder
: 在 Java 中需要把多个项目放到一个 Workspace 目录下, 才能正常进行定义跳转, 可以自定义这个函数, 函数输入是项目路径, 返回对应的 Workspace 目录lsp-bridge-c-lsp-server
: C 语言的服务器,可以选择clangd
或者ccls
lsp-bridge-python-lsp-server
: Python 语言的服务器,可以选择pyright
或者jedi
lsp-bridge-tex-lsp-server
: LaTeX 语言的服务器,可以选择texlab
或者digestif
lsp-bridge-org-babel-lang-list
: 支持 org-mode 代码块补全的语言列表lsp-bridge-enable-diagnostics
: 代码诊断, 默认打开lsp-bridge-enable-search-words
: 索引打开文件的单词, 默认打开lsp-bridge-enable-auto-format-code
: 自动格式化代码, 默认关闭lsp-bridge-enable-signature-help
: 支持函数参数显示, 默认打开lsp-bridge-enable-log
: 启用 LSP 消息日志, 默认关闭lsp-bridge-enable-debug
: 启用程序调试, 默认关闭lsp-bridge-disable-backup
: 禁止 emacs 对文件做版本管理, 默认打开lsp-bridge-diagnostic-fetch-idle
: 诊断延迟,默认是停止敲键盘后 0.5 秒开始拉取诊断信息lsp-bridge-signature-show-function
: 用于显示签名信息的函数lsp-bridge-completion-popup-predicates
: 补全菜单显示的检查函数, 这个选项包括的所有函数都检查过以后, 补全菜单才能显示lsp-bridge-completion-stop-commands
: 这些命令执行以后,不再弹出补全菜单lsp-bridge-completion-hide-characters
: 这些字符的后面不再弹出补全菜单acm-enable-doc
: 补全菜单是否显示帮助文档acm-enable-icon
: 补全菜单是否显示图标, macOS 用户需要给 brew 命令增加选项 --with-rsvg
来安装 Emacs 才能显示 SVG 图片acm-enable-tabnine
: 是否打开 tabnine 补全支持,默认打开,打开后需要运行命令 lsp-bridge-install-tabnine
来安装 tabnine 后就可以使用了。 TabNine 会消耗巨大的 CPU, 导致你整个电脑都卡顿, 如果电脑性能不好, 不建议开启此选项acm-enable-search-words
: 补全菜单是否显示打开文件的单词, 默认打开acm-enable-quick-access
: 是否在图标后面显示索引, 可以通过 Alt + Number 来快速选择后选词, 默认关闭acm-enable-yas
: yasnippet 补全,默认打开acm-enable-citre
: citre 补全,默认关闭acm-doc-frame-max-lines
: 帮助窗口的最大行数, 默认是 20acm-snippet-insert-index
: 代码模板候选词在补全菜单中的显示位置acm-candidate-match-function
: 补全菜单匹配算法, orderless-* 开头的算法需要额外安装 orderlessacm-backend-lsp-enable-auto-import
: 支持自动导入, 默认打开acm-backend-yas-candidates-number
: yasnippet 显示个数,默认 2 个acm-backend-citre-keyword-complete
: 根据acm-backend-citre-keywords-alist
定义的各个模式的关键字进行补全,需要使能 citre 后才生效lsp-bridge 每种语言的服务器配置存储在lsp-bridge/langserver.
大多数情况, 你可以根据以下优先级顺序来自定义服务器配置:
lsp-bridge-get-single-lang-server-by-project
: 用户自定义函数, 输入参数是 project-path
和 file-path
, 返回对应的 LSP 服务器字符串, 可以在 lsp-bridge-single-lang-server-mode-list
列表中查询所有 LSP 服务器的名称, 默认这个函数返回 nillsp-bridge-single-lang-server-extension-list
: 根据文件的扩展名来返回服务器,比如打开*.wxml 文件时,我们会使用 wxml
LSP 服务器提供补全lsp-bridge-single-lang-server-mode-list
: 根据 Emacs 的 major-mode 来返回对应的服务器如果你在编写 JavaScript 代码, 你可能需要自定义多服务器配置:
lsp-bridge-get-multi-lang-server-by-project
: 用户自定义函数, 输入参数是 project-path
和 file-path
, 返回多服务器配置名, 可以在子目录 lsp-bridge/multiserver 中查找lsp-bridge-multi-lang-server-extension-list
: 根据文件的扩展名来返回多服务器配置名, 比如打开*.vue 文件时,我们会使用 volar_emmet
来同时利用 volar
和 emmet-ls
两种 LSP 服务器提供补全lsp-bridge-multi-lang-server-mode-list
: 根据 Emacs 的 major-mode 来返回对应的多服务器配置名pyright.json
就是 pyright 服务器的配置文件 (windows 平台用pyright_windows.json
, macOS 平台用pyright_darwin.json
)。(mode . server_name)
到 lsp-bridge.el
文件中的 lsp-bridge-single-lang-server-mode-list
选项中, 比如 (python-mode . "pyright")
。lsp-bridge.el
文件中的 lsp-bridge-default-mode-hooks
选项中。lsp-bridge.el
文件中的 lsp-bridge-formatting-indent-alist
选项中。欢迎发送补丁帮助我们支持更多的 LSP 服务器,感谢你的帮助!
你需要安装每个编程语言对应的 LSP 服务器, lsp-bridge 才能提供代码补全服务。
序号 | LSP 服务器 | 语言 | 备注 |
---|---|---|---|
1 | clangd | c, c++, object-c | |
2 | pyright | python | pip install pyright |
3 | solargraph | ruby | |
4 | rust-analyzer | rust | |
5 | elixirLS | elixir | 请确保导出 elixir-ls 目录到你系统的 PATH 路径 |
6 | gopls | go | 确保安装 go-mode, 同时确保 gopls 在 PATH 环境变量中, 执行命令 ln -s ~/go/bin/gopls ~/.local/bin , 还要在补全之前执行 go mod init 命令 |
7 | hls | haskell | |
8 | dart-analysis-server | dart | |
9 | metals | scala | |
10 | typescript | typescript, javascript | |
11 | ocamllsp | ocaml | |
12 | erlang-ls | erlang | |
13 | texlab | latex | |
14 | eclipse.jdt.ls | java | 请确保导出 org.eclipse.jdt.ls.product/target/repository/bin 到你系统的 PATH 路径 |
15 | clojure-lsp | clojure | 如果使用 homebrew 安装的,请确保安装的是 clojure-lsp/brew/clojure-lsp-native clojure-lsp-native |
16 | bash-language-server | bash | |
17 | volar | vue | npm install typescript volar -g |
18 | sumneko | lua | 请确保导出 sumneko 的 bin 目录到你系统的 PATH 路径 |
19 | wxml-language-server | wxml | |
20 | vscode-html-language-server | html | |
21 | vscode-css-language-server | css | |
22 | elm-language-server | elm | |
23 | intelephense | php | |
24 | yaml-language-server | yaml | npm install -g yaml-language-server |
25 | zls | zig | 运行 zls config 来生成 zls 的配置。参考 Configuration Options |
26 | groovy-language-server | groovy | 在 PATH 中创建一个名为 "groovy-language-server" 的脚本, 内容为 $JAVA_HOME/bin/java -jar <path>/groovy-language-server-all.jar |
27 | docker-language-server | Dockerfiles | |
28 | serve-d | d | serve-d 不支持单文件模式, 使用前请先在项目目录下初始 git 仓库或者自定义 lsp-bridge-get-project-path-by-filepath 返回项目目录 |
29 | fortls | Fortran | |
30 | ccls | c, c++, object-c | lsp-bridge-c-lsp-server 设置成 ccls |
31 | jedi | python | lsp-bridge-python-lsp-server 设置成 jedi |
32 | emmet-ls | html, js, css, sass, scss, less | |
33 | rnix-lsp | nix | |
34 | digestif | latex | lsp-bridge-tex-lsp-server 设置成 digestif |
35 | rlanguageserver | R | |
36 | graphql-lsp | GraphQL | |
37 | microsoft-python-language-server | Python | 支持 Python2 的 lsp |
38 | cmake-language-server | cmake | pip install cmake-language-server |
39 | Wen | org-mode | pip install pygls pypinyin |
40 | sourcekit-lsp | swift | Sourcekit-lsp 包含在 swift toolchain 中。 |
41 | omnisharp | c# | OmniSharp dotnet 平台的 lsp. 使用 M-x lsp-bridge-install-omnisharp 安装 |
lsp-bridge 的目标是实现 Emacs 生态中性能最快的 LSP 客户端, 但不是实现 LSP 协议最全的 LSP 客户端。
下面的功能用 Emacs 现有生态做更好:
lsp-bridge-find-references
来查看代码引用。下图是 lsp-bridge 的架构设计:
下面是 lsp-bridge 项目的目录结构:
文件名 | 作用 |
---|---|
lsp-bridge.el | lsp-bridge 的 Elisp 主逻辑部分,提供自定义选项和 Elisp 函数供 python 子进程调用,比如代码跳转、重命名等 |
lsp-bridge-epc.el | 和 lsp-bridge python 子进程通讯的代码,主要实现 Elisp IPC 来对接 Python EPC, 实现数据序列化、发送、接收和反序列化 |
lsp-bridge-ref.el | 代码引用查看框架,提供引用查看、批量重命名、引用结果正则过滤等,核心代码 fork 自 color-rg.el |
lsp-bridge-jdtls.el | 提供 Java 语言第三方库跳转功能 |
lsp-bridge-lsp-installer.el | 安装 TabNine 和 Omnisharp |
lsp-bridge.py | lsp-bridge 的 Python 主逻辑部分,提供事件循环、消息调度和状态管理 |
acm/acm.el | 异步补全菜单, 专门为 lsp-bridge 后端而设计, 支持 lsp, elisp, words, TabNine 等后端 |
core/fileaction.py | 主要记录每个文件状态,处理 LSP 响应消息,调用 Emacs Elisp 函数 |
core/lspserver.py | LSP 消息处理模块,主要是解析、发送和接受 LSP 消息,并保证 LSP 请求顺序符合 LSP 协议规范 |
core/utils.py | 一些全局工具函数,方便各模块调用 |
core/mergedeep.py | JSON 信息合并, 主要用于发送自定义选项给 LSP 服务器 |
core/hanlder/ | LSP 消息发送和接受的实现,其中 init.py 是基类 |
langserver | 主要放置 LSP 服务器的配置,每一个服务器一个 json 文件,分别定义服务器的名称、语言 ID、启动命令和设置选项等 |
请先阅读下面的文章:
接着打开开发选项 lsp-bridge-enable-log
, happy hacking!
请用命令 emacs -q
并只添加 lsp-bridge 配置做一个对比测试,如果 emacs -q
可以正常工作,请检查你个人的配置文件。
如果emacs -q
环境下问题依旧,请到这里反馈, 并附带 *lsp-bridge*
窗口的内容给我们提交 issue,那里面有很多线索可以帮助我们排查问题。。
如果你遇到崩溃的问题, 请用下面的方式来收集崩溃信息:
(setq lsp-bridge-enable-debug t)
lsp-bridge-stop-process
停止 LSP-BRIDGE 进程*lsp-bridge*
的内容此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。