Skip to content

Commit f73ec14

Browse files
fix(files): ensure current win is within explorer after closing any win
Details: - Closing the current window will temporarily switch focus to some other window (probably the first "normal" window in the tabpage). This can be a problem since it triggers all relevant events (like `BufEnter`). This can manifest in directory buffer being unexpectedly closed if current window is at depth that will be not shown (`go_in`+`go_in`+`trim_left`). A general rule of thumb is that current window should be set before closing any window. - This also removes a window close logic in explorer normalization since it seems to be redundant: an overlapping actions will be done later during explorer refresh. Resolve #2478 Co-authored-by: abeldekat <58370433+abeldekat@users.noreply.github.com>
1 parent a12fe93 commit f73ec14

2 files changed

Lines changed: 30 additions & 15 deletions

File tree

lua/mini/files.lua

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,17 +1569,18 @@ H.explorer_refresh = function(explorer, opts)
15691569
cur_win_col = cur_win_col + cur_width + 2
15701570
end
15711571

1572+
-- Focus on target window. Do this before closing windows to keep current
1573+
-- window within the explorer.
1574+
local win_focus_count = explorer.depth_focus - depth_range.from + 1
1575+
local win_id_focused = explorer.windows[win_focus_count]
1576+
H.window_focus(win_id_focused)
1577+
15721578
-- Close possibly opened window that don't fit (like after `VimResized`)
15731579
for depth = cur_win_count + 1, #explorer.windows do
15741580
H.window_close(explorer.windows[depth])
15751581
explorer.windows[depth] = nil
15761582
end
15771583

1578-
-- Focus on proper window
1579-
local win_focus_count = explorer.depth_focus - depth_range.from + 1
1580-
local win_id_focused = explorer.windows[win_focus_count]
1581-
H.window_focus(win_id_focused)
1582-
15831584
-- Register as currently opened
15841585
explorer.tabpage_id = vim.api.nvim_win_get_tabpage(win_id_focused)
15851586
H.opened_explorers[explorer.tabpage_id] = explorer
@@ -1634,17 +1635,8 @@ H.explorer_normalize = function(explorer)
16341635
table.insert(norm_branch, path)
16351636
end
16361637

1637-
local cur_max_depth = #norm_branch
1638-
16391638
explorer.branch = norm_branch
1640-
explorer.depth_focus = math.min(math.max(explorer.depth_focus, 1), cur_max_depth)
1641-
1642-
-- Close all guaranteed to be unnecessary windows. NOTE: some windows might
1643-
-- still get outdated later if branch is too deep to fit into Neovim's width.
1644-
for i = cur_max_depth + 1, #explorer.windows do
1645-
H.window_close(explorer.windows[i])
1646-
explorer.windows[i] = nil
1647-
end
1639+
explorer.depth_focus = math.min(math.max(explorer.depth_focus, 1), #norm_branch)
16481640

16491641
-- Compute if explorer is corrupted and should not operate further
16501642
for _, win_id in pairs(explorer.windows) do

tests/test_files.lua

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6369,6 +6369,29 @@ T['Default explorer']['handles forcing other window as current'] = function()
63696369
if child.fn.has('nvim-0.10') == 1 then eq(child.api.nvim_get_current_win(), init_win_id) end
63706370
end
63716371

6372+
T['Default explorer']['keeps directory buffer open when number of windows decreases'] = function()
6373+
child.set_size(5, 90)
6374+
local validate = function(fn_str)
6375+
local test_path = make_test_path('nested')
6376+
child.cmd('edit ' .. test_path)
6377+
local dir_buf_id = child.fn.bufnr(test_path)
6378+
6379+
go_in()
6380+
go_in()
6381+
child.lua(fn_str)
6382+
6383+
-- Directory buffer should still present
6384+
eq(child.api.nvim_buf_is_valid(dir_buf_id), true)
6385+
6386+
-- Closing explorer should always wipeout directory buffer
6387+
close()
6388+
eq(child.api.nvim_buf_is_valid(dir_buf_id), false)
6389+
end
6390+
6391+
validate('MiniFiles.refresh({ windows = { max_number = 1 } })')
6392+
validate('MiniFiles.trim_left()')
6393+
end
6394+
63726395
T['Internal helpers'] = new_set()
63736396

63746397
T['Internal helpers']['path normalization works'] = function()

0 commit comments

Comments
 (0)