mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 9.0.1462: recursively calling :defer function if it does :qa
Problem: Recursively calling :defer function if it does :qa. Solution: Clear the defer entry before calling the function. (closes #12266)
This commit is contained in:
parent
fc8a601c32
commit
42994bf678
@ -656,6 +656,7 @@ func Test_defer_quitall()
|
|||||||
vim9script
|
vim9script
|
||||||
func DeferLevelTwo()
|
func DeferLevelTwo()
|
||||||
call writefile(['text'], 'XQuitallTwo', 'D')
|
call writefile(['text'], 'XQuitallTwo', 'D')
|
||||||
|
call writefile(['quit'], 'XQuitallThree', 'a')
|
||||||
qa!
|
qa!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
@ -671,6 +672,9 @@ func Test_defer_quitall()
|
|||||||
call assert_equal(0, v:shell_error)
|
call assert_equal(0, v:shell_error)
|
||||||
call assert_false(filereadable('XQuitallOne'))
|
call assert_false(filereadable('XQuitallOne'))
|
||||||
call assert_false(filereadable('XQuitallTwo'))
|
call assert_false(filereadable('XQuitallTwo'))
|
||||||
|
call assert_equal(['quit'], readfile('XQuitallThree'))
|
||||||
|
|
||||||
|
call delete('XQuitallThree')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_defer_quitall_in_expr_func()
|
func Test_defer_quitall_in_expr_func()
|
||||||
|
@ -6096,20 +6096,27 @@ handle_defer_one(funccall_T *funccal)
|
|||||||
|
|
||||||
for (idx = funccal->fc_defer.ga_len - 1; idx >= 0; --idx)
|
for (idx = funccal->fc_defer.ga_len - 1; idx >= 0; --idx)
|
||||||
{
|
{
|
||||||
funcexe_T funcexe;
|
|
||||||
typval_T rettv;
|
|
||||||
defer_T *dr = ((defer_T *)funccal->fc_defer.ga_data) + idx;
|
defer_T *dr = ((defer_T *)funccal->fc_defer.ga_data) + idx;
|
||||||
int i;
|
|
||||||
|
|
||||||
|
if (dr->dr_name == NULL)
|
||||||
|
// already being called, can happen if function does ":qa"
|
||||||
|
continue;
|
||||||
|
|
||||||
|
funcexe_T funcexe;
|
||||||
CLEAR_FIELD(funcexe);
|
CLEAR_FIELD(funcexe);
|
||||||
funcexe.fe_evaluate = TRUE;
|
funcexe.fe_evaluate = TRUE;
|
||||||
|
|
||||||
|
typval_T rettv;
|
||||||
rettv.v_type = VAR_UNKNOWN; // clear_tv() uses this
|
rettv.v_type = VAR_UNKNOWN; // clear_tv() uses this
|
||||||
call_func(dr->dr_name, -1, &rettv,
|
|
||||||
dr->dr_argcount, dr->dr_argvars, &funcexe);
|
char_u *name = dr->dr_name;
|
||||||
|
dr->dr_name = NULL;
|
||||||
|
|
||||||
|
call_func(name, -1, &rettv, dr->dr_argcount, dr->dr_argvars, &funcexe);
|
||||||
|
|
||||||
clear_tv(&rettv);
|
clear_tv(&rettv);
|
||||||
vim_free(dr->dr_name);
|
vim_free(name);
|
||||||
for (i = dr->dr_argcount - 1; i >= 0; --i)
|
for (int i = dr->dr_argcount - 1; i >= 0; --i)
|
||||||
clear_tv(&dr->dr_argvars[i]);
|
clear_tv(&dr->dr_argvars[i]);
|
||||||
}
|
}
|
||||||
ga_clear(&funccal->fc_defer);
|
ga_clear(&funccal->fc_defer);
|
||||||
|
@ -695,6 +695,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1462,
|
||||||
/**/
|
/**/
|
||||||
1461,
|
1461,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user