Skip to content

Instantly share code, notes, and snippets.

@rbtnn
Created July 24, 2016 06:48
Show Gist options
  • Save rbtnn/435568a26615f09e1e638788b090b0b0 to your computer and use it in GitHub Desktop.
Save rbtnn/435568a26615f09e1e638788b090b0b0 to your computer and use it in GitHub Desktop.
diff --git src/eval.c src/eval.c
index 53c188b..3d2c22b 100644
--- src/eval.c
+++ src/eval.c
@@ -187,6 +187,7 @@ static struct vimvar
{VV_NAME("t_none", VAR_NUMBER), VV_RO},
{VV_NAME("t_job", VAR_NUMBER), VV_RO},
{VV_NAME("t_channel", VAR_NUMBER), VV_RO},
+ {VV_NAME("stacktrace", VAR_LIST), VV_RO},
};
/* shorthand */
@@ -296,6 +297,7 @@ eval_init(void)
set_vim_var_nr(VV_HLSEARCH, 1L);
set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
set_vim_var_list(VV_ERRORS, list_alloc());
+ set_vim_var_list(VV_STACKTRACE, list_alloc());
set_vim_var_nr(VV_FALSE, VVAL_FALSE);
set_vim_var_nr(VV_TRUE, VVAL_TRUE);
@@ -6655,6 +6657,63 @@ v_throwpoint(char_u *oldval)
return NULL;
}
+ void
+pop_stacktrace()
+{
+ list_T *li = NULL;
+
+ li = vimvars[VV_STACKTRACE].vv_list;
+ if (li == NULL)
+ return;
+
+ if (0 < li->lv_len && li->lv_last != NULL)
+ listitem_remove(li, li->lv_last);
+}
+
+ void
+push_stacktrace(char_u *name, linenr_T lnum, scid_T id)
+{
+ list_T *li = NULL;
+ dict_T *di = NULL;
+ typval_T tv;
+ int idx = 0;
+
+ if (name == NULL)
+ return;
+
+ li = vimvars[VV_STACKTRACE].vv_list;
+ if (li == NULL)
+ return;
+
+ di = dict_alloc();
+ if (di == NULL)
+ return;
+
+ if (STRNCMP("function ", name, 9) == 0)
+ {
+ // get the function name without callstack.
+ idx = STRLEN(name);
+ while (0 < idx)
+ if (name[idx - 1] == '.' || name[idx - 1] == ' ')
+ break;
+ else
+ idx--;
+ }
+ else
+ // 'name' is a filepath.
+ idx = 0;
+
+ tv.v_type = VAR_DICT;
+ tv.v_lock = VAR_LOCKED;
+ tv.vval.v_dict = di;
+
+ dict_add_nr_str(di, "name", 0L, name + idx);
+ dict_add_nr_str(di, "lnum", lnum, NULL);
+ dict_add_nr_str(di, "path", 0L, get_scriptname(id));
+
+ list_append_tv(li, &tv);
+}
+
#if defined(FEAT_AUTOCMD) || defined(PROTO)
/*
* Set v:cmdarg.
diff --git src/userfunc.c src/userfunc.c
index af1863f..019f4f7 100644
--- src/userfunc.c
+++ src/userfunc.c
@@ -480,8 +480,10 @@ get_func_tv(
&argvars[i];
}
+ push_stacktrace(sourcing_name, sourcing_lnum, current_SID);
ret = call_func(name, len, rettv, argcount, argvars, NULL,
firstline, lastline, doesrange, evaluate, partial, selfdict);
+ pop_stacktrace();
funcargs.ga_len -= i;
}
diff --git src/vim.h src/vim.h
index e2d4cc4..c5f35a3 100644
--- src/vim.h
+++ src/vim.h
@@ -1981,7 +1981,8 @@ typedef int sock_T;
#define VV_TYPE_NONE 78
#define VV_TYPE_JOB 79
#define VV_TYPE_CHANNEL 80
-#define VV_LEN 81 /* number of v: vars */
+#define VV_STACKTRACE 81
+#define VV_LEN 82 /* number of v: vars */
/* used for v_number in VAR_SPECIAL */
#define VVAL_FALSE 0L
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment