aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/eval')
-rw-r--r--src/nvim/eval/funcs.c17
-rw-r--r--src/nvim/eval/userfunc.c26
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);
+ }
}
}