diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-04-19 08:35:27 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-19 08:35:27 +0800 |
commit | dd8781128f4b93d402bab281d11b85f2c45b987e (patch) | |
tree | 7067cacec0c072c6289a2f3a2b417775ef47e491 /src/nvim/eval/userfunc.c | |
parent | 0a3645a72307afa563683a6e06c544810e0b65eb (diff) | |
parent | a0c982671ee2f4c4e87a6480d2ea4d23ba807273 (diff) | |
download | rneovim-dd8781128f4b93d402bab281d11b85f2c45b987e.tar.gz rneovim-dd8781128f4b93d402bab281d11b85f2c45b987e.tar.bz2 rneovim-dd8781128f4b93d402bab281d11b85f2c45b987e.zip |
Merge pull request #23188 from zeertzjq/vim-9.0.1462
vim-patch:9.0.{1462,1468,1469}: :defer fixes
Diffstat (limited to 'src/nvim/eval/userfunc.c')
-rw-r--r-- | src/nvim/eval/userfunc.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index 63d5f94f11..4cb2f9bd2b 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]); } @@ -3258,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); } } |