diff options
author | glepnir <glephunter@gmail.com> | 2025-03-11 20:10:09 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-11 05:10:09 -0700 |
commit | a14fca432b963b01ae9b47598f5d787520402810 (patch) | |
tree | 31c1cdc976eb661e15e80cbece52bd058f1432f4 | |
parent | 55bdb077b7069c018cc5ccf682417770abec5b4a (diff) | |
download | rneovim-a14fca432b963b01ae9b47598f5d787520402810.tar.gz rneovim-a14fca432b963b01ae9b47598f5d787520402810.tar.bz2 rneovim-a14fca432b963b01ae9b47598f5d787520402810.zip |
fix(lsp): improve LSP floating preview window cleanup #31353
Problem: The current implementation creates a unique autocommand group for each floating preview window, which is inefficient and can lead to numerous autocommand groups.
Solution: Use a single shared autocommand group with improved window validation to properly clean up LSP floating preview windows.
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 31 | ||||
-rw-r--r-- | test/functional/plugin/lsp/utils_spec.lua | 58 |
2 files changed, 45 insertions, 44 deletions
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index ef177e903f..307a55c2a2 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -1622,23 +1622,24 @@ function M.open_floating_preview(contents, syntax, opts) api.nvim_win_set_var(floating_winnr, opts.focus_id, bufnr) end api.nvim_buf_set_var(bufnr, 'lsp_floating_preview', floating_winnr) + api.nvim_win_set_var(floating_winnr, 'lsp_floating_bufnr', bufnr) end - local augroup_name = ('nvim.closing_floating_preview_%d'):format(floating_winnr) - local ok = - pcall(api.nvim_get_autocmds, { group = augroup_name, pattern = tostring(floating_winnr) }) - if not ok then - api.nvim_create_autocmd('WinClosed', { - group = api.nvim_create_augroup(augroup_name, {}), - pattern = tostring(floating_winnr), - callback = function() - if api.nvim_buf_is_valid(bufnr) then - vim.b[bufnr].lsp_floating_preview = nil - end - api.nvim_del_augroup_by_name(augroup_name) - end, - }) - end + api.nvim_create_autocmd('WinClosed', { + group = api.nvim_create_augroup('nvim.closing_floating_preview', { clear = true }), + callback = function(args) + local winid = tonumber(args.match) + local ok, preview_bufnr = pcall(api.nvim_win_get_var, winid, 'lsp_floating_bufnr') + if + ok + and api.nvim_buf_is_valid(preview_bufnr) + and winid == vim.b[preview_bufnr].lsp_floating_preview + then + vim.b[bufnr].lsp_floating_preview = nil + return true + end + end, + }) vim.wo[floating_winnr].foldenable = false -- Disable folding. vim.wo[floating_winnr].wrap = opts.wrap -- Soft wrapping. diff --git a/test/functional/plugin/lsp/utils_spec.lua b/test/functional/plugin/lsp/utils_spec.lua index 7bfb354c2e..fac9a2c69d 100644 --- a/test/functional/plugin/lsp/utils_spec.lua +++ b/test/functional/plugin/lsp/utils_spec.lua @@ -267,38 +267,38 @@ describe('vim.lsp.util', function() eq(56, opts.height) end) + end) + end) - describe('vim.lsp.util.open_floating_preview', function() - local var_name = 'lsp_floating_preview' - local curbuf = api.nvim_get_current_buf() - - it('clean bufvar after fclose', function() - exec_lua(function() - vim.lsp.util.open_floating_preview({ 'test' }, '', { height = 5, width = 2 }) - end) - eq(true, api.nvim_win_is_valid(api.nvim_buf_get_var(curbuf, var_name))) - command('fclose') - eq( - 'Key not found: lsp_floating_preview', - pcall_err(api.nvim_buf_get_var, curbuf, var_name) - ) - end) + describe('open_floating_preview', function() + before_each(function() + n.clear() + Screen.new(10, 10) + feed('9i<CR><Esc>G4k') + end) - it('clean bufvar after CursorMoved', function() - local result = exec_lua(function() - vim.lsp.util.open_floating_preview({ 'test' }, '', { height = 5, width = 2 }) - local winnr = vim.b[vim.api.nvim_get_current_buf()].lsp_floating_preview - local result = vim.api.nvim_win_is_valid(winnr) - vim.api.nvim_feedkeys(vim.keycode('G'), 'txn', false) - return result - end) - eq(true, result) - eq( - 'Key not found: lsp_floating_preview', - pcall_err(api.nvim_buf_get_var, curbuf, var_name) - ) - end) + local var_name = 'lsp_floating_preview' + local curbuf = api.nvim_get_current_buf() + + it('clean bufvar after fclose', function() + exec_lua(function() + vim.lsp.util.open_floating_preview({ 'test' }, '', { height = 5, width = 2 }) + end) + eq(true, api.nvim_win_is_valid(api.nvim_buf_get_var(curbuf, var_name))) + command('fclose') + eq('Key not found: lsp_floating_preview', pcall_err(api.nvim_buf_get_var, curbuf, var_name)) + end) + + it('clean bufvar after CursorMoved', function() + local result = exec_lua(function() + vim.lsp.util.open_floating_preview({ 'test' }, '', { height = 5, width = 2 }) + local winnr = vim.b[vim.api.nvim_get_current_buf()].lsp_floating_preview + local result = vim.api.nvim_win_is_valid(winnr) + vim.api.nvim_feedkeys(vim.keycode('G'), 'txn', false) + return result end) + eq(true, result) + eq('Key not found: lsp_floating_preview', pcall_err(api.nvim_buf_get_var, curbuf, var_name)) end) end) |