Skip to content

Commit 02672bf

Browse files
committed
Merge remote-tracking branch 'vim/master'
2 parents adfd1ac + 92053ce commit 02672bf

27 files changed

Lines changed: 498 additions & 138 deletions

runtime/doc/eval.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5035,8 +5035,9 @@ getchar([expr]) *getchar()*
50355035
When the user clicks a mouse button, the mouse event will be
50365036
returned. The position can then be found in |v:mouse_col|,
50375037
|v:mouse_lnum|, |v:mouse_winid| and |v:mouse_win|.
5038-
|getmousepos()| can also be used. This example positions the
5039-
mouse as it would normally happen: >
5038+
|getmousepos()| can also be used. Mouse move events will be
5039+
ignored.
5040+
This example positions the mouse as it would normally happen: >
50405041
let c = getchar()
50415042
if c == "\<LeftMouse>" && v:mouse_win > 0
50425043
exe v:mouse_win . "wincmd w"

src/eval.c

Lines changed: 112 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -379,59 +379,93 @@ skip_expr(char_u **pp)
379379
* Skip over an expression at "*pp".
380380
* If in Vim9 script and line breaks are encountered, the lines are
381381
* concatenated. "evalarg->eval_tofree" will be set accordingly.
382+
* "arg" is advanced to just after the expression.
383+
* "start" is set to the start of the expression, "end" to just after the end.
384+
* Also when the expression is copied to allocated memory.
382385
* Return FAIL for an error, OK otherwise.
383386
*/
384387
int
385-
skip_expr_concatenate(char_u **start, char_u **end, evalarg_T *evalarg)
388+
skip_expr_concatenate(
389+
char_u **arg,
390+
char_u **start,
391+
char_u **end,
392+
evalarg_T *evalarg)
386393
{
387394
typval_T rettv;
388395
int res;
389396
int vim9script = current_sctx.sc_version == SCRIPT_VERSION_VIM9;
390397
garray_T *gap = &evalarg->eval_ga;
391398
int save_flags = evalarg == NULL ? 0 : evalarg->eval_flags;
392399

393-
if (vim9script && evalarg->eval_cookie != NULL)
400+
if (vim9script
401+
&& (evalarg->eval_cookie != NULL || evalarg->eval_cctx != NULL))
394402
{
395403
ga_init2(gap, sizeof(char_u *), 10);
404+
// leave room for "start"
396405
if (ga_grow(gap, 1) == OK)
397-
// leave room for "start"
398406
++gap->ga_len;
399407
}
408+
*start = *arg;
400409

401410
// Don't evaluate the expression.
402411
if (evalarg != NULL)
403412
evalarg->eval_flags &= ~EVAL_EVALUATE;
404-
*end = skipwhite(*end);
405-
res = eval1(end, &rettv, evalarg);
413+
*arg = skipwhite(*arg);
414+
res = eval1(arg, &rettv, evalarg);
415+
*end = *arg;
406416
if (evalarg != NULL)
407417
evalarg->eval_flags = save_flags;
408418

409-
if (vim9script && evalarg->eval_cookie != NULL
410-
&& evalarg->eval_ga.ga_len > 1)
419+
if (vim9script
420+
&& (evalarg->eval_cookie != NULL || evalarg->eval_cctx != NULL))
411421
{
412-
char_u *p;
413-
size_t endoff = STRLEN(*end);
414-
415-
// Line breaks encountered, concatenate all the lines.
416-
*((char_u **)gap->ga_data) = *start;
417-
p = ga_concat_strings(gap, "");
418-
*((char_u **)gap->ga_data) = NULL;
419-
ga_clear_strings(gap);
420-
gap->ga_itemsize = 0;
421-
if (p == NULL)
422-
return FAIL;
423-
*start = p;
424-
vim_free(evalarg->eval_tofree);
425-
evalarg->eval_tofree = p;
426-
// Compute "end" relative to the end.
427-
*end = *start + STRLEN(*start) - endoff;
422+
if (evalarg->eval_ga.ga_len == 1)
423+
{
424+
// just one line, no need to concatenate
425+
ga_clear(gap);
426+
gap->ga_itemsize = 0;
427+
}
428+
else
429+
{
430+
char_u *p;
431+
size_t endoff = STRLEN(*arg);
432+
433+
// Line breaks encountered, concatenate all the lines.
434+
*((char_u **)gap->ga_data) = *start;
435+
p = ga_concat_strings(gap, "");
436+
437+
// free the lines only when using getsourceline()
438+
if (evalarg->eval_cookie != NULL)
439+
{
440+
// Do not free the first line, the caller can still use it.
441+
*((char_u **)gap->ga_data) = NULL;
442+
// Do not free the last line, "arg" points into it, free it
443+
// later.
444+
vim_free(evalarg->eval_tofree);
445+
evalarg->eval_tofree =
446+
((char_u **)gap->ga_data)[gap->ga_len - 1];
447+
((char_u **)gap->ga_data)[gap->ga_len - 1] = NULL;
448+
ga_clear_strings(gap);
449+
}
450+
else
451+
ga_clear(gap);
452+
gap->ga_itemsize = 0;
453+
if (p == NULL)
454+
return FAIL;
455+
*start = p;
456+
vim_free(evalarg->eval_tofree_lambda);
457+
evalarg->eval_tofree_lambda = p;
458+
// Compute "end" relative to the end.
459+
*end = *start + STRLEN(*start) - endoff;
460+
}
428461
}
429462

430463
return res;
431464
}
432465

