Hi,

Consider the following script:

function! Callback(arg1, arg2, name)
  echo [a:arg1, a:arg2, a:name]
endfunction
let Func = function('Callback', ['one', 'two'])
let Func2 = function(Func, ['name'])
call Func2()

I expect ['one', 'two', 'name'] for the output, but this doesn't work and
even it crashes.  Attached patch fixes this.

Should `function({partial}, {args})` append {args} to the existing arguments
or replace them?  I think it should append.

Regards,
Ken Takata

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
# HG changeset patch
# Parent  811908dd6c7f053712cbb8694d1babc99ef2f3e6

diff --git a/src/eval.c b/src/eval.c
--- a/src/eval.c
+++ b/src/eval.c
@@ -11832,6 +11832,7 @@ f_function(typval_T *argvars, typval_T *
     char_u	*s;
     char_u	*name;
     int		use_string = FALSE;
+    partial_T   *pt_arg = NULL;
 
     if (argvars[0].v_type == VAR_FUNC)
     {
@@ -11840,8 +11841,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;
+	pt_arg = argvars[0].vval.v_partial;
+	s = pt_arg->pt_name;
+    }
     else
     {
 	/* function('MyFunc', [arg], dict) */
@@ -11919,30 +11923,42 @@ f_function(typval_T *argvars, typval_T *
 		    arg_idx = 0;
 	    }
 	}
-	if (dict_idx > 0 || arg_idx > 0)
+	if (dict_idx > 0 || arg_idx > 0 || pt_arg != NULL)
 	{
 	    partial_T	*pt = (partial_T *)alloc_clear(sizeof(partial_T));
 
 	    if (pt != NULL)
 	    {
-		if (arg_idx > 0)
+		if (arg_idx > 0 || pt_arg != NULL)
 		{
 		    listitem_T	*li;
 		    int		i = 0;
-
-		    pt->pt_argv = (typval_T *)alloc(
-					     sizeof(typval_T) * list->lv_len);
-		    if (pt->pt_argv == NULL)
-		    {
-			vim_free(pt);
-			vim_free(name);
-			return;
-		    }
-		    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++]);
+		    int		arg_len = 0, lv_len = 0;
+
+		    if (pt_arg != NULL)
+			arg_len = pt_arg->pt_argc;
+		    if (list != NULL)
+			lv_len = list->lv_len;
+		    pt->pt_argc = arg_len + lv_len;
+		    if (pt->pt_argc > 0)
+		    {
+			pt->pt_argv = (typval_T *)alloc(
+					    sizeof(typval_T) * pt->pt_argc);
+			if (pt->pt_argv == NULL)
+			{
+			    vim_free(pt);
+			    vim_free(name);
+			    return;
+			}
+			else
+			{
+			    for (i = 0; i < arg_len; i++)
+				copy_tv(&pt_arg->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++]);
+			}
 		    }
 		}
 
@@ -11953,10 +11969,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 (pt_arg != NULL)
+		{
+		    pt->pt_dict = pt_arg->pt_dict;
+		    if (pt->pt_dict != NULL)
+			++pt->pt_dict->dv_refcount;
 		}
 
 		pt->pt_refcount = 1;
diff --git a/src/testdir/test_partial.vim b/src/testdir/test_partial.vim
--- 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))

Raspunde prin e-mail lui