Mercurial > vim
changeset 8593:dc36cef103de v7.4.1586
commit https://github.com/vim/vim/commit/8a1bb046378f4bc68d6a04af2eab80fb3ce04da6
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Mar 17 21:11:53 2016 +0100
patch 7.4.1586
Problem: Nesting partials doesn't work.
Solution: Append arguments. (Ken Takata)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 17 Mar 2016 21:15:10 +0100 |
parents | 628fe55c56ba |
children | f5836ba956b1 |
files | src/eval.c src/testdir/test_partial.vim src/version.c |
diffstat | 3 files changed, 39 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/src/eval.c +++ b/src/eval.c @@ -11814,6 +11814,7 @@ f_function(typval_T *argvars, typval_T * char_u *s; char_u *name; int use_string = FALSE; + partial_T *arg_pt = NULL; if (argvars[0].v_type == VAR_FUNC) { @@ -11822,8 +11823,11 @@ f_function(typval_T *argvars, typval_T * } else if (argvars[0].v_type == VAR_PARTIAL && argvars[0].vval.v_partial != NULL) + { /* function(dict.MyFunc, [arg]) */ - s = argvars[0].vval.v_partial->pt_name; + arg_pt = argvars[0].vval.v_partial; + s = arg_pt->pt_name; + } else { /* function('MyFunc', [arg], dict) */ @@ -11901,19 +11905,27 @@ f_function(typval_T *argvars, typval_T * arg_idx = 0; } } - if (dict_idx > 0 || arg_idx > 0) + if (dict_idx > 0 || arg_idx > 0 || arg_pt != NULL) { partial_T *pt = (partial_T *)alloc_clear(sizeof(partial_T)); + /* result is a VAR_PARTIAL */ if (pt != NULL) { - if (arg_idx > 0) + if (arg_idx > 0 || (arg_pt != NULL && arg_pt->pt_argc > 0)) { listitem_T *li; int i = 0; - + int arg_len = 0; + int lv_len = 0; + + if (arg_pt != NULL) + arg_len = arg_pt->pt_argc; + if (list != NULL) + lv_len = list->lv_len; + pt->pt_argc = arg_len + lv_len; pt->pt_argv = (typval_T *)alloc( - sizeof(typval_T) * list->lv_len); + sizeof(typval_T) * pt->pt_argc); if (pt->pt_argv == NULL) { vim_free(pt); @@ -11922,9 +11934,12 @@ f_function(typval_T *argvars, typval_T * } else { - pt->pt_argc = list->lv_len; - for (li = list->lv_first; li != NULL; li = li->li_next) - copy_tv(&li->li_tv, &pt->pt_argv[i++]); + for (i = 0; i < arg_len; i++) + copy_tv(&arg_pt->pt_argv[i], &pt->pt_argv[i]); + if (lv_len > 0) + for (li = list->lv_first; li != NULL; + li = li->li_next) + copy_tv(&li->li_tv, &pt->pt_argv[i++]); } } @@ -11935,10 +11950,11 @@ f_function(typval_T *argvars, typval_T * pt->pt_dict = argvars[dict_idx].vval.v_dict; ++pt->pt_dict->dv_refcount; } - else if (argvars[0].v_type == VAR_PARTIAL) - { - pt->pt_dict = argvars[0].vval.v_partial->pt_dict; - ++pt->pt_dict->dv_refcount; + else if (arg_pt != NULL) + { + pt->pt_dict = arg_pt->pt_dict; + if (pt->pt_dict != NULL) + ++pt->pt_dict->dv_refcount; } pt->pt_refcount = 1; @@ -11950,6 +11966,7 @@ f_function(typval_T *argvars, typval_T * } else { + /* result is a VAR_FUNC */ rettv->v_type = VAR_FUNC; rettv->vval.v_string = name; func_ref(name);
--- a/src/testdir/test_partial.vim +++ b/src/testdir/test_partial.vim @@ -20,9 +20,17 @@ func Test_partial_args() call Cb("zzz") call assert_equal("foo/bar/xxx", Cb("xxx")) call assert_equal("foo/bar/yyy", call(Cb, ["yyy"])) + let Cb2 = function(Cb) + call assert_equal("foo/bar/zzz", Cb2("zzz")) + let Cb3 = function(Cb, ["www"]) + call assert_equal("foo/bar/www", Cb3()) let Cb = function('MyFunc', []) call assert_equal("a/b/c", Cb("a", "b", "c")) + let Cb2 = function(Cb, []) + call assert_equal("a/b/d", Cb2("a", "b", "d")) + let Cb3 = function(Cb, ["a", "b"]) + call assert_equal("a/b/e", Cb3("e")) let Sort = function('MySort', [1]) call assert_equal([1, 2, 3], sort([3, 1, 2], Sort))