Another way is without a plugin, and creating your own logic in your
configuration. The following code will work for any checkout of rust-lang/rust (newer than Febuary 2025):
```lua
local function expand_config_variables(option)
local var_placeholders = {
['${workspaceFolder}'] = function(_)
return vim.lsp.buf.list_workspace_folders()[1]
end,
}
if type(option) == "table" then
local mt = getmetatable(option)
local result = {}
for k, v in pairs(option) do
result[expand_config_variables(k)] = expand_config_variables(v)
end
return setmetatable(result, mt)
end
if type(option) ~= "string" then
return option
end
local ret = option
for key, fn in pairs(var_placeholders) do
ret = ret:gsub(key, fn)
end
return ret
end
lspconfig.rust_analyzer.setup {
root_dir = function()
local default = lspconfig.rust_analyzer.config_def.default_config.root_dir()
-- the default root detection uses the cargo workspace root.
-- but for rust-lang/rust, the standard library is in its own workspace.
-- use the git root instead.
local compiler_config = vim.fs.joinpath(default, "../src/bootstrap/defaults/config.compiler.toml")
if vim.fs.basename(default) == "library" and vim.uv.fs_stat(compiler_config) then
return vim.fs.dirname(default)
end
return default
end,
on_init = function(client)
local path = client.workspace_folders[1].name
local config = vim.fs.joinpath(path, "src/etc/rust_analyzer_zed.json")
if vim.uv.fs_stat(config) then
-- load rust-lang/rust settings
local file = io.open(config)
local json = vim.json.decode(file:read("*a"))
client.config.settings["rust-analyzer"] = expand_config_variables(json.lsp["rust-analyzer"].initialization_options)
client.notify("workspace/didChangeConfiguration", { settings = client.config.settings })
end
return true
end
}
```
If you would like to use the build task that is described above, you may either
make your own command in your config, or you can install a plugin such as
[overseer.nvim](https://github.com/stevearc/overseer.nvim) that can [read
VSCode's `task.json`
files](https://github.com/stevearc/overseer.nvim/blob/master/doc/guides.md#vs-code-tasks),
and follow the same instructions as above.
### Emacs
Emacs provides support for rust-analyzer with project-local configuration
through [Eglot](https://www.gnu.org/software/emacs/manual/html_node/eglot/).
Steps for setting up Eglot with rust-analyzer can be [found
here](https://rust-analyzer.github.io/manual.html#eglot).
Having set up Emacs & Eglot for Rust development in general, you can run
`./x setup editor` and select `emacs`, which will prompt you to create
`.dir-locals.el` with the recommended configuration for Eglot.
The recommended settings live at [`src/etc/rust_analyzer_eglot.el`].
For more information on project-specific Eglot configuration, consult [the
manual](https://www.gnu.org/software/emacs/manual/html_node/eglot/Project_002dspecific-configuration.html).
### Helix
Helix comes with built-in LSP and rust-analyzer support.
It can be configured through `languages.toml`, as described
[here](https://docs.helix-editor.com/languages.html).
You can run `./x setup editor` and select `helix`, which will prompt you to
create `languages.toml` with the recommended configuration for Helix. The
recommended settings live at [`src/etc/rust_analyzer_helix.toml`].
### Zed
Zed comes with built-in LSP and rust-analyzer support.
It can be configured through `.zed/settings.json`, as described
[here](https://zed.dev/docs/configuring-languages). Selecting `zed`
in `./x setup editor` will prompt you to create a `.zed/settings.json`
file which will configure Zed with the recommended configuration. The
recommended `rust-analyzer` settings live
at [`src/etc/rust_analyzer_zed.json`].