Skip to content
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

feat(codeAction): <Plug> mappings for confirm and quit #624

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,15 @@ vim.keymap.set(
to `true` (defaults to `false`), it will fall back to `vim.ui.select`
if there are no grouped code actions.

The default keymaps are `<CR>` to confirm a code action and `q` or `<Esc>` to cancel
a selection.
You can modify these by defining `<Plug>rustaceanvim.code_action.confirm` or
`<Plug>rustaceanvim.code_action.quit` mappings, for example:

```lua
vim.keymap.set('n', '<C-y>', '<Plug>rustaceanvim.code_action.confirm')
```

![](https://github.com/mrcjkb/rustaceanvim/assets/12857160/866d3cb1-8e56-4380-8c03-812386441f47)

</details>
Expand All @@ -408,9 +417,6 @@ vim.keymap.set(
vim.cmd.RustLsp { 'hover', 'actions' }
```

By default, this plugin replaces Neovim's built-in hover handler with hover
actions, so you can also use `vim.lsp.buf.hover()`.

You can invoke a hover action by switching to the hover window and entering `<CR>`
on the respective line, or with a keymap for the `<Plug>RustHoverAction` mapping,
which accepts a `<count>` prefix as the (1-based) index of the hover action to invoke.
Expand Down
17 changes: 17 additions & 0 deletions doc/rustaceanvim.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,24 @@ It accepts the following subcommands:
`args[]` allows you to override the executable's arguments.
'expandMacro' - Expand macros recursively.
'moveItem {up|down}' - Move items up or down.
'codeAction' - Sometimes, rust-analyzer groups code actions by category,
which is not supported by Neovim's built-in |vim.lsp.buf.codeAction|.
This command provides a command with a UI that does.
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.

The default keymaps are `<CR>` to confirm a code action and `q` or `<Esc>` to cancel
a selection.
You can modify these by defining `<Plug>rustaceanvim.code_action.confirm` or
`<Plug>rustaceanvim.code_action.quit` mappings.
'hover {actions|range}' - Hover actions, or hover over visually selected range.
You can invoke a hover action by switching to the hover window and entering `<CR>`
on the respective line, or with a keymap for the `<Plug>RustHoverAction` mapping,
which accepts a `<count>` prefix as the (1-based) index of the hover action to invoke.

For example, if you set the keymap: `vim.keymap.set('n', '<space>a', '<Plug>RustHoverAction')`,
you can invoke the third hover action with `3<space>a`.
'explainError {cycle?|current?}' - Display a hover window with explanations form the Rust error index.
- If called with |cycle| or no args:
Like |vim.diagnostic.goto_next|,
Expand Down
99 changes: 91 additions & 8 deletions lua/rustaceanvim/commands/code_action_group.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,39 @@ function M.apply_action(action, client, ctx)
end
end

---@class rustaceanvim.code_action_group.set_user_keymaps
---@field confirm boolean
---@field quit boolean

---@class rustaceanvim.api.keyset.keymap: vim.api.keyset.keymap
---@field rhs string

---@return rustaceanvim.code_action_group.set_user_keymaps
local function search_for_user_keymaps()
return vim
.iter(vim.api.nvim_get_keymap('n'))
:map(function(keymap)
return keymap.rhs
end)
:filter(function(rhs)
return type(rhs) == 'string' and vim.startswith(rhs, '<Plug>')
end)
:fold(
{},
---@param acc rustaceanvim.code_action_group.set_user_keymaps
---@param rhs string
function(acc, rhs)
if type(rhs) ~= 'string' then
return acc
end
return {
confirm = acc.confirm or rhs:find('rustaceanvim%.code_action%.confirm') ~= nil,
quit = acc.quit or rhs:find('rustaceanvim%.code_action%.quit') ~= nil,
}
end
)
end

---@alias action_tuple { [1]: number, [2]: rustaceanvim.RACodeAction|rustaceanvim.RACommand }

---@param action_tuple action_tuple | nil
Expand Down Expand Up @@ -86,7 +119,7 @@ local function compute_width(action_tuples, is_group)
return { width = width + 5 }
end

local function on_primary_enter_press()
local function on_primary_confirm()
if M.state.secondary.winnr then
vim.api.nvim_set_current_win(M.state.secondary.winnr)
return
Expand Down Expand Up @@ -194,10 +227,30 @@ local function on_code_action_results(results, ctx)

vim.api.nvim_buf_set_lines(M.state.primary.bufnr, 0, 1, false, {})

vim.keymap.set('n', '<CR>', on_primary_enter_press, { buffer = M.state.primary.bufnr, noremap = true, silent = true })
local user_keymaps = search_for_user_keymaps()

vim.keymap.set('n', 'q', on_primary_quit, { buffer = M.state.primary.bufnr, noremap = true, silent = true })
vim.keymap.set('n', '<Esc>', on_primary_quit, { buffer = M.state.primary.bufnr, noremap = true, silent = true })
if user_keymaps.confirm then
vim.keymap.set(
'n',
'<Plug>rustaceanvim.code_action.confirm',
on_primary_confirm,
{ buffer = M.state.primary.bufnr, noremap = true, silent = true }
)
else
vim.keymap.set('n', '<CR>', on_primary_confirm, { buffer = M.state.primary.bufnr, noremap = true, silent = true })
end

if user_keymaps.quit then
vim.keymap.set(
'n',
'<Plug>rustaceanvim.code_action.quit',
on_primary_quit,
{ buffer = M.state.primary.bufnr, noremap = true, silent = true }
)
else
vim.keymap.set('n', 'q', on_primary_quit, { buffer = M.state.primary.bufnr, noremap = true, silent = true })
vim.keymap.set('n', '<Esc>', on_primary_quit, { buffer = M.state.primary.bufnr, noremap = true, silent = true })
end

M.codeactionify_window_buffer(M.state.primary.winnr, M.state.primary.bufnr)

Expand Down Expand Up @@ -230,7 +283,7 @@ function M.codeactionify_window_buffer(winnr, bufnr)
vim.wo[winnr].cul = true
end

local function on_secondary_enter_press()
local function on_secondary_confirm()
local line = vim.api.nvim_win_get_cursor(M.state.secondary.winnr)[1]
local active_group = nil

Expand Down Expand Up @@ -319,10 +372,40 @@ function M.on_cursor_move()

M.codeactionify_window_buffer(M.state.secondary.winnr, M.state.secondary.bufnr)

vim.keymap.set('n', '<CR>', on_secondary_enter_press, { buffer = M.state.secondary.bufnr })

vim.keymap.set('n', 'q', on_secondary_quit, { buffer = M.state.secondary.bufnr })
local user_keymaps = search_for_user_keymaps()

if user_keymaps.confirm then
vim.keymap.set(
'n',
'<Plug>rustaceanvim.code_action.confirm',
on_secondary_confirm,
{ buffer = M.state.secondary.bufnr, noremap = true, silent = true }
)
else
vim.keymap.set(
'n',
'<CR>',
on_secondary_confirm,
{ buffer = M.state.secondary.bufnr, noremap = true, silent = true }
)
end

if user_keymaps.quit then
vim.keymap.set(
'n',
'<Plug>rustaceanvim.code_action.quit',
on_secondary_quit,
{ buffer = M.state.secondary.bufnr, noremap = true, silent = true }
)
else
vim.keymap.set('n', 'q', on_secondary_quit, { buffer = M.state.secondary.bufnr, noremap = true, silent = true })
vim.keymap.set(
'n',
'<Esc>',
on_secondary_quit,
{ buffer = M.state.secondary.bufnr, noremap = true, silent = true }
)
end
return
end

Expand Down
17 changes: 17 additions & 0 deletions lua/rustaceanvim/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,24 @@
--- `args[]` allows you to override the executable's arguments.
--- 'expandMacro' - Expand macros recursively.
--- 'moveItem {up|down}' - Move items up or down.
--- 'codeAction' - Sometimes, rust-analyzer groups code actions by category,
--- which is not supported by Neovim's built-in |vim.lsp.buf.codeAction|.
--- This command provides a command with a UI that does.
--- 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.
---
--- The default keymaps are `<CR>` to confirm a code action and `q` or `<Esc>` to cancel
--- a selection.
--- You can modify these by defining `<Plug>rustaceanvim.code_action.confirm` or
--- `<Plug>rustaceanvim.code_action.quit` mappings.
--- 'hover {actions|range}' - Hover actions, or hover over visually selected range.
--- You can invoke a hover action by switching to the hover window and entering `<CR>`
--- on the respective line, or with a keymap for the `<Plug>RustHoverAction` mapping,
--- which accepts a `<count>` prefix as the (1-based) index of the hover action to invoke.
---
--- For example, if you set the keymap: `vim.keymap.set('n', '<space>a', '<Plug>RustHoverAction')`,
--- you can invoke the third hover action with `3<space>a`.
--- 'explainError {cycle?|current?}' - Display a hover window with explanations form the Rust error index.
--- - If called with |cycle| or no args:
--- Like |vim.diagnostic.goto_next|,
Expand Down
Loading