-
Notifications
You must be signed in to change notification settings - Fork 581
Update neovim instructions for neovim 0.11+ #2814
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -144,77 +144,81 @@ 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](https://github.com/folke/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](https://github.com/folke/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](https://rust-analyzer.github.io/book/other_editors.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. | ||||||
|
|
||||||
| #### 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 is set up | ||||||
| <https://rust-analyzer.github.io/book/other_editors.html#nvim-lsp> | ||||||
| 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) | ||||||
| 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) | ||||||
| -- 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', { | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not very familiar with Lua, so is it correct that there is a difference between |
||||||
| 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 | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| -- 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 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. | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| 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) | ||||||
| local content = file:read("*a") | ||||||
| file:close() | ||||||
| -- vim.json.decode doesn't support JSONC so we need strip out comments. | ||||||
| content = content:gsub("//[^\n]*", "") | ||||||
| local json = vim.json.decode(content) | ||||||
| config.settings["rust-analyzer"] = 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 | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels a bit strange to make a suggestion via GitHub suggest, so...
could you please change it so that the references to https://github.com/folke/neoconf.nvim/ and https://rust-analyzer.github.io/book/other_editors.html#nvim-lsp
are placed at the end of the line and then applied?
like
If a link is referenced multiple times, I think it would be better to manage it this way.