433466
/*
434-
* Top level evaluation function, returning a string.
467+
* Top level evaluation function, returning a string. Does not handle line
468+
* breaks.
435469
* When "convert" is TRUE convert a List into a sequence of lines and convert
436470
* a Float to a String.
437471
* Return pointer to allocated memory, or NULL for failure.
@@ -1878,11 +1912,16 @@ eval_next_non_blank(char_u *arg, evalarg_T *evalarg, int *getnext)
18781912
*getnext = FALSE;
18791913
if (current_sctx.sc_version == SCRIPT_VERSION_VIM9
18801914
&& evalarg != NULL
1881-
&& evalarg->eval_cookie != NULL
1915+
&& (evalarg->eval_cookie != NULL || evalarg->eval_cctx != NULL)
18821916
&& (*arg == NUL || (VIM_ISWHITE(arg[-1])
18831917
&& *arg == '#' && arg[1] != '{')))
18841918
{
1885-
char_u *p = getline_peek(evalarg->eval_getline, evalarg->eval_cookie);
1919+
char_u *p;
1920+
1921+
if (evalarg->eval_cookie != NULL)
1922+
p = getline_peek(evalarg->eval_getline, evalarg->eval_cookie);
1923+
else
1924+
p = peek_next_line_from_context(evalarg->eval_cctx);
18861925

18871926
if (p != NULL)
18881927
{
@@ -1902,15 +1941,18 @@ eval_next_line(evalarg_T *evalarg)
19021941
garray_T *gap = &evalarg->eval_ga;
19031942
char_u *line;
19041943

1905-
line = evalarg->eval_getline(0, evalarg->eval_cookie, 0, TRUE);
1944+
if (evalarg->eval_cookie != NULL)
1945+
line = evalarg->eval_getline(0, evalarg->eval_cookie, 0, TRUE);
1946+
else
1947+
line = next_line_from_context(evalarg->eval_cctx, TRUE);
19061948
++evalarg->eval_break_count;
19071949
if (gap->ga_itemsize > 0 && ga_grow(gap, 1) == OK)
19081950
{
19091951
// Going to concatenate the lines after parsing.
19101952
((char_u **)gap->ga_data)[gap->ga_len] = line;
19111953
++gap->ga_len;
19121954
}
1913-
else
1955+
else if (evalarg->eval_cookie != NULL)
19141956
{
19151957
vim_free(evalarg->eval_tofree);
19161958
evalarg->eval_tofree = line;
@@ -1936,25 +1978,31 @@ skipwhite_and_linebreak(char_u *arg, evalarg_T *evalarg)
19361978
}
19371979

19381980
/*
1939-
* After using "evalarg" filled from "eap" free the memory.
1981+
* After using "evalarg" filled from "eap": free the memory.
19401982
*/
19411983
void
19421984
clear_evalarg(evalarg_T *evalarg, exarg_T *eap)
19431985
{
1944-
if (evalarg != NULL && evalarg->eval_tofree != NULL)
1986+
if (evalarg != NULL)
19451987
{
1946-
if (eap != NULL)
1988+
if (evalarg->eval_tofree != NULL)
19471989
{
1948-
// We may need to keep the original command line, e.g. for
1949-
// ":let" it has the variable names. But we may also need the
1950-
// new one, "nextcmd" points into it. Keep both.
1951-
vim_free(eap->cmdline_tofree);
1952-
eap->cmdline_tofree = *eap->cmdlinep;
1953-
*eap->cmdlinep = evalarg->eval_tofree;
1990+
if (eap != NULL)
1991+
{
1992+
// We may need to keep the original command line, e.g. for
1993+
// ":let" it has the variable names. But we may also need the
1994+
// new one, "nextcmd" points into it. Keep both.
1995+
vim_free(eap->cmdline_tofree);
1996+
eap->cmdline_tofree = *eap->cmdlinep;
1997+
*eap->cmdlinep = evalarg->eval_tofree;
1998+
}
1999+
else
2000+
vim_free(evalarg->eval_tofree);
2001+
evalarg->eval_tofree = NULL;
19542002
}
1955-
else
1956-
vim_free(evalarg->eval_tofree);
1957-
evalarg->eval_tofree = NULL;
2003+
2004+
vim_free(evalarg->eval_tofree_lambda);
2005+
evalarg->eval_tofree_lambda = NULL;
19582006
}
19592007
}
19602008

