Skip to content

Commit f90b6b8

Browse files
committed
feat(files): allow confirm in synchronize() to cancel sync
Resolve #1439
1 parent 62501d6 commit f90b6b8

File tree

4 files changed

+41
-15
lines changed

4 files changed

+41
-15
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
## mini.files
1212

1313
- FEATURE: closing and refreshing explorer now requires confirmation only if there are pending file system actions (and not in case of at least one modified buffer present).
14+
- FEATURE: confirming file system actions in `synchronize()` now can cancel synchronization (by pressing `c`) while keeping buffer contents the same. `synchronize()` also returns a boolean representing whether synchronization was done.
1415

1516
## mini.git
1617

doc/mini-files.txt

+4
Original file line numberDiff line numberDiff line change
@@ -750,9 +750,13 @@ Synchronize explorer
750750

751751
- Parse user edits in directory buffers.
752752
- Convert edits to file system actions and apply them after confirmation.
753+
Choosing "No" skips application while "Cancel" stops synchronization.
753754
- Update all directory buffers with the most relevant file system information.
754755
Can be used without user edits to account for external file system changes.
755756

757+
Return ~
758+
`(boolean)` Whether synchronization was done.
759+
756760
------------------------------------------------------------------------------
757761
*MiniFiles.reset()*
758762
`MiniFiles.reset`()

lua/mini/files.lua

+10-7
Original file line numberDiff line numberDiff line change
@@ -820,17 +820,26 @@ end
820820
---
821821
--- - Parse user edits in directory buffers.
822822
--- - Convert edits to file system actions and apply them after confirmation.
823+
--- Choosing "No" skips application while "Cancel" stops synchronization.
823824
--- - Update all directory buffers with the most relevant file system information.
824825
--- Can be used without user edits to account for external file system changes.
826+
---
827+
---@return boolean Whether synchronization was done.
825828
MiniFiles.synchronize = function()
826829
local explorer = H.explorer_get()
827830
if explorer == nil then return end
828831

829832
-- Parse and apply file system operations
830833
local fs_actions = H.explorer_compute_fs_actions(explorer)
831-
if fs_actions ~= nil and H.fs_actions_confirm(fs_actions) then H.fs_actions_apply(fs_actions) end
834+
if fs_actions ~= nil then
835+
local msg = table.concat(H.fs_actions_to_lines(fs_actions), '\n')
836+
local confirm_res = vim.fn.confirm(msg, '&Yes\n&No\n&Cancel', 1, 'Question')
837+
if confirm_res == 3 then return false end
838+
if confirm_res == 1 then H.fs_actions_apply(fs_actions) end
839+
end
832840

833841
H.explorer_refresh(explorer, { force_update = true })
842+
return true
834843
end
835844

836845
--- Reset explorer
@@ -2632,12 +2641,6 @@ H.fs_get_type = function(path)
26322641
end
26332642

26342643
-- File system actions --------------------------------------------------------
2635-
H.fs_actions_confirm = function(fs_actions)
2636-
local msg = table.concat(H.fs_actions_to_lines(fs_actions), '\n')
2637-
local confirm_res = vim.fn.confirm(msg, '&Yes\n&No', 1, 'Question')
2638-
return confirm_res == 1
2639-
end
2640-
26412644
H.fs_actions_to_lines = function(fs_actions)
26422645
-- Gather actions per source directory
26432646
local short = H.fs_shorten_path

tests/test_files.lua

+26-8
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,11 @@ local validate_fs_entry = function(x)
9494
eq(type(x.path), 'string')
9595
end
9696

97-
local validate_confirm_args = function(ref_msg_pattern)
97+
local validate_confirm_args = function(ref_msg_pattern, can_cancel)
98+
if can_cancel == nil then can_cancel = true end
9899
local args = child.lua_get('_G.confirm_args')
99100
expect.match(args[1], ref_msg_pattern)
100-
if args[2] ~= nil then eq(args[2], '&Yes\n&No') end
101+
if args[2] ~= nil then eq(args[2], '&Yes\n&No' .. (can_cancel and '\n&Cancel' or '')) end
101102
if args[3] ~= nil then eq(args[3], 1) end
102103
if args[4] ~= nil then eq(args[4], 'Question') end
103104
end
@@ -926,7 +927,7 @@ T['open()']['properly closes currently opened explorer with pending file system
926927
-- Should mention modified buffers and ask for confirmation
927928
mock_confirm(1)
928929
open(path_2)
929-
validate_confirm_args('pending file system actions.*Close without sync')
930+
validate_confirm_args('pending file system actions.*Close without sync', false)
930931

931932
-- Should trigger proper event for closing explorer
932933
eq(child.lua_get('_G.had_close_event'), true)
@@ -1075,7 +1076,7 @@ T['refresh()']['handles presence of pending file system actions'] = function()
10751076
child.lua('MiniFiles.refresh({ content = { filter = _G.hide_dotfiles }, windows = { width_focus = 30 } })')
10761077
child.expect_screenshot()
10771078

1078-
validate_confirm_args('pending file system actions.*Update buffers without sync')
1079+
validate_confirm_args('pending file system actions.*Update buffers without sync', false)
10791080

10801081
-- On no confirm should not update buffers, but still apply other changes
10811082
type_keys('o', 'new-file-2', '<Esc>')
@@ -1111,7 +1112,7 @@ T['synchronize()']['can update external file system changes'] = function()
11111112
validate_cur_line(1)
11121113

11131114
vim.fn.mkdir(join_path(temp_dir, 'aaa'))
1114-
synchronize()
1115+
eq(synchronize(), true)
11151116
child.expect_screenshot()
11161117

11171118
-- Cursor should be "sticked" to current entry
@@ -1124,14 +1125,31 @@ T['synchronize()']['can apply file system actions'] = function()
11241125
open(temp_dir)
11251126
type_keys('i', 'new-file', '<Esc>')
11261127

1127-
local new_file_path = join_path(temp_dir, 'new-file')
11281128
mock_confirm(1)
11291129

11301130
validate_tree(temp_dir, {})
1131-
synchronize()
1131+
eq(synchronize(), true)
11321132
validate_tree(temp_dir, { 'new-file' })
11331133
end
11341134

1135+
T['synchronize()']['can cancel synchronization'] = function()
1136+
local temp_dir = make_temp_dir('temp', {})
1137+
1138+
open(temp_dir)
1139+
type_keys('i', 'new-file', '<Esc>')
1140+
1141+
child.fn.writefile({ '' }, join_path(temp_dir, 'aaa'))
1142+
1143+
mock_confirm(3)
1144+
1145+
validate_tree(temp_dir, { 'aaa' })
1146+
eq(synchronize(), false)
1147+
-- Should not apply file system changes, not sync external changes, and keep
1148+
-- buffers as is
1149+
validate_tree(temp_dir, { 'aaa' })
1150+
eq(get_lines(), { 'new-file' })
1151+
end
1152+
11351153
T['synchronize()']['should follow cursor on current entry path'] = function()
11361154
local temp_dir = make_temp_dir('temp', { 'dir/', 'file' })
11371155

@@ -1256,7 +1274,7 @@ T['close()']['checks for pending file system actions'] = function()
12561274
mock_confirm(2)
12571275
eq(close(), false)
12581276
child.expect_screenshot()
1259-
validate_confirm_args('pending file system actions.*Close without sync')
1277+
validate_confirm_args('pending file system actions.*Close without sync', false)
12601278

12611279
-- - Should not trigger close event (as there was no closing)
12621280
eq(child.lua_get('_G.had_close_event'), vim.NIL)

0 commit comments

Comments
 (0)