neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit aaec3e5b0dab1e38099abb6371724ab2b199532e
parent 25322a3a3b225c54f2fcec83654d9d2fc99ad543
Author: Tomas Slusny <slusnucky@gmail.com>
Date:   Mon, 13 Oct 2025 20:12:42 +0200

fix(difftool): add check for window number when cleaning up layout #36161

- Move autocmd cleanup logic back to setup_layout as WinClosed autocmds
  were triggering for every closed window even when buf scoped, and when
  buf scoped, pattern filter did not work.
- Cleanup when quickfix window is closed as well to prevent state where
  on closing quickfix setup_layout will reset it after with empty
  content because of WinClosed autocmds triggering.

Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
Diffstat:
Mruntime/pack/dist/opt/nvim.difftool/lua/difftool.lua | 94++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
1 file changed, 52 insertions(+), 42 deletions(-)

diff --git a/runtime/pack/dist/opt/nvim.difftool/lua/difftool.lua b/runtime/pack/dist/opt/nvim.difftool/lua/difftool.lua @@ -28,31 +28,36 @@ local layout = { group = nil, left_win = nil, right_win = nil, + qf_win = nil, } local util = require('vim._core.util') +--- Clean up the layout state, autocmds and quickfix list +--- @param with_qf boolean whether the layout included a quickfix window +local function cleanup_layout(with_qf) + if layout.group then + vim.api.nvim_del_augroup_by_id(layout.group) + layout.group = nil + end + layout.left_win = nil + layout.right_win = nil + layout.qf_win = nil + + if with_qf then + vim.fn.setqflist({}) + vim.cmd.cclose() + end +end + --- Set up a consistent layout with two diff windows --- @param with_qf boolean whether to open the quickfix window local function setup_layout(with_qf) - local wins = vim.api.nvim_tabpage_list_wins(0) local left_valid = layout.left_win and vim.api.nvim_win_is_valid(layout.left_win) local right_valid = layout.right_win and vim.api.nvim_win_is_valid(layout.right_win) - local wins_passed = left_valid and right_valid - - local qf_passed = not with_qf - if not qf_passed and wins_passed then - for _, win in ipairs(wins) do - local buf = vim.api.nvim_win_get_buf(win) - local ft = vim.bo[buf].filetype - if ft == 'qf' then - qf_passed = true - break - end - end - end + local qf_valid = layout.qf_win and vim.api.nvim_win_is_valid(layout.qf_win) - if wins_passed and qf_passed then + if left_valid and right_valid and (not with_qf or qf_valid) then return false end @@ -63,47 +68,52 @@ local function setup_layout(with_qf) if with_qf then vim.cmd('botright copen') + layout.qf_win = vim.api.nvim_get_current_win() + else + layout.qf_win = nil end vim.api.nvim_set_current_win(layout.right_win) -end - ---- Diff two files ---- @param left_file string ---- @param right_file string ---- @param with_qf boolean? whether to open the quickfix window -local function diff_files(left_file, right_file, with_qf) - setup_layout(with_qf or false) - - local left_buf = util.edit_in(layout.left_win, left_file) - local right_buf = util.edit_in(layout.right_win, right_file) -- When one of the windows is closed, clean up the layout vim.api.nvim_create_autocmd('WinClosed', { group = layout.group, - buffer = left_buf, + pattern = tostring(layout.left_win), callback = function() - if layout.group and layout.left_win then - vim.api.nvim_del_augroup_by_id(layout.group) - layout.left_win = nil - layout.group = nil - vim.fn.setqflist({}) - vim.cmd.cclose() - end + cleanup_layout(with_qf) end, }) vim.api.nvim_create_autocmd('WinClosed', { group = layout.group, - buffer = right_buf, + pattern = tostring(layout.right_win), callback = function() - if layout.group and layout.right_win then - vim.api.nvim_del_augroup_by_id(layout.group) - layout.right_win = nil - layout.group = nil - vim.fn.setqflist({}) - vim.cmd.cclose() - end + cleanup_layout(with_qf) end, }) + if with_qf then + vim.api.nvim_create_autocmd('WinClosed', { + group = layout.group, + pattern = tostring(layout.qf_win), + callback = function() + -- For quickfix also close one of diff windows + if layout.left_win and vim.api.nvim_win_is_valid(layout.left_win) then + vim.api.nvim_win_close(layout.left_win, true) + end + + cleanup_layout(with_qf) + end, + }) + end +end + +--- Diff two files +--- @param left_file string +--- @param right_file string +--- @param with_qf boolean? whether to open the quickfix window +local function diff_files(left_file, right_file, with_qf) + setup_layout(with_qf or false) + + util.edit_in(layout.left_win, left_file) + util.edit_in(layout.right_win, right_file) vim.cmd('diffoff!') vim.api.nvim_win_call(layout.left_win, vim.cmd.diffthis)