Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 62 additions & 54 deletions src/building/suggested.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,77 +144,82 @@ If running `./x check` on save is inconvenient, in VS Code you can use a [Build

### Neovim

For Neovim users, there are a few options.
The easiest way is by using [neoconf.nvim](https://github.com/folke/neoconf.nvim/),
which allows for project-local configuration files with the native LSP.
The steps for how to use it are below.
Note that they require rust-analyzer to already be configured with Neovim.
Steps for this can be [found here](https://rust-analyzer.github.io/manual.html#nvim-lsp).
For Neovim users, there are a few options:

1. The easiest way is using [neoconf.nvim][neoconf.nvim] but it uses the
deprecated `require('lspconfig')` API which displays a warning on neovim 0.11+.
2. Using `coc.nvim` is another option but it requires node.js to be installed.
3. Using a custom script to load rust-analyzer settings.

#### neoconf.nvim

[neoconf.nvim][neoconf.nvim] allows for project-local configuration
files with the native LSP. The steps for how to use it are below. Note that they require
rust-analyzer to already be configured with Neovim. Steps for this can be
[found here][r-a nvim lsp].

1. First install the plugin.
This can be done by following the steps in the README.
2. Run `./x setup editor`, and select `vscode` to create a `.vscode/settings.json` file.
`neoconf` is able to read and update
rust-analyzer settings automatically when the project is opened when this file is detected.

#### coc.nvim

If you're using `coc.nvim`, you can run `./x setup editor` and select `vim` to
create a `.vim/coc-settings.json`.
The settings can be edited with `:CocLocalConfig`.
The recommended settings live at [`src/etc/rust_analyzer_settings.json`].

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 February 2025):
#### Custom LSP settings

If you're running neovim 0.11+, you can configure rust-analyzer with just
[nvim-lspconfig](https://github.com/neovim/nvim-lspconfig) and a custom script.

1. Make sure [rust-analyzer LSP][r-a nvim lsp] is set up
2. Create `$HOME/.config/nvim/after/plugged/rust_analyzer.lua` with the following content:

```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)
-- Capture the default functions from nvim-lspconfig/lsp/rust_analyzer.lua before overriding it.
-- This file is in after/plugin to guarantee nvim-lspconfig has been initialised already.
local default_root_dir = vim.lsp.config["rust_analyzer"].root_dir
local default_before_init = vim.lsp.config["rust_analyzer"].before_init

vim.lsp.config("rust_analyzer", {
cmd = { "rust-analyzer" },
filetypes = { "rust" },
-- To support rust-lang/rust, we need to detect when we're in the rust repo and use the git root
-- instead of cargo project root.
root_dir = function(bufnr, on_dir)
local git_root = vim.fs.root(bufnr, { ".git" })
if git_root then
if vim.uv.fs_stat(vim.fs.joinpath(git_root, "src/etc/rust_analyzer_zed.json")) then
on_dir(git_root)
return
end
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
-- For anything that doesn't match rust-lang/rust, fallback to default root_dir
default_root_dir(bufnr, on_dir)
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 })
before_init = function(init_params, config)
-- When inside rust-lang/rust, we need to use the special rust-analyzer settings.
local settings = vim.fs.joinpath(config.root_dir, "src/etc/rust_analyzer_zed.json")
if vim.uv.fs_stat(settings) then
local file = io.open(settings)
-- nvim 0.12+ supports comments otherwise you'll need content:gsub("//[^\n]*", "").
local json = vim.json.decode(file:read("*a"), { skip_comments = true })
file:close()
config.settings["rust-analyzer"] = vim.tbl_deep_extend(
"force", -- Overwrite with the special settings when there is a conflict.
config.settings["rust-analyzer"] or {},
json.lsp["rust-analyzer"].initialization_options
)
end
return true
end
}
default_before_init(init_params, config)
end,
})

vim.lsp.enable("rust_analyzer")
```

If you would like to use the build task that is described above, you may either
Expand All @@ -223,6 +228,9 @@ make your own command in your config, or you can install a plugin such as
files](https://github.com/stevearc/overseer.nvim/blob/master/doc/guides.md#vs-code-tasks),
and follow the same instructions as above.

[neoconf.nvim]: https://github.com/folke/neoconf.nvim/
[r-a nvim lsp]: https://rust-analyzer.github.io/book/other_editors.html#nvim-lsp

### Emacs

Emacs provides support for rust-analyzer with project-local configuration
Expand Down
Loading