Skip to content

Commit e2af226

Browse files
committed
feat(rust_analyzer): port config for neovim 0.11
1 parent db492ae commit e2af226

File tree

1 file changed

+126
-0
lines changed

1 file changed

+126
-0
lines changed

lsp/rust_analyzer.lua

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

0 commit comments

Comments
 (0)