Skip to content

Commit 6dc8b4d

Browse files
committed
Merge remote-tracking branch 'vim/master'
2 parents afc384e + 89c394f commit 6dc8b4d

File tree

13 files changed

+158
-61
lines changed

13 files changed

+158
-61
lines changed

runtime/doc/eval.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6784,6 +6784,7 @@ searchpair({start}, {middle}, {end} [, {flags} [, {skip}
67846784
When {skip} is omitted or empty, every match is accepted.
67856785
When evaluating {skip} causes an error the search is aborted
67866786
and -1 returned.
6787+
{skip} can be a string, a lambda, a funcref or a partial.
67876788

67886789
For {stopline} and {timeout} see |search()|.
67896790

src/eval.c

Lines changed: 66 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,70 @@ eval_to_bool(
696696
return (int)retval;
697697
}
698698

699+
static int
700+
eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv)
701+
{
702+
char_u *s;
703+
int dummy;
704+
char_u buf[NUMBUFLEN];
705+
706+
if (expr->v_type == VAR_FUNC)
707+
{
708+
s = expr->vval.v_string;
709+
if (s == NULL || *s == NUL)
710+
return FAIL;
711+
if (call_func(s, (int)STRLEN(s), rettv, argc, argv, NULL,
712+
0L, 0L, &dummy, TRUE, NULL, NULL) == FAIL)
713+
return FAIL;
714+
}
715+
else if (expr->v_type == VAR_PARTIAL)
716+
{
717+
partial_T *partial = expr->vval.v_partial;
718+
719+
s = partial_name(partial);
720+
if (s == NULL || *s == NUL)
721+
return FAIL;
722+
if (call_func(s, (int)STRLEN(s), rettv, argc, argv, NULL,
723+
0L, 0L, &dummy, TRUE, partial, NULL) == FAIL)
724+
return FAIL;
725+
}
726+
else
727+
{
728+
s = get_tv_string_buf_chk(expr, buf);
729+
if (s == NULL)
730+
return FAIL;
731+
s = skipwhite(s);
732+
if (eval1(&s, rettv, TRUE) == FAIL)
733+
return FAIL;
734+
if (*s != NUL) /* check for trailing chars after expr */
735+
{
736+
EMSG2(_(e_invexpr2), s);
737+
return FAIL;
738+
}
739+
}
740+
return OK;
741+
}
742+
743+
/*
744+
* Like eval_to_bool() but using a typval_T instead of a string.
745+
* Works for string, funcref and partial.
746+
*/
747+
int
748+
eval_expr_to_bool(typval_T *expr, int *error)
749+
{
750+
typval_T rettv;
751+
int res;
752+
753+
if (eval_expr_typval(expr, NULL, 0, &rettv) == FAIL)
754+
{
755+
*error = TRUE;
756+
return FALSE;
757+
}
758+
res = (get_tv_number_chk(&rettv, error) != 0);
759+
clear_tv(&rettv);
760+
return res;
761+
}
762+
699763
/*
700764
* Top level evaluation function, returning a string. If "skip" is TRUE,
701765
* only parsing to "nextcmd" is done, without reporting errors. Return
@@ -9971,44 +10035,13 @@ filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp)
997110035
{
997210036
typval_T rettv;
997310037
typval_T argv[3];
9974-
char_u buf[NUMBUFLEN];
9975-
char_u *s;
997610038
int retval = FAIL;
9977-
int dummy;
997810039

997910040
copy_tv(tv, &vimvars[VV_VAL].vv_tv);
998010041
argv[0] = vimvars[VV_KEY].vv_tv;
998110042
argv[1] = vimvars[VV_VAL].vv_tv;
9982-
if (expr->v_type == VAR_FUNC)
9983-
{
9984-
s = expr->vval.v_string;
9985-
if (call_func(s, (int)STRLEN(s), &rettv, 2, argv, NULL,
9986-
0L, 0L, &dummy, TRUE, NULL, NULL) == FAIL)
9987-
goto theend;
9988-
}
9989-
else if (expr->v_type == VAR_PARTIAL)
9990-
{
9991-
partial_T *partial = expr->vval.v_partial;
9992-
9993-
s = partial_name(partial);
9994-
if (call_func(s, (int)STRLEN(s), &rettv, 2, argv, NULL,
9995-
0L, 0L, &dummy, TRUE, partial, NULL) == FAIL)
9996-
goto theend;
9997-
}
9998-
else
9999-
{
10000-
s = get_tv_string_buf_chk(expr, buf);
10001-
if (s == NULL)
10002-
goto theend;
10003-
s = skipwhite(s);
10004-
if (eval1(&s, &rettv, TRUE) == FAIL)
10005-
goto theend;
10006-
if (*s != NUL) /* check for trailing chars after expr */
10007-
{
10008-
EMSG2(_(e_invexpr2), s);
10009-
goto theend;
10010-
}
10011-
}
10043+
if (eval_expr_typval(expr, argv, 2, &rettv) == FAIL)
10044+
goto theend;
1001210045
if (map)
1001310046
{
1001410047
/* map(): replace the list item value */

src/evalfunc.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9558,13 +9558,12 @@ f_searchdecl(typval_T *argvars, typval_T *rettv)
95589558
searchpair_cmn(typval_T *argvars, pos_T *match_pos)
95599559
{
95609560
char_u *spat, *mpat, *epat;
9561-
char_u *skip;
9561+
typval_T *skip;
95629562
int save_p_ws = p_ws;
95639563
int dir;
95649564
int flags = 0;
95659565
char_u nbuf1[NUMBUFLEN];
95669566
char_u nbuf2[NUMBUFLEN];
9567-
char_u nbuf3[NUMBUFLEN];
95689567
int retval = 0; /* default: FAIL */
95699568
long lnum_stop = 0;
95709569
long time_limit = 0;
@@ -9598,10 +9597,16 @@ searchpair_cmn(typval_T *argvars, pos_T *match_pos)
95989597
/* Optional fifth argument: skip expression */
95999598
if (argvars[3].v_type == VAR_UNKNOWN
96009599
|| argvars[4].v_type == VAR_UNKNOWN)
9601-
skip = (char_u *)"";
9600+
skip = NULL;
96029601
else
96039602
{
9604-
skip = get_tv_string_buf_chk(&argvars[4], nbuf3);
9603+
skip = &argvars[4];
9604+
if (skip->v_type != VAR_FUNC && skip->v_type != VAR_PARTIAL
9605+
&& skip->v_type != VAR_STRING)
9606+
{
9607+
/* Type error */
9608+
goto theend;
9609+
}
96059610
if (argvars[5].v_type != VAR_UNKNOWN)
96069611
{
96079612
lnum_stop = (long)get_tv_number_chk(&argvars[5], NULL);
@@ -9617,8 +9622,6 @@ searchpair_cmn(typval_T *argvars, pos_T *match_pos)
96179622
#endif
96189623
}
96199624
}
9620-
if (skip == NULL)
9621-
goto theend; /* type error */
96229625

96239626
retval = do_searchpair(spat, mpat, epat, dir, skip, flags,
96249627
match_pos, lnum_stop, time_limit);
@@ -9672,7 +9675,7 @@ do_searchpair(
96729675
char_u *mpat, /* middle pattern */
96739676
char_u *epat, /* end pattern */
96749677
int dir, /* BACKWARD or FORWARD */
9675-
char_u *skip, /* skip expression */
9678+
typval_T *skip, /* skip expression */
96769679
int flags, /* SP_SETPCMARK and other SP_ values */
96779680
pos_T *match_pos,
96789681
linenr_T lnum_stop, /* stop at this line if not zero */
@@ -9689,6 +9692,7 @@ do_searchpair(
96899692
int n;
96909693
int r;
96919694
int nest = 1;
9695+
int use_skip = FALSE;
96929696
int err;
96939697
int options = SEARCH_KEEP;
96949698
proftime_T tm;
@@ -9717,6 +9721,14 @@ do_searchpair(
97179721
if (flags & SP_START)
97189722
options |= SEARCH_START;
97199723

9724+
if (skip != NULL)
9725+
{
9726+
/* Empty string means to not use the skip expression. */
9727+
if (skip->v_type == VAR_STRING || skip->v_type == VAR_FUNC)
9728+
use_skip = skip->vval.v_string != NULL
9729+
&& *skip->vval.v_string != NUL;
9730+
}
9731+
97209732
save_cursor = curwin->w_cursor;
97219733
pos = curwin->w_cursor;
97229734
CLEAR_POS(&firstpos);
@@ -9748,11 +9760,12 @@ do_searchpair(
97489760
options &= ~SEARCH_START;
97499761

97509762
/* If the skip pattern matches, ignore this match. */
9751-
if (*skip != NUL)
9763+
if (use_skip)
97529764
{
97539765
save_pos = curwin->w_cursor;
97549766
curwin->w_cursor = pos;
9755-
r = eval_to_bool(skip, &err, NULL, FALSE);
9767+
err = FALSE;
9768+
r = eval_expr_to_bool(skip, &err);
97569769
curwin->w_cursor = save_pos;
97579770
if (err)
97589771
{

src/os_win32.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5033,8 +5033,8 @@ job_io_file_open(
50335033
* Turn the dictionary "env" into a NUL separated list that can be used as the
50345034
* environment argument of vim_create_process().
50355035
*/
5036-
static void
5037-
make_job_env(garray_T *gap, dict_T *env)
5036+
void
5037+
win32_build_env(dict_T *env, garray_T *gap)
50385038
{
50395039
hashitem_T *hi;
50405040
int todo = (int)env->dv_hashtab.ht_used;
@@ -5133,7 +5133,7 @@ mch_job_start(char *cmd, job_T *job, jobopt_T *options)
51335133
}
51345134

51355135
if (options->jo_env != NULL)
5136-
make_job_env(&ga, options->jo_env);
5136+
win32_build_env(options->jo_env, &ga);
51375137

51385138
ZeroMemory(&pi, sizeof(pi));
51395139
ZeroMemory(&si, sizeof(si));

src/proto/eval.pro

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ int eval_printexpr(char_u *fname, char_u *args);
1010
void eval_diff(char_u *origfile, char_u *newfile, char_u *outfile);
1111
void eval_patch(char_u *origfile, char_u *difffile, char_u *outfile);
1212
int eval_to_bool(char_u *arg, int *error, char_u **nextcmd, int skip);
13+
int eval_expr_to_bool(typval_T *expr, int *error);
1314
char_u *eval_to_string_skip(char_u *arg, char_u **nextcmd, int skip);
1415
int skip_expr(char_u **pp);
1516
char_u *eval_to_string(char_u *arg, char_u **nextcmd, int convert);
@@ -47,7 +48,7 @@ int garbage_collect(int testing);
4748
int set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack);
4849
int set_ref_in_list(list_T *l, int copyID, ht_stack_T **ht_stack);
4950
int set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack, list_stack_T **list_stack);
50-
char_u *echo_string_core(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID, int echo_style, int restore_copyID, int dict_val);
51+
char_u *echo_string_core(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID, int echo_style, int restore_copyID, int composite_val);
5152
char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
5253
char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
5354
char_u *string_quote(char_u *str, int function);

src/proto/evalfunc.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ buf_T *buflist_find_by_name(char_u *name, int curtab_only);
88
void execute_redir_str(char_u *value, int value_len);
99
void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv);
1010
float_T vim_round(float_T f);
11-
long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, char_u *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit);
11+
long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit);
1212
char_u *get_callback(typval_T *arg, partial_T **pp);
1313
void free_callback(char_u *callback, partial_T *partial);
1414
/* vim: set ft=c : */

src/proto/os_win32.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,5 @@ void used_file_arg(char *name, int literal, int full_path, int diff_mode);
6767
void set_alist_count(void);
6868
void fix_arg_enc(void);
6969
int mch_setenv(char *var, char *value, int x);
70+
void win32_build_env(dict_T *l, garray_T *gap);
7071
/* vim: set ft=c : */

src/search.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4024,7 +4024,7 @@ current_tagblock(
40244024
{
40254025
if (do_searchpair((char_u *)"<[^ \t>/!]\\+\\%(\\_s\\_[^>]\\{-}[^/]>\\|$\\|\\_s\\=>\\)",
40264026
(char_u *)"",
4027-
(char_u *)"</[^>]*>", BACKWARD, (char_u *)"", 0,
4027+
(char_u *)"</[^>]*>", BACKWARD, NULL, 0,
40284028
NULL, (linenr_T)0, 0L) <= 0)
40294029
{
40304030
curwin->w_cursor = old_pos;
@@ -4058,7 +4058,7 @@ current_tagblock(
40584058
sprintf((char *)spat, "<%.*s\\>\\%%(\\s\\_[^>]\\{-}[^/]>\\|>\\)\\c", len, p);
40594059
sprintf((char *)epat, "</%.*s>\\c", len, p);
40604060

4061-
r = do_searchpair(spat, (char_u *)"", epat, FORWARD, (char_u *)"",
4061+
r = do_searchpair(spat, (char_u *)"", epat, FORWARD, NULL,
40624062
0, NULL, (linenr_T)0, 0L);
40634063

40644064
vim_free(spat);

src/terminal.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,18 @@
4646
* - Redirecting output does not work on MS-Windows, Test_terminal_redir_file()
4747
* is disabled.
4848
* - cursor blinks in terminal on widows with a timer. (xtal8, #2142)
49+
* - When closing gvim with an active terminal buffer, the dialog suggests
50+
* saving the buffer. Should say something else. (Manas Thakur, #2215)
51+
* Also: #2223
4952
* - implement term_setsize()
53+
* - Termdebug does not work when Vim build with mzscheme. gdb hangs.
54+
* - Termdebug: issue #2154 might be avoided by adding -quiet to gdb?
55+
* patch by Christian, 2017 Oct 23.
5056
* - MS-Windows GUI: WinBar has tearoff item
5157
* - MS-Windows GUI: still need to type a key after shell exits? #1924
58+
* - What to store in a session file? Shell at the prompt would be OK to
59+
* restore, but others may not. Open the window and let the user start the
60+
* command?
5261
* - add test for giving error for invalid 'termsize' value.
5362
* - support minimal size when 'termsize' is "rows*cols".
5463
* - support minimal size when 'termsize' is empty?
@@ -3395,6 +3404,7 @@ term_and_job_init(
33953404
{
33963405
WCHAR *cmd_wchar = NULL;
33973406
WCHAR *cwd_wchar = NULL;
3407+
WCHAR *env_wchar = NULL;
33983408
channel_T *channel = NULL;
33993409
job_T *job = NULL;
34003410
DWORD error;
@@ -3403,7 +3413,7 @@ term_and_job_init(
34033413
HANDLE child_thread_handle;
34043414
void *winpty_err;
34053415
void *spawn_config = NULL;
3406-
garray_T ga;
3416+
garray_T ga_cmd, ga_env;
34073417
char_u *cmd;
34083418

34093419
if (dyn_winpty_init(TRUE) == FAIL)
@@ -3413,17 +3423,23 @@ term_and_job_init(
34133423
cmd = argvar->vval.v_string;
34143424
else
34153425
{
3416-
ga_init2(&ga, (int)sizeof(char*), 20);
3417-
if (win32_build_cmd(argvar->vval.v_list, &ga) == FAIL)
3426+
ga_init2(&ga_cmd, (int)sizeof(char*), 20);
3427+
if (win32_build_cmd(argvar->vval.v_list, &ga_cmd) == FAIL)
34183428
goto failed;
3419-
cmd = ga.ga_data;
3429+
cmd = ga_cmd.ga_data;
34203430
}
34213431

34223432
cmd_wchar = enc_to_utf16(cmd, NULL);
34233433
if (cmd_wchar == NULL)
34243434
return FAIL;
34253435
if (opt->jo_cwd != NULL)
34263436
cwd_wchar = enc_to_utf16(opt->jo_cwd, NULL);
3437+
if (opt->jo_env != NULL)
3438+
{
3439+
ga_init2(&ga_env, (int)sizeof(char*), 20);
3440+
win32_build_env(opt->jo_env, &ga_env);
3441+
env_wchar = ga_env.ga_data;
3442+
}
34273443

34283444
job = job_alloc();
34293445
if (job == NULL)
@@ -3451,7 +3467,7 @@ term_and_job_init(
34513467
NULL,
34523468
cmd_wchar,
34533469
cwd_wchar,
3454-
NULL,
3470+
env_wchar,
34553471
&winpty_err);
34563472
if (spawn_config == NULL)
34573473
goto failed;
@@ -3524,7 +3540,9 @@ term_and_job_init(
35243540

35253541
failed:
35263542
if (argvar->v_type == VAR_LIST)
3527-
vim_free(ga.ga_data);
3543+
vim_free(ga_cmd.ga_data);
3544+
if (opt->jo_env != NULL)
3545+
vim_free(ga_env.ga_data);
35283546
vim_free(cmd_wchar);
35293547
vim_free(cwd_wchar);
35303548
if (spawn_config != NULL)

src/testdir/test_popup.vim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ func Test_popup_and_window_resize()
639639
endif
640640
let g:buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': h / 3})
641641
call term_sendkeys(g:buf, (h / 3 - 1)."o\<esc>")
642-
call term_wait(g:buf, 200)
642+
call term_wait(g:buf, 500)
643643
call term_sendkeys(g:buf, "Gi\<c-x>")
644644
call term_sendkeys(g:buf, "\<c-v>")
645645
call term_wait(g:buf, 100)

0 commit comments

Comments
 (0)