Skip to content

Commit 1be4b81

Browse files
zeertzjqbrammool
authored andcommitted
patch 9.0.1470: deferred functions invoked in unexpected order
Problem: Deferred functions invoked in unexpected order when using :qa and autocommands. Solution: Call deferred functions for the current funccal before using the stack. (closes #12278)
1 parent 960cf91 commit 1be4b81

3 files changed

Lines changed: 32 additions & 14 deletions

File tree

src/testdir/test_user_func.vim

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -704,29 +704,45 @@ endfunc
704704

705705
func Test_defer_quitall_autocmd()
706706
let lines =<< trim END
707-
autocmd User DeferAutocmdThree qa!
707+
func DeferLevelFive()
708+
defer writefile(['5'], 'XQuitallAutocmd', 'a')
709+
qa!
710+
endfunc
708711

709-
func DeferLevelTwo()
710-
call writefile(['text'], 'XQuitallAutocmdTwo', 'D')
711-
doautocmd User DeferAutocmdThree
712+
autocmd User DeferAutocmdFive call DeferLevelFive()
713+
714+
def DeferLevelFour()
715+
defer writefile(['4'], 'XQuitallAutocmd', 'a')
716+
doautocmd User DeferAutocmdFive
717+
enddef
718+
719+
func DeferLevelThree()
720+
defer writefile(['3'], 'XQuitallAutocmd', 'a')
721+
call DeferLevelFour()
712722
endfunc
713723

714-
autocmd User DeferAutocmdTwo ++nested call DeferLevelTwo()
724+
autocmd User DeferAutocmdThree ++nested call DeferLevelThree()
715725

716-
def DeferLevelOne()
717-
call writefile(['text'], 'XQuitallAutocmdOne', 'D')
718-
doautocmd User DeferAutocmdTwo
726+
def DeferLevelTwo()
727+
defer writefile(['2'], 'XQuitallAutocmd', 'a')
728+
doautocmd User DeferAutocmdThree
719729
enddef
720730

731+
func DeferLevelOne()
732+
defer writefile(['1'], 'XQuitallAutocmd', 'a')
733+
call DeferLevelTwo()
734+
endfunc
735+
721736
autocmd User DeferAutocmdOne ++nested call DeferLevelOne()
722737

723738
doautocmd User DeferAutocmdOne
724739
END
725740
call writefile(lines, 'XdeferQuitallAutocmd', 'D')
726-
let res = system(GetVimCommand() .. ' -X -S XdeferQuitallAutocmd')
741+
call system(GetVimCommand() .. ' -X -S XdeferQuitallAutocmd')
727742
call assert_equal(0, v:shell_error)
728-
call assert_false(filereadable('XQuitallAutocmdOne'))
729-
call assert_false(filereadable('XQuitallAutocmdTwo'))
743+
call assert_equal(['5', '4', '3', '2', '1'], readfile('XQuitallAutocmd'))
744+
745+
call delete('XQuitallAutocmd')
730746
endfunc
731747

732748
func Test_defer_quitall_in_expr_func()

src/userfunc.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6144,12 +6144,12 @@ invoke_funccall_defer(funccall_T *fc)
61446144
void
61456145
invoke_all_defer(void)
61466146
{
6147+
for (funccall_T *fc = current_funccal; fc != NULL; fc = fc->fc_caller)
6148+
invoke_funccall_defer(fc);
6149+
61476150
for (funccal_entry_T *fce = funccal_stack; fce != NULL; fce = fce->next)
61486151
for (funccall_T *fc = fce->top_funccal; fc != NULL; fc = fc->fc_caller)
61496152
invoke_funccall_defer(fc);
6150-
6151-
for (funccall_T *fc = current_funccal; fc != NULL; fc = fc->fc_caller)
6152-
invoke_funccall_defer(fc);
61536153
}
61546154

61556155
/*

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,8 @@ static char *(features[]) =
695695

696696
static int included_patches[] =
697697
{ /* Add new patch number below this line */
698+
/**/
699+
1470,
698700
/**/
699701
1469,
700702
/**/

0 commit comments

Comments
 (0)