diff --git a/src/testdir/test_window_cmd.vim b/src/testdir/test_window_cmd.vim index b5ec9e5e75..e7f391ed9c 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 7c9c18a7db..cf4cf4f2dc 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 46302b848d..bd56885008 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