mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-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 vim/vim#12266)
42994bf678
Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
parent
0a3645a723
commit
8e0ad6e261
@ -3242,12 +3242,24 @@ static void handle_defer_one(funccall_T *funccal)
|
||||
{
|
||||
for (int idx = funccal->fc_defer.ga_len - 1; idx >= 0; idx--) {
|
||||
defer_T *dr = ((defer_T *)funccal->fc_defer.ga_data) + idx;
|
||||
|
||||
if (dr->dr_name == NULL) {
|
||||
// already being called, can happen if function does ":qa"
|
||||
continue;
|
||||
}
|
||||
|
||||
funcexe_T funcexe = { .fe_evaluate = true };
|
||||
|
||||
typval_T rettv;
|
||||
rettv.v_type = VAR_UNKNOWN; // tv_clear() uses this
|
||||
call_func(dr->dr_name, -1, &rettv, dr->dr_argcount, dr->dr_argvars, &funcexe);
|
||||
|
||||
char *name = dr->dr_name;
|
||||
dr->dr_name = NULL;
|
||||
|
||||
call_func(name, -1, &rettv, dr->dr_argcount, dr->dr_argvars, &funcexe);
|
||||
|
||||
tv_clear(&rettv);
|
||||
xfree(dr->dr_name);
|
||||
xfree(name);
|
||||
for (int i = dr->dr_argcount - 1; i >= 0; i--) {
|
||||
tv_clear(&dr->dr_argvars[i]);
|
||||
}
|
||||
|
@ -614,6 +614,7 @@ func Test_defer_quitall()
|
||||
" vim9script
|
||||
func DeferLevelTwo()
|
||||
call writefile(['text'], 'XQuitallTwo', 'D')
|
||||
call writefile(['quit'], 'XQuitallThree', 'a')
|
||||
qa!
|
||||
endfunc
|
||||
|
||||
@ -632,6 +633,9 @@ func Test_defer_quitall()
|
||||
call assert_equal(0, v:shell_error)
|
||||
call assert_false(filereadable('XQuitallOne'))
|
||||
call assert_false(filereadable('XQuitallTwo'))
|
||||
call assert_equal(['quit'], readfile('XQuitallThree'))
|
||||
|
||||
call delete('XQuitallThree')
|
||||
endfunc
|
||||
|
||||
func Test_defer_quitall_in_expr_func()
|
||||
|
Loading…
Reference in New Issue
Block a user