From 7667be1910b1adc232fea9ae04a9f65772a555b2 Mon Sep 17 00:00:00 2001 From: abeldekat <58370433+abeldekat@users.noreply.github.com> Date: Tue, 9 Dec 2025 12:23:12 +0100 Subject: [PATCH 1/6] fix(pick): prevent invalid buffer when opening mini.files --- lua/mini/files.lua | 2 +- ...on-external-`vim.api.nvim_set_current_win` | 33 +++++++++++++++++++ ...xternal-`vim.api.nvim_set_current_win`-002 | 33 +++++++++++++++++++ tests/test_files.lua | 18 ++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 tests/screenshots/tests-test_files.lua---Default-explorer---does-not-crash-on-external-`vim.api.nvim_set_current_win` create mode 100644 tests/screenshots/tests-test_files.lua---Default-explorer---does-not-crash-on-external-`vim.api.nvim_set_current_win`-002 diff --git a/lua/mini/files.lua b/lua/mini/files.lua index 470cb20f..ace4fc6f 100644 --- a/lua/mini/files.lua +++ b/lua/mini/files.lua @@ -1383,7 +1383,7 @@ H.track_dir_edit = function(data) -- Smartly delete directory buffer if already visited local alt_buf = vim.fn.bufnr('#') if alt_buf ~= data.buf and vim.fn.buflisted(alt_buf) == 1 then vim.api.nvim_win_set_buf(0, alt_buf) end - return vim.api.nvim_buf_delete(data.buf, { force = true }) + return end local path = vim.api.nvim_buf_get_name(0) diff --git a/tests/screenshots/tests-test_files.lua---Default-explorer---does-not-crash-on-external-`vim.api.nvim_set_current_win` b/tests/screenshots/tests-test_files.lua---Default-explorer---does-not-crash-on-external-`vim.api.nvim_set_current_win` new file mode 100644 index 00000000..d5e8befd --- /dev/null +++ b/tests/screenshots/tests-test_files.lua---Default-explorer---does-not-crash-on-external-`vim.api.nvim_set_current_win` @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------|---------|---------|---------|---------| +01|┌MOCK_ROOT/tests/dir-files/common ─────────────────┐ +02|│ .a-dir │ +03|│ a-dir │ +04|│ b-dir │ +05|│ .a-file │ +06|│ a-file │ +07|│ A-file-2 │ +08|│ b-file │ +09|└──────────────────────────────────────────────────┘ +10|~ +11|~ +12|~ +13|~ +14|~ +15| 1,1 All + +--|---------|---------|---------|---------|---------|---------|---------|---------| +01|01111111111111111111111111111111110000000000000000002222222222222222222222222222 +02|03333333344444444444444444444444444444444444444444405555555555555555555555555555 +03|06666666777777777777777777777777777777777777777777705555555555555555555555555555 +04|06666666777777777777777777777777777777777777777777705555555555555555555555555555 +05|07777777777777777777777777777777777777777777777777705555555555555555555555555555 +06|07777777777777777777777777777777777777777777777777705555555555555555555555555555 +07|07777777777777777777777777777777777777777777777777705555555555555555555555555555 +08|07777777777777777777777777777777777777777777777777705555555555555555555555555555 +09|00000000000000000000000000000000000000000000000000005555555555555555555555555555 +10|55555555555555555555555555555555555555555555555555555555555555555555555555555555 +11|55555555555555555555555555555555555555555555555555555555555555555555555555555555 +12|55555555555555555555555555555555555555555555555555555555555555555555555555555555 +13|55555555555555555555555555555555555555555555555555555555555555555555555555555555 +14|55555555555555555555555555555555555555555555555555555555555555555555555555555555 +15|88888888888888888888888888888888888888888888888888888888888888888888888888888888 diff --git a/tests/screenshots/tests-test_files.lua---Default-explorer---does-not-crash-on-external-`vim.api.nvim_set_current_win`-002 b/tests/screenshots/tests-test_files.lua---Default-explorer---does-not-crash-on-external-`vim.api.nvim_set_current_win`-002 new file mode 100644 index 00000000..61a21223 --- /dev/null +++ b/tests/screenshots/tests-test_files.lua---Default-explorer---does-not-crash-on-external-`vim.api.nvim_set_current_win`-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------|---------|---------|---------|---------| +01|a-file +02|~ +03|~ +04|~ +05|~ +06|~ +07|~ +08|~ +09|~ +10|~ +11|~ +12|~ +13|~ +14|~ +15| 1,1 All + +--|---------|---------|---------|---------|---------|---------|---------|---------| +01|00000000000000000000000000000000000000000000000000000000000000000000000000000000 +02|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +03|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +04|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +05|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +06|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +07|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +08|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +09|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +10|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +11|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +12|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +13|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +14|11111111111111111111111111111111111111111111111111111111111111111111111111111111 +15|22222222222222222222222222222222222222222222222222222222222222222222222222222222 diff --git a/tests/test_files.lua b/tests/test_files.lua index 106e5644..78443e6a 100644 --- a/tests/test_files.lua +++ b/tests/test_files.lua @@ -5740,6 +5740,24 @@ T['Default explorer']['works in `:edit .`'] = function() child.expect_screenshot() end +T['Default explorer']['does not crash on external `vim.api.nvim_set_current_win`'] = function() + -- BufEnter Autocommands for "*": Vim(append):Lua callback : Invalid buffer id: 2 + + child.cmd('edit ' .. test_file_path) + child.cmd('edit ' .. test_dir_path) + + -- Mimic MiniPick when stopping the picker(H.picker_stop -> H.set_curwin) + child.lua([[ + local win_id = 1000 -- vim.api.nvim_get_current_win() + vim.api.nvim_set_current_win(win_id) + ]]) + + child.expect_screenshot() + close() + child.expect_screenshot() + eq(#child.api.nvim_list_bufs(), 1) +end + T['Default explorer']['works in `:vsplit .`'] = function() child.cmd('vsplit ' .. test_dir_path) child.expect_screenshot() From eddcd47401e7f9fb2cad499cc9232be0624618f0 Mon Sep 17 00:00:00 2001 From: abeldekat <58370433+abeldekat@users.noreply.github.com> Date: Wed, 10 Dec 2025 09:33:24 +0100 Subject: [PATCH 2/6] fix(pick): prevent invalid buffer when opening mini.files --- lua/mini/files.lua | 6 +++++- tests/test_files.lua | 31 ++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/lua/mini/files.lua b/lua/mini/files.lua index ace4fc6f..4259dbd8 100644 --- a/lua/mini/files.lua +++ b/lua/mini/files.lua @@ -1382,7 +1382,11 @@ H.track_dir_edit = function(data) if vim.b.minifiles_processed_dir then -- Smartly delete directory buffer if already visited local alt_buf = vim.fn.bufnr('#') - if alt_buf ~= data.buf and vim.fn.buflisted(alt_buf) == 1 then vim.api.nvim_win_set_buf(0, alt_buf) end + if alt_buf ~= data.buf and vim.fn.buflisted(alt_buf) == 1 then + vim.api.nvim_win_set_buf(0, alt_buf) + else + vim.api.nvim_buf_delete(data.buf, { force = true }) + end return end diff --git a/tests/test_files.lua b/tests/test_files.lua index 78443e6a..60b37b0c 100644 --- a/tests/test_files.lua +++ b/tests/test_files.lua @@ -5740,6 +5740,35 @@ T['Default explorer']['works in `:edit .`'] = function() child.expect_screenshot() end +T['Default explorer']['deletes directory buffer if already visited(no alternate)'] = function() + -- Starting with empty buffer having id 1, open and close the explorer + child.cmd('edit ' .. test_dir_path) + close() + + -- There should only be 1 buffer after closing the explorer + local bufs = child.api.nvim_list_bufs() + eq(#bufs, 1) + + -- Assert that buffer with id 1 has been deleted, otherwise it would be for directory test_dir_path + local is_still_one = bufs[1] == 1 + eq(is_still_one, false) +end + +T['Default explorer']['deletes directory buffer if already visited'] = function() + -- Starting with listed buffer having id 1, open and close the explorer + child.cmd('edit ' .. test_file_path) + child.cmd('edit ' .. test_dir_path) + close() + + -- There should only be 1 buffer after closing the explorer + local bufs = child.api.nvim_list_bufs() + eq(#bufs, 1) + + -- Assert that the buffer id is still 1 + local bufid = bufs[1] + eq(bufid, 1) +end + T['Default explorer']['does not crash on external `vim.api.nvim_set_current_win`'] = function() -- BufEnter Autocommands for "*": Vim(append):Lua callback : Invalid buffer id: 2 @@ -5748,7 +5777,7 @@ T['Default explorer']['does not crash on external `vim.api.nvim_set_current_win` -- Mimic MiniPick when stopping the picker(H.picker_stop -> H.set_curwin) child.lua([[ - local win_id = 1000 -- vim.api.nvim_get_current_win() + local win_id = vim.api.nvim_list_wins()[1] -- vim.api.nvim_get_current_win() vim.api.nvim_set_current_win(win_id) ]]) From 6da03e52c1d277201993c46877bf0822dc728f9a Mon Sep 17 00:00:00 2001 From: abeldekat <58370433+abeldekat@users.noreply.github.com> Date: Wed, 10 Dec 2025 19:43:42 +0100 Subject: [PATCH 3/6] fix(pick): prevent invalid buffer when opening mini.files --- tests/dir-extra/mocks/mock-win-functions.lua | 19 +++++++++++ ...can-open-visited-directory-in-'mini.files' | 33 +++++++++++++++++++ ...open-visited-directory-in-'mini.files'-002 | 33 +++++++++++++++++++ tests/test_extra.lua | 30 ++++++++++++++++- 4 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 tests/dir-extra/mocks/mock-win-functions.lua create mode 100644 tests/screenshots/tests-test_extra.lua---pickers---visit_paths()---can-open-visited-directory-in-'mini.files' create mode 100644 tests/screenshots/tests-test_extra.lua---pickers---visit_paths()---can-open-visited-directory-in-'mini.files'-002 diff --git a/tests/dir-extra/mocks/mock-win-functions.lua b/tests/dir-extra/mocks/mock-win-functions.lua new file mode 100644 index 00000000..e3c094db --- /dev/null +++ b/tests/dir-extra/mocks/mock-win-functions.lua @@ -0,0 +1,19 @@ +local mock_title = function(x) + if type(x) ~= 'string' then return x end + -- Make sure that full path title is same on any machine + return x:gsub('^.*/tests/dir%-files', 'MOCK_ROOT/tests/dir-files') +end + +_G.nvim_open_win_orig = vim.api.nvim_open_win + +vim.api.nvim_open_win = function(buf_id, enter, config) + config.title = mock_title(config.title) + return nvim_open_win_orig(buf_id, enter, config) +end + +_G.nvim_win_set_config_orig = vim.api.nvim_win_set_config + +vim.api.nvim_win_set_config = function(win_id, config) + config.title = mock_title(config.title) + return nvim_win_set_config_orig(win_id, config) +end diff --git a/tests/screenshots/tests-test_extra.lua---pickers---visit_paths()---can-open-visited-directory-in-'mini.files' b/tests/screenshots/tests-test_extra.lua---pickers---visit_paths()---can-open-visited-directory-in-'mini.files' new file mode 100644 index 00000000..4b4af8c7 --- /dev/null +++ b/tests/screenshots/tests-test_extra.lua---pickers---visit_paths()---can-open-visited-directory-in-'mini.files' @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01|local a = 1 +02|local t = { +03| x = math.max(a, 2), +04| y = math.min(a, 2), +05|┌> ▏─────────────────────┐ +06|│ real-files │ +07|│ │ +08|│ │ +09|│ │ +10|│ │ +11|│ │ +12|│ │ +13|│ │ +14|└ Visit paths (cwd) ─────┘ +15| + +--|---------|---------|---------|---------| +01|0000011111211111111111111111111111111111 +02|0000011111311111111111111111111111111111 +03|1141113333566651512551111111111111111111 +04|1141113333566651512551111111111111111111 +05|7889777777777777777777777711111111111111 +06|7::;;;;;;;;;;;;;;;;;;;;;;7<<<<<<<<<<<<<< +07|7========================7<<<<<<<<<<<<<< +08|7========================7<<<<<<<<<<<<<< +09|7========================7<<<<<<<<<<<<<< +10|7========================7<<<<<<<<<<<<<< +11|7========================7<<<<<<<<<<<<<< +12|7========================7<<<<<<<<<<<<<< +13|7========================7<<<<<<<<<<<<<< +14|7>>>>>>>>>>>>>>>>>>>777777<<<<<<<<<<<<<< +15|1111111111111111111111111111111111111111 diff --git a/tests/screenshots/tests-test_extra.lua---pickers---visit_paths()---can-open-visited-directory-in-'mini.files'-002 b/tests/screenshots/tests-test_extra.lua---pickers---visit_paths()---can-open-visited-directory-in-'mini.files'-002 new file mode 100644 index 00000000..2ec1ded9 --- /dev/null +++ b/tests/screenshots/tests-test_extra.lua---pickers---visit_paths()---can-open-visited-directory-in-'mini.files'-002 @@ -0,0 +1,33 @@ +--|---------|---------|---------|---------| +01|┌…s/mini.nvim/tests/dir-extra/real-file┐ +02|│ a.lua │ +03|│ b.txt │ +04|│ c.gif │ +05|│ LICENSE │ +06|│ Makefile │ +07|└──────────────────────────────────────┘ +08|~ +09|~ +10|~ +11|~ +12|~ +13|~ +14|~ +15| + +--|---------|---------|---------|---------| +01|0111111111111111111111111111111111111110 +02|0222222222222222222222222222222222222220 +03|0333333333333333333333333333333333333330 +04|0333333333333333333333333333333333333330 +05|0333333333333333333333333333333333333330 +06|0333333333333333333333333333333333333330 +07|0000000000000000000000000000000000000000 +08|4444444444444444444444444444444444444444 +09|4444444444444444444444444444444444444444 +10|4444444444444444444444444444444444444444 +11|4444444444444444444444444444444444444444 +12|4444444444444444444444444444444444444444 +13|4444444444444444444444444444444444444444 +14|4444444444444444444444444444444444444444 +15|5555555555555555555555555555555555555555 diff --git a/tests/test_extra.lua b/tests/test_extra.lua index 1f05e77b..500ec545 100644 --- a/tests/test_extra.lua +++ b/tests/test_extra.lua @@ -119,6 +119,8 @@ local get_extra_picker_extmarks = function(from, to) end -- Common mocks +local mock_win_functions = function() child.cmd('source tests/dir-extra/mocks/mock-win-functions.lua') end + local mock_fn_executable = function(available_executables) local lua_cmd = string.format( 'vim.fn.executable = function(x) return vim.tbl_contains(%s, x) and 1 or 0 end', @@ -3780,7 +3782,13 @@ local setup_visits = function() child.fn.chdir(dir) end -T['pickers']['visit_paths()'] = new_set({ hooks = { pre_case = setup_visits } }) +T['pickers']['visit_paths()'] = + new_set({ hooks = { + pre_case = function() + mock_win_functions() + setup_visits() + end, + } }) local pick_visit_paths = forward_lua_notify('MiniExtra.pickers.visit_paths') @@ -3880,6 +3888,26 @@ T['pickers']['visit_paths()']["checks for present 'mini.visits'"] = function() expect.error(function() child.lua('MiniExtra.pickers.visit_paths()') end, '`pickers%.visit_paths`.*mini%.visits') end +T['pickers']['visit_paths()']["can open visited directory in 'mini.files'"] = function() + child.lua([[require('mini.files').setup()]]) + + -- NOTE: 'mini.visits' uses forward slashes in index + local dir = test_dir_absolute:gsub('\\', '/') + local visit_index = { + [dir] = { + [dir .. '/real-files'] = { count = 10, latest = 10 }, + }, + } + child.lua([[require('mini.visits').set_index(...)]], { visit_index }) + child.fn.chdir(dir) + + child.cmd('edit real-files/a.lua') + pick_visit_paths() + child.expect_screenshot() + type_keys('') + child.expect_screenshot() +end + T['pickers']['visit_labels()'] = new_set({ hooks = { pre_case = setup_visits } }) local pick_visit_labels = forward_lua_notify('MiniExtra.pickers.visit_labels') From 7fe39e06020ecd7dde5995284f5b2c411b528f35 Mon Sep 17 00:00:00 2001 From: abeldekat <58370433+abeldekat@users.noreply.github.com> Date: Wed, 10 Dec 2025 19:53:54 +0100 Subject: [PATCH 4/6] fix(pick): prevent invalid buffer when opening mini.files --- tests/test_files.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_files.lua b/tests/test_files.lua index 60b37b0c..08ffd146 100644 --- a/tests/test_files.lua +++ b/tests/test_files.lua @@ -5777,7 +5777,7 @@ T['Default explorer']['does not crash on external `vim.api.nvim_set_current_win` -- Mimic MiniPick when stopping the picker(H.picker_stop -> H.set_curwin) child.lua([[ - local win_id = vim.api.nvim_list_wins()[1] -- vim.api.nvim_get_current_win() + local win_id = vim.api.nvim_list_wins()[1] -- win id 1000 vim.api.nvim_set_current_win(win_id) ]]) From 05e09fd616987a03f3ffca5fd4d00537ca2580d2 Mon Sep 17 00:00:00 2001 From: abeldekat <58370433+abeldekat@users.noreply.github.com> Date: Thu, 11 Dec 2025 07:53:55 +0100 Subject: [PATCH 5/6] fix(pick): review, shorten code remove the else --- lua/mini/files.lua | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lua/mini/files.lua b/lua/mini/files.lua index 4259dbd8..b845560c 100644 --- a/lua/mini/files.lua +++ b/lua/mini/files.lua @@ -1382,12 +1382,8 @@ H.track_dir_edit = function(data) if vim.b.minifiles_processed_dir then -- Smartly delete directory buffer if already visited local alt_buf = vim.fn.bufnr('#') - if alt_buf ~= data.buf and vim.fn.buflisted(alt_buf) == 1 then - vim.api.nvim_win_set_buf(0, alt_buf) - else - vim.api.nvim_buf_delete(data.buf, { force = true }) - end - return + if alt_buf ~= data.buf and vim.fn.buflisted(alt_buf) == 1 then return vim.api.nvim_win_set_buf(0, alt_buf) end + return vim.api.nvim_buf_delete(data.buf, { force = true }) end local path = vim.api.nvim_buf_get_name(0) From f1db59bd7201e5a45d5afba9713b916720e0b136 Mon Sep 17 00:00:00 2001 From: abeldekat <58370433+abeldekat@users.noreply.github.com> Date: Thu, 11 Dec 2025 08:22:55 +0100 Subject: [PATCH 6/6] fix(pick): review, less verbose test_files --- ...xternal-`vim.api.nvim_set_current_win`-002 | 33 ------------------- tests/test_files.lua | 21 +++--------- 2 files changed, 4 insertions(+), 50 deletions(-) delete mode 100644 tests/screenshots/tests-test_files.lua---Default-explorer---does-not-crash-on-external-`vim.api.nvim_set_current_win`-002 diff --git a/tests/screenshots/tests-test_files.lua---Default-explorer---does-not-crash-on-external-`vim.api.nvim_set_current_win`-002 b/tests/screenshots/tests-test_files.lua---Default-explorer---does-not-crash-on-external-`vim.api.nvim_set_current_win`-002 deleted file mode 100644 index 61a21223..00000000 --- a/tests/screenshots/tests-test_files.lua---Default-explorer---does-not-crash-on-external-`vim.api.nvim_set_current_win`-002 +++ /dev/null @@ -1,33 +0,0 @@ ---|---------|---------|---------|---------|---------|---------|---------|---------| -01|a-file -02|~ -03|~ -04|~ -05|~ -06|~ -07|~ -08|~ -09|~ -10|~ -11|~ -12|~ -13|~ -14|~ -15| 1,1 All - ---|---------|---------|---------|---------|---------|---------|---------|---------| -01|00000000000000000000000000000000000000000000000000000000000000000000000000000000 -02|11111111111111111111111111111111111111111111111111111111111111111111111111111111 -03|11111111111111111111111111111111111111111111111111111111111111111111111111111111 -04|11111111111111111111111111111111111111111111111111111111111111111111111111111111 -05|11111111111111111111111111111111111111111111111111111111111111111111111111111111 -06|11111111111111111111111111111111111111111111111111111111111111111111111111111111 -07|11111111111111111111111111111111111111111111111111111111111111111111111111111111 -08|11111111111111111111111111111111111111111111111111111111111111111111111111111111 -09|11111111111111111111111111111111111111111111111111111111111111111111111111111111 -10|11111111111111111111111111111111111111111111111111111111111111111111111111111111 -11|11111111111111111111111111111111111111111111111111111111111111111111111111111111 -12|11111111111111111111111111111111111111111111111111111111111111111111111111111111 -13|11111111111111111111111111111111111111111111111111111111111111111111111111111111 -14|11111111111111111111111111111111111111111111111111111111111111111111111111111111 -15|22222222222222222222222222222222222222222222222222222222222222222222222222222222 diff --git a/tests/test_files.lua b/tests/test_files.lua index 08ffd146..230df055 100644 --- a/tests/test_files.lua +++ b/tests/test_files.lua @@ -5741,50 +5741,37 @@ T['Default explorer']['works in `:edit .`'] = function() end T['Default explorer']['deletes directory buffer if already visited(no alternate)'] = function() - -- Starting with empty buffer having id 1, open and close the explorer + -- Starting with empty buffer having id 1 child.cmd('edit ' .. test_dir_path) close() - -- There should only be 1 buffer after closing the explorer local bufs = child.api.nvim_list_bufs() eq(#bufs, 1) - -- Assert that buffer with id 1 has been deleted, otherwise it would be for directory test_dir_path + -- Assert that buffer with id 1 has been deleted, otherwise it would be named to directory test_dir_path local is_still_one = bufs[1] == 1 eq(is_still_one, false) end T['Default explorer']['deletes directory buffer if already visited'] = function() - -- Starting with listed buffer having id 1, open and close the explorer + -- Starting with listed buffer having id 1 child.cmd('edit ' .. test_file_path) child.cmd('edit ' .. test_dir_path) close() - -- There should only be 1 buffer after closing the explorer local bufs = child.api.nvim_list_bufs() eq(#bufs, 1) - - -- Assert that the buffer id is still 1 - local bufid = bufs[1] - eq(bufid, 1) + eq(bufs[1], 1) end T['Default explorer']['does not crash on external `vim.api.nvim_set_current_win`'] = function() - -- BufEnter Autocommands for "*": Vim(append):Lua callback : Invalid buffer id: 2 - child.cmd('edit ' .. test_file_path) child.cmd('edit ' .. test_dir_path) - - -- Mimic MiniPick when stopping the picker(H.picker_stop -> H.set_curwin) child.lua([[ local win_id = vim.api.nvim_list_wins()[1] -- win id 1000 vim.api.nvim_set_current_win(win_id) ]]) - child.expect_screenshot() - close() - child.expect_screenshot() - eq(#child.api.nvim_list_bufs(), 1) end T['Default explorer']['works in `:vsplit .`'] = function()