Skip to content

Commit 436394b

Browse files
committed
Merge remote-tracking branch 'vim/master'
2 parents e259374 + 870b749 commit 436394b

15 files changed

Lines changed: 197 additions & 45 deletions

File tree

runtime/doc/eval.txt

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*eval.txt* For Vim version 7.4. Last change: 2016 Jul 16
1+
*eval.txt* For Vim version 7.4. Last change: 2016 Jul 22
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -1535,7 +1535,7 @@ v:false A Number with value zero. Used to put "false" in JSON. See
15351535
echo v:false
15361536
< v:false ~
15371537
That is so that eval() can parse the string back to the same
1538-
value.
1538+
value. Read-only.
15391539

15401540
*v:fcs_reason* *fcs_reason-variable*
15411541
v:fcs_reason The reason why the |FileChangedShell| event was triggered.
@@ -1682,7 +1682,7 @@ v:none An empty String. Used to put an empty item in JSON. See
16821682
echo v:none
16831683
< v:none ~
16841684
That is so that eval() can parse the string back to the same
1685-
value.
1685+
value. Read-only.
16861686

16871687
*v:null* *null-variable*
16881688
v:null An empty String. Used to put "null" in JSON. See
@@ -1692,7 +1692,7 @@ v:null An empty String. Used to put "null" in JSON. See
16921692
echo v:null
16931693
< v:null ~
16941694
That is so that eval() can parse the string back to the same
1695-
value.
1695+
value. Read-only.
16961696

16971697
*v:oldfiles* *oldfiles-variable*
16981698
v:oldfiles List of file names that is loaded from the |viminfo| file on
@@ -1890,7 +1890,7 @@ v:true A Number with value one. Used to put "true" in JSON. See
18901890
echo v:true
18911891
< v:true ~
18921892
That is so that eval() can parse the string back to the same
1893-
value.
1893+
value. Read-only.
18941894
*v:val* *val-variable*
18951895
v:val Value of the current item of a |List| or |Dictionary|. Only
18961896
valid while evaluating the expression used with |map()| and
@@ -7144,16 +7144,24 @@ substitute({expr}, {pat}, {sub}, {flags}) *substitute()*
71447144
unmodified.
71457145

71467146
Example: >
7147-
:let &path = substitute(&path, ",\\=[^,]*$", "", "")
7147+
:let &path = substitute(&path, ",\\=[^,]*$", "", "")
71487148
< This removes the last component of the 'path' option. >
7149-
:echo substitute("testing", ".*", "\\U\\0", "")
7149+
:echo substitute("testing", ".*", "\\U\\0", "")
71507150
< results in "TESTING".
71517151

