From 5d9b8d92ffdaa4f76df3e2f0cdc64e3c1527dab5 Mon Sep 17 00:00:00 2001 From: Guillaume Lagrange Date: Thu, 21 Mar 2024 23:23:36 +0100 Subject: [PATCH 1/3] feat(lsp): add command to reload lsp settings --- CHANGELOG.md | 4 +++ doc/rustaceanvim.txt | 1 + lua/rustaceanvim/lsp.lua | 57 ++++++++++++++++++++++++++++++---------- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b297569e..be849f2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- LSP: `RustAnalyzer reloadSettings` command to reload settings without restarting. + ### Fixed - DAP: Defer automatic registration of nvim-dap configurations on LSP client init, diff --git a/doc/rustaceanvim.txt b/doc/rustaceanvim.txt index 9b3461a1..1c804ba4 100644 --- a/doc/rustaceanvim.txt +++ b/doc/rustaceanvim.txt @@ -22,6 +22,7 @@ Commands: `:RustAnalyzer start` - Start the LSP client. `:RustAnalyzer stop` - Stop the LSP client. `:RustAnalyzer restart` - Restart the LSP client. + `:RustAnalyzer reloadSettings` - Reload settings for the LSP client. The `:RustLsp[!]` command is available after the LSP client has initialized. It accepts the following subcommands: diff --git a/lua/rustaceanvim/lsp.lua b/lua/rustaceanvim/lsp.lua index b26b712b..6afb4a3b 100644 --- a/lua/rustaceanvim/lsp.lua +++ b/lua/rustaceanvim/lsp.lua @@ -35,8 +35,8 @@ local function is_in_workspace(client, root_dir) return false end ----@Searches upward for a .vscode/settings.json that contains rust-analyzer ---- settings and applies them. +---Searches upward for a .vscode/settings.json that contains rust-analyzer +---settings and returns them. ---@param bufname string ---@return table server_settings or an empty table if no settings were found local function find_vscode_settings(bufname) @@ -54,6 +54,25 @@ local function find_vscode_settings(bufname) return content and require('rustaceanvim.config.json').silent_decode(content) or {} end +---Generate the settings from config and vscode settings if found. +---settings and returns them. +---@param bufname string +---@param root_dir string | nil +---@param client_config table +---@return table server_settings or an empty table if no settings were found +local function get_start_settings(bufname, root_dir, client_config) + local settings = client_config.settings + local evaluated_settings = type(settings) == 'function' and settings(root_dir, client_config.default_settings) + or settings + + if config.server.load_vscode_settings then + local json_settings = find_vscode_settings(bufname) + require('rustaceanvim.config.json').override_with_rust_analyzer_json_keys(evaluated_settings, json_settings) + end + + return evaluated_settings +end + ---@class LspStartConfig: RustaceanLspClientConfig ---@field root_dir string | nil ---@field init_options? table @@ -84,17 +103,7 @@ M.start = function(bufnr) lsp_start_config.init_options = { detachedFiles = { bufname } } end - local settings = client_config.settings - local evaluated_settings = type(settings) == 'function' and settings(root_dir, client_config.default_settings) - or settings - - ---@cast evaluated_settings table - lsp_start_config.settings = evaluated_settings - - if config.server.load_vscode_settings then - local json_settings = find_vscode_settings(bufname) - require('rustaceanvim.config.json').override_with_rust_analyzer_json_keys(lsp_start_config.settings, json_settings) - end + lsp_start_config.settings = get_start_settings(bufname, root_dir, client_config) -- Check if a client is already running and add the workspace folder if necessary. for _, client in pairs(rust_analyzer.get_active_rustaceanvim_clients()) do @@ -222,6 +231,23 @@ M.stop = function(bufnr) return clients end +---Reload settings for the LSP client. +---@param bufnr? number The buffer number, defaults to the current buffer +---@return table[] clients A list of clients that will be have their settings reloaded +M.reload_settings = function(bufnr) + bufnr = bufnr or vim.api.nvim_get_current_buf() + local clients = rust_analyzer.get_active_rustaceanvim_clients(bufnr) + ---@cast clients lsp.Client[] + for _, client in ipairs(clients) do + local settings = get_start_settings(vim.api.nvim_buf_get_name(bufnr), client.root_dir, config.server) + client.settings = settings + client.notify('workspace/didChangeConfiguration', { + settings = client.settings, + }) + end + return clients +end + ---Restart the LSP client. ---Fails silently if the buffer's filetype is not one of the filetypes specified in the config. ---@param bufnr? number The buffer number (optional), defaults to the current buffer @@ -262,6 +288,7 @@ local RustAnalyzerCmd = { start = 'start', stop = 'stop', restart = 'restart', + reload_settings = 'reloadSettings', } local function rust_analyzer_cmd(opts) @@ -274,6 +301,8 @@ local function rust_analyzer_cmd(opts) M.stop() elseif cmd == RustAnalyzerCmd.restart then M.restart() + elseif cmd == RustAnalyzerCmd.reload_settings then + M.reload_settings() end end @@ -283,7 +312,7 @@ vim.api.nvim_create_user_command('RustAnalyzer', rust_analyzer_cmd, { complete = function(arg_lead, cmdline, _) local clients = rust_analyzer.get_active_rustaceanvim_clients() ---@type RustAnalyzerCmd[] - local commands = #clients == 0 and { 'start' } or { 'stop', 'restart' } + local commands = #clients == 0 and { 'start' } or { 'stop', 'restart', 'reloadSettings' } if cmdline:match('^RustAnalyzer%s+%w*$') then return vim.tbl_filter(function(command) return command:find(arg_lead) ~= nil From eca51724832763f11867d9279badcfc4686231dd Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Sat, 23 Mar 2024 23:50:50 +0100 Subject: [PATCH 2/3] chore: apply PR suggestion --- lua/rustaceanvim/lsp.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/rustaceanvim/lsp.lua b/lua/rustaceanvim/lsp.lua index 6afb4a3b..13f17e11 100644 --- a/lua/rustaceanvim/lsp.lua +++ b/lua/rustaceanvim/lsp.lua @@ -239,7 +239,7 @@ M.reload_settings = function(bufnr) local clients = rust_analyzer.get_active_rustaceanvim_clients(bufnr) ---@cast clients lsp.Client[] for _, client in ipairs(clients) do - local settings = get_start_settings(vim.api.nvim_buf_get_name(bufnr), client.root_dir, config.server) + local settings = get_start_settings(vim.api.nvim_buf_get_name(bufnr), client.config.root_dir, config.server) client.settings = settings client.notify('workspace/didChangeConfiguration', { settings = client.settings, From b313c0ebf08ef72823b500679ac753e687b14cd3 Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Sat, 23 Mar 2024 23:51:03 +0100 Subject: [PATCH 3/3] chore: apply PR suggestion --- lua/rustaceanvim/lsp.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/lua/rustaceanvim/lsp.lua b/lua/rustaceanvim/lsp.lua index 13f17e11..698dbc30 100644 --- a/lua/rustaceanvim/lsp.lua +++ b/lua/rustaceanvim/lsp.lua @@ -240,6 +240,7 @@ M.reload_settings = function(bufnr) ---@cast clients lsp.Client[] for _, client in ipairs(clients) do local settings = get_start_settings(vim.api.nvim_buf_get_name(bufnr), client.config.root_dir, config.server) + ---@diagnostic disable-next-line: inject-field client.settings = settings client.notify('workspace/didChangeConfiguration', { settings = client.settings,