patch 9.2.0566: <C-w>f duplicates window if do_ecmd() is aborted
Commit:
https://github.com/vim/vim/commit/113e507cdd7be13607db81dcd6cd09aaedf93540
Author: Yohei Kojima <[email protected]>
Date: Sat May 30 18:07:21 2026 +0000
patch 9.2.0566: <C-w>f duplicates window if do_ecmd() is aborted
Problem: If got_int is true when win_close() is called, it unexpectedly
fails in the branch that detects failure in apply_autocmds().
This causes wingotofile in do_window() to duplicate current
window when do_ecmd() is aborted with got_int.
Solution: Fix do_window() to save the got_int value before trying to
close the split window (Yohei Kojima).
Steps to reproduce:
1. run `touch a && touch .a.swp && echo a > b && vim b`
2. Type `<C-w>f`
3. In the warning dialogue, type `a` to abort
4. Current window is duplicated
closes: #20382
Signed-off-by: Yohei Kojima <[email protected]>
Signed-off-by: Christian Brabandt <[email protected]>
diff --git a/src/testdir/test_window_cmd.vim b/src/testdir/test_window_cmd.vim
index b5ec9e5e7..e7f391ed9 100644
--- a/src/testdir/test_window_cmd.vim
+++ b/src/testdir/test_window_cmd.vim
@@ -113,7 +113,39 @@ func Test_window_cmd_wincmd_gf()
call assert_notequal(fname, bufname("%"))
new | only!
+ au! test_window_cmd_wincmd_gf
augroup! test_window_cmd_wincmd_gf
+ delfunc s:swap_exists
+ bw!
+endfunc
+
+func Test_abort_in_wincmd_f()
+ let fname = 'test_f.txt'
+ let swp_fname = $'.{fname}.swp'
+ call writefile([], fname, 'D')
+ call writefile([], swp_fname, 'D')
+ " Remove the catch-all that runtest.vim adds
+ au! SwapExists
+ augroup test_window_cmd_wincmd_f
+ autocmd!
+ " (A)bort
+ autocmd SwapExists test_f.txt let v:swapchoice = 'a'
+ augroup END
+
+ call setline(1, fname)
+ call assert_equal(1, winnr('$'))
+ try
+ wincmd f
+ catch /^Vim:Interrupt$/
+ " expected interrupt by abort
+ endtry
+ call assert_equal(1, winnr('$'))
+ new | only!
+
+ " See :h W19 for the background of this au!. Ideally other tests
+ " should also follow this.
+ au! test_window_cmd_wincmd_f
+ augroup! test_window_cmd_wincmd_f
bw!
endfunc
diff --git a/src/version.c b/src/version.c
index 7c9c18a7d..cf4cf4f2d 100644
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 566,
/**/
565,
/**/
diff --git a/src/window.c b/src/window.c
index 46302b848..bd5688500 100644
--- a/src/window.c
+++ b/src/window.c
@@ -682,9 +682,21 @@ wingotofile:
if (do_ecmd(0, ptr, NULL, NULL, ECMD_LASTL,
ECMD_HIDE, NULL) == FAIL)
{
+ /*
+ * Note: if FEAT_EVAL is defined and do_ecmd() is
aborted resulting
+ * in got_int be true, win_close() unconditionally
fails. In such
+ * case, the window split for do_ecmd() is left
unclosed, i.e. the
+ * current window is just duplicated. To avoid
this, save and load
+ * got_int value before and after closing the
window.
+ */
+ sig_atomic_t old_got_int = got_int;
+ got_int = FALSE;
+
// Failed to open the file, close the window
// opened for it.
win_close(curwin, FALSE);
+ got_int = got_int || old_got_int;
+
goto_tabpage_win(oldtab, oldwin);
}
else
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/vim_dev/E1wTODA-00Ehft-9F%40256bit.org.