@@ -5034,35 +5082,27 @@ handle_subscript(
50345082
int ret = OK;
50355083
dict_T *selfdict = NULL;
50365084
int check_white = TRUE;
5085+
int getnext;
5086+
char_u *p;
50375087

5038-
// When at the end of the line and ".name" follows in the next line then
5039-
// consume the line break. Only when rettv is a dict.
5040-
if (rettv->v_type == VAR_DICT)
5088+
while (ret == OK)
50415089
{
5042-
int getnext;
5043-
char_u *p = eval_next_non_blank(*arg, evalarg, &getnext);
5044-
5045-
if (getnext && *p == '.' && ASCII_ISALPHA(p[1]))
5090+
// When at the end of the line and ".name" or "->{" or "->X" follows in
5091+
// the next line then consume the line break.
5092+
p = eval_next_non_blank(*arg, evalarg, &getnext);
5093+
if (getnext
5094+
&& ((rettv->v_type == VAR_DICT && *p == '.'
5095+
&& ASCII_ISALPHA(p[1]))
5096+
|| (*p == '-' && p[1] == '>'
5097+
&& (p[2] == '{' || ASCII_ISALPHA(p[2])))))
50465098
{
50475099
*arg = eval_next_line(evalarg);
50485100
check_white = FALSE;
50495101
}
5050-
}
50515102

5052-
// "." is ".name" lookup when we found a dict or when evaluating and
5053-
// scriptversion is at least 2, where string concatenation is "..".
5054-
while (ret == OK
5055-
&& (((**arg == '['
5056-
|| (**arg == '.' && (rettv->v_type == VAR_DICT
5057-
|| (!evaluate
5058-
&& (*arg)[1] != '.'
5059-
&& current_sctx.sc_version >= 2)))
5060-
|| (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC
5061-
|| rettv->v_type == VAR_PARTIAL)))
5062-
&& (!check_white || !VIM_ISWHITE(*(*arg - 1))))
5063-
|| (**arg == '-' && (*arg)[1] == '>')))
5064-
{
5065-
if (**arg == '(')
5103+
if ((**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC
5104+
|| rettv->v_type == VAR_PARTIAL))
5105+
&& (!check_white || !VIM_ISWHITE(*(*arg - 1))))
50665106
{
50675107
ret = call_func_rettv(arg, evalarg, rettv, evaluate,
50685108
selfdict, NULL);
@@ -5079,7 +5119,7 @@ handle_subscript(
50795119
dict_unref(selfdict);
50805120
selfdict = NULL;
50815121
}
5082-
else if (**arg == '-')
5122+
else if (**arg == '-' && (*arg)[1] == '>')
50835123
{
50845124
if (ret == OK)
50855125
{
@@ -5091,7 +5131,13 @@ handle_subscript(
50915131
ret = eval_method(arg, rettv, evalarg, verbose);
50925132
}
50935133
}
5094-
else // **arg == '[' || **arg == '.'
5134+
// "." is ".name" lookup when we found a dict or when evaluating and
5135+
// scriptversion is at least 2, where string concatenation is "..".
5136+
else if (**arg == '['
5137+
|| (**arg == '.' && (rettv->v_type == VAR_DICT
5138+
|| (!evaluate
5139+
&& (*arg)[1] != '.'
5140+
&& current_sctx.sc_version >= 2))))
50955141
{
50965142
dict_unref(selfdict);
50975143
if (rettv->v_type == VAR_DICT)
@@ -5108,6 +5154,8 @@ handle_subscript(
51085154
ret = FAIL;
51095155
}
51105156
}
5157+
else
5158+
break;
51115159
}
51125160

51135161
// Turn "dict.Func" into a partial for "Func" bound to "dict".

src/evalfunc.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -465,8 +465,8 @@ static funcentry_T global_functions[] =
465465
{"acos", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_acos)},
466466
{"add", 2, 2, FEARG_1, ret_first_arg, f_add},
467467
{"and", 2, 2, FEARG_1, ret_number, f_and},
468-
{"append", 2, 2, FEARG_LAST, ret_number, f_append},
469-
{"appendbufline", 3, 3, FEARG_LAST, ret_number, f_appendbufline},
468+
{"append", 2, 2, FEARG_2, ret_number, f_append},
469+
{"appendbufline", 3, 3, FEARG_3, ret_number, f_appendbufline},
470470
{"argc", 0, 1, 0, ret_number, f_argc},
471471
{"argidx", 0, 0, 0, ret_number, f_argidx},
472472
{"arglistid", 0, 2, 0, ret_number, f_arglistid},
@@ -1191,7 +1191,9 @@ internal_func_ret_type(int idx, int argcount, type_T **argtypes)
11911191

11921192
/*
11931193
* Check the argument count to use for internal function "idx".
1194-
* Returns OK or FAIL;
1194+
* Returns -1 for failure, 0 if no method base accepted, 1 if method base is
1195+
* first argument, 2 if method base is second argument, etc. 9 if method base
1196+
* is last argument.
11951197
*/
11961198
int
11971199
check_internal_func(int idx, int argcount)
@@ -1204,14 +1206,14 @@ check_internal_func(int idx, int argcount)
12041206
else if (argcount > global_functions[idx].f_max_argc)
12051207
res = FCERR_TOOMANY;
12061208
else
1207-
return OK;
1209+
return global_functions[idx].f_argtype;
12081210

12091211
name = internal_func_name(idx);
12101212
if (res == FCERR_TOOMANY)
12111213
semsg(_(e_toomanyarg), name);
12121214
else
12131215
semsg(_(e_toofewarg), name);
1214-
return FAIL;
1216+
return -1;
12151217
}
12161218

12171219
int

src/evalvars.c

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2377,6 +2377,7 @@ eval_variable(
23772377
{
23782378
int ret = OK;
23792379
typval_T *tv = NULL;
2380+
int foundFunc = FALSE;
23802381
dictitem_T *v;
23812382
int cc;
23822383

@@ -2404,21 +2405,36 @@ eval_variable(
24042405
// imported variable from another script
24052406
if (import != NULL)
24062407
{
2407-
scriptitem_T *si = SCRIPT_ITEM(import->imp_sid);
2408-
svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
2408+
if (import->imp_funcname != NULL)
2409+
{
2410+
foundFunc = TRUE;
2411+
if (rettv != NULL)
2412+
{
2413+
rettv->v_type = VAR_FUNC;
2414+
rettv->vval.v_string = vim_strsave(import->imp_funcname);
2415+
}
2416+
}
2417+
else
2418+
{
2419+
scriptitem_T *si = SCRIPT_ITEM(import->imp_sid);
2420+
svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
24092421
+ import->imp_var_vals_idx;
2410-
tv = sv->sv_tv;
2422+
tv = sv->sv_tv;
2423+
}
24112424
}
24122425
}
24132426

2414-
if (tv == NULL)
2427+
if (!foundFunc)
24152428
{
2416-
if (rettv != NULL && verbose)
2417-
semsg(_(e_undefvar), name);
2418-
ret = FAIL;
2429+
if (tv == NULL)
2430+
{
2431+
if (rettv != NULL && verbose)
2432+
semsg(_(e_undefvar), name);
2433+
ret = FAIL;
2434+
}
2435+
else if (rettv != NULL)
2436+
copy_tv(tv, rettv);
24192437
}
2420-
else if (rettv != NULL)
2421-
copy_tv(tv, rettv);
24222438

24232439
name[len] = cc;
24242440

0 commit comments

Comments
 (0)