71527152
When {sub} starts with "\=", the remainder is interpreted as
71537153
an expression. See |sub-replace-expression|. Example: >
7154-
:echo substitute(s, '%\(\x\x\)',
7154+
:echo substitute(s, '%\(\x\x\)',
71557155
\ '\=nr2char("0x" . submatch(1))', 'g')
71567156
7157+
< When {sub} is a Funcref that function is called, with one
7158+
optional argument. Example: >
7159+
:echo substitute(s, '%\(\x\x\)', SubNr, 'g')
7160+
< The optional argument is a list which contains the whole
7161+
matched string and up to nine submatches,like what
7162+
|submatch()| returns. Example: >
7163+
:echo substitute(s, '\(\x\x\)', {m -> '0x' . m[1]}, 'g')
7164+
71577165
synID({lnum}, {col}, {trans}) *synID()*
71587166
The result is a Number, which is the syntax ID at the position
71597167
{lnum} and {col} in the current window.
@@ -7546,18 +7554,20 @@ trunc({expr}) *trunc()*
75467554
{only available when compiled with the |+float| feature}
75477555

75487556
*type()*
7549-
type({expr}) The result is a Number, depending on the type of {expr}:
7550-
Number: 0
7551-
String: 1
7552-
Funcref: 2
7553-
List: 3
7554-
Dictionary: 4
7555-
Float: 5
7556-
Boolean: 6 (v:false and v:true)
7557-
None 7 (v:null and v:none)
7558-
Job 8
7559-
Channel 9
7560-
To avoid the magic numbers it should be used this way: >
7557+
type({expr}) The result is a Number representing the type of {expr}.
7558+
Instead of using the number directly, it is better to use the
7559+
v:t_ variable that has the value:
7560+
Number: 0 |v:t_number|
7561+
String: 1 |v:t_string|
7562+
Funcref: 2 |v:t_func|
7563+
List: 3 |v:t_list|
7564+
Dictionary: 4 |v:t_dict|
7565+
Float: 5 |v:t_float|
7566+
Boolean: 6 |v:t_bool| (v:false and v:true)
7567+
None 7 |v:t_none| (v:null and v:none)
7568+
Job 8 |v:t_job|
7569+
Channel 9 |v:t_channel|
7570+
For backward compatibility, this method can be used: >
75617571
:if type(myvar) == type(0)
75627572
:if type(myvar) == type("")
75637573
:if type(myvar) == type(function("tr"))
@@ -7566,6 +7576,8 @@ type({expr}) The result is a Number, depending on the type of {expr}:
75667576
:if type(myvar) == type(0.0)
75677577
:if type(myvar) == type(v:false)
75687578
:if type(myvar) == type(v:none)
7579+
< To check if the v:t_ variables exist use this: >
7580+
:if exists('v:t_number')
75697581
75707582
undofile({name}) *undofile()*
75717583
Return the name of the undo file that would be used for a file

src/channel.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,8 +1554,8 @@ invoke_callback(channel_T *channel, char_u *callback, partial_T *partial,
15541554
argv[0].v_type = VAR_CHANNEL;
15551555
argv[0].vval.v_channel = channel;
15561556

1557-
call_func(callback, (int)STRLEN(callback),
1558-
&rettv, 2, argv, 0L, 0L, &dummy, TRUE, partial, NULL);
1557+
call_func(callback, (int)STRLEN(callback), &rettv, 2, argv, NULL,
1558+
0L, 0L, &dummy, TRUE, partial, NULL);
15591559
clear_tv(&rettv);
15601560
channel_need_redraw = TRUE;
15611561
}
@@ -2716,7 +2716,7 @@ channel_close(channel_T *channel, int invoke_close_cb)
27162716
argv[0].v_type = VAR_CHANNEL;
27172717
argv[0].vval.v_channel = channel;
27182718
call_func(channel->ch_close_cb, (int)STRLEN(channel->ch_close_cb),
2719-
&rettv, 1, argv, 0L, 0L, &dummy, TRUE,
2719+
&rettv, 1, argv, NULL, 0L, 0L, &dummy, TRUE,
27202720
channel->ch_close_partial, NULL);
27212721
clear_tv(&rettv);
27222722
channel_need_redraw = TRUE;
@@ -4783,7 +4783,7 @@ job_status(job_T *job)
47834783
argv[1].v_type = VAR_NUMBER;
47844784
argv[1].vval.v_number = job->jv_exitval;
47854785
call_func(job->jv_exit_cb, (int)STRLEN(job->jv_exit_cb),
4786-
&rettv, 2, argv, 0L, 0L, &dummy, TRUE,
4786+
&rettv, 2, argv, NULL, 0L, 0L, &dummy, TRUE,
47874787
job->jv_exit_partial, NULL);
47884788
clear_tv(&rettv);
47894789
--job->jv_refcount;

src/eval.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -988,7 +988,7 @@ call_vim_function(
988988
}
989989

990990
rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */
991-
ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars,
991+
ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, NULL,
992992
curwin->w_cursor.lnum, curwin->w_cursor.lnum,
993993
&doesrange, TRUE, NULL, NULL);
994994
if (safe)
@@ -9930,18 +9930,17 @@ filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp)
99309930
if (expr->v_type == VAR_FUNC)
99319931
{
99329932
s = expr->vval.v_string;
9933-
if (call_func(s, (int)STRLEN(s),
9934-
&rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL, NULL) == FAIL)
9933+
if (call_func(s, (int)STRLEN(s), &rettv, 2, argv, NULL,
9934+
0L, 0L, &dummy, TRUE, NULL, NULL) == FAIL)
99359935
goto theend;
99369936
}
99379937
else if (expr->v_type == VAR_PARTIAL)
99389938
{
99399939
partial_T *partial = expr->vval.v_partial;
99409940

99419941
s = partial->pt_name;
9942-
if (call_func(s, (int)STRLEN(s),
9943-
&rettv, 2, argv, 0L, 0L, &dummy, TRUE, partial, NULL)
9944-
== FAIL)
9942+
if (call_func(s, (int)STRLEN(s), &rettv, 2, argv, NULL,
9943+
0L, 0L, &dummy, TRUE, partial, NULL) == FAIL)
99459944
goto theend;
99469945
}
99479946
else

src/evalfunc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10128,7 +10128,7 @@ item_compare2(const void *s1, const void *s2)
1012810128

1012910129
rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */
1013010130
res = call_func(func_name, (int)STRLEN(func_name),
10131-
&rettv, 2, argv, 0L, 0L, &dummy, TRUE,
10131+
&rettv, 2, argv, NULL, 0L, 0L, &dummy, TRUE,
1013210132
partial, sortinfo->item_compare_selfdict);
1013310133
clear_tv(&argv[0]);
1013410134
clear_tv(&argv[1]);

src/ex_cmds2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1163,7 +1163,7 @@ timer_callback(timer_T *timer)
11631163
argv[1].v_type = VAR_UNKNOWN;
11641164

11651165
call_func(timer->tr_callback, (int)STRLEN(timer->tr_callback),
1166-
&rettv, 1, argv, 0L, 0L, &dummy, TRUE,
1166+
&rettv, 1, argv, NULL, 0L, 0L, &dummy, TRUE,
11671167
timer->tr_partial, NULL);
11681168
clear_tv(&rettv);
11691169
}

src/gui_beval.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,7 +1046,9 @@ set_printable_label_text(GtkLabel *label, char_u *text)
10461046
guicolor_T pixel;
10471047
#if GTK_CHECK_VERSION(3,0,0)
10481048
GdkRGBA color = { 0.0, 0.0, 0.0, 1.0 };
1049+
# if PANGO_VERSION_CHECK(1,38,0)
10491050
PangoAttribute *attr_alpha;
1051+
# endif
10501052
#else
10511053
GdkColor color = { 0, 0, 0, 0 };
10521054
#endif
@@ -1115,8 +1117,10 @@ set_printable_label_text(GtkLabel *label, char_u *text)
11151117
DOUBLE2UINT16(color.red),
11161118
DOUBLE2UINT16(color.green),
11171119
DOUBLE2UINT16(color.blue));
1120+
# if PANGO_VERSION_CHECK(1,38,0)
11181121
attr_alpha = pango_attr_foreground_alpha_new(
11191122
DOUBLE2UINT16(color.alpha));
1123+
# endif
11201124
# undef DOUBLE2UINT16
11211125
#else
11221126
attr = pango_attr_foreground_new(
@@ -1126,9 +1130,11 @@ set_printable_label_text(GtkLabel *label, char_u *text)
11261130
attr->end_index = pdest - buf + outlen;
11271131
pango_attr_list_insert(attr_list, attr);
11281132
#if GTK_CHECK_VERSION(3,0,0)
1133+
# if PANGO_VERSION_CHECK(1,38,0)
11291134
attr_alpha->start_index = pdest - buf;
11301135
attr_alpha->end_index = pdest - buf + outlen;
11311136
pango_attr_list_insert(attr_list, attr_alpha);
1137+
# endif
11321138
#endif
11331139
}
11341140
pdest += outlen;

src/list.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -924,4 +924,35 @@ write_list(FILE *fd, list_T *list, int binary)
924924
return ret;
925925
}
926926

927+
/*
928+
* Initialize a static list with 10 items.
929+
*/
930+
void
931+
init_static_list(staticList10_T *sl)
932+
{
933+
list_T *l = &sl->sl_list;
934+
int i;
935+
936+
memset(sl, 0, sizeof(staticList10_T));
937+
l->lv_first = &sl->sl_items[0];
938+
l->lv_last = &sl->sl_items[9];
939+
l->lv_refcount = DO_NOT_FREE_CNT;
940+
l->lv_lock = VAR_FIXED;
941+
sl->sl_list.lv_len = 10;
942+
943+
for (i = 0; i < 10; ++i)
944+
{
945+
listitem_T *li = &sl->sl_items[i];
946+
947+
if (i == 0)
948+
li->li_prev = NULL;
949+
else
950+
li->li_prev = li - 1;
951+
if (i == 9)
952+
li->li_next = NULL;
953+
else
954+
li->li_next = li + 1;
955+
}
956+
}
957+
927958
#endif /* defined(FEAT_EVAL) */

src/proto/list.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,5 @@ char_u *list2string(typval_T *tv, int copyID, int restore_copyID);
3232
int list_join(garray_T *gap, list_T *l, char_u *sep, int echo_style, int restore_copyID, int copyID);
3333
int get_list_tv(char_u **arg, typval_T *rettv, int evaluate);
3434
int write_list(FILE *fd, list_T *list, int binary);
35+
void init_static_list(staticList10_T *sl);
3536
/* vim: set ft=c : */

src/proto/userfunc.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ char_u *deref_func_name(char_u *name, int *lenp, partial_T **partialp, int no_au
55
int get_func_tv(char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, partial_T *partial, dict_T *selfdict);
66
void free_all_functions(void);
77
int func_call(char_u *name, typval_T *args, partial_T *partial, dict_T *selfdict, typval_T *rettv);
8-
int call_func(char_u *funcname, int len, typval_T *rettv, int argcount_in, typval_T *argvars_in, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, partial_T *partial, dict_T *selfdict_in);
8+
int call_func(char_u *funcname, int len, typval_T *rettv, int argcount_in, typval_T *argvars_in, int (*argv_func)(int, typval_T *, int), linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, partial_T *partial, dict_T *selfdict_in);
99
void ex_function(exarg_T *eap);
1010
int eval_fname_script(char_u *p);
1111
int translated_function_exists(char_u *name);

src/regexp.c

Lines changed: 67 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7290,6 +7290,50 @@ static int submatch_line_lbr;
72907290
#endif
72917291

72927292
#if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO)
7293+
7294+
/*
7295+
* Put the submatches in "argv[0]" which is a list passed into call_func() by
7296+
* vim_regsub_both().
7297+
*/
7298+
static int
7299+
fill_submatch_list(int argc UNUSED, typval_T *argv, int argcount)
7300+
{
7301+
listitem_T *li;
7302+
int i;
7303+
char_u *s;
7304+
7305+
if (argcount == 0)
7306+
/* called function doesn't take an argument */
7307+
return 0;
7308+
7309+
/* Relies on sl_list to be the first item in staticList10_T. */
7310+
init_static_list((staticList10_T *)(argv->vval.v_list));
7311+
7312+
/* There are always 10 list items in staticList10_T. */
7313+
li = argv->vval.v_list->lv_first;
7314+
for (i = 0; i < 10; ++i)
7315+
{
7316+
s = submatch_match->startp[i];
7317+
if (s == NULL || submatch_match->endp[i] == NULL)
7318+
s = NULL;
7319+
else
7320+
s = vim_strnsave(s, (int)(submatch_match->endp[i] - s));
7321+
li->li_tv.v_type = VAR_STRING;
7322+
li->li_tv.vval.v_string = s;
7323+
li = li->li_next;
7324+
}
7325+
return 1;
7326+
}
7327+
7328+
static void
7329+
clear_submatch_list(staticList10_T *sl)
7330+
{
7331+
int i;
7332+
7333+
for (i = 0; i < 10; ++i)
7334+
vim_free(sl->sl_items[i].li_tv.vval.v_string);
7335+
}
7336+
72937337
/*
72947338
* vim_regsub() - perform substitutions after a vim_regexec() or
72957339
* vim_regexec_multi() match.
@@ -7427,34 +7471,47 @@ vim_regsub_both(
74277471

74287472
if (expr != NULL)
74297473
{
7430-
typval_T argv[1];
7474+
typval_T argv[2];
74317475
int dummy;
74327476
char_u buf[NUMBUFLEN];
74337477
typval_T rettv;
7478+
staticList10_T matchList;
74347479

74357480
rettv.v_type = VAR_STRING;
74367481
rettv.vval.v_string = NULL;
74377482
if (prev_can_f_submatch)
74387483
{
74397484
/* can't do this recursively */
74407485
}
7441-
else if (expr->v_type == VAR_FUNC)
7486+
else
74427487
{
7443-
s = expr->vval.v_string;
7444-
call_func(s, (int)STRLEN(s), &rettv, 0, argv,
7488+
argv[0].v_type = VAR_LIST;
7489+
argv[0].vval.v_list = &matchList.sl_list;
7490+
matchList.sl_list.lv_len = 0;
7491+
if (expr->v_type == VAR_FUNC)
7492+
{
7493+
s = expr->vval.v_string;
7494+
call_func(s, (int)STRLEN(s), &rettv,
7495+
1, argv, fill_submatch_list,
74457496
0L, 0L, &dummy, TRUE, NULL, NULL);
7446-
}
7447-
else if (expr->v_type == VAR_PARTIAL)
7448-
{
7449-
partial_T *partial = expr->vval.v_partial;
7497+
}
7498+
else if (expr->v_type == VAR_PARTIAL)
7499+
{
7500+
partial_T *partial = expr->vval.v_partial;
74507501

7451-
s = partial->pt_name;
7452-
call_func(s, (int)STRLEN(s), &rettv, 0, argv,
7502+
s = partial->pt_name;
7503+
call_func(s, (int)STRLEN(s), &rettv,
7504+
1, argv, fill_submatch_list,
74537505
0L, 0L, &dummy, TRUE, partial, NULL);
7506+
}
7507+
if (matchList.sl_list.lv_len > 0)
7508+
/* fill_submatch_list() was called */
7509+
clear_submatch_list(&matchList);
74547510
}
74557511
eval_result = get_tv_string_buf_chk(&rettv, buf);
74567512
if (eval_result != NULL)
74577513
eval_result = vim_strsave(eval_result);
7514+
clear_tv(&rettv);
74587515
}
74597516
else
74607517
eval_result = eval_to_string(source + 2, NULL, TRUE);

0 commit comments

Comments
 (0)