Compare commits

...

11 Commits

Author SHA1 Message Date
Bram Moolenaar
5130f31661 patch 8.0.1248: stray + in README file
Problem:    Stray + in README file.
Solution:   Remove the +.  Add a line break.
2017-11-02 18:13:00 +01:00
Bram Moolenaar
86b21bb3e7 patch 8.0.1247: not easy to find Debian build info
Problem:    Not easy to find Debian build info.
Solution:   Add a badge in the README file. (Dominique Pelle)
2017-11-02 18:10:00 +01:00
Bram Moolenaar
b315876efa patch 8.0.1246: popup test has an arbitrary delay
Problem:    Popup test has an arbitrary delay.
Solution:   Wait for the ruler to show. (James McCoy)
2017-11-02 17:50:14 +01:00
Bram Moolenaar
3e1c617d49 patch 8.0.1245: when WaitFor() has a wrong expression it just waits a second
Problem:    When WaitFor() has a wrong expression it just waits a second,
            which goes unnoticed. (James McCoy)
Solution:   When WaitFor() times out throw an exception.  Fix places where the
            expression was wrong.
2017-11-02 16:58:00 +01:00
Bram Moolenaar
b94340c04f patch 8.0.1244: search test does not work correctly on MS-Windows
Problem:    Search test does not work correctly on MS-Windows.
Solution:   Put text in a file instead of sending it to the terminal.
            (Christian Brabandt)
2017-11-02 16:16:31 +01:00
Bram Moolenaar
f45938cc20 patch 8.0.1243: no test for what 8.0.1227 fixes
Problem:    No test for what 8.0.1227 fixes.
Solution:   Add a test that triggers the problem. (Christian Brabandt)
2017-11-02 15:59:57 +01:00
Bram Moolenaar
ffd99f729b patch 8.0.1242: function argument with only dash is seen as number zero
Problem:    Function argument with only dash is seen as number zero. (Wang
            Shidong)
Solution:   See a dash as a string. (Christian Brabandt)
2017-11-02 15:44:14 +01:00
Bram Moolenaar
89c394faca patch 8.0.1241: popup test is flaky
Problem:    Popup test is flaky. (James McCoy)
Solution:   Increase the wait time. (Dominique Pelle)
2017-10-31 22:19:58 +01:00
Bram Moolenaar
ba6febd380 patch 8.0.1240: MS-Windows: term_start() does not support environment
Problem:    MS-Windows: term_start() does not support environment.
Solution:   Implement the environment argument. (Yasuhiro Matsumoto, closes
            #2264)
2017-10-30 21:56:23 +01:00
Bram Moolenaar
48570488f1 patch 8.0.1239: cannot use a lambda for the skip argument to searchpair()
Problem:    Cannot use a lambda for the skip argument to searchpair().
Solution:   Evaluate a partial, funcref and lambda. (LemonBoy, closes #1454,
            closes #2265)
2017-10-30 21:48:41 +01:00
Bram Moolenaar
2e51d9a097 patch 8.0.1238: incremental search only shows one match
Problem:    Incremental search only shows one match.
Solution:   When 'incsearch' and and 'hlsearch' are both set highlight all
            matches. (haya14busa, closes #2198)
2017-10-29 16:40:30 +01:00
23 changed files with 447 additions and 97 deletions

View File

@@ -1,9 +1,11 @@
`README.md` for version 8.0 of Vim: Vi IMproved.
[![Build Status](https://travis-ci.org/vim/vim.svg?branch=master)](https://travis-ci.org/vim/vim)
[![Coverage Status](https://codecov.io/gh/vim/vim/coverage.svg?branch=master)](https://codecov.io/gh/vim/vim?branch=master)
[![Coverage Status](https://coveralls.io/repos/vim/vim/badge.svg?branch=master&service=github)](https://coveralls.io/github/vim/vim?branch=master)
[![Appveyor Build status](https://ci.appveyor.com/api/projects/status/o2qht2kjm02sgghk?svg=true)](https://ci.appveyor.com/project/chrisbra/vim)
[![Coverity Scan](https://scan.coverity.com/projects/241/badge.svg)](https://scan.coverity.com/projects/vim)
[![Debian CI](https://badges.debian.net/badges/debian/testing/vim/version.svg)](https://buildd.debian.org/vim)[![Debian CI](https://badges.debian.net/badges/debian/testing/vim/version.svg)](https://buildd.debian.org/vim)
## What is Vim? ##

View File

@@ -6784,6 +6784,7 @@ searchpair({start}, {middle}, {end} [, {flags} [, {skip}
When {skip} is omitted or empty, every match is accepted.
When evaluating {skip} causes an error the search is aborted
and -1 returned.
{skip} can be a string, a lambda, a funcref or a partial.
For {stopline} and {timeout} see |search()|.

View File

@@ -4447,7 +4447,17 @@ A jump table for the options with a short description can be found at |Q_op|.
match may not be found. This is to avoid that Vim hangs while you
are typing the pattern.
The highlighting can be set with the 'i' flag in 'highlight'.
See also: 'hlsearch'.
When 'hlsearch' is on, all matched strings are highlighted too while typing
a search command. See also: 'hlsearch'.
If you don't want turn 'hlsearch' on, but want to highlight all matches
while searching, you can turn on and off 'hlsearch' with autocmd.
Example: >
augroup vimrc-incsearch-highlight
autocmd!
autocmd CmdlineEnter [/\?] :set hlsearch
autocmd CmdlineLeave [/\?] :set nohlsearch
augroup END
<
CTRL-L can be used to add one character from after the current match
to the command line. If 'ignorecase' and 'smartcase' are set and the
command line has no uppercase characters, the added character is

View File

@@ -2189,6 +2189,7 @@ test_arglist \
test_hlsearch \
test_increment \
test_increment_dbcs \
test_ins_complete \
test_job_fails \
test_join \
test_json \

View File

@@ -696,6 +696,70 @@ eval_to_bool(
return (int)retval;
}
static int
eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv)
{
char_u *s;
int dummy;
char_u buf[NUMBUFLEN];
if (expr->v_type == VAR_FUNC)
{
s = expr->vval.v_string;
if (s == NULL || *s == NUL)
return FAIL;
if (call_func(s, (int)STRLEN(s), rettv, argc, argv, NULL,
0L, 0L, &dummy, TRUE, NULL, NULL) == FAIL)
return FAIL;
}
else if (expr->v_type == VAR_PARTIAL)
{
partial_T *partial = expr->vval.v_partial;
s = partial_name(partial);
if (s == NULL || *s == NUL)
return FAIL;
if (call_func(s, (int)STRLEN(s), rettv, argc, argv, NULL,
0L, 0L, &dummy, TRUE, partial, NULL) == FAIL)
return FAIL;
}
else
{
s = get_tv_string_buf_chk(expr, buf);
if (s == NULL)
return FAIL;
s = skipwhite(s);
if (eval1(&s, rettv, TRUE) == FAIL)
return FAIL;
if (*s != NUL) /* check for trailing chars after expr */
{
EMSG2(_(e_invexpr2), s);
return FAIL;
}
}
return OK;
}
/*
* Like eval_to_bool() but using a typval_T instead of a string.
* Works for string, funcref and partial.
*/
int
eval_expr_to_bool(typval_T *expr, int *error)
{
typval_T rettv;
int res;
if (eval_expr_typval(expr, NULL, 0, &rettv) == FAIL)
{
*error = TRUE;
return FALSE;
}
res = (get_tv_number_chk(&rettv, error) != 0);
clear_tv(&rettv);
return res;
}
/*
* Top level evaluation function, returning a string. If "skip" is TRUE,
* only parsing to "nextcmd" is done, without reporting errors. Return
@@ -992,8 +1056,13 @@ call_vim_function(
if (str_arg_only)
len = 0;
else
/* Recognize a number argument, the others must be strings. */
{
/* Recognize a number argument, the others must be strings. A dash
* is a string too. */
vim_str2nr(argv[i], NULL, &len, STR2NR_ALL, &n, NULL, 0);
if (len == 1 && *argv[i] == '-')
len = 0;
}
if (len != 0 && len == (int)STRLEN(argv[i]))
{
argvars[i].v_type = VAR_NUMBER;
@@ -9971,44 +10040,13 @@ filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp)
{
typval_T rettv;
typval_T argv[3];
char_u buf[NUMBUFLEN];
char_u *s;
int retval = FAIL;
int dummy;
copy_tv(tv, &vimvars[VV_VAL].vv_tv);
argv[0] = vimvars[VV_KEY].vv_tv;
argv[1] = vimvars[VV_VAL].vv_tv;
if (expr->v_type == VAR_FUNC)
{
s = expr->vval.v_string;
if (call_func(s, (int)STRLEN(s), &rettv, 2, argv, NULL,
0L, 0L, &dummy, TRUE, NULL, NULL) == FAIL)
goto theend;
}
else if (expr->v_type == VAR_PARTIAL)
{
partial_T *partial = expr->vval.v_partial;
s = partial_name(partial);
if (call_func(s, (int)STRLEN(s), &rettv, 2, argv, NULL,
0L, 0L, &dummy, TRUE, partial, NULL) == FAIL)
goto theend;
}
else
{
s = get_tv_string_buf_chk(expr, buf);
if (s == NULL)
goto theend;
s = skipwhite(s);
if (eval1(&s, &rettv, TRUE) == FAIL)
goto theend;
if (*s != NUL) /* check for trailing chars after expr */
{
EMSG2(_(e_invexpr2), s);
goto theend;
}
}
if (eval_expr_typval(expr, argv, 2, &rettv) == FAIL)
goto theend;
if (map)
{
/* map(): replace the list item value */

View File

@@ -9531,13 +9531,12 @@ f_searchdecl(typval_T *argvars, typval_T *rettv)
searchpair_cmn(typval_T *argvars, pos_T *match_pos)
{
char_u *spat, *mpat, *epat;
char_u *skip;
typval_T *skip;
int save_p_ws = p_ws;
int dir;
int flags = 0;
char_u nbuf1[NUMBUFLEN];
char_u nbuf2[NUMBUFLEN];
char_u nbuf3[NUMBUFLEN];
int retval = 0; /* default: FAIL */
long lnum_stop = 0;
long time_limit = 0;
@@ -9571,10 +9570,16 @@ searchpair_cmn(typval_T *argvars, pos_T *match_pos)
/* Optional fifth argument: skip expression */
if (argvars[3].v_type == VAR_UNKNOWN
|| argvars[4].v_type == VAR_UNKNOWN)
skip = (char_u *)"";
skip = NULL;
else
{
skip = get_tv_string_buf_chk(&argvars[4], nbuf3);
skip = &argvars[4];
if (skip->v_type != VAR_FUNC && skip->v_type != VAR_PARTIAL
&& skip->v_type != VAR_STRING)
{
/* Type error */
goto theend;
}
if (argvars[5].v_type != VAR_UNKNOWN)
{
lnum_stop = (long)get_tv_number_chk(&argvars[5], NULL);
@@ -9590,8 +9595,6 @@ searchpair_cmn(typval_T *argvars, pos_T *match_pos)
#endif
}
}
if (skip == NULL)
goto theend; /* type error */
retval = do_searchpair(spat, mpat, epat, dir, skip, flags,
match_pos, lnum_stop, time_limit);
@@ -9645,7 +9648,7 @@ do_searchpair(
char_u *mpat, /* middle pattern */
char_u *epat, /* end pattern */
int dir, /* BACKWARD or FORWARD */
char_u *skip, /* skip expression */
typval_T *skip, /* skip expression */
int flags, /* SP_SETPCMARK and other SP_ values */
pos_T *match_pos,
linenr_T lnum_stop, /* stop at this line if not zero */
@@ -9662,6 +9665,7 @@ do_searchpair(
int n;
int r;
int nest = 1;
int use_skip = FALSE;
int err;
int options = SEARCH_KEEP;
proftime_T tm;
@@ -9690,6 +9694,14 @@ do_searchpair(
if (flags & SP_START)
options |= SEARCH_START;
if (skip != NULL)
{
/* Empty string means to not use the skip expression. */
if (skip->v_type == VAR_STRING || skip->v_type == VAR_FUNC)
use_skip = skip->vval.v_string != NULL
&& *skip->vval.v_string != NUL;
}
save_cursor = curwin->w_cursor;
pos = curwin->w_cursor;
CLEAR_POS(&firstpos);
@@ -9721,11 +9733,12 @@ do_searchpair(
options &= ~SEARCH_START;
/* If the skip pattern matches, ignore this match. */
if (*skip != NUL)
if (use_skip)
{
save_pos = curwin->w_cursor;
curwin->w_cursor = pos;
r = eval_to_bool(skip, &err, NULL, FALSE);
err = FALSE;
r = eval_expr_to_bool(skip, &err);
curwin->w_cursor = save_pos;
if (err)
{

View File

@@ -1715,8 +1715,9 @@ getcmdline(
if (p_is && !cmd_silent && (firstc == '/' || firstc == '?'))
{
pos_T t;
int search_flags = SEARCH_KEEP + SEARCH_NOOF;
int search_flags = SEARCH_NOOF;
save_last_search_pattern();
cursor_off();
out_flush();
if (c == Ctrl_G)
@@ -1726,6 +1727,8 @@ getcmdline(
}
else
t = match_start;
if (!p_hls)
search_flags += SEARCH_KEEP;
++emsg_off;
i = searchit(curwin, curbuf, &t,
c == Ctrl_G ? FORWARD : BACKWARD,
@@ -1777,6 +1780,7 @@ getcmdline(
# endif
old_botline = curwin->w_botline;
update_screen(NOT_VALID);
restore_last_search_pattern();
redrawcmdline();
}
else
@@ -1934,12 +1938,17 @@ cmdline_changed:
}
incsearch_postponed = FALSE;
curwin->w_cursor = search_start; /* start at old position */
save_last_search_pattern();
/* If there is no command line, don't do anything */
if (ccline.cmdlen == 0)
{
i = 0;
SET_NO_HLSEARCH(TRUE); /* turn off previous highlight */
}
else
{
int search_flags = SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK;
cursor_off(); /* so the user knows we're busy */
out_flush();
++emsg_off; /* So it doesn't beep if bad expr */
@@ -1947,8 +1956,10 @@ cmdline_changed:
/* Set the time limit to half a second. */
profile_setlimit(500L, &tm);
#endif
if (!p_hls)
search_flags += SEARCH_KEEP;
i = do_search(NULL, firstc, ccline.cmdbuff, count,
SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK,
search_flags,
#ifdef FEAT_RELTIME
&tm, NULL
#else
@@ -2005,6 +2016,7 @@ cmdline_changed:
save_cmdline(&save_ccline);
update_screen(SOME_VALID);
restore_cmdline(&save_ccline);
restore_last_search_pattern();
/* Leave it at the end to make CTRL-R CTRL-W work. */
if (i != 0)

View File

@@ -5033,8 +5033,8 @@ job_io_file_open(
* Turn the dictionary "env" into a NUL separated list that can be used as the
* environment argument of vim_create_process().
*/
static void
make_job_env(garray_T *gap, dict_T *env)
void
win32_build_env(dict_T *env, garray_T *gap)
{
hashitem_T *hi;
int todo = (int)env->dv_hashtab.ht_used;
@@ -5133,7 +5133,7 @@ mch_job_start(char *cmd, job_T *job, jobopt_T *options)
}
if (options->jo_env != NULL)
make_job_env(&ga, options->jo_env);
win32_build_env(options->jo_env, &ga);
ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&si, sizeof(si));

View File

@@ -10,6 +10,7 @@ int eval_printexpr(char_u *fname, char_u *args);
void eval_diff(char_u *origfile, char_u *newfile, char_u *outfile);
void eval_patch(char_u *origfile, char_u *difffile, char_u *outfile);
int eval_to_bool(char_u *arg, int *error, char_u **nextcmd, int skip);
int eval_expr_to_bool(typval_T *expr, int *error);
char_u *eval_to_string_skip(char_u *arg, char_u **nextcmd, int skip);
int skip_expr(char_u **pp);
char_u *eval_to_string(char_u *arg, char_u **nextcmd, int convert);
@@ -47,7 +48,7 @@ int garbage_collect(int testing);
int set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack);
int set_ref_in_list(list_T *l, int copyID, ht_stack_T **ht_stack);
int set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack, list_stack_T **list_stack);
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);
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);
char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
char_u *string_quote(char_u *str, int function);

View File

@@ -8,7 +8,7 @@ buf_T *buflist_find_by_name(char_u *name, int curtab_only);
void execute_redir_str(char_u *value, int value_len);
void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv);
float_T vim_round(float_T f);
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);
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);
char_u *get_callback(typval_T *arg, partial_T **pp);
void free_callback(char_u *callback, partial_T *partial);
/* vim: set ft=c : */

View File

@@ -67,4 +67,5 @@ void used_file_arg(char *name, int literal, int full_path, int diff_mode);
void set_alist_count(void);
void fix_arg_enc(void);
int mch_setenv(char *var, char *value, int x);
void win32_build_env(dict_T *l, garray_T *gap);
/* vim: set ft=c : */

View File

@@ -5,6 +5,8 @@ char_u *reverse_text(char_u *s);
void save_re_pat(int idx, char_u *pat, int magic);
void save_search_patterns(void);
void restore_search_patterns(void);
void save_last_search_pattern(void);
void restore_last_search_pattern(void);
void free_search_patterns(void);
int ignorecase(char_u *pat);
int ignorecase_opt(char_u *pat, int ic_in, int scs);

View File

@@ -100,11 +100,14 @@ static int lastc_bytelen = 1; /* >1 for multi-byte char */
#if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO)
/* copy of spats[], for keeping the search patterns while executing autocmds */
static struct spat saved_spats[2];
static int saved_last_idx = 0;
#endif
# ifdef FEAT_SEARCH_EXTRA
/* copy of spats[RE_SEARCH], for keeping the search patterns while incremental
* searching */
static struct spat saved_last_search_spat;
static int saved_last_idx = 0;
static int saved_no_hlsearch = 0;
# endif
#endif
static char_u *mr_pattern = NULL; /* pattern used by search_regcomp() */
#ifdef FEAT_RIGHTLEFT
@@ -329,9 +332,9 @@ restore_search_patterns(void)
{
vim_free(spats[0].pat);
spats[0] = saved_spats[0];
#if defined(FEAT_EVAL)
# if defined(FEAT_EVAL)
set_vv_searchforward();
#endif
# endif
vim_free(spats[1].pat);
spats[1] = saved_spats[1];
last_idx = saved_last_idx;
@@ -360,6 +363,38 @@ free_search_patterns(void)
}
#endif
#ifdef FEAT_SEARCH_EXTRA
/*
* Save and restore the search pattern for incremental highlight search
* feature.
*
* It's similar but differnt from save_search_patterns() and
* restore_search_patterns(), because the search pattern must be restored when
* cannceling incremental searching even if it's called inside user functions.
*/
void
save_last_search_pattern(void)
{
saved_last_search_spat = spats[RE_SEARCH];
if (spats[RE_SEARCH].pat != NULL)
saved_last_search_spat.pat = vim_strsave(spats[RE_SEARCH].pat);
saved_last_idx = last_idx;
saved_no_hlsearch = no_hlsearch;
}
void
restore_last_search_pattern(void)
{
vim_free(spats[RE_SEARCH].pat);
spats[RE_SEARCH] = saved_last_search_spat;
# if defined(FEAT_EVAL)
set_vv_searchforward();
# endif
last_idx = saved_last_idx;
SET_NO_HLSEARCH(saved_no_hlsearch);
}
#endif
/*
* Return TRUE when case should be ignored for search pattern "pat".
* Uses the 'ignorecase' and 'smartcase' options.
@@ -3980,7 +4015,7 @@ again:
{
if (do_searchpair((char_u *)"<[^ \t>/!]\\+\\%(\\_s\\_[^>]\\{-}[^/]>\\|$\\|\\_s\\=>\\)",
(char_u *)"",
(char_u *)"</[^>]*>", BACKWARD, (char_u *)"", 0,
(char_u *)"</[^>]*>", BACKWARD, NULL, 0,
NULL, (linenr_T)0, 0L) <= 0)
{
curwin->w_cursor = old_pos;
@@ -4014,7 +4049,7 @@ again:
sprintf((char *)spat, "<%.*s\\>\\%%(\\s\\_[^>]\\{-}[^/]>\\|>\\)\\c", len, p);
sprintf((char *)epat, "</%.*s>\\c", len, p);
r = do_searchpair(spat, (char_u *)"", epat, FORWARD, (char_u *)"",
r = do_searchpair(spat, (char_u *)"", epat, FORWARD, NULL,
0, NULL, (linenr_T)0, 0L);
vim_free(spat);

View File

@@ -46,9 +46,18 @@
* - Redirecting output does not work on MS-Windows, Test_terminal_redir_file()
* is disabled.
* - cursor blinks in terminal on widows with a timer. (xtal8, #2142)
* - When closing gvim with an active terminal buffer, the dialog suggests
* saving the buffer. Should say something else. (Manas Thakur, #2215)
* Also: #2223
* - implement term_setsize()
* - Termdebug does not work when Vim build with mzscheme. gdb hangs.
* - Termdebug: issue #2154 might be avoided by adding -quiet to gdb?
* patch by Christian, 2017 Oct 23.
* - MS-Windows GUI: WinBar has tearoff item
* - MS-Windows GUI: still need to type a key after shell exits? #1924
* - What to store in a session file? Shell at the prompt would be OK to
* restore, but others may not. Open the window and let the user start the
* command?
* - add test for giving error for invalid 'termsize' value.
* - support minimal size when 'termsize' is "rows*cols".
* - support minimal size when 'termsize' is empty?
@@ -3390,6 +3399,7 @@ term_and_job_init(
{
WCHAR *cmd_wchar = NULL;
WCHAR *cwd_wchar = NULL;
WCHAR *env_wchar = NULL;
channel_T *channel = NULL;
job_T *job = NULL;
DWORD error;
@@ -3398,7 +3408,7 @@ term_and_job_init(
HANDLE child_thread_handle;
void *winpty_err;
void *spawn_config = NULL;
garray_T ga;
garray_T ga_cmd, ga_env;
char_u *cmd;
if (dyn_winpty_init(TRUE) == FAIL)
@@ -3408,10 +3418,10 @@ term_and_job_init(
cmd = argvar->vval.v_string;
else
{
ga_init2(&ga, (int)sizeof(char*), 20);
if (win32_build_cmd(argvar->vval.v_list, &ga) == FAIL)
ga_init2(&ga_cmd, (int)sizeof(char*), 20);
if (win32_build_cmd(argvar->vval.v_list, &ga_cmd) == FAIL)
goto failed;
cmd = ga.ga_data;
cmd = ga_cmd.ga_data;
}
cmd_wchar = enc_to_utf16(cmd, NULL);
@@ -3419,6 +3429,12 @@ term_and_job_init(
return FAIL;
if (opt->jo_cwd != NULL)
cwd_wchar = enc_to_utf16(opt->jo_cwd, NULL);
if (opt->jo_env != NULL)
{
ga_init2(&ga_env, (int)sizeof(char*), 20);
win32_build_env(opt->jo_env, &ga_env);
env_wchar = ga_env.ga_data;
}
job = job_alloc();
if (job == NULL)
@@ -3446,7 +3462,7 @@ term_and_job_init(
NULL,
cmd_wchar,
cwd_wchar,
NULL,
env_wchar,
&winpty_err);
if (spawn_config == NULL)
goto failed;
@@ -3519,7 +3535,9 @@ term_and_job_init(
failed:
if (argvar->v_type == VAR_LIST)
vim_free(ga.ga_data);
vim_free(ga_cmd.ga_data);
if (opt->jo_env != NULL)
vim_free(ga_env.ga_data);
vim_free(cmd_wchar);
vim_free(cwd_wchar);
if (spawn_config != NULL)

View File

@@ -139,7 +139,7 @@ func WaitFor(expr, ...)
endif
sleep 10m
endfor
return timeout
throw 'WaitFor() timed out after ' . timeout . ' msec'
endfunc
" Wait for up to a given milliseconds.

View File

@@ -709,7 +709,7 @@ func Run_test_pipe_to_buffer(use_name, nomod, do_msg)
call ch_sendraw(handle, "double this\n")
call ch_sendraw(handle, "quit\n")
sp pipe-output
call WaitFor('line("$") >= 6 && g:Ch_bufClosed == "yes"')
call WaitFor('line("$") == ' . len(expected) . ' && g:Ch_bufClosed == "yes"')
call assert_equal(expected, getline(1, '$'))
if a:nomod
call assert_equal(0, &modifiable)
@@ -804,7 +804,7 @@ func Run_test_pipe_err_to_buffer(use_name, nomod, do_msg)
call ch_sendraw(handle, "doubleerr this\n")
call ch_sendraw(handle, "quit\n")
sp pipe-err
call WaitFor('line("$") >= 5')
call WaitFor('line("$") == ' . len(expected))
call assert_equal(expected, getline(1, '$'))
if a:nomod
call assert_equal(0, &modifiable)
@@ -1130,12 +1130,14 @@ func Test_pipe_to_buffer_raw()
let job = job_start([s:python, '-c',
\ 'import sys; [sys.stdout.write(".") and sys.stdout.flush() for _ in range(10000)]'], options)
call assert_equal("run", job_status(job))
call WaitFor('len(join(getline(2,line("$")),"") >= 10000')
call WaitFor('len(join(getline(1, "$"), "")) >= 10000', 3000)
try
for line in getline(2, '$')
let line = substitute(line, '^\.*', '', '')
call assert_equal('', line)
let totlen = 0
for line in getline(1, '$')
call assert_equal('', substitute(line, '^\.*', '', ''))
let totlen += len(line)
endfor
call assert_equal(10000, totlen)
finally
call job_stop(job)
bwipe!
@@ -1300,24 +1302,25 @@ func Test_close_and_exit_cb()
endif
call ch_log('Test_close_and_exit_cb')
let dict = {'ret': {}}
func dict.close_cb(ch) dict
let g:retdict = {'ret': {}}
func g:retdict.close_cb(ch) dict
let self.ret['close_cb'] = job_status(ch_getjob(a:ch))
endfunc
func dict.exit_cb(job, status) dict
func g:retdict.exit_cb(job, status) dict
let self.ret['exit_cb'] = job_status(a:job)
endfunc
let g:job = job_start('echo', {
\ 'close_cb': dict.close_cb,
\ 'exit_cb': dict.exit_cb,
\ 'close_cb': g:retdict.close_cb,
\ 'exit_cb': g:retdict.exit_cb,
\ })
call assert_equal('run', job_status(g:job))
unlet g:job
call WaitFor('len(dict.ret) >= 2')
call assert_equal(2, len(dict.ret))
call assert_match('^\%(dead\|run\)', dict.ret['close_cb'])
call assert_equal('dead', dict.ret['exit_cb'])
call WaitFor('len(g:retdict.ret) >= 2')
call assert_equal(2, len(g:retdict.ret))
call assert_match('^\%(dead\|run\)', g:retdict.ret['close_cb'])
call assert_equal('dead', g:retdict.ret['exit_cb'])
unlet g:retdict
endfunc
""""""""""
@@ -1547,13 +1550,14 @@ func Test_job_stop_immediately()
return
endif
let job = job_start([s:python, '-c', 'import time;time.sleep(10)'])
let g:job = job_start([s:python, '-c', 'import time;time.sleep(10)'])
try
call job_stop(job)
call WaitFor('"dead" == job_status(job)')
call assert_equal('dead', job_status(job))
call job_stop(g:job)
call WaitFor('"dead" == job_status(g:job)')
call assert_equal('dead', job_status(g:job))
finally
call job_stop(job, 'kill')
call job_stop(g:job, 'kill')
unlet g:job
endtry
endfunc
@@ -1585,7 +1589,7 @@ func Test_collapse_buffers()
split testout
1,$delete
call job_start('cat test_channel.vim', {'out_io': 'buffer', 'out_name': 'testout'})
call WaitFor('line("$") > g:linecount')
call WaitFor('line("$") >= g:linecount')
call assert_inrange(g:linecount, g:linecount + 1, line('$'))
bwipe!
endfunc

View File

@@ -90,3 +90,22 @@ func Test_ins_complete()
call delete('Xtestdata')
set cpt& cot& def& tags& tagbsearch& hidden&
endfunc
func Test_omni_dash()
func Omni(findstart, base)
if a:findstart
return 5
else
echom a:base
return ['-help', '-v']
endif
endfunc
set omnifunc=Omni
new
exe "normal Gofind -\<C-x>\<C-o>"
call assert_equal("\n-\nmatch 1 of 2", execute(':2mess'))
bwipe!
delfunc Omni
set omnifunc=
endfunc

View File

@@ -27,7 +27,7 @@ func Nb_basic(port)
" Opening README.txt will result in a setDot command
call WaitFor('len(readfile("Xnetbeans")) > 4')
call WaitFor('getcurpos()[1] == 2')
call WaitFor('getcurpos()[1] == 3')
let pos = getcurpos()
call assert_equal(3, pos[1])
call assert_equal(20, pos[2])

View File

@@ -1208,6 +1208,13 @@ func! Test_normal19_z_spell()
call assert_match("Word 'goood' added to ./Xspellfile2.add", a)
call assert_equal('goood', cnt[0])
" Test for :spellgood!
let temp = execute(':spe!0/0')
call assert_match('Invalid region', temp)
let spellfile = matchstr(temp, 'Invalid region nr in \zs.*\ze line \d: 0')
call assert_equal(['# goood', '# goood/!', '#oood', '0/0'], readfile(spellfile))
call delete(spellfile)
" clean up
exe "lang" oldlang
call delete("./Xspellfile.add")

View File

@@ -637,9 +637,13 @@ func Test_popup_and_window_resize()
if h < 15
return
endif
let g:buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': h / 3})
call term_sendkeys(g:buf, (h / 3 - 1)."o\<esc>")
call term_wait(g:buf, 200)
let rows = h / 3
let g:buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': rows})
call term_sendkeys(g:buf, (h / 3 - 1) . "o\<esc>")
" Wait for the nested Vim to exit insert mode, where it will show the ruler.
" Need to trigger a redraw.
call WaitFor(printf('execute("redraw") == "" && term_getline(g:buf, %d) =~ "\\<%d,.*Bot"', rows, rows))
call term_sendkeys(g:buf, "Gi\<c-x>")
call term_sendkeys(g:buf, "\<c-v>")
call term_wait(g:buf, 100)

View File

@@ -1,5 +1,7 @@
" Test for the search command
source shared.vim
func Test_search_cmdline()
if !exists('+incsearch')
return
@@ -294,6 +296,25 @@ func Test_searchpair()
q!
endfunc
func Test_searchpair_skip()
func Zero()
return 0
endfunc
func Partial(x)
return a:x
endfunc
new
call setline(1, ['{', 'foo', 'foo', 'foo', '}'])
3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', ''))
3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', '0'))
3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', {-> 0}))
3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Zero')))
3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Partial', [0])))
" invalid argument
3 | call assert_equal(0, searchpair('{', '', '}', 'bWn', 0))
bw!
endfunc
func Test_searchc()
" These commands used to cause memory overflow in searchc().
new
@@ -431,3 +452,136 @@ func Test_search_regexp()
set undolevels&
enew!
endfunc
func Test_search_cmdline_incsearch_highlight()
if !exists('+incsearch')
return
endif
set incsearch hlsearch
" need to disable char_avail,
" so that expansion of commandline works
call test_override("char_avail", 1)
new
call setline(1, ['aaa 1 the first', ' 2 the second', ' 3 the third'])
1
call feedkeys("/second\<cr>", 'tx')
call assert_equal('second', @/)
call assert_equal(' 2 the second', getline('.'))
" Canceling search won't change @/
1
let @/ = 'last pattern'
call feedkeys("/third\<C-c>", 'tx')
call assert_equal('last pattern', @/)
call feedkeys("/third\<Esc>", 'tx')
call assert_equal('last pattern', @/)
call feedkeys("/3\<bs>\<bs>", 'tx')
call assert_equal('last pattern', @/)
call feedkeys("/third\<c-g>\<c-t>\<Esc>", 'tx')
call assert_equal('last pattern', @/)
" clean up
set noincsearch nohlsearch
bw!
endfunc
func Test_search_cmdline_incsearch_highlight_attr()
if !exists('+incsearch') || !has('terminal') || has('gui_running')
return
endif
let h = winheight(0)
if h < 3
return
endif
" Prepare buffer text
let g:lines = ['abb vim vim vi', 'vimvivim']
call writefile(g:lines, 'Xsearch.txt')
let g:buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
call WaitFor('g:lines[0] == term_getline(g:buf, 1)')
call assert_equal(g:lines[0], term_getline(g:buf, 1))
call assert_equal(g:lines[1], term_getline(g:buf, 2))
unlet g:lines
" Get attr of normal(a0), incsearch(a1), hlsearch(a2) highlight
call term_sendkeys(g:buf, ":set incsearch hlsearch\<cr>")
call term_sendkeys(g:buf, '/b')
call term_wait(g:buf, 200)
let screen_line1 = term_scrape(g:buf, 1)
call assert_true(len(screen_line1) > 2)
" a0: attr_normal
let a0 = screen_line1[0].attr
" a1: attr_incsearch
let a1 = screen_line1[1].attr
" a2: attr_hlsearch
let a2 = screen_line1[2].attr
call assert_notequal(a0, a1)
call assert_notequal(a0, a2)
call assert_notequal(a1, a2)
call term_sendkeys(g:buf, "\<cr>gg0")
" Test incremental highlight search
call term_sendkeys(g:buf, "/vim")
call term_wait(g:buf, 200)
" Buffer:
" abb vim vim vi
" vimvivim
" Search: /vim
let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a2,a2,a2,a0,a0,a0]
let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
call assert_equal(attr_line1, map(term_scrape(g:buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
call assert_equal(attr_line2, map(term_scrape(g:buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
" Test <C-g>
call term_sendkeys(g:buf, "\<C-g>\<C-g>")
call term_wait(g:buf, 200)
let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
let attr_line2 = [a1,a1,a1,a0,a0,a2,a2,a2]
call assert_equal(attr_line1, map(term_scrape(g:buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
call assert_equal(attr_line2, map(term_scrape(g:buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
" Test <C-t>
call term_sendkeys(g:buf, "\<C-t>")
call term_wait(g:buf, 200)
let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a1,a1,a1,a0,a0,a0]
let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
call assert_equal(attr_line1, map(term_scrape(g:buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
call assert_equal(attr_line2, map(term_scrape(g:buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
" Type Enter and a1(incsearch highlight) should become a2(hlsearch highlight)
call term_sendkeys(g:buf, "\<cr>")
call term_wait(g:buf, 200)
let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
call assert_equal(attr_line1, map(term_scrape(g:buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
call assert_equal(attr_line2, map(term_scrape(g:buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
" Test nohlsearch. a2(hlsearch highlight) should become a0(normal highlight)
call term_sendkeys(g:buf, ":1\<cr>")
call term_sendkeys(g:buf, ":set nohlsearch\<cr>")
call term_sendkeys(g:buf, "/vim")
call term_wait(g:buf, 200)
let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a0,a0,a0,a0,a0,a0]
let attr_line2 = [a0,a0,a0,a0,a0,a0,a0,a0]
call assert_equal(attr_line1, map(term_scrape(g:buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
call assert_equal(attr_line2, map(term_scrape(g:buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
call delete('Xsearch.txt')
bwipe!
endfunc
func Test_search_undefined_behaviour()
if !has("terminal")
return
endif
let h = winheight(0)
if h < 3
return
endif
" did cause an undefined left shift
let g:buf = term_start([GetVimProg(), '--clean', '-e', '-s', '-c', 'call search(getline("."))', 'samples/test000'], {'term_rows': 3})
call assert_equal([''], getline(1, '$'))
call term_sendkeys(g:buf, ":qa!\<cr>")
bwipe!
endfunc

View File

@@ -11,7 +11,11 @@ let s:python = PythonProg()
" Open a terminal with a shell, assign the job to g:job and return the buffer
" number.
func Run_shell_in_terminal(options)
let buf = term_start(&shell, a:options)
if has('win32')
let buf = term_start([&shell,'/k'], a:options)
else
let buf = term_start(&shell, a:options)
endif
let termlist = term_list()
call assert_equal(1, len(termlist))
@@ -430,13 +434,14 @@ func Test_terminal_cwd()
endfunc
func Test_terminal_env()
if !has('unix')
return
endif
let g:buf = Run_shell_in_terminal({'env': {'TESTENV': 'correct'}})
" Wait for the shell to display a prompt
call WaitFor('term_getline(g:buf, 1) != ""')
call term_sendkeys(g:buf, "echo $TESTENV\r")
if has('win32')
call term_sendkeys(g:buf, "echo %TESTENV%\r")
else
call term_sendkeys(g:buf, "echo $TESTENV\r")
endif
call term_wait(g:buf)
call Stop_shell_in_terminal(g:buf)
call WaitFor('getline(2) == "correct"')
@@ -700,7 +705,7 @@ func Test_terminal_composing_unicode()
enew
let buf = term_start(cmd, {'curwin': bufnr('')})
let job = term_getjob(buf)
let g:job = term_getjob(buf)
call term_wait(buf, 50)
" ascii + composing
@@ -737,8 +742,9 @@ func Test_terminal_composing_unicode()
call assert_equal("\u00a0\u0308", l[3].chars)
call term_sendkeys(buf, "exit\r")
call WaitFor('job_status(job) == "dead"')
call assert_equal('dead', job_status(job))
call WaitFor('job_status(g:job) == "dead"')
call assert_equal('dead', job_status(g:job))
bwipe!
unlet g:job
let &encoding = save_enc
endfunc

View File

@@ -761,6 +761,28 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1248,
/**/
1247,
/**/
1246,
/**/
1245,
/**/
1244,
/**/
1243,
/**/
1242,
/**/
1241,
/**/
1240,
/**/
1239,
/**/
1238,
/**/
1237,
/**/