@@ -3461,7 +3461,7 @@ ex_call(exarg_T *eap)
34613461 int doesrange;
34623462 int failed = FALSE;
34633463 funcdict_T fudi;
3464- partial_T *partial;
3464+ partial_T *partial = NULL ;
34653465
34663466 if (eap->skip)
34673467 {
@@ -3497,12 +3497,6 @@ ex_call(exarg_T *eap)
34973497 name = deref_func_name(tofree, &len,
34983498 partial != NULL ? NULL : &partial, FALSE);
34993499
3500- /* When calling fdict.func(), where "func" is a partial, use "fdict"
3501- * instead of the dict in the partial, for backwards compatibility.
3502- * TODO: Do use the arguments in the partial? */
3503- if (fudi.fd_dict != NULL)
3504- partial = NULL;
3505-
35063500 /* Skip white space to allow ":call func ()". Not good, but required for
35073501 * backward compatibility. */
35083502 startarg = skipwhite(arg);
@@ -11814,6 +11808,7 @@ f_function(typval_T *argvars, typval_T *rettv)
1181411808 char_u *s;
1181511809 char_u *name;
1181611810 int use_string = FALSE;
11811+ partial_T *arg_pt = NULL;
1181711812
1181811813 if (argvars[0].v_type == VAR_FUNC)
1181911814 {
@@ -11822,8 +11817,11 @@ f_function(typval_T *argvars, typval_T *rettv)
1182211817 }
1182311818 else if (argvars[0].v_type == VAR_PARTIAL
1182411819 && argvars[0].vval.v_partial != NULL)
11820+ {
1182511821 /* function(dict.MyFunc, [arg]) */
11826- s = argvars[0].vval.v_partial->pt_name;
11822+ arg_pt = argvars[0].vval.v_partial;
11823+ s = arg_pt->pt_name;
11824+ }
1182711825 else
1182811826 {
1182911827 /* function('MyFunc', [arg], dict) */
@@ -11901,19 +11899,27 @@ f_function(typval_T *argvars, typval_T *rettv)
1190111899 arg_idx = 0;
1190211900 }
1190311901 }
11904- if (dict_idx > 0 || arg_idx > 0)
11902+ if (dict_idx > 0 || arg_idx > 0 || arg_pt != NULL )
1190511903 {
1190611904 partial_T *pt = (partial_T *)alloc_clear(sizeof(partial_T));
1190711905
11906+ /* result is a VAR_PARTIAL */
1190811907 if (pt != NULL)
1190911908 {
11910- if (arg_idx > 0)
11909+ if (arg_idx > 0 || (arg_pt != NULL && arg_pt->pt_argc > 0) )
1191111910 {
1191211911 listitem_T *li;
1191311912 int i = 0;
11914-
11913+ int arg_len = 0;
11914+ int lv_len = 0;
11915+
11916+ if (arg_pt != NULL)
11917+ arg_len = arg_pt->pt_argc;
11918+ if (list != NULL)
11919+ lv_len = list->lv_len;
11920+ pt->pt_argc = arg_len + lv_len;
1191511921 pt->pt_argv = (typval_T *)alloc(
11916- sizeof(typval_T) * list->lv_len );
11922+ sizeof(typval_T) * pt->pt_argc );
1191711923 if (pt->pt_argv == NULL)
1191811924 {
1191911925 vim_free(pt);
@@ -11922,9 +11928,12 @@ f_function(typval_T *argvars, typval_T *rettv)
1192211928 }
1192311929 else
1192411930 {
11925- pt->pt_argc = list->lv_len;
11926- for (li = list->lv_first; li != NULL; li = li->li_next)
11927- copy_tv(&li->li_tv, &pt->pt_argv[i++]);
11931+ for (i = 0; i < arg_len; i++)
11932+ copy_tv(&arg_pt->pt_argv[i], &pt->pt_argv[i]);
11933+ if (lv_len > 0)
11934+ for (li = list->lv_first; li != NULL;
11935+ li = li->li_next)
11936+ copy_tv(&li->li_tv, &pt->pt_argv[i++]);
1192811937 }
1192911938 }
1193011939
@@ -11935,10 +11944,11 @@ f_function(typval_T *argvars, typval_T *rettv)
1193511944 pt->pt_dict = argvars[dict_idx].vval.v_dict;
1193611945 ++pt->pt_dict->dv_refcount;
1193711946 }
11938- else if (argvars[0].v_type == VAR_PARTIAL )
11947+ else if (arg_pt != NULL )
1193911948 {
11940- pt->pt_dict = argvars[0].vval.v_partial->pt_dict;
11941- ++pt->pt_dict->dv_refcount;
11949+ pt->pt_dict = arg_pt->pt_dict;
11950+ if (pt->pt_dict != NULL)
11951+ ++pt->pt_dict->dv_refcount;
1194211952 }
1194311953
1194411954 pt->pt_refcount = 1;
@@ -11950,6 +11960,7 @@ f_function(typval_T *argvars, typval_T *rettv)
1195011960 }
1195111961 else
1195211962 {
11963+ /* result is a VAR_FUNC */
1195311964 rettv->v_type = VAR_FUNC;
1195411965 rettv->vval.v_string = name;
1195511966 func_ref(name);
@@ -21744,17 +21755,18 @@ handle_subscript(
2174421755 }
2174521756 }
2174621757
21747- if (rettv->v_type == VAR_FUNC && selfdict != NULL)
21758+ if ((rettv->v_type == VAR_FUNC || rettv->v_type == VAR_PARTIAL)
21759+ && selfdict != NULL)
2174821760 {
21749- char_u *fname;
21761+ char_u *fname = rettv->v_type == VAR_FUNC ? rettv->vval.v_string
21762+ : rettv->vval.v_partial->pt_name;
2175021763 char_u *tofree = NULL;
2175121764 ufunc_T *fp;
2175221765 char_u fname_buf[FLEN_FIXED + 1];
2175321766 int error;
2175421767
2175521768 /* Translate "s:func" to the stored function name. */
21756- fname = fname_trans_sid(rettv->vval.v_string, fname_buf,
21757- &tofree, &error);
21769+ fname = fname_trans_sid(fname, fname_buf, &tofree, &error);
2175821770 fp = find_func(fname);
2175921771 vim_free(tofree);
2176021772
@@ -21768,7 +21780,34 @@ handle_subscript(
2176821780 pt->pt_refcount = 1;
2176921781 pt->pt_dict = selfdict;
2177021782 selfdict = NULL;
21771- pt->pt_name = rettv->vval.v_string;
21783+ if (rettv->v_type == VAR_FUNC)
21784+ {
21785+ /* just a function: use selfdict */
21786+ pt->pt_name = rettv->vval.v_string;
21787+ }
21788+ else
21789+ {
21790+ partial_T *ret_pt = rettv->vval.v_partial;
21791+ int i;
21792+
21793+ /* partial: use selfdict and copy args */
21794+ pt->pt_name = vim_strsave(ret_pt->pt_name);
21795+ if (ret_pt->pt_argc > 0)
21796+ {
21797+ pt->pt_argv = (typval_T *)alloc(
21798+ sizeof(typval_T) * ret_pt->pt_argc);
21799+ if (pt->pt_argv == NULL)
21800+ /* out of memory: drop the arguments */
21801+ pt->pt_argc = 0;
21802+ else
21803+ {
21804+ pt->pt_argc = ret_pt->pt_argc;
21805+ for (i = 0; i < pt->pt_argc; i++)
21806+ copy_tv(&ret_pt->pt_argv[i], &pt->pt_argv[i]);
21807+ }
21808+ }
21809+ partial_unref(ret_pt);
21810+ }
2177221811 func_ref(pt->pt_name);
2177321812 rettv->v_type = VAR_PARTIAL;
2177421813 rettv->vval.v_partial = pt;
@@ -23920,6 +23959,14 @@ trans_function_name(
2392023959 name = vim_strsave(lv.ll_tv->vval.v_string);
2392123960 *pp = end;
2392223961 }
23962+ else if (lv.ll_tv->v_type == VAR_PARTIAL
23963+ && lv.ll_tv->vval.v_partial != NULL)
23964+ {
23965+ name = vim_strsave(lv.ll_tv->vval.v_partial->pt_name);
23966+ *pp = end;
23967+ if (partial != NULL)
23968+ *partial = lv.ll_tv->vval.v_partial;
23969+ }
2392323970 else
2392423971 {
2392523972 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL
0 commit comments