#instance #cargo-workspace #rust-analyzer #lsp #editor #clients #multiple

bin+lib ra-multiplex

在多个 LSP 客户端之间共享一个 rust-analyzer 服务器实例以节省资源

14 个版本

0.2.5 2024 年 8 月 8 日
0.2.4 2024 年 5 月 15 日
0.2.3 2024 年 3 月 17 日
0.2.2 2023 年 5 月 2 日
0.1.7 2022 年 2 月 5 日

55文本编辑器

Download history 136/week @ 2024-05-12 42/week @ 2024-05-19 12/week @ 2024-05-26 10/week @ 2024-06-02 5/week @ 2024-06-09 1/week @ 2024-06-16 36/week @ 2024-07-07 7/week @ 2024-07-28 121/week @ 2024-08-04

每月 128 次下载

MIT 许可证

105KB
2.5K SLoC

ra-multiplex — 最新版本

rust-analyzer 提供的代理服务器,允许多个 LSP 客户端(编辑器窗口)在每个 cargo 工作区共享单个 rust-analyzer 实例。

工作原理

ra-multiplex 类似于 rust-analyzer,但仅连接到 127.0.0.1:27631 的 TCP 套接字,并通过它传递 stdin 和 stdout。

根据编辑器在初始化过程中提供的 workspaceFolders,它可以使用已经启动的 rust-analyzer 实例。

由于 LSP 和 rust-analyzer 本身都不支持每个服务器多个客户端,因此 ra-multiplex 会在握手过程中进行拦截,并修改请求和响应的 ID 以跟踪哪个响应属于哪个客户端。由于并非所有消息都可以以这种方式跟踪,因此它将丢弃一些,特别是它将丢弃来自服务器的任何请求,这在 neovim 中的 coc-rust-analyzer 中似乎没有问题,但可能因情况而异。

如果您有任何问题,欢迎在此仓库中提交问题。

如何使用

使用以下命令构建项目:

$ cargo build --release

以服务器模式运行 ra-multiplex,确保 rust-analyzer 在您的 PATH

$ which rust-analyzer
/home/user/.cargo/bin/rust-analyzer
$ target/release/ra-multiplex --help
share one rust-analyzer server instance between multiple LSP clients to save resources

Usage: ra-multiplex [COMMAND]

Commands:
  client  Connect to a ra-mux server [default]
  server  Start a ra-mux server
  status  Print server status
  reload  Reload workspace
  help    Print this message or the help of the given subcommand(s)

Options:
  -h, --help     Print help
  -V, --version  Print version

ra-multiplex 可以作为 systemd 用户服务运行,请参阅示例 ra-mux.service

将您的编辑器配置为使用 ra-multiplex 作为 rust-analyzer,例如在 neovim 的 CoC 中编辑 ~/.config/nvim/coc-settings.json,添加

{
    "rust-analyzer.serverPath": "/path/to/ra-multiplex"
}

如果你的编辑器可以通过TCP连接到语言服务器,你不需要使用ra-multiplex客户端,而是直接连接到服务器,但你需要提供与代理命令相同的信息。有关详细信息,请参阅neovim的示例配置

配置

配置存储在系统默认配置目录中的TOML文件中,例如~/.config/ra-multiplex/config.toml。如果你不确定系统中的位置,在没有配置文件的情况下启动ra-multiplex将打印出预期路径的通知。

请注意,配置文件可能不是必需的,并且ra-multiplex应该可以与所有默认值一起使用。

示例配置文件

# this is an example configuration file for ra-multiplex
#
# all configuration options here are set to their default value they'll have if
# they're not present in the file or if the config file is missing completely.

# time in seconds after which a rust-analyzer server instance with no clients
# connected will get killed to save system memory.
#
# you can set this option to `false` for infinite timeout
instance_timeout = 300 # after 5 minutes

# time in seconds how long to wait between the gc task checks for disconnected
# clients and possibly starts a timeout task. the value must be at least 1.
gc_interval = 10 # every 10 seconds

# ip address and port on which ra-multiplex-server listens
# or unix socket path on *nix operating systems
#
# the default "127.0.0.1" only allows connections from localhost which is
# preferred since the protocol doesn't worry about security.
# ra-multiplex server expects the filesystem structure and contents to be the
# same on its machine as on ra-multiplex's machine. if you want to run the
# server on a different computer it's theoretically possible but at least for
# now you're on your own.
#
# ports below 1024 will typically require root privileges and should be
# avoided, the default was picked at random, this only needs to change if
# another application happens to collide with ra-multiplex.
listen = ["127.0.0.1", 27631] # localhost & some random unprivileged port
# listen = "/var/run/ra-mux/ra-mux.sock" # unix socket

# ip address and port to which ra-multiplex will connect to
# or unix socket path on *nix operating systems
#
# this should usually just match the value of `listen`
connect = ["127.0.0.1", 27631] # same as `listen`
# connect = "/var/run/ra-mux/ra-mux.sock" # same as `listen`

# default log filters
#
# RUST_LOG env variable overrides this option, both use the same syntax which
# is documented in the `env_logger` documentation here:
# <https://docs.rs/env_logger/0.9.0/env_logger/index.html#enabling-logging>
log_filters = "info"

# environemnt variable names passed from `ra-multiplex client` to the server
#
# by default no variables are passed. and all servers are spawned in
# the same environment as the `ra-multiplex server` is. when a name like
# "LD_LIBRARY_PATH" is specifified the proxy reads the variable value from its
# environment and passes it to the server which then passes it on to the server
# executable.
#
# if "PATH" is specified here then the PATH from the client environment is
# going to be used for looking up a relative `--server-path`.
pass_environment = []

其他LSP服务器

默认情况下,ra-multiplex使用其$PATH中找到的rust-analyzer二进制文件作为服务器。可以使用客户端子命令的--server-path CLI选项或RA_MUX_SERVER环境变量来覆盖它。你通常可以在编辑器配置中配置其中之一。如果两者都指定了,CLI选项将覆盖环境变量。

例如,在neovim的CoC中使用coc-clangd,请将其添加到~/.config/nvim/coc-settings.json

{
    "clangd.path": "/home/user/.cargo/bin/ra-multiplex",
    "clangd.arguments": ["client", "--server-path", "/usr/bin/clangd"]
}

或者,在coc-rust-analyzer中设置rust-analyzer的自定义路径,请将其添加到~/.config/nvim/coc-settings.json

{
    "rust-analyzer.server.path": "/home/user/.cargo/bin/ra-multiplex",
    "rust-analyzer.server.extraEnv": { "RA_MUX_SERVER": "/custom/path/rust-analyzer" }
}

如果你的编辑器配置或插件不允许添加任何一项,你可以创建一个包装shell脚本并将其直接设置为服务器路径。例如,如果coc-clangd不允许传递额外的参数,你需要一个像/usr/local/bin/clangd-proxy这样的脚本

#!/bin/sh
RA_MUX_SERVER=/usr/bin/clangd exec /home/user/.cargo/bin/ra-multiplex client --server-path /usr/bin/clangd $@

然后配置编辑器在~/.config/nvim/coc-settings.json中使用包装脚本

{
    "clangd.path": "/usr/local/bin/clangd-proxy"
}

依赖关系

~10–21MB
~264K SLoC