diff options
Diffstat (limited to 'src/nvim/eval')
-rw-r--r-- | src/nvim/eval/funcs.c | 17 | ||||
-rw-r--r-- | src/nvim/eval/userfunc.c | 26 |
2 files changed, 35 insertions, 8 deletions
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 28901d6e55..d903d498e7 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -44,6 +44,7 @@ #include "nvim/eval/executor.h" #include "nvim/eval/funcs.h" #include "nvim/eval/typval.h" +#include "nvim/eval/typval_defs.h" #include "nvim/eval/userfunc.h" #include "nvim/eval/vars.h" #include "nvim/eval/window.h" @@ -2264,7 +2265,8 @@ static void f_fnamemodify(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) /// "foreground()" function static void f_foreground(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) -{} +{ +} static void f_funcref(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { @@ -2940,7 +2942,8 @@ static void f_gettagstack(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) /// Dummy timer callback. Used by f_wait(). static void dummy_timer_due_cb(TimeWatcher *tw, void *data) -{} +{ +} /// Dummy timer close callback. Used by f_wait(). static void dummy_timer_close_cb(TimeWatcher *tw, void *data) @@ -3850,8 +3853,7 @@ static void f_insert(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) } /// "interrupt()" function -static void f_interrupt(typval_T *argvars FUNC_ATTR_UNUSED, typval_T *rettv FUNC_ATTR_UNUSED, - EvalFuncData fptr FUNC_ATTR_UNUSED) +static void f_interrupt(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { got_int = true; } @@ -8523,6 +8525,13 @@ static void f_substitute(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) } } +/// "swapfilelist()" function +static void f_swapfilelist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) +{ + tv_list_alloc_ret(rettv, kListLenUnknown); + recover_names(NULL, false, rettv->vval.v_list, 0, NULL); +} + /// "swapinfo(swap_filename)" function static void f_swapinfo(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index 63d5f94f11..51e109fdfb 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 (funccall_T *fc = current_funccal; fc != NULL; fc = fc->fc_caller) { + handle_defer_one(fc); + } + + 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); + } } } |