Skip to content

Commit ea2e1e4

Browse files
committed
feat(rust_analyzer): port config for neovim 0.11
1 parent 7955b7a commit ea2e1e4

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed

lsp/rust_analyzer.lua

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
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 = vim.lsp.get_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 vim.fs.relpath(item, fname) ~= nil then
29+
local clients = vim.lsp.get_clients { name = 'rust_analyzer' }
30+
return #clients > 0 and clients[#clients].config.root_dir or nil
31+
end
32+
end
33+
end
34+
35+
local commands = {
36+
{
37+
name = 'CargoReload',
38+
func = function()
39+
reload_workspace(0)
40+
end,
41+
{
42+
desc = 'Reload current cargo workspace',
43+
},
44+
},
45+
}
46+
47+
---https://github.com/rust-lang/rust-analyzer
48+
--
49+
-- rust-analyzer (aka rls 2.0), a language server for Rust
50+
--
51+
--
52+
-- See [docs](https://rust-analyzer.github.io/book/configuration.html) for extra settings. The settings can be used like this:
53+
-- ```lua
54+
-- vim.lsp.config('rust_analyzer', {
55+
-- settings = {
56+
-- ['rust-analyzer'] = {
57+
-- diagnostics = {
58+
-- enable = false;
59+
-- }
60+
-- }
61+
-- }
62+
-- })
63+
-- ```
64+
--
65+
-- Note: do not set `init_options` for this LS config, it will be automatically populated by the contents of settings["rust-analyzer"] per
66+
-- https://github.com/rust-lang/rust-analyzer/blob/eb5da56d839ae0a9e9f50774fa3eb78eb0964550/docs/dev/lsp-extensions.md?plain=1#L26.
67+
return {
68+
cmd = { 'rust-analyzer' },
69+
filetypes = { 'rust' },
70+
root_dir = function(bufnr, done_callback)
71+
local fname = vim.api.nvim_buf_get_name(bufnr)
72+
local reuse_active = is_library(fname)
73+
if reuse_active then
74+
return reuse_active
75+
end
76+
77+
local cargo_crate_dir = util.root_pattern 'Cargo.toml'(fname)
78+
79+
if cargo_crate_dir == nil then
80+
done_callback(
81+
util.root_pattern 'rust-project.json'(fname)
82+
or vim.fs.dirname(vim.fs.find('.git', { path = fname, upward = true })[1])
83+
)
84+
return
85+
end
86+
87+
local cmd = {
88+
'cargo',
89+
'metadata',
90+
'--no-deps',
91+
'--format-version',
92+
'1',
93+
'--manifest-path',
94+
cargo_crate_dir .. '/Cargo.toml',
95+
}
96+
97+
async.run_job(cmd, function(output)
98+
local cargo_workspace_root
99+
100+
if output and output[1] then
101+
output = vim.json.decode(table.concat(output, ''))
102+
if output['workspace_root'] then
103+
cargo_workspace_root = vim.fs.normalize(output['workspace_root'])
104+
end
105+
end
106+
107+
done_callback(
108+
cargo_workspace_root
109+
or cargo_crate_dir
110+
or util.root_pattern 'rust-project.json'(fname)
111+
or vim.fs.dirname(vim.fs.find('.git', { path = fname, upward = true })[1])
112+
)
113+
end)
114+
end,
115+
capabilities = {
116+
experimental = {
117+
serverStatusNotification = true,
118+
},
119+
},
120+
before_init = function(init_params, config)
121+
-- See https://github.com/rust-lang/rust-analyzer/blob/eb5da56d839ae0a9e9f50774fa3eb78eb0964550/docs/dev/lsp-extensions.md?plain=1#L26
122+
if config.settings and config.settings['rust-analyzer'] then
123+
init_params.initializationOptions = config.settings['rust-analyzer']
124+
end
125+
end,
126+
on_attach = function()
127+
util.register_commands(commands)
128+
end,
129+
}

0 commit comments

Comments
 (0)