fix(ui): close floating window on BufLeave event (#16664)

When buffer is visible in two splits simultaneously, BufHidden event is
not triggered, causing the floating window to remain on screen after
switching to another buffer.

Remove BufHidden event from close_events defaults, and close the window
if we changed the buffer to something other than the buffer that spawned
the floating window or the floating window buffer itself.
This commit is contained in:
github-actions[bot] 2021-12-15 08:12:35 -07:00 committed by GitHub
parent aa0ddc6690
commit 785baceaee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 18 deletions

View File

@ -1377,18 +1377,6 @@ character_offset({bufnr}, {row}, {col})
(number, number) UTF-32 and UTF-16 index of the character
in line {row} column {col} in buffer {buf}
*vim.lsp.util.close_preview_autocmd()*
close_preview_autocmd({events}, {winnr})
Creates autocommands to close a preview window when events
happen.
Parameters: ~
{events} (table) list of events
{winnr} (number) window id of preview window
See also: ~
|autocmd-events|
*vim.lsp.util.convert_input_to_markdown_lines()*
convert_input_to_markdown_lines({input}, {contents})
Converts any of `MarkedString` | `MarkedString[]` |

View File

@ -1218,17 +1218,57 @@ function M.stylize_markdown(bufnr, contents, opts)
return stripped
end
---@private
--- Creates autocommands to close a preview window when events happen.
---
---@param events (table) list of events
---@param winnr (number) window id of preview window
---@param events table list of events
---@param winnr number window id of preview window
---@param bufnrs table list of buffers where the preview window will remain visible
---@see |autocmd-events|
function M.close_preview_autocmd(events, winnr)
local function close_preview_autocmd(events, winnr, bufnrs)
local augroup = 'preview_window_'..winnr
-- close the preview window when entered a buffer that is not
-- the floating window buffer or the buffer that spawned it
vim.cmd(string.format([[
augroup %s
autocmd!
autocmd BufEnter * lua vim.lsp.util._close_preview_window(%d, {%s})
augroup end
]], augroup, winnr, table.concat(bufnrs, ',')))
if #events > 0 then
api.nvim_command("autocmd "..table.concat(events, ',').." <buffer> ++once lua pcall(vim.api.nvim_win_close, "..winnr..", true)")
vim.cmd(string.format([[
augroup %s
autocmd %s <buffer> lua vim.lsp.util._close_preview_window(%d)
augroup end
]], augroup, table.concat(events, ','), winnr))
end
end
---@private
--- Closes the preview window
---
---@param winnr number window id of preview window
---@param bufnrs table|nil optional list of ignored buffers
function M._close_preview_window(winnr, bufnrs)
vim.schedule(function()
-- exit if we are in one of ignored buffers
if bufnrs and vim.tbl_contains(bufnrs, api.nvim_get_current_buf()) then
return
end
local augroup = 'preview_window_'..winnr
vim.cmd(string.format([[
augroup %s
autocmd!
augroup end
augroup! %s
]], augroup, augroup))
pcall(vim.api.nvim_win_close, winnr, true)
end)
end
---@internal
--- Computes size of float needed to show contents (with optional wrapping)
---
@ -1335,7 +1375,7 @@ function M.open_floating_preview(contents, syntax, opts)
opts.wrap = opts.wrap ~= false -- wrapping by default
opts.stylize_markdown = opts.stylize_markdown ~= false
opts.focus = opts.focus ~= false
opts.close_events = opts.close_events or {"CursorMoved", "CursorMovedI", "BufHidden", "InsertCharPre"}
opts.close_events = opts.close_events or {"CursorMoved", "CursorMovedI", "InsertCharPre"}
local bufnr = api.nvim_get_current_buf()
@ -1404,7 +1444,7 @@ function M.open_floating_preview(contents, syntax, opts)
api.nvim_buf_set_option(floating_bufnr, 'modifiable', false)
api.nvim_buf_set_option(floating_bufnr, 'bufhidden', 'wipe')
api.nvim_buf_set_keymap(floating_bufnr, "n", "q", "<cmd>bdelete<cr>", {silent = true, noremap = true, nowait = true})
M.close_preview_autocmd(opts.close_events, floating_winnr)
close_preview_autocmd(opts.close_events, floating_winnr, {floating_bufnr, bufnr})
-- save focus_id
if opts.focus_id then