diff options
| author | batsumaru <> | 2026-09-23 10:32:02 +0900 |
|---|---|---|
| committer | batsumaru <> | 2026-09-23 10:32:02 +0900 |
| commit | f984d924b9efd2de55713510ff1305162a87fa13 (patch) | |
| tree | 94f3e5c9274ccb385a6b0253bcb1066250449bfa /nvim/lua/plugins/rust.lua | |
| parent | 536b9147885b92c0def298b594af5b0f52795640 (diff) | |
Diffstat (limited to 'nvim/lua/plugins/rust.lua')
| -rw-r--r-- | nvim/lua/plugins/rust.lua | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/nvim/lua/plugins/rust.lua b/nvim/lua/plugins/rust.lua new file mode 100644 index 0000000..8813700 --- /dev/null +++ b/nvim/lua/plugins/rust.lua @@ -0,0 +1,90 @@ +-- rustaceanvim / rust-analyzer, matched to the VSCodium setup in ../../vscode/settings.json: +-- clippy instead of cargo check, rustfmt on save, source.fixAll on save, hard tabs. +-- +-- Drop at: ~/.config/nvim/lua/plugins/rust.lua, and delete the rustaceanvim block +-- from lua/plugins/init.lua — two lazy.nvim specs for the same plugin will fight. + +local timeout_ms = 2000 + +-- Equivalent of VS Code's "editor.codeActionsOnSave": { "source.fixAll.rust-analyzer" }. +-- +-- vim.lsp.buf.code_action{apply=true} is asynchronous, so from a BufWritePre autocmd +-- the buffer is usually written before the edit arrives. buf_request_sync blocks, +-- which is what makes this actually run before the write. +-- +-- Same caveat as in VS Code: this applies rust-analyzer's own fixes only. Lints that +-- come from cargo check or clippy are not included — those still need `cargo fix` or +-- `cargo clippy --fix` on the command line. +local function apply_fix_all(bufnr) + local client = vim.lsp.get_clients({ bufnr = bufnr, name = "rust-analyzer" })[1] + if not client then + return + end + + local params = vim.lsp.util.make_range_params(0, client.offset_encoding) + params.context = { only = { "source.fixAll" }, diagnostics = {} } + + local responses = vim.lsp.buf_request_sync(bufnr, "textDocument/codeAction", params, timeout_ms) + if not responses then + return + end + + for _, response in pairs(responses) do + for _, action in ipairs(response.result or {}) do + -- A server may return the action unresolved, carrying only `data`; + -- the edit then has to be fetched with a second request. + if not action.edit and action.data then + local resolved = + client:request_sync("codeAction/resolve", action, timeout_ms, bufnr) + action = (resolved and resolved.result) or action + end + if action.edit then + vim.lsp.util.apply_workspace_edit(action.edit, client.offset_encoding) + end + end + end +end + +vim.api.nvim_create_autocmd("BufWritePre", { + group = vim.api.nvim_create_augroup("rust_on_save", { clear = true }), + pattern = "*.rs", + callback = function(args) + apply_fix_all(args.buf) + -- VS Code's "editor.formatOnSave" for [rust]: rustfmt, driven by rust-analyzer. + vim.lsp.buf.format({ + bufnr = args.buf, + timeout_ms = timeout_ms, + filter = function(client) + return client.name == "rust-analyzer" + end, + }) + end, +}) + +return { + { + "mrcjkb/rustaceanvim", + version = "^6", + -- No `ft = { "rust" }` here. It is dead weight next to lazy = false, and + -- rustaceanvim's own docs advise against lazy-loading it by filetype: + -- it installs the FileType handler that starts the LSP itself. + lazy = false, + config = function() + vim.g.rustaceanvim = { + server = { + on_attach = function(client, bufnr) + require("nvchad.configs.lspconfig").on_attach(client, bufnr) + end, + default_settings = { + ["rust-analyzer"] = { + cargo = { allFeatures = true }, + checkOnSave = true, + -- Matches "rust-analyzer.check.command": "clippy". + check = { command = "clippy" }, + }, + }, + }, + } + end, + }, +} |
