diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/eval.c | 44 | ||||
-rw-r--r-- | src/nvim/testdir/test_partial.vim | 30 | ||||
-rw-r--r-- | src/nvim/version.c | 2 |
3 files changed, 63 insertions, 13 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 diff --git a/src/nvim/testdir/test_partial.vim b/src/nvim/testdir/test_partial.vim index ae4f74cf5b..2b6b56c358 100644 --- a/src/nvim/testdir/test_partial.vim +++ b/src/nvim/testdir/test_partial.vim @@ -114,6 +114,36 @@ func Test_script_function_in_dict() call assert_equal('bar', B()) endfunc +function! s:cache_arg(arg) dict + let s:result = self.name . '/' . a:arg + return s:result +endfunction + +func Test_script_function_in_dict_arg() + let s:obj = {'name': 'foo'} + let s:obj['clear'] = function('s:cache_arg') + + call assert_equal('foo/bar', s:obj.clear('bar')) + let F = s:obj.clear + let s:result = '' + call assert_equal('foo/bar', F('bar')) + call assert_equal('foo/bar', s:result) + + let s:obj['clear'] = function('s:cache_arg', ['bar']) + call assert_equal('foo/bar', s:obj.clear()) + let s:result = '' + call s:obj.clear() + call assert_equal('foo/bar', s:result) + + let F = s:obj.clear + call assert_equal('foo/bar', F()) + let s:result = '' + call F() + call assert_equal('foo/bar', s:result) + + call assert_equal('foo/bar', call(s:obj.clear, [], s:obj)) +endfunc + func Test_partial_exists() let F = function('MyFunc') call assert_true(exists('*F')) diff --git a/src/nvim/version.c b/src/nvim/version.c index da9387c14d..24fe2ecd9e 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -853,7 +853,7 @@ static int included_patches[] = { 1592, 1591, // 1590, - // 1589, + 1589, 1588, // 1587 NA 1586, |