Skip to content

Commit 6a75247

Browse files
committed
feat(rust_analyzer): port config for neovim 0.11
1 parent 4efb9b0 commit 6a75247

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed

lsp/rust_analyzer.lua

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
local util = require 'lspconfig.util'
2+
local async = require 'lspconfig.async'
3+
4+
local function reload_workspace(bufnr)
5+
bufnr = util.validate_bufnr(bufnr)
6+
local clients = util.get_lsp_clients { bufnr = bufnr, name = 'rust_analyzer' }
7+
for _, client in ipairs(clients) do
8+
vim.notify 'Reloading Cargo Workspace'
9+
client.request('rust-analyzer/reloadWorkspace', nil, function(err)
10+
if err then
11+
error(tostring(err))
12+
end
13+
vim.notify 'Cargo workspace reloaded'
14+
end, 0)
15+
end
16+
end
17+
18+
local function is_library(fname)
19+
local user_home = vim.fs.normalize(vim.env.HOME)
20+
local cargo_home = os.getenv 'CARGO_HOME' or user_home .. '/.cargo'
21+
local registry = cargo_home .. '/registry/src'
22+
local git_registry = cargo_home .. '/git/checkouts'
23+
24+
local rustup_home = os.getenv 'RUSTUP_HOME' or user_home .. '/.rustup'
25+
local toolchains = rustup_home .. '/toolchains'
26+
27+
for _, item in ipairs { toolchains, registry, git_registry } do
28+
if util.path.is_descendant(item, fname) then
29+
local clients = util.get_lsp_clients { name = 'rust_analyzer' }
30+
return #clients > 0 and clients[#clients].config.root_dir or nil
31+
end
32+
end
33+
end
34+
35+
---@brief
36+
---
37+
---https://github.com/rust-lang/rust-analyzer
38+
--
39+
-- rust-analyzer (aka rls 2.0), a language server for Rust
40+
--
41+
--
42+
-- See [docs](https://rust-analyzer.github.io/book/configuration.html) for extra settings. The settings can be used like this:
43+
-- ```lua
44+
-- vim.lsp.config('rust_analyzer', {
45+
-- settings = {
46+
-- ['rust-analyzer'] = {
47+
-- diagnostics = {
48+
-- enable = false;
49+
-- }
50+
-- }
51+
-- }
52+
-- })
53+
-- ```
54+
--
55+
-- Note: do not set `init_options` for this LS config, it will be automatically populated by the contents of settings["rust-analyzer"] per
56+
-- https://github.com/rust-lang/rust-analyzer/blob/eb5da56d839ae0a9e9f50774fa3eb78eb0964550/docs/dev/lsp-extensions.md?plain=1#L26.
57+
return {
58+
cmd = { 'rust-analyzer' },
59+
filetypes = { 'rust' },
60+
root_dir = function(bufnr, done_callback)
61+
local fname = vim.api.nvim_buf_get_name(bufnr)
62+
local reuse_active = is_library(fname)
63+
if reuse_active then
64+
return reuse_active
65+
end
66+
67+
local cargo_crate_dir = util.root_pattern 'Cargo.toml'(fname)
68+
local cargo_workspace_root
69+
70+
if cargo_crate_dir == nil then
71+
done_callback(
72+
util.root_pattern 'rust-project.json'(fname)
73+
or vim.fs.dirname(vim.fs.find('.git', { path = fname, upward = true })[1])
74+
)
75+
end
76+
77+
local cmd = {
78+
'cargo',
79+
'metadata',
80+
'--no-deps',
81+
'--format-version',
82+
'1',
83+
'--manifest-path',
84+
cargo_crate_dir .. '/Cargo.toml',
85+
}
86+
87+
async.run_job(cmd, function(result)
88+
if result and result[1] then
89+
result = vim.json.decode(table.concat(result, ''))
90+
if result['workspace_root'] then
91+
cargo_workspace_root = vim.fs.normalize(result['workspace_root'])
92+
end
93+
end
94+
95+
done_callback(cargo_workspace_root or cargo_crate_dir)
96+
end)
97+
end,
98+
capabilities = {
99+
experimental = {
100+
serverStatusNotification = true,
101+
},
102+
},
103+
before_init = function(init_params, config)
104+
-- See https://github.com/rust-lang/rust-analyzer/blob/eb5da56d839ae0a9e9f50774fa3eb78eb0964550/docs/dev/lsp-extensions.md?plain=1#L26
105+
if config.settings and config.settings['rust-analyzer'] then
106+
init_params.initializationOptions = config.settings['rust-analyzer']
107+
end
108+
end,
109+
on_attach = function()
110+
vim.api.nvim_buf_create_user_command(0, 'CargoReload', function()
111+
reload_workspace(0)
112+
end, { desc = 'Reload current cargo workspace' })
113+
end,
114+
}

0 commit comments

Comments
 (0)