diff --git a/lua/rust-tools/code_action_group.lua b/lua/rust-tools/code_action_group.lua index 66900bf..255f34c 100644 --- a/lua/rust-tools/code_action_group.lua +++ b/lua/rust-tools/code_action_group.lua @@ -102,6 +102,13 @@ local function on_primary_quit() M.cleanup() end +local function cleanup_state(state) + if state.winnr then + utils.close_win(state.winnr) + state.clear() + end +end + local function on_code_action_results(results, ctx) M.state.ctx = ctx @@ -116,7 +123,7 @@ local function on_code_action_results(results, ctx) return end - M.state.primary.geometry = compute_width(action_tuples, true) + local geometry = compute_width(action_tuples, true) M.state.actions.grouped = {} @@ -139,10 +146,12 @@ local function on_code_action_results(results, ctx) end end + cleanup_state(M.state.primary) + M.state.primary.geometry = geometry 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", - width = M.state.primary.geometry.width, + width = geometry.width, height = vim.tbl_count(M.state.actions.grouped) + vim.tbl_count(M.state.actions.ungrouped), focusable = true, @@ -249,19 +258,13 @@ local function on_secondary_quit() end function M.cleanup() - if M.state.primary.winnr then - utils.close_win(M.state.primary.winnr) - M.state.primary.clear() - end - - if M.state.secondary.winnr then - utils.close_win(M.state.secondary.winnr) - M.state.secondary.clear() - end + cleanup_state(M.state.primary) + cleanup_state(M.state.secondary) M.state.actions = {} M.state.active_group_index = nil M.state.ctx = {} + M.state.left_buf = nil end function M.on_cursor_move() @@ -276,14 +279,14 @@ function M.on_cursor_move() M.state.secondary.clear() end - M.state.secondary.geometry = compute_width(value.actions, false) + local geometry = compute_width(value.actions, false) M.state.secondary.bufnr = vim.api.nvim_create_buf(false, true) M.state.secondary.winnr = vim.api.nvim_open_win(M.state.secondary.bufnr, false, { relative = "win", win = M.state.primary.winnr, - width = M.state.secondary.geometry.width, + width = geometry.width, height = #value.actions, focusable = true, border = "rounded", @@ -336,6 +339,38 @@ function M.on_cursor_move() end end +-- Handles win leave and enter in order to get if any code action win needs to be closed. +local close_on_exit_group = vim.api.nvim_create_augroup( + "rust-tools-code-actions-close-on-exit", + { clear = true } +) + +vim.api.nvim_create_autocmd("WinLeave", { + group = close_on_exit_group, + callback = function(args) + if args.buf == M.state.primary.bufnr or args.buf == M.state.secondary.bufnr then + M.state.left_buf = args.buf + else + M.state.left_buf = nil + end + end +}) + +vim.api.nvim_create_autocmd("WinEnter", { + group = close_on_exit_group, + callback = function(args) + if not M.state.left_buf then + return + end + + if args.buf == M.state.primary.bufnr or args.buf == M.state.secondary.bufnr then + return; + end + + M.cleanup() + end +}) + M.state = { ctx = {}, actions = {}, @@ -353,13 +388,12 @@ M.state = { secondary = { bufnr = nil, winnr = nil, - geometry = nil, clear = function() - M.state.secondary.geometry = nil M.state.secondary.bufnr = nil M.state.secondary.winnr = nil end, }, + left_buf = nil, } function M.code_action_group()