aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/eval.c')
-rw-r--r--src/nvim/eval.c44
1 files changed, 32 insertions, 12 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index c61476cbfe..38ddd55855 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -2759,7 +2759,7 @@ void ex_call(exarg_T *eap)
int doesrange;
int failed = false;
funcdict_T fudi;
- partial_T *partial;
+ partial_T *partial = NULL;
if (eap->skip) {
/* trans_function_name() doesn't work well when skipping, use eval0()
@@ -2793,13 +2793,6 @@ void ex_call(exarg_T *eap)
name = deref_func_name(tofree, &len,
partial != NULL ? NULL : &partial, false);
- // When calling fdict.func(), where "func" is a partial, use "fdict"
- // instead of the dict in the partial, for backwards compatibility.
- // TODO(vim): Do use the arguments in the partial?
- if (fudi.fd_dict != NULL) {
- partial = NULL;
- }
-
/* Skip white space to allow ":call func ()". Not good, but required for
* backward compatibility. */
startarg = skipwhite(arg);
@@ -18378,15 +18371,17 @@ handle_subscript (
}
}
- if (rettv->v_type == VAR_FUNC && selfdict != NULL) {
- char_u *fname;
+ if ((rettv->v_type == VAR_FUNC || rettv->v_type == VAR_PARTIAL)
+ && selfdict != NULL) {
+ char_u *fname = rettv->v_type == VAR_FUNC ? rettv->vval.v_string
+ : rettv->vval.v_partial->pt_name;
char_u *tofree = NULL;
ufunc_T *fp;
char_u fname_buf[FLEN_FIXED + 1];
int error;
// Translate "s:func" to the stored function name.
- fname = fname_trans_sid(rettv->vval.v_string, fname_buf, &tofree, &error);
+ fname = fname_trans_sid(fname, fname_buf, &tofree, &error);
fp = find_func(fname);
xfree(tofree);
@@ -18399,7 +18394,29 @@ handle_subscript (
pt->pt_refcount = 1;
pt->pt_dict = selfdict;
selfdict = NULL;
- pt->pt_name = rettv->vval.v_string;
+ if (rettv->v_type == VAR_FUNC) {
+ // just a function: use selfdict
+ pt->pt_name = rettv->vval.v_string;
+ } else {
+ partial_T *ret_pt = rettv->vval.v_partial;
+ int i;
+
+ // partial: use selfdict and copy args
+ pt->pt_name = vim_strsave(ret_pt->pt_name);
+ if (ret_pt->pt_argc > 0) {
+ pt->pt_argv = (typval_T *)xmalloc(sizeof(typval_T) * ret_pt->pt_argc);
+ if (pt->pt_argv == NULL) {
+ // out of memory: drop the arguments
+ pt->pt_argc = 0;
+ } else {
+ pt->pt_argc = ret_pt->pt_argc;
+ for (i = 0; i < pt->pt_argc; i++) {
+ copy_tv(&ret_pt->pt_argv[i], &pt->pt_argv[i]);
+ }
+ }
+ }
+ partial_unref(ret_pt);
+ }
func_ref(pt->pt_name);
rettv->v_type = VAR_PARTIAL;
rettv->vval.v_partial = pt;
@@ -20344,6 +20361,9 @@ trans_function_name (
&& lv.ll_tv->vval.v_partial != NULL) {
name = vim_strsave(lv.ll_tv->vval.v_partial->pt_name);
*pp = end;
+ if (partial != NULL) {
+ *partial = lv.ll_tv->vval.v_partial;
+ }
} else {
if (!skip && !(flags & TFN_QUIET) && (fdp == NULL
|| lv.ll_dict == NULL