@@ -7851,10 +7851,50 @@ echo_string(
78517851 break;
78527852
78537853 case VAR_PARTIAL:
7854- *tofree = NULL;
7855- /* TODO: arguments */
7856- r = tv->vval.v_partial == NULL ? NULL : tv->vval.v_partial->pt_name;
7857- break;
7854+ {
7855+ partial_T *pt = tv->vval.v_partial;
7856+ char_u *fname = string_quote(pt == NULL ? NULL
7857+ : pt->pt_name, FALSE);
7858+ garray_T ga;
7859+ int i;
7860+ char_u *tf;
7861+
7862+ ga_init2(&ga, 1, 100);
7863+ ga_concat(&ga, (char_u *)"function(");
7864+ if (fname != NULL)
7865+ {
7866+ ga_concat(&ga, fname);
7867+ vim_free(fname);
7868+ }
7869+ if (pt != NULL && pt->pt_argc > 0)
7870+ {
7871+ ga_concat(&ga, (char_u *)", [");
7872+ for (i = 0; i < pt->pt_argc; ++i)
7873+ {
7874+ if (i > 0)
7875+ ga_concat(&ga, (char_u *)", ");
7876+ ga_concat(&ga,
7877+ tv2string(&pt->pt_argv[i], &tf, numbuf, copyID));
7878+ vim_free(tf);
7879+ }
7880+ ga_concat(&ga, (char_u *)"]");
7881+ }
7882+ if (pt != NULL && pt->pt_dict != NULL)
7883+ {
7884+ typval_T dtv;
7885+
7886+ ga_concat(&ga, (char_u *)", ");
7887+ dtv.v_type = VAR_DICT;
7888+ dtv.vval.v_dict = pt->pt_dict;
7889+ ga_concat(&ga, tv2string(&dtv, &tf, numbuf, copyID));
7890+ vim_free(tf);
7891+ }
7892+ ga_concat(&ga, (char_u *)")");
7893+
7894+ *tofree = ga.ga_data;
7895+ r = *tofree;
7896+ break;
7897+ }
78587898
78597899 case VAR_LIST:
78607900 if (tv->vval.v_list == NULL)
@@ -7941,50 +7981,6 @@ tv2string(
79417981 case VAR_FUNC:
79427982 *tofree = string_quote(tv->vval.v_string, TRUE);
79437983 return *tofree;
7944- case VAR_PARTIAL:
7945- {
7946- partial_T *pt = tv->vval.v_partial;
7947- char_u *fname = string_quote(pt == NULL ? NULL
7948- : pt->pt_name, FALSE);
7949- garray_T ga;
7950- int i;
7951- char_u *tf;
7952-
7953- ga_init2(&ga, 1, 100);
7954- ga_concat(&ga, (char_u *)"function(");
7955- if (fname != NULL)
7956- {
7957- ga_concat(&ga, fname);
7958- vim_free(fname);
7959- }
7960- if (pt != NULL && pt->pt_argc > 0)
7961- {
7962- ga_concat(&ga, (char_u *)", [");
7963- for (i = 0; i < pt->pt_argc; ++i)
7964- {
7965- if (i > 0)
7966- ga_concat(&ga, (char_u *)", ");
7967- ga_concat(&ga,
7968- tv2string(&pt->pt_argv[i], &tf, numbuf, copyID));
7969- vim_free(tf);
7970- }
7971- ga_concat(&ga, (char_u *)"]");
7972- }
7973- if (pt != NULL && pt->pt_dict != NULL)
7974- {
7975- typval_T dtv;
7976-
7977- ga_concat(&ga, (char_u *)", ");
7978- dtv.v_type = VAR_DICT;
7979- dtv.vval.v_dict = pt->pt_dict;
7980- ga_concat(&ga, tv2string(&dtv, &tf, numbuf, copyID));
7981- vim_free(tf);
7982- }
7983- ga_concat(&ga, (char_u *)")");
7984-
7985- *tofree = ga.ga_data;
7986- return *tofree;
7987- }
79887984 case VAR_STRING:
79897985 *tofree = string_quote(tv->vval.v_string, FALSE);
79907986 return *tofree;
@@ -7997,6 +7993,7 @@ tv2string(
79977993 case VAR_NUMBER:
79987994 case VAR_LIST:
79997995 case VAR_DICT:
7996+ case VAR_PARTIAL:
80007997 case VAR_SPECIAL:
80017998 case VAR_JOB:
80027999 case VAR_CHANNEL:
@@ -19285,7 +19282,8 @@ f_string(typval_T *argvars, typval_T *rettv)
1928519282 char_u numbuf[NUMBUFLEN];
1928619283
1928719284 rettv->v_type = VAR_STRING;
19288- rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0);
19285+ rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf,
19286+ get_copyID());
1928919287 /* Make a copy if we have a value but it's not in allocated memory. */
1929019288 if (rettv->vval.v_string != NULL && tofree == NULL)
1929119289 rettv->vval.v_string = vim_strsave(rettv->vval.v_string);
@@ -23484,7 +23482,8 @@ ex_function(exarg_T *eap)
2348423482 else
2348523483 arg = fudi.fd_newkey;
2348623484 if (arg != NULL && (fudi.fd_di == NULL
23487- || fudi.fd_di->di_tv.v_type != VAR_FUNC))
23485+ || (fudi.fd_di->di_tv.v_type != VAR_FUNC
23486+ && fudi.fd_di->di_tv.v_type != VAR_PARTIAL)))
2348823487 {
2348923488 if (*arg == K_SPECIAL)
2349023489 j = 3;
@@ -26467,8 +26466,10 @@ modify_fname(
2646726466 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'S')
2646826467 {
2646926468 /* vim_strsave_shellescape() needs a NUL terminated string. */
26469+ c = (*fnamep)[*fnamelen];
2647026470 (*fnamep)[*fnamelen] = NUL;
2647126471 p = vim_strsave_shellescape(*fnamep, FALSE, FALSE);
26472+ (*fnamep)[*fnamelen] = c;
2647226473 if (p == NULL)
2647326474 return -1;
2647426475 vim_free(*bufp);
0 commit comments