file for one of the supported editors. You can also create the config file as a
step of running `./x setup`.
### Using a separate build directory for rust-analyzer
By default, when rust-analyzer runs a check or format command, it will share
the same build directory as manual command-line builds. This can be inconvenient
for two reasons:
- Each build will lock the build directory and force the other to wait, so it
becomes impossible to run command-line builds while rust-analyzer is running
commands in the background.
- There is an increased risk of one of the builds deleting previously-built
artifacts due to conflicting compiler flags or other settings, forcing
additional rebuilds in some cases.
To avoid these problems:
- Add `--build-dir=build/rust-analyzer` to all of the custom `x` commands in
your editor's rust-analyzer configuration.
(Feel free to choose a different directory name if desired.)
- Modify the `rust-analyzer.rustfmt.overrideCommand` setting so that it points
to the copy of `rustfmt` in that other build directory.
- Modify the `rust-analyzer.procMacro.server` setting so that it points to the
copy of `rust-analyzer-proc-macro-srv` in that other build directory.
Using separate build directories for command-line builds and rust-analyzer
requires extra disk space.
### Visual Studio Code
Selecting `vscode` in `./x setup editor` will prompt you to create a
`.vscode/settings.json` file which will configure Visual Studio code. The
recommended `rust-analyzer` settings live at
[`src/etc/rust_analyzer_settings.json`].
If running `./x check` on save is inconvenient, in VS Code you can use a [Build
Task] instead:
```JSON
// .vscode/tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "./x check",
"command": "./x check",
"type": "shell",
"problemMatcher": "$rustc",
"presentation": { "clear": true },
"group": { "kind": "build", "isDefault": true }
}
]
}
```
### 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).
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.
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 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.