diff --git a/CHANGELOG.md b/CHANGELOG.md index 79d483fb..92eadb5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- LSP: Option to fall back to `vim.ui.select` if there + are no code action groups when running `:RustLsp codeAction`. + ### Fixed - LSP: Focus lost when secondary float opens on `:RustLsp codeAction` [[#169](https://github.com/mrcjkb/rustaceanvim/issues/169)]. diff --git a/README.md b/README.md index 7b1d712e..68841098 100644 --- a/README.md +++ b/README.md @@ -245,6 +245,30 @@ vim.keymap.set( ``` +
+ + Grouped code actions + + + Sometimes, rust-analyzer groups code actions by category, + which is not supported by Neovim's built-in `vim.lsp.buf.codeAction`. + This plugin provides a command with a UI that does: + + ```vimscript + :RustLsp codeAction + ``` + ```lua + vim.cmd.RustLsp('codeAction') + ``` + + If you set the option `vim.g.rustaceanvim.tools.code_actions.ui_select_fallback` + to `true` (defaults to `false`), it will fall back to `vim.ui.select` + if there are no grouped code actions. + +![](https://github.com/mrcjkb/rustaceanvim/assets/12857160/866d3cb1-8e56-4380-8c03-812386441f47) + +
+
Hover Actions diff --git a/doc/rustaceanvim.txt b/doc/rustaceanvim.txt index 25a1cdef..e9ce4042 100644 --- a/doc/rustaceanvim.txt +++ b/doc/rustaceanvim.txt @@ -109,6 +109,7 @@ RustaceanToolsOpts *RustaceanToolsOpts* {on_initialized?} (fun(health:RustAnalyzerInitializedStatus)) Function that is invoked when the LSP server has finished initializing {reload_workspace_from_cargo_toml?} (boolean) Automatically call `RustReloadWorkspace` when writing to a Cargo.toml file {hover_actions?} (RustaceanHoverActionsOpts) Options for hover actions + {code_actions?} (RustaceanCodeActionOpts) Options for code actions {float_win_config?} (table) Options applied to floating windows. See |api-win_config|. {create_graph?} (RustaceanCrateGraphConfig) Options for showing the crate graph based on graphviz and the dot {open_url?} (fun(url:string):nil) If set, overrides how to open URLs @@ -120,6 +121,12 @@ RustaceanHoverActionsOpts *RustaceanHoverActionsOpts* {replace_builtin_hover?} (boolean) Whether to replace Neovim's built-in `vim.lsp.buf.hover` with hover actions. Default: `true` +RustaceanCodeActionOpts *RustaceanCodeActionOpts* + + Fields: ~ + {ui_select_fallback?} (boolean) Whether to fall back to `vim.ui.select` if there are no grouped code actions. Default: `false` + + lsp_server_health_status *lsp_server_health_status* Type: ~ diff --git a/lua/rustaceanvim/commands/code_action_group.lua b/lua/rustaceanvim/commands/code_action_group.lua index 8b4c02ca..47165e54 100644 --- a/lua/rustaceanvim/commands/code_action_group.lua +++ b/lua/rustaceanvim/commands/code_action_group.lua @@ -1,4 +1,5 @@ local ui = require('rustaceanvim.ui') +local config = require('rustaceanvim.config.internal') local M = {} ---@class RACodeAction @@ -147,6 +148,22 @@ local function on_code_action_results(results, ctx) table.insert(M.state.actions.ungrouped, value) end end + + if #M.state.actions.grouped == 0 and config.tools.code_actions.ui_select_fallback then + ---@param item action_tuple + local function format_item(item) + local title = item[2].title:gsub('\r\n', '\\r\\n') + return title:gsub('\n', '\\n') + end + local select_opts = { + prompt = 'Code actions:', + kind = 'codeaction', + format_item = format_item, + } + vim.ui.select(M.state.actions.ungrouped, select_opts, M.on_user_choice) + return + end + M.state.primary.bufnr = vim.api.nvim_create_buf(false, true) M.state.primary.winnr = vim.api.nvim_open_win(M.state.primary.bufnr, true, { relative = 'cursor', diff --git a/lua/rustaceanvim/config/init.lua b/lua/rustaceanvim/config/init.lua index b7cfc097..91e36cde 100644 --- a/lua/rustaceanvim/config/init.lua +++ b/lua/rustaceanvim/config/init.lua @@ -59,6 +59,7 @@ vim.g.rustaceanvim = vim.g.rustaceanvim ---@field on_initialized? fun(health:RustAnalyzerInitializedStatus) Function that is invoked when the LSP server has finished initializing ---@field reload_workspace_from_cargo_toml? boolean Automatically call `RustReloadWorkspace` when writing to a Cargo.toml file ---@field hover_actions? RustaceanHoverActionsOpts Options for hover actions +---@field code_actions? RustaceanCodeActionOpts Options for code actions ---@field float_win_config? table Options applied to floating windows. See |api-win_config|. ---@field create_graph? RustaceanCrateGraphConfig Options for showing the crate graph based on graphviz and the dot ---@field open_url? fun(url:string):nil If set, overrides how to open URLs @@ -66,6 +67,9 @@ vim.g.rustaceanvim = vim.g.rustaceanvim ---@class RustaceanHoverActionsOpts ---@field replace_builtin_hover? boolean Whether to replace Neovim's built-in `vim.lsp.buf.hover` with hover actions. Default: `true` +---@class RustaceanCodeActionOpts +---@field ui_select_fallback? boolean Whether to fall back to `vim.ui.select` if there are no grouped code actions. Default: `false` + ---@alias lsp_server_health_status 'ok' | 'warning' | 'error' ---@class RustAnalyzerInitializedStatus diff --git a/lua/rustaceanvim/config/internal.lua b/lua/rustaceanvim/config/internal.lua index 76d101d9..883f9aa1 100644 --- a/lua/rustaceanvim/config/internal.lua +++ b/lua/rustaceanvim/config/internal.lua @@ -53,11 +53,16 @@ local RustaceanDefaultConfig = { hover_actions = { --- whether to replace Neovim's built-in `vim.lsp.buf.hover`. - --- default: true ---@type boolean replace_builtin_hover = true, }, + code_actions = { + --- whether to fall back to `vim.ui.select` if there are no grouped code actions + ---@type boolean + ui_select_fallback = false, + }, + --- options same as lsp hover ---@see vim.lsp.util.open_floating_preview ---@type table Options applied to floating windows. @@ -331,6 +336,7 @@ local RustaceanDefaultConfig = { return dap_config end, }, + -- debug info was_g_rustaceanvim_sourced = vim.g.rustaceanvim ~= nil, } local rustaceanvim = vim.g.rustaceanvim or {}