From 8e0ad6e261b81e9e2649bdba103904867b7ff6ef Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 19 Apr 2023 07:52:53 +0800 Subject: 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) https://github.com/vim/vim/commit/42994bf678f46dc9ca66e49f512261da8864fff6 Co-authored-by: Bram Moolenaar --- src/nvim/eval/userfunc.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/nvim/eval/userfunc.c') diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index 63d5f94f11..e8b50d8c94 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -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]); } -- cgit From a0c982671ee2f4c4e87a6480d2ea4d23ba807273 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 19 Apr 2023 07:59:35 +0800 Subject: vim-patch:9.0.1469: deferred functions not called from autocommands Problem: Deferred functions not called from autocommands. Solution: Also go through the funccal_stack. (closes vim/vim#12267) https://github.com/vim/vim/commit/960cf9119e3f4922ca9719feb5e0c0bc5e3b9840 --- src/nvim/eval/userfunc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/nvim/eval/userfunc.c') diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index e8b50d8c94..4cb2f9bd2b 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -3270,8 +3270,14 @@ static void handle_defer_one(funccall_T *funccal) /// Called when exiting: call all defer functions. void invoke_all_defer(void) { - for (funccall_T *funccal = current_funccal; funccal != NULL; funccal = funccal->fc_caller) { - handle_defer_one(funccal); + for (funccal_entry_T *fce = funccal_stack; fce != NULL; fce = fce->next) { + for (funccall_T *fc = fce->top_funccal; fc != NULL; fc = fc->fc_caller) { + handle_defer_one(fc); + } + } + + for (funccall_T *fc = current_funccal; fc != NULL; fc = fc->fc_caller) { + handle_defer_one(fc); } } -- cgit