Compare commits

...

16 Commits

Author SHA1 Message Date
Bram Moolenaar
15618fa643 patch 8.0.0493: crash with cd command with very long argument
Problem:    Crash with cd command with very long argument.
Solution:   Check for running out of space. (Dominique pending, closes #1576)
2017-03-19 21:37:13 +01:00
Bram Moolenaar
81b9d0bd5c patch 8.0.0492: a failing client-server request can make Vim hang
Problem:    A failing client-server request can make Vim hang.
Solution:   Add a timeout argument to functions that wait.
2017-03-19 21:20:53 +01:00
Bram Moolenaar
bfd830d3e2 patch 8.0.0491: quotestar test fails when features are missing
Problem:    The quotestar test fails when a required feature is missing.
Solution:   Prepend "Skipped" to the thrown exception.
2017-03-19 21:01:14 +01:00
Bram Moolenaar
38e3483637 patch 8.0.0490: vertical split makes 'winfixwidth' window smaller
Problem:    Splitting a 'winfixwidth' window vertically makes it one column
            smaller. (Dominique Pelle)
Solution:   Add one to the width for the separator.
2017-03-19 20:22:36 +01:00
Bram Moolenaar
7dd4850698 patch 8.0.0489: clipboard and "* register is not tested
Problem:    Clipboard and "* register is not tested.
Solution:   Add a test for Mac and X11. (Kazunobu Kuriyama)
2017-03-19 20:04:22 +01:00
Bram Moolenaar
b4c5572e74 patch 8.0.0488: running tests leaves an "xxx" file behind
Problem:    Running tests leaves an "xxx" file behind.
Solution:   Delete the 'verbosefile' after resetting the option.
2017-03-19 19:11:35 +01:00
Bram Moolenaar
651e4056ac patch 8.0.0487: the autocmd test hangs on MS-Windows
Problem:    The autocmd test hangs on MS-Windows.
Solution:   Skip the hanging tests for now.
2017-03-19 18:34:46 +01:00
Bram Moolenaar
8c752bd6c4 patch 8.0.0486: crash and endless loop when closing windows in autocmd
Problem:    Crash and endless loop when closing windows in a SessionLoadPost
            autocommand.
Solution:   Check for valid tabpage.  (partly neovim #6308)
2017-03-19 17:09:56 +01:00
Bram Moolenaar
4520d440c5 patch 8.0.0485: not all windows commands are tested
Problem:    Not all windows commands are tested.
Solution:   Add more tests for windows commands. (Dominique Pelle,
            closes #1575) Run test_autocmd separately, it interferes with
            other tests.  Fix tests that depended on side effects.
2017-03-19 16:09:46 +01:00
Bram Moolenaar
ee85df3763 patch 8.0.0484: :lhelpgrep does not fail after a successful one
Problem:    Using :lhelpgrep with an argument that should fail does not
            produce an error if the previous :helpgrep worked.
Solution:   Use another way to detect that autocommands made the quickfix info
            invalid. (Yegappan Lakshmanan)
2017-03-19 14:19:50 +01:00
Bram Moolenaar
f79225ed4f patch 8.0.0483: illegal memory access when using :all
Problem:    Illegal memory access when using :all. (Dominique Pelle)
Solution:   Adjust the cursor position right after setting "curwin".
2017-03-18 23:11:04 +01:00
Bram Moolenaar
2c90d51123 patch 8.0.0482: the setbufvar() function may mess up the window layout
Problem:    The setbufvar() function may mess up the window layout. (Kay Z.)
Solution:   Do not check the window to be valid if it is NULL.
2017-03-18 22:35:30 +01:00
Bram Moolenaar
aab93b12cb patch 8.0.0481: unnecessary if statement
Problem:    Unnecessary if statement.
Solution:   Remove the statement.  Fix "it's" vs "its" mistakes. (Dominique
            Pelle, closes #1568)
2017-03-18 21:37:28 +01:00
Bram Moolenaar
15e737f768 patch 8.0.0480: the remote_peek() test fails on MS-Windows
Problem:    The remote_peek() test fails on MS-Windows.
Solution:   Check for pending messages. Also report errors in the first run if
            a flaky test fails twice.
2017-03-18 21:22:47 +01:00
Bram Moolenaar
6caf606b14 patch 8.0.0479: remote_peek() is not tested
Problem:    remote_peek() is not tested.
Solution:   Add a test.
2017-03-18 20:45:05 +01:00
Bram Moolenaar
37175409d7 patch 8.0.0478: tests use assert_true(0) and assert_false(1) to report errors
Problem:    Tests use assert_true(0) and assert_false(1) to report errors.
Solution:   Use assert_report().
2017-03-18 20:18:45 +01:00
40 changed files with 1063 additions and 208 deletions

View File

@@ -6320,15 +6320,17 @@ reltimestr({time}) *reltimestr()*
{only available when compiled with the |+reltime| feature}
*remote_expr()* *E449*
remote_expr({server}, {string} [, {idvar}])
remote_expr({server}, {string} [, {idvar} [, {timeout}]])
Send the {string} to {server}. The string is sent as an
expression and the result is returned after evaluation.
The result must be a String or a |List|. A |List| is turned
into a String by joining the items with a line break in
between (not at the end), like with join(expr, "\n").
If {idvar} is present, it is taken as the name of a
variable and a {serverid} for later use with
If {idvar} is present and not empty, it is taken as the name
of a variable and a {serverid} for later use with
remote_read() is stored there.
If {timeout} is given the read times out after this many
seconds. Otherwise a timeout of 600 seconds is used.
See also |clientserver| |RemoteReply|.
This function is not available in the |sandbox|.
{only available when compiled with the |+clientserver| feature}
@@ -6367,9 +6369,10 @@ remote_peek({serverid} [, {retvar}]) *remote_peek()*
:let repl = ""
:echo "PEEK: ".remote_peek(id, "repl").": ".repl
remote_read({serverid}) *remote_read()*
remote_read({serverid}, [{timeout}]) *remote_read()*
Return the oldest available reply from {serverid} and consume
it. It blocks until a reply is available.
it. Unless a {timeout} in seconds is given, it blocks until a
reply is available.
See also |clientserver|.
This function is not available in the |sandbox|.
{only available when compiled with the |+clientserver| feature}

View File

@@ -2096,6 +2096,7 @@ test_arglist \
test_backspace_opt \
test_breakindent \
test_bufwintabinfo \
test_cd \
test_cdo \
test_changedtick \
test_channel \
@@ -2185,6 +2186,7 @@ test_arglist \
test_pyx2 \
test_pyx3 \
test_quickfix \
test_quotestar \
test_recover \
test_regexp_latin \
test_regexp_utf8 \

View File

@@ -739,10 +739,10 @@ static struct fst
{"reltimefloat", 1, 1, f_reltimefloat},
#endif
{"reltimestr", 1, 1, f_reltimestr},
{"remote_expr", 2, 3, f_remote_expr},
{"remote_expr", 2, 4, f_remote_expr},
{"remote_foreground", 1, 1, f_remote_foreground},
{"remote_peek", 1, 2, f_remote_peek},
{"remote_read", 1, 1, f_remote_read},
{"remote_read", 1, 2, f_remote_read},
{"remote_send", 2, 3, f_remote_send},
{"remote_startserver", 1, 1, f_remote_startserver},
{"remove", 2, 3, f_remove},
@@ -8515,6 +8515,7 @@ remote_common(typval_T *argvars, typval_T *rettv, int expr)
char_u *keys;
char_u *r = NULL;
char_u buf[NUMBUFLEN];
int timeout = 0;
# ifdef WIN32
HWND w;
# else
@@ -8528,16 +8529,19 @@ remote_common(typval_T *argvars, typval_T *rettv, int expr)
if (check_connection() == FAIL)
return;
# endif
if (argvars[2].v_type != VAR_UNKNOWN
&& argvars[3].v_type != VAR_UNKNOWN)
timeout = get_tv_number(&argvars[3]);
server_name = get_tv_string_chk(&argvars[0]);
if (server_name == NULL)
return; /* type error; errmsg already given */
keys = get_tv_string_buf(&argvars[1], buf);
# ifdef WIN32
if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0)
if (serverSendToVim(server_name, keys, &r, &w, expr, timeout, TRUE) < 0)
# else
if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE)
< 0)
if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, timeout,
0, TRUE) < 0)
# endif
{
if (r != NULL)
@@ -8555,13 +8559,15 @@ remote_common(typval_T *argvars, typval_T *rettv, int expr)
char_u str[30];
char_u *idvar;
sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w);
v.di_tv.v_type = VAR_STRING;
v.di_tv.vval.v_string = vim_strsave(str);
idvar = get_tv_string_chk(&argvars[2]);
if (idvar != NULL)
if (idvar != NULL && *idvar != NUL)
{
sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w);
v.di_tv.v_type = VAR_STRING;
v.di_tv.vval.v_string = vim_strsave(str);
set_var(idvar, &v.di_tv, FALSE);
vim_free(v.di_tv.vval.v_string);
vim_free(v.di_tv.vval.v_string);
}
}
}
#endif
@@ -8633,7 +8639,7 @@ f_remote_peek(typval_T *argvars UNUSED, typval_T *rettv)
rettv->vval.v_number = -1;
else
{
s = serverGetReply((HWND)n, FALSE, FALSE, FALSE);
s = serverGetReply((HWND)n, FALSE, FALSE, FALSE, 0);
rettv->vval.v_number = (s != NULL);
}
# else
@@ -8670,17 +8676,23 @@ f_remote_read(typval_T *argvars UNUSED, typval_T *rettv)
if (serverid != NULL && !check_restricted() && !check_secure())
{
int timeout = 0;
if (argvars[1].v_type != VAR_UNKNOWN)
timeout = get_tv_number(&argvars[1]);
# ifdef WIN32
/* The server's HWND is encoded in the 'id' parameter */
long_u n = 0;
sscanf((char *)serverid, SCANF_HEX_LONG_U, &n);
if (n != 0)
r = serverGetReply((HWND)n, FALSE, TRUE, TRUE);
r = serverGetReply((HWND)n, FALSE, TRUE, TRUE, timeout);
if (r == NULL)
# else
if (check_connection() == FAIL || serverReadReply(X_DISPLAY,
serverStrToWin(serverid), &r, FALSE) < 0)
if (check_connection() == FAIL
|| serverReadReply(X_DISPLAY, serverStrToWin(serverid),
&r, FALSE, timeout) < 0)
# endif
EMSG(_("E277: Unable to read a server reply"));
}

View File

@@ -9033,6 +9033,11 @@ win_found:
win_remove(curwin, NULL);
aucmd_win_used = FALSE;
last_status(FALSE); /* may need to remove last status line */
if (!valid_tabpage_win(curtab))
/* no valid window in current tabpage */
close_tabpage(curtab);
restore_snapshot(SNAP_AUCMD_IDX, FALSE);
(void)win_comp_pos(); /* recompute window positions */
unblock_autocmds();

View File

@@ -373,6 +373,7 @@ serverSendToVim(
char_u **result, /* Result of eval'ed expression */
Window *server, /* Actual ID of receiving app */
Bool asExpr, /* Interpret as keystrokes or expr ? */
int timeout, /* seconds to wait or zero */
Bool localLoop, /* Throw away everything but result */
int silent) /* don't complain about no server */
{
@@ -485,7 +486,8 @@ serverSendToVim(
pending.nextPtr = pendingCommands;
pendingCommands = &pending;
ServerWait(dpy, w, WaitForPend, &pending, localLoop, 600);
ServerWait(dpy, w, WaitForPend, &pending, localLoop,
timeout > 0 ? timeout : 600);
/*
* Unregister the information about the pending command
@@ -790,6 +792,7 @@ WaitForReply(void *p)
/*
* Wait for replies from id (win)
* When "timeout" is non-zero wait up to this many seconds.
* Return 0 and the malloc'ed string when a reply is available.
* Return -1 if the window becomes invalid while waiting.
*/
@@ -798,13 +801,15 @@ serverReadReply(
Display *dpy,
Window win,
char_u **str,
int localLoop)
int localLoop,
int timeout)
{
int len;
char_u *s;
struct ServerReply *p;
ServerWait(dpy, win, WaitForReply, &win, localLoop, -1);
ServerWait(dpy, win, WaitForReply, &win, localLoop,
timeout > 0 ? timeout : -1);
if ((p = ServerReplyFind(win, SROP_Find)) != NULL && p->strings.ga_len > 0)
{

View File

@@ -3791,10 +3791,10 @@ cmdsrv_main(
}
else
ret = serverSendToVim(xterm_dpy, sname, *serverStr,
NULL, &srv, 0, 0, silent);
NULL, &srv, 0, 0, 0, silent);
# else
/* Win32 always works? */
ret = serverSendToVim(sname, *serverStr, NULL, &srv, 0, silent);
ret = serverSendToVim(sname, *serverStr, NULL, &srv, 0, 0, silent);
# endif
if (ret < 0)
{
@@ -3854,11 +3854,11 @@ cmdsrv_main(
while (memchr(done, 0, numFiles) != NULL)
{
# ifdef WIN32
p = serverGetReply(srv, NULL, TRUE, TRUE);
p = serverGetReply(srv, NULL, TRUE, TRUE, 0);
if (p == NULL)
break;
# else
if (serverReadReply(xterm_dpy, srv, &p, TRUE) < 0)
if (serverReadReply(xterm_dpy, srv, &p, TRUE, -1) < 0)
break;
# endif
j = atoi((char *)p);
@@ -3885,12 +3885,12 @@ cmdsrv_main(
# ifdef WIN32
/* Win32 always works? */
if (serverSendToVim(sname, (char_u *)argv[i + 1],
&res, NULL, 1, FALSE) < 0)
&res, NULL, 1, 0, FALSE) < 0)
# else
if (xterm_dpy == NULL)
mch_errmsg(_("No display: Send expression failed.\n"));
else if (serverSendToVim(xterm_dpy, sname, (char_u *)argv[i + 1],
&res, NULL, 1, 1, FALSE) < 0)
&res, NULL, 1, 0, 1, FALSE) < 0)
# endif
{
if (res != NULL && *res != NUL)

View File

@@ -4637,13 +4637,23 @@ vim_findfile(void *search_ctx_arg)
if (!vim_isAbsName(stackp->ffs_fix_path)
&& search_ctx->ffsc_start_dir)
{
STRCPY(file_path, search_ctx->ffsc_start_dir);
add_pathsep(file_path);
if (STRLEN(search_ctx->ffsc_start_dir) + 1 < MAXPATHL)
{
STRCPY(file_path, search_ctx->ffsc_start_dir);
add_pathsep(file_path);
}
else
goto fail;
}
/* append the fix part of the search path */
STRCAT(file_path, stackp->ffs_fix_path);
add_pathsep(file_path);
if (STRLEN(file_path) + STRLEN(stackp->ffs_fix_path) + 1 < MAXPATHL)
{
STRCAT(file_path, stackp->ffs_fix_path);
add_pathsep(file_path);
}
else
goto fail;
#ifdef FEAT_PATH_EXTRA
rest_of_wildcards = stackp->ffs_wc_path;
@@ -4660,7 +4670,10 @@ vim_findfile(void *search_ctx_arg)
if (*p > 0)
{
(*p)--;
file_path[len++] = '*';
if (len + 1 < MAXPATHL)
file_path[len++] = '*';
else
goto fail;
}
if (*p == 0)
@@ -4688,7 +4701,10 @@ vim_findfile(void *search_ctx_arg)
*/
while (*rest_of_wildcards
&& !vim_ispathsep(*rest_of_wildcards))
file_path[len++] = *rest_of_wildcards++;
if (len + 1 < MAXPATHL)
file_path[len++] = *rest_of_wildcards++;
else
goto fail;
file_path[len] = NUL;
if (vim_ispathsep(*rest_of_wildcards))
@@ -4749,9 +4765,15 @@ vim_findfile(void *search_ctx_arg)
/* prepare the filename to be checked for existence
* below */
STRCPY(file_path, stackp->ffs_filearray[i]);
add_pathsep(file_path);
STRCAT(file_path, search_ctx->ffsc_file_to_search);
if (STRLEN(stackp->ffs_filearray[i]) + 1
+ STRLEN(search_ctx->ffsc_file_to_search) < MAXPATHL)
{
STRCPY(file_path, stackp->ffs_filearray[i]);
add_pathsep(file_path);
STRCAT(file_path, search_ctx->ffsc_file_to_search);
}
else
goto fail;
/*
* Try without extra suffix and then with suffixes
@@ -4924,9 +4946,15 @@ vim_findfile(void *search_ctx_arg)
if (*search_ctx->ffsc_start_dir == 0)
break;
STRCPY(file_path, search_ctx->ffsc_start_dir);
add_pathsep(file_path);
STRCAT(file_path, search_ctx->ffsc_fix_path);
if (STRLEN(search_ctx->ffsc_start_dir) + 1
+ STRLEN(search_ctx->ffsc_fix_path) < MAXPATHL)
{
STRCPY(file_path, search_ctx->ffsc_start_dir);
add_pathsep(file_path);
STRCAT(file_path, search_ctx->ffsc_fix_path);
}
else
goto fail;
/* create a new stack entry */
sptr = ff_create_stack_element(file_path,
@@ -4940,6 +4968,7 @@ vim_findfile(void *search_ctx_arg)
}
#endif
fail:
vim_free(file_path);
return NULL;
}

View File

@@ -2401,6 +2401,7 @@ serverSendToVim(
char_u **result, /* Result of eval'ed expression */
void *ptarget, /* HWND of server */
int asExpr, /* Expression or keys? */
int timeout, /* timeout in seconds or zero */
int silent) /* don't complain about no server */
{
HWND target;
@@ -2444,7 +2445,7 @@ serverSendToVim(
return -1;
if (asExpr)
retval = serverGetReply(target, &retcode, TRUE, TRUE);
retval = serverGetReply(target, &retcode, TRUE, TRUE, timeout);
if (result == NULL)
vim_free(retval);
@@ -2521,13 +2522,17 @@ save_reply(HWND server, char_u *reply, int expr)
* if "wait" is TRUE block until a message arrives (or the server exits).
*/
char_u *
serverGetReply(HWND server, int *expr_res, int remove, int wait)
serverGetReply(HWND server, int *expr_res, int remove, int wait, int timeout)
{
int i;
char_u *reply;
reply_T *rep;
int did_process = FALSE;
time_t start;
time_t now;
/* When waiting, loop until the message waiting for is received. */
time(&start);
for (;;)
{
/* Reset this here, in case a message arrives while we are going
@@ -2562,7 +2567,17 @@ serverGetReply(HWND server, int *expr_res, int remove, int wait)
/* If we got here, we didn't find a reply. Return immediately if the
* "wait" parameter isn't set. */
if (!wait)
{
/* Process pending messages once. Without this, looping on
* remote_peek() would never get the reply. */
if (!did_process)
{
did_process = TRUE;
serverProcessPendingMessages();
continue;
}
break;
}
/* We need to wait for a reply. Enter a message loop until the
* "reply_received" flag gets set. */
@@ -2573,6 +2588,10 @@ serverGetReply(HWND server, int *expr_res, int remove, int wait)
#ifdef FEAT_TIMERS
check_due_timer();
#endif
time(&now);
if (timeout > 0 && (now - start) >= timeout)
break;
/* Wait for a SendMessage() call to us. This could be the reply
* we are waiting for. Use a timeout of a second, to catch the
* situation that the server died unexpectedly. */

View File

@@ -1,11 +1,11 @@
/* if_xcmdsrv.c */
int serverRegisterName(Display *dpy, char_u *name);
void serverChangeRegisteredWindow(Display *dpy, Window newwin);
int serverSendToVim(Display *dpy, char_u *name, char_u *cmd, char_u **result, Window *server, int asExpr, int localLoop, int silent);
int serverSendToVim(Display *dpy, char_u *name, char_u *cmd, char_u **result, Window *server, int asExpr, int timeout, int localLoop, int silent);
char_u *serverGetVimNames(Display *dpy);
Window serverStrToWin(char_u *str);
int serverSendReply(char_u *name, char_u *str);
int serverReadReply(Display *dpy, Window win, char_u **str, int localLoop);
int serverReadReply(Display *dpy, Window win, char_u **str, int localLoop, int timeout);
int serverPeekReply(Display *dpy, Window win, char_u **str);
void serverEventProc(Display *dpy, XEvent *eventPtr, int immediate);
void server_parse_messages(void);

View File

@@ -43,9 +43,9 @@ void serverInitMessaging(void);
void serverSetName(char_u *name);
char_u *serverGetVimNames(void);
int serverSendReply(char_u *name, char_u *reply);
int serverSendToVim(char_u *name, char_u *cmd, char_u **result, void *ptarget, int asExpr, int silent);
int serverSendToVim(char_u *name, char_u *cmd, char_u **result, void *ptarget, int asExpr, int timeout, int silent);
void serverForeground(char_u *name);
char_u *serverGetReply(HWND server, int *expr_res, int remove, int wait);
char_u *serverGetReply(HWND server, int *expr_res, int remove, int wait, int timeout);
void serverProcessPendingMessages(void);
char *charset_id2name(int id);
char *quality_id2name(DWORD id);

View File

@@ -26,6 +26,8 @@ int win_new_tabpage(int after);
int may_open_tabpage(void);
int make_tabpages(int maxcount);
int valid_tabpage(tabpage_T *tpc);
int valid_tabpage_win(tabpage_T *tpc);
void close_tabpage(tabpage_T *tpc);
tabpage_T *find_tabpage(int n);
int tabpage_index(tabpage_T *ftp);
void goto_tabpage(int n);

View File

@@ -5077,6 +5077,7 @@ ex_helpgrep(exarg_T *eap)
char_u *lang;
#endif
qf_info_T *qi = &ql_info;
qf_info_T *save_qi;
int new_qi = FALSE;
win_T *wp;
#ifdef FEAT_AUTOCMD
@@ -5130,6 +5131,9 @@ ex_helpgrep(exarg_T *eap)
}
}
/* Autocommands may change the list. Save it for later comparison */
save_qi = qi;
regmatch.regprog = vim_regcomp(eap->arg, RE_MAGIC + RE_STRING);
regmatch.rm_ic = FALSE;
if (regmatch.regprog != NULL)
@@ -5262,7 +5266,7 @@ ex_helpgrep(exarg_T *eap)
{
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
curbuf->b_fname, TRUE, curbuf);
if (!new_qi && qi != &ql_info && qf_find_buf(qi) == NULL)
if (!new_qi && qi != save_qi && qf_find_buf(qi) == NULL)
/* autocommands made "qi" invalid */
return;
}

View File

@@ -1782,36 +1782,33 @@ syn_finish_line(
stateitem_T *cur_si;
colnr_T prev_current_col;
if (!current_finished)
while (!current_finished)
{
while (!current_finished)
(void)syn_current_attr(syncing, FALSE, NULL, FALSE);
/*
* When syncing, and found some item, need to check the item.
*/
if (syncing && current_state.ga_len)
{
(void)syn_current_attr(syncing, FALSE, NULL, FALSE);
/*
* When syncing, and found some item, need to check the item.
* Check for match with sync item.
*/
if (syncing && current_state.ga_len)
{
/*
* Check for match with sync item.
*/
cur_si = &CUR_STATE(current_state.ga_len - 1);
if (cur_si->si_idx >= 0
&& (SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags
& (HL_SYNC_HERE|HL_SYNC_THERE)))
return TRUE;
cur_si = &CUR_STATE(current_state.ga_len - 1);
if (cur_si->si_idx >= 0
&& (SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags
& (HL_SYNC_HERE|HL_SYNC_THERE)))
return TRUE;
/* syn_current_attr() will have skipped the check for an item
* that ends here, need to do that now. Be careful not to go
* past the NUL. */
prev_current_col = current_col;
if (syn_getcurline()[current_col] != NUL)
++current_col;
check_state_ends();
current_col = prev_current_col;
}
++current_col;
/* syn_current_attr() will have skipped the check for an item
* that ends here, need to do that now. Be careful not to go
* past the NUL. */
prev_current_col = current_col;
if (syn_getcurline()[current_col] != NUL)
++current_col;
check_state_ends();
current_col = prev_current_col;
}
++current_col;
}
return FALSE;
}
@@ -3333,7 +3330,7 @@ syn_regexec(
/*
* Check one position in a line for a matching keyword.
* The caller must check if a keyword can start at startcol.
* Return it's ID if found, 0 otherwise.
* Return its ID if found, 0 otherwise.
*/
static int
check_keyword_id(
@@ -5495,7 +5492,7 @@ syn_combine_list(short **clstr1, short **clstr2, int list_op)
}
/*
* Lookup a syntax cluster name and return it's ID.
* Lookup a syntax cluster name and return its ID.
* If it is not found, 0 is returned.
*/
static int
@@ -5535,7 +5532,7 @@ syn_scl_namen2id(char_u *linep, int len)
}
/*
* Find syntax cluster name in the table and return it's ID.
* Find syntax cluster name in the table and return its ID.
* The argument is a pointer to the name and the length of the name.
* If it doesn't exist yet, a new entry is created.
* Return 0 for failure.
@@ -5559,7 +5556,7 @@ syn_check_cluster(char_u *pp, int len)
}
/*
* Add new syntax cluster and return it's ID.
* Add new syntax cluster and return its ID.
* "name" must be an allocated string, it will be consumed.
* Return 0 for failure.
*/
@@ -7752,7 +7749,7 @@ do_highlight(
break;
}
/* Use the _16 table to check if its a valid color name. */
/* Use the _16 table to check if it's a valid color name. */
color = color_numbers_16[i];
if (color >= 0)
{
@@ -9346,7 +9343,7 @@ set_hl_attr(
}
/*
* Lookup a highlight group name and return it's ID.
* Lookup a highlight group name and return its ID.
* If it is not found, 0 is returned.
*/
int
@@ -9411,7 +9408,7 @@ syn_namen2id(char_u *linep, int len)
}
/*
* Find highlight group name in the table and return it's ID.
* Find highlight group name in the table and return its ID.
* The argument is a pointer to the name and the length of the name.
* If it doesn't exist yet, a new entry is created.
* Return 0 for failure.
@@ -9435,7 +9432,7 @@ syn_check_group(char_u *pp, int len)
}
/*
* Add new highlight group and return it's ID.
* Add new highlight group and return its ID.
* "name" must be an allocated string, it will be consumed.
* Return 0 for failure.
*/

View File

@@ -137,6 +137,7 @@ NEW_TESTS = test_arabic.res \
test_arglist.res \
test_assert.res \
test_autochdir.res \
test_autocmd.res \
test_backspace_opt.res \
test_breakindent.res \
test_bufwintabinfo.res \
@@ -193,6 +194,7 @@ NEW_TESTS = test_arabic.res \
test_pyx2.res \
test_pyx3.res \
test_quickfix.res \
test_quotestar.res \
test_retab.res \
test_ruby.res \
test_search.res \

View File

@@ -175,10 +175,6 @@ while 1
for val in a[0]
call add(script, 'set ' . name . '=' . val)
call add(script, 'set ' . shortname . '=' . val)
if name == 'verbosefile' && !empty(val)
call add(script, 'call delete("'. val. '")')
endif
endfor
" setting an option can only fail when it's implemented.
@@ -192,6 +188,9 @@ while 1
call add(script, 'set ' . name . '&')
call add(script, 'set ' . shortname . '&')
if name == 'verbosefile'
call add(script, 'call delete("xxx")')
endif
if name == 'more'
call add(script, 'set nomore')

View File

@@ -228,6 +228,7 @@ let s:flaky = [
\ 'Test_pipe_through_sort_all()',
\ 'Test_pipe_through_sort_some()',
\ 'Test_quoteplus()',
\ 'Test_quotestar()',
\ 'Test_reltime()',
\ ]
@@ -247,9 +248,20 @@ for s:test in sort(s:tests)
call RunTheTest(s:test)
if len(v:errors) > 0 && index(s:flaky, s:test) >= 0
call add(s:messages, 'Found errors in ' . s:test . ':')
call extend(s:messages, v:errors)
call add(s:messages, 'Flaky test failed, running it again')
let first_run = v:errors
let v:errors = []
call RunTheTest(s:test)
if len(v:errors) > 0
let second_run = v:errors
let v:errors = ['First run:']
call extend(v:errors, first_run)
call add(v:errors, 'Second run:')
call extend(v:errors, second_run)
endif
endif
call AfterTheTest()

View File

@@ -3,7 +3,7 @@
set belloff=all
source test_assign.vim
source test_autocmd.vim
source test_cd.vim
source test_changedtick.vim
source test_cursor_func.vim
source test_delete.vim

View File

@@ -36,6 +36,12 @@ func Test_assert_notequal()
call remove(v:errors, 0)
endfunc
func Test_assert_report()
call assert_report('something is wrong')
call assert_match('something is wrong', v:errors[0])
call remove(v:errors, 0)
endfunc
func Test_assert_exception()
try
nocommand

View File

@@ -1,5 +1,7 @@
" Tests for autocommands
set belloff=all
function! s:cleanup_buffers() abort
for bnr in range(1, bufnr('$'))
if bufloaded(bnr) && bufnr('%') != bnr
@@ -318,6 +320,8 @@ func Test_three_windows()
call assert_equal('Xanother', expand('%'))
au!
enew
bwipe! Xtestje1
call delete('Xtestje1')
call delete('Xtestje2')
call delete('Xtestje3')
@@ -341,3 +345,72 @@ func Test_BufEnter()
call delete('Xdir', 'd')
au! BufEnter
endfunc
" Closing a window might cause an endless loop
" E814 for older Vims
function Test_autocmd_bufwipe_in_SessLoadPost()
if has('win32')
throw 'Skipped: test hangs on MS-Windows'
endif
tabnew
set noswapfile
let g:bufnr=bufnr('%')
mksession!
let content=['set nocp noswapfile',
\ 'let v:swapchoice="e"',
\ 'augroup test_autocmd_sessionload',
\ 'autocmd!',
\ 'autocmd SessionLoadPost * 4bw!',
\ 'augroup END'
\ ]
call writefile(content, 'Xvimrc')
let a=system(v:progpath. ' -u Xvimrc --noplugins -S Session.vim')
call assert_match('E814', a)
unlet! g:bufnr
set swapfile
for file in ['Session.vim', 'Xvimrc']
call delete(file)
endfor
endfunc
" SEGV occurs in older versions.
function Test_autocmd_bufwipe_in_SessLoadPost2()
if has('win32')
throw 'Skipped: test hangs on MS-Windows'
endif
tabnew
set noswapfile
let g:bufnr=bufnr('%')
mksession!
let content = ['set nocp noswapfile',
\ 'function! DeleteInactiveBufs()',
\ ' tabfirst',
\ ' let tabblist = []',
\ ' for i in range(1, tabpagenr(''$''))',
\ ' call extend(tabblist, tabpagebuflist(i))',
\ ' endfor',
\ ' for b in range(1, bufnr(''$''))',
\ ' if bufexists(b) && buflisted(b) && (index(tabblist, b) == -1 || bufname(b) =~# ''^$'')',
\ ' exec ''bwipeout '' . b',
\ ' endif',
\ ' endfor',
\ 'call append("1", "SessionLoadPost DONE")',
\ 'endfunction',
\ 'au SessionLoadPost * call DeleteInactiveBufs()']
call writefile(content, 'Xvimrc')
let a=system(v:progpath. ' -u Xvimrc --noplugins -S Session.vim')
" this probably only matches on unix
if has("unix")
call assert_notmatch('Caught deadly signal SEGV', a)
endif
call assert_match('SessionLoadPost DONE', a)
unlet! g:bufnr
set swapfile
for file in ['Session.vim', 'Xvimrc']
call delete(file)
endfor
endfunc

13
src/testdir/test_cd.vim Normal file
View File

@@ -0,0 +1,13 @@
" Test for :cd
func Test_cd_large_path()
" This used to crash with a heap write overflow.
call assert_fails('cd ' . repeat('x', 5000), 'E472:')
endfunc
func Test_cd_up_and_down()
let path = getcwd()
cd ..
exe 'cd ' . path
call assert_equal(path, getcwd())
endfunc

View File

@@ -8,10 +8,14 @@ source shared.vim
let s:python = PythonProg()
if s:python == ''
" Can't run this test.
" Can't run this test without Python.
finish
endif
" Uncomment the next line to see what happens. Output is in
" src/testdir/channellog.
" call ch_logfile('channellog', 'w')
let s:chopt = {}
" Run "testfunc" after sarting the server and stop the server afterwards.
@@ -31,7 +35,7 @@ func Ch_communicate(port)
let handle = ch_open('localhost:' . a:port, s:chopt)
unlet s:chopt.drop
if ch_status(handle) == "fail"
call assert_false(1, "Can't open channel")
call assert_report("Can't open channel")
return
endif
if has('job')
@@ -93,7 +97,7 @@ func Ch_communicate(port)
call ch_sendexpr(handle, 'hello!', {'callback': 'Ch_requestHandler'})
call WaitFor('exists("g:Ch_responseHandle")')
if !exists('g:Ch_responseHandle')
call assert_false(1, 'g:Ch_responseHandle was not set')
call assert_report('g:Ch_responseHandle was not set')
else
call assert_equal(handle, g:Ch_responseHandle)
unlet g:Ch_responseHandle
@@ -104,7 +108,7 @@ func Ch_communicate(port)
call ch_sendexpr(handle, 'hello!', {'callback': function('Ch_requestHandler')})
call WaitFor('exists("g:Ch_responseHandle")')
if !exists('g:Ch_responseHandle')
call assert_false(1, 'g:Ch_responseHandle was not set')
call assert_report('g:Ch_responseHandle was not set')
else
call assert_equal(handle, g:Ch_responseHandle)
unlet g:Ch_responseHandle
@@ -116,7 +120,7 @@ func Ch_communicate(port)
call ch_sendexpr(handle, 'hello!', {'callback': {a, b -> Ch_requestHandler(a, b)}})
call WaitFor('exists("g:Ch_responseHandle")')
if !exists('g:Ch_responseHandle')
call assert_false(1, 'g:Ch_responseHandle was not set')
call assert_report('g:Ch_responseHandle was not set')
else
call assert_equal(handle, g:Ch_responseHandle)
unlet g:Ch_responseHandle
@@ -209,7 +213,7 @@ func Ch_two_channels(port)
let handle = ch_open('localhost:' . a:port, s:chopt)
call assert_equal(v:t_channel, type(handle))
if ch_status(handle) == "fail"
call assert_false(1, "Can't open channel")
call assert_report("Can't open channel")
return
endif
@@ -217,7 +221,7 @@ func Ch_two_channels(port)
let newhandle = ch_open('localhost:' . a:port, s:chopt)
if ch_status(newhandle) == "fail"
call assert_false(1, "Can't open second channel")
call assert_report("Can't open second channel")
return
endif
call assert_equal('got it', ch_evalexpr(newhandle, 'hello!'))
@@ -238,7 +242,7 @@ endfunc
func Ch_server_crash(port)
let handle = ch_open('localhost:' . a:port, s:chopt)
if ch_status(handle) == "fail"
call assert_false(1, "Can't open channel")
call assert_report("Can't open channel")
return
endif
@@ -263,7 +267,7 @@ endfunc
func Ch_channel_handler(port)
let handle = ch_open('localhost:' . a:port, s:chopt)
if ch_status(handle) == "fail"
call assert_false(1, "Can't open channel")
call assert_report("Can't open channel")
return
endif
@@ -306,7 +310,7 @@ endfunc
func Ch_channel_zero(port)
let handle = ch_open('localhost:' . a:port, s:chopt)
if ch_status(handle) == "fail"
call assert_false(1, "Can't open channel")
call assert_report("Can't open channel")
return
endif
@@ -373,7 +377,7 @@ endfunc
func Ch_raw_one_time_callback(port)
let handle = ch_open('localhost:' . a:port, s:chopt)
if ch_status(handle) == "fail"
call assert_false(1, "Can't open channel")
call assert_report("Can't open channel")
return
endif
call ch_setoptions(handle, {'mode': 'raw'})
@@ -429,7 +433,7 @@ func Test_connect_waittime()
endif
catch
if v:exception !~ 'Connection reset by peer'
call assert_false(1, "Caught exception: " . v:exception)
call assert_report("Caught exception: " . v:exception)
endif
endtry
endfunc
@@ -1343,7 +1347,7 @@ func Ch_open_delay(port)
let channel = ch_open('localhost:' . a:port, s:chopt)
unlet s:chopt.waittime
if ch_status(channel) == "fail"
call assert_false(1, "Can't open channel")
call assert_report("Can't open channel")
return
endif
call assert_equal('got it', ch_evalexpr(channel, 'hello!'))
@@ -1365,7 +1369,7 @@ endfunc
function Ch_test_call(port)
let handle = ch_open('localhost:' . a:port, s:chopt)
if ch_status(handle) == "fail"
call assert_false(1, "Can't open channel")
call assert_report("Can't open channel")
return
endif
@@ -1463,7 +1467,7 @@ endfunc
function Ch_test_close_callback(port)
let handle = ch_open('localhost:' . a:port, s:chopt)
if ch_status(handle) == "fail"
call assert_false(1, "Can't open channel")
call assert_report("Can't open channel")
return
endif
call ch_setoptions(handle, {'close_cb': 'MyCloseCb'})
@@ -1481,7 +1485,7 @@ endfunc
function Ch_test_close_partial(port)
let handle = ch_open('localhost:' . a:port, s:chopt)
if ch_status(handle) == "fail"
call assert_false(1, "Can't open channel")
call assert_report("Can't open channel")
return
endif
let g:Ch_d = {}
@@ -1631,7 +1635,7 @@ endfunc
function Ch_test_close_lambda(port)
let handle = ch_open('localhost:' . a:port, s:chopt)
if ch_status(handle) == "fail"
call assert_false(1, "Can't open channel")
call assert_report("Can't open channel")
return
endif
let g:Ch_close_ret = ''
@@ -1646,6 +1650,3 @@ func Test_close_lambda()
call ch_log('Test_close_lambda()')
call s:run_server('Ch_test_close_lambda')
endfunc
" Uncomment this to see what happens, output is in src/testdir/channellog.
" call ch_logfile('channellog', 'w')

View File

@@ -6,22 +6,12 @@ endif
source shared.vim
let s:where = 0
func Abort(id)
call assert_report('Test timed out at ' . s:where)
call FinishTesting()
endfunc
func Test_client_server()
let cmd = GetVimCommand()
if cmd == ''
return
endif
" Some of these commands may hang when failing.
call timer_start(10000, 'Abort')
let s:where = 1
let name = 'XVIMTEST'
let cmd .= ' --servername ' . name
let g:job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'})
@@ -30,61 +20,68 @@ func Test_client_server()
call assert_report('Cannot run the Vim server')
return
endif
let s:where = 2
" Takes a short while for the server to be active.
call WaitFor('serverlist() =~ "' . name . '"')
call assert_match(name, serverlist())
let s:where = 3
call remote_foreground(name)
let s:where = 4
call remote_send(name, ":let testvar = 'yes'\<CR>")
let s:where = 5
call WaitFor('remote_expr("' . name . '", "testvar") == "yes"')
let s:where = 6
call assert_equal('yes', remote_expr(name, "testvar"))
let s:where = 7
call WaitFor('remote_expr("' . name . '", "testvar", "", 1) == "yes"')
call assert_equal('yes', remote_expr(name, "testvar", "", 2))
if has('unix') && has('gui') && !has('gui_running')
" Running in a terminal and the GUI is avaiable: Tell the server to open
" the GUI and check that the remote command still works.
" Need to wait for the GUI to start up, otherwise the send hangs in trying
" to send to the terminal window.
call remote_send(name, ":gui -f\<CR>")
let s:where = 8
sleep 500m
if has('gui_athena') || has('gui_motif')
" For those GUIs, ignore the 'failed to create input context' error.
call remote_send(name, ":call test_ignore_error('E285') | gui -f\<CR>")
else
call remote_send(name, ":gui -f\<CR>")
endif
" Wait for the server to be up and answering requests.
call WaitFor('remote_expr("' . name . '", "v:version", "", 1) != ""')
call remote_send(name, ":let testvar = 'maybe'\<CR>")
let s:where = 9
call WaitFor('remote_expr("' . name . '", "testvar") == "maybe"')
let s:where = 10
call assert_equal('maybe', remote_expr(name, "testvar"))
let s:where = 11
call WaitFor('remote_expr("' . name . '", "testvar", "", 1) == "maybe"')
call assert_equal('maybe', remote_expr(name, "testvar", "", 2))
endif
call assert_fails('call remote_send("XXX", ":let testvar = ''yes''\<CR>")', 'E241')
let s:where = 12
" Expression evaluated locally.
if v:servername == ''
call remote_startserver('MYSELF')
let s:where = 13
call assert_equal('MYSELF', v:servername)
" May get MYSELF1 when running the test again.
call assert_match('MYSELF', v:servername)
endif
let g:testvar = 'myself'
call assert_equal('myself', remote_expr(v:servername, 'testvar'))
let s:where = 14
call remote_send(name, ":call server2client(expand('<client>'), 'got it')\<CR>", 'g:myserverid')
let s:where = 15
call assert_equal('got it', remote_read(g:myserverid))
let s:where = 16
call assert_equal('got it', remote_read(g:myserverid, 2))
call remote_send(name, ":call server2client(expand('<client>'), 'another')\<CR>", 'g:myserverid')
let peek_result = 'nothing'
let r = remote_peek(g:myserverid, 'peek_result')
" unpredictable whether the result is already avaialble.
if r > 0
call assert_equal('another', peek_result)
elseif r == 0
call assert_equal('nothing', peek_result)
else
call assert_report('remote_peek() failed')
endif
let g:peek_result = 'empty'
call WaitFor('remote_peek(g:myserverid, "g:peek_result") > 0')
call assert_equal('another', g:peek_result)
call assert_equal('another', remote_read(g:myserverid, 2))
call remote_send(name, ":qa!\<CR>")
let s:where = 17
call WaitFor('job_status(g:job) == "dead"')
let s:where = 18
if job_status(g:job) != 'dead'
call assert_report('Server did not exit')
call job_stop(g:job, 'kill')

View File

@@ -28,7 +28,7 @@ func Test_cscopeWithCscopeConnections()
cscope add Xcscope.out
set cscopeverbose
catch
call assert_true(0)
call assert_report('exception thrown')
endtry
call assert_fails('cscope add', 'E560')
call assert_fails('cscope add Xcscope.out', 'E568')

View File

@@ -1,13 +1,7 @@
" Tests for cursor().
func Test_wrong_arguments()
try
call cursor(1. 3)
" not reached
call assert_false(1)
catch
call assert_exception('E474:')
endtry
call assert_fails('call cursor(1. 3)', 'E474:')
endfunc
func Test_move_cursor()

View File

@@ -8,6 +8,7 @@ func Test_file_delete()
call assert_equal(0, delete('Xfile'))
call assert_fails('call readfile("Xfile")', 'E484:')
call assert_equal(-1, delete('Xfile'))
bwipe Xfile
endfunc
func Test_dir_delete()
@@ -35,6 +36,8 @@ func Test_recursive_delete()
call assert_equal(0, delete('Xdir1', 'rf'))
call assert_false(isdirectory('Xdir1'))
call assert_equal(-1, delete('Xdir1', 'd'))
bwipe Xdir1/Xfile
bwipe Xdir1/subdir/Xfile
endfunc
func Test_symlink_delete()
@@ -49,6 +52,7 @@ func Test_symlink_delete()
call assert_equal(0, delete('Xlink'))
call assert_equal(-1, delete('Xlink'))
call assert_equal(0, delete('Xfile'))
bwipe Xfile
endfunc
func Test_symlink_dir_delete()
@@ -96,4 +100,8 @@ func Test_symlink_recursive_delete()
call assert_equal(['a', 'b'], readfile('Xdir4/Xfile'))
call assert_equal(0, delete('Xdir4/Xfile'))
call assert_equal(0, delete('Xdir4', 'd'))
bwipe Xdir3/Xfile
bwipe Xdir3/subdir/Xfile
bwipe Xdir4/Xfile
endfunc

View File

@@ -87,7 +87,7 @@ endfunc
func Test_loop_over_null_list()
let null_list = test_null_list()
for i in null_list
call assert_true(0, 'should not get here')
call assert_report('should not get here')
endfor
endfunc

View File

@@ -33,8 +33,8 @@ func Test_fnamemodify()
call assert_equal('''abc"%"def''', fnamemodify('abc"%"def', ':S'))
call assert_equal('''abc''\'''' ''\''''def''', fnamemodify('abc'' ''def', ':S'))
call assert_equal('''abc''\''''%''\''''def''', fnamemodify('abc''%''def', ':S'))
call assert_equal(expand('%:r:S'), shellescape(expand('%:r')))
sp test_alot.vim
call assert_equal(expand('%:r:S'), shellescape(expand('%:r')))
call assert_equal('test_alot,''test_alot'',test_alot.vim', join([expand('%:r'), expand('%:r:S'), expand('%')], ','))
quit

View File

@@ -460,8 +460,8 @@ func Test_getbufvar()
let bd = getbufvar(bnr, '',def_num)
call assert_equal(1, len(bd))
call assert_equal('', getbufvar(9, ''))
call assert_equal(def_num, getbufvar(9, '', def_num))
call assert_equal('', getbufvar(9999, ''))
call assert_equal(def_num, getbufvar(9999, '', def_num))
unlet def_num
call assert_equal(0, getbufvar(bnr, '&autoindent'))
@@ -725,3 +725,34 @@ func Test_balloon_show()
call balloon_show('hi!')
endif
endfunc
func Test_setbufvar_options()
" This tests that aucmd_prepbuf() and aucmd_restbuf() properly restore the
" window layout.
call assert_equal(1, winnr('$'))
split dummy_preview
resize 2
set winfixheight winfixwidth
let prev_id = win_getid()
wincmd j
let wh = winheight('.')
let dummy_buf = bufnr('dummy_buf1', v:true)
call setbufvar(dummy_buf, '&buftype', 'nofile')
execute 'belowright vertical split #' . dummy_buf
call assert_equal(wh, winheight('.'))
let dum1_id = win_getid()
wincmd h
let wh = winheight('.')
let dummy_buf = bufnr('dummy_buf2', v:true)
call setbufvar(dummy_buf, '&buftype', 'nofile')
execute 'belowright vertical split #' . dummy_buf
call assert_equal(wh, winheight('.'))
bwipe!
call win_gotoid(prev_id)
bwipe!
call win_gotoid(dum1_id)
bwipe!
endfunc

View File

@@ -505,7 +505,7 @@ func Test_set_guifontwide()
" Case 2: guifontset is invalid
try
set guifontset=-*-notexist-*
call assert_false(1, "'set guifontset=-*-notexist-*' should have failed")
call assert_report("'set guifontset=-*-notexist-*' should have failed")
catch
call assert_exception('E598')
endtry

View File

@@ -8,7 +8,7 @@ func Test_load_menu()
try
source $VIMRUNTIME/menu.vim
catch
call assert_false(1, 'error while loading menus: ' . v:exception)
call assert_report('error while loading menus: ' . v:exception)
endtry
call assert_match('browse confirm w', execute(':menu File.Save'))
source $VIMRUNTIME/delmenu.vim

View File

@@ -132,7 +132,7 @@ func <SID>catch_peval(expr)
catch
return v:exception
endtry
call assert_true(0, 'no exception for `perleval("'.a:expr.'")`')
call assert_report('no exception for `perleval("'.a:expr.'")`')
return ''
endfunc

View File

@@ -562,7 +562,7 @@ func Test_completion_comment_formatting()
%d
try
call feedkeys("o/*\<cr>\<cr>\<c-x>\<c-u>/\<esc>", 'tx')
call assert_false(1, 'completefunc not set, should have failed')
call assert_report('completefunc not set, should have failed')
catch
call assert_exception('E764:')
endtry

View File

@@ -31,7 +31,8 @@ func s:setup_commands(cchar)
command! -nargs=* -bang Xnfile <mods>cnfile<bang> <args>
command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args>
command! -nargs=* Xexpr <mods>cexpr <args>
command! -nargs=* Xvimgrep <mods>vimgrep <args>
command! -range -nargs=* Xvimgrep <mods><count>vimgrep <args>
command! -nargs=* Xvimgrepadd <mods>vimgrepadd <args>
command! -nargs=* Xgrep <mods> grep <args>
command! -nargs=* Xgrepadd <mods> grepadd <args>
command! -nargs=* Xhelpgrep helpgrep <args>
@@ -61,7 +62,8 @@ func s:setup_commands(cchar)
command! -nargs=* -bang Xnfile <mods>lnfile<bang> <args>
command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
command! -nargs=* Xexpr <mods>lexpr <args>
command! -nargs=* Xvimgrep <mods>lvimgrep <args>
command! -range -nargs=* Xvimgrep <mods><count>lvimgrep <args>
command! -nargs=* Xvimgrepadd <mods>lvimgrepadd <args>
command! -nargs=* Xgrep <mods> lgrep <args>
command! -nargs=* Xgrepadd <mods> lgrepadd <args>
command! -nargs=* Xhelpgrep lhelpgrep <args>
@@ -85,57 +87,52 @@ func XlistTests(cchar)
\ 'non-error 3', 'Xtestfile3:3:1:Line3']
" List only valid entries
redir => result
Xlist
redir END
let l = split(result, "\n")
let l = split(execute('Xlist', ''), "\n")
call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
\ ' 4 Xtestfile2:2 col 2: Line2',
\ ' 6 Xtestfile3:3 col 1: Line3'], l)
" List all the entries
redir => result
Xlist!
redir END
let l = split(result, "\n")
let l = split(execute('Xlist!', ''), "\n")
call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
\ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
\ ' 5: non-error 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
" List a range of errors
redir => result
Xlist 3,6
redir END
let l = split(result, "\n")
let l = split(execute('Xlist 3,6', ''), "\n")
call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
\ ' 6 Xtestfile3:3 col 1: Line3'], l)
redir => result
Xlist! 3,4
redir END
let l = split(result, "\n")
let l = split(execute('Xlist! 3,4', ''), "\n")
call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
redir => result
Xlist -6,-4
redir END
let l = split(result, "\n")
let l = split(execute('Xlist -6,-4', ''), "\n")
call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
redir => result
Xlist! -5,-3
redir END
let l = split(result, "\n")
let l = split(execute('Xlist! -5,-3', ''), "\n")
call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
\ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
" Test for '+'
redir => result
Xlist! +2
redir END
let l = split(result, "\n")
let l = split(execute('Xlist! +2', ''), "\n")
call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
\ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
" Different types of errors
call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11},
\ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22},
\ {'lnum':30,'col':15,'type':'i','text':'Info','nr':33},
\ {'lnum':40,'col':20,'type':'x', 'text':'Other','nr':44},
\ {'lnum':50,'col':25,'type':"\<C-A>",'text':'one','nr':55}])
let l = split(execute('Xlist', ""), "\n")
call assert_equal([' 1:10 col 5 warning 11: Warning',
\ ' 2:20 col 10 error 22: Error',
\ ' 3:30 col 15 info 33: Info',
\ ' 4:40 col 20 x 44: Other',
\ ' 5:50 col 25 55: one'], l)
" Error cases
call assert_fails('Xlist abc', 'E488:')
endfunc
func Test_clist()
@@ -324,6 +321,23 @@ func XbufferTests(cchar)
\ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
enew!
" Check for invalid buffer
call assert_fails('Xbuffer 199', 'E474:')
" Check for unloaded buffer
edit Xtestfile1
let bnr = bufnr('%')
enew!
call assert_fails('Xbuffer ' . bnr, 'E681:')
" Check for invalid range
" Using Xbuffer will not run the range check in the cbuffer/lbuffer
" commands. So directly call the commands.
if (a:cchar == 'c')
call assert_fails('900,999cbuffer', 'E16:')
else
call assert_fails('900,999lbuffer', 'E16:')
endif
endfunc
func Test_cbuffer()
@@ -372,6 +386,9 @@ func Xtest_browse(cchar)
call assert_equal('Xqftestfile1', bufname('%'))
call assert_equal(5, line('.'))
Xexpr ""
call assert_fails('Xnext', 'E42:')
call delete('Xqftestfile1')
call delete('Xqftestfile2')
endfunc
@@ -411,6 +428,9 @@ func s:test_xhelpgrep(cchar)
call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
" This wipes out the buffer, make sure that doesn't cause trouble.
Xclose
" Search for non existing help string
call assert_fails('Xhelpgrep a1b2c3', 'E480:')
endfunc
func Test_helpgrep()
@@ -604,7 +624,7 @@ func Test_locationlist()
wincmd n | only
augroup! testgroup
endfunc
endfunc
func Test_locationlist_curwin_was_closed()
augroup testgroup
@@ -623,7 +643,7 @@ func Test_locationlist_curwin_was_closed()
call assert_fails('lrewind', 'E924:')
augroup! testgroup
endfunc
endfunc
func Test_locationlist_cross_tab_jump()
call writefile(['loclistfoo'], 'loclistfoo')
@@ -760,7 +780,7 @@ func Test_efm1()
call delete('Xerrorfile1')
call delete('Xerrorfile2')
call delete('Xtestfile')
endfunc
endfunc
" Test for quickfix directory stack support
func s:dir_stack_tests(cchar)
@@ -919,20 +939,26 @@ func Test_efm2()
call assert_equal(l[0].pattern, '^\VLine search text\$')
call assert_equal(l[0].lnum, 0)
let l = split(execute('clist', ''), "\n")
call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
" Test for %P, %Q and %t format specifiers
let lines=["[Xtestfile1]",
\ "(1,17) error: ';' missing",
\ "(21,2) warning: variable 'z' not defined",
\ "(67,3) error: end of file found before string ended",
\ "--",
\ "",
\ "[Xtestfile2]",
\ "--",
\ "",
\ "[Xtestfile3]",
\ "NEW compiler v1.1",
\ "(2,2) warning: variable 'x' not defined",
\ "(67,3) warning: 's' already defined"
\ "(67,3) warning: 's' already defined",
\ "--"
\]
set efm=%+P[%f],(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%-Q
set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
" To exercise the push/pop file functionality in quickfix, the test files
" need to be created.
call writefile(['Line1'], 'Xtestfile1')
@@ -943,7 +969,7 @@ func Test_efm2()
caddexpr l
endfor
let l = getqflist()
call assert_equal(9, len(l))
call assert_equal(12, len(l))
call assert_equal(21, l[2].lnum)
call assert_equal(2, l[2].col)
call assert_equal('w', l[2].type)
@@ -1098,6 +1124,13 @@ func SetXlistTests(cchar, bnum)
call g:Xsetlist([])
let l = g:Xgetlist()
call assert_equal(0, len(l))
" Error cases:
" Refer to a non-existing buffer and pass a non-dictionary type
call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
\ " {'bufnr':999, 'lnum':5}])", 'E92:')
call g:Xsetlist([[1, 2,3]])
call assert_equal(0, len(g:Xgetlist()))
endfunc
func Test_setqflist()
@@ -1116,7 +1149,8 @@ func Xlist_empty_middle(cchar)
call s:setup_commands(a:cchar)
" create three quickfix lists
Xvimgrep Test_ test_quickfix.vim
let @/ = 'Test_'
Xvimgrep // test_quickfix.vim
let testlen = len(g:Xgetlist())
call assert_true(testlen > 0)
Xvimgrep empty test_quickfix.vim
@@ -1609,6 +1643,22 @@ func Xproperty_tests(cchar)
call g:Xsetlist([], ' ', {'title' : 'N3'})
call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
" Changing the title of an earlier quickfix list
call g:Xsetlist([], ' ', {'title' : 'NewTitle', 'nr' : 2})
call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
" Changing the title of an invalid quickfix list
call assert_equal(-1, g:Xsetlist([], ' ',
\ {'title' : 'SomeTitle', 'nr' : 99}))
call assert_equal(-1, g:Xsetlist([], ' ',
\ {'title' : 'SomeTitle', 'nr' : 'abc'}))
if a:cchar == 'c'
copen
call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
cclose
endif
" Invalid arguments
call assert_fails('call g:Xgetlist([])', 'E715')
call assert_fails('call g:Xsetlist([], "a", [])', 'E715')
@@ -1616,16 +1666,18 @@ func Xproperty_tests(cchar)
call assert_equal(-1, s)
call assert_equal({}, g:Xgetlist({'abc':1}))
call assert_equal({}, g:Xgetlist({'nr':99, 'title':1}))
call assert_equal({}, g:Xgetlist({'nr':[], 'title':1}))
if a:cchar == 'l'
call assert_equal({}, getloclist(99, {'title': 1}))
endif
endfunc
endfunc
func Test_qf_property()
call Xproperty_tests('c')
call Xproperty_tests('l')
endfunc
endfunc
" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
func QfAutoCmdHandler(loc, cmd)
@@ -1774,3 +1826,55 @@ func Test_cwindow_jump()
enew | only
set efm&vim
endfunc
func XvimgrepTests(cchar)
call s:setup_commands(a:cchar)
call writefile(['Editor:VIM vim',
\ 'Editor:Emacs EmAcS',
\ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
call writefile(['Linux', 'MacOS', 'MS-Windows'], 'Xtestfile2')
" Error cases
call assert_fails('Xvimgrep /abc *', 'E682:')
let @/=''
call assert_fails('Xvimgrep // *', 'E35:')
call assert_fails('Xvimgrep abc', 'E683:')
call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
Xexpr ""
Xvimgrepadd Notepad Xtestfile1
Xvimgrepadd MacOS Xtestfile2
let l = g:Xgetlist()
call assert_equal(2, len(l))
call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
Xvimgrep #\cvim#g Xtestfile?
let l = g:Xgetlist()
call assert_equal(2, len(l))
call assert_equal(8, l[0].col)
call assert_equal(12, l[1].col)
1Xvimgrep ?Editor? Xtestfile*
let l = g:Xgetlist()
call assert_equal(1, len(l))
call assert_equal('Editor:VIM vim', l[0].text)
edit +3 Xtestfile2
Xvimgrep +\cemacs+j Xtestfile1
let l = g:Xgetlist()
call assert_equal('Xtestfile2', bufname(''))
call assert_equal('Editor:Emacs EmAcS', l[0].text)
call delete('Xtestfile1')
call delete('Xtestfile2')
endfunc
" Tests for the :vimgrep command
func Test_vimgrep()
call XvimgrepTests('c')
call XvimgrepTests('l')
endfunc

View File

@@ -0,0 +1,139 @@
" *-register (quotestar) tests
if !has('clipboard')
finish
endif
source shared.vim
let s:where = 0
func Abort(id)
call assert_report('Test timed out at ' . s:where)
call FinishTesting()
endfunc
func Do_test_quotestar_for_macunix()
if empty(exepath('pbcopy')) || empty(exepath('pbpaste'))
return 'Test requires pbcopy(1) and pbpaste(1)'
endif
let @* = ''
" Test #1: Pasteboard to Vim
let test_msg = "text from pasteboard to vim via quotestar"
" Write a piece of text to the pasteboard.
call system('/bin/echo -n "' . test_msg . '" | pbcopy')
" See if the *-register is changed as expected.
call assert_equal(test_msg, @*)
" Test #2: Vim to Pasteboard
let test_msg = "text from vim to pasteboard via quotestar"
" Write a piece of text to the *-register.
let @* = test_msg
" See if the pasteboard is changed as expected.
call assert_equal(test_msg, system('pbpaste'))
return ''
endfunc
func Do_test_quotestar_for_x11()
if !has('clientserver') || !has('job')
return 'Test requires the client-server and job features'
endif
let cmd = GetVimCommand()
if cmd == ''
return 'GetVimCommand() failed'
endif
" Some of these commands may hang when failing.
call timer_start(10000, 'Abort')
let s:where = 1
let name = 'XVIMCLIPBOARD'
let cmd .= ' --servername ' . name
let g:job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'})
call WaitFor('job_status(g:job) == "run"')
if job_status(g:job) != 'run'
call assert_report('Cannot run the Vim server')
return ''
endif
let s:where = 2
" Takes a short while for the server to be active.
call WaitFor('serverlist() =~ "' . name . '"')
call assert_match(name, serverlist())
let s:where = 3
" Clear the *-register of this vim instance.
let @* = ''
" Try to change the *-register of the server.
call remote_foreground(name)
let s:where = 4
call remote_send(name, ":let @* = 'yes'\<CR>")
let s:where = 5
call WaitFor('remote_expr("' . name . '", "@*") == "yes"')
let s:where = 6
call assert_equal('yes', remote_expr(name, "@*"))
let s:where = 7
" Check that the *-register of this vim instance is changed as expected.
call assert_equal('yes', @*)
if has('unix') && has('gui') && !has('gui_running')
let @* = ''
" Running in a terminal and the GUI is avaiable: Tell the server to open
" the GUI and check that the remote command still works.
" Need to wait for the GUI to start up, otherwise the send hangs in trying
" to send to the terminal window.
if has('gui_athena') || has('gui_motif')
" For those GUIs, ignore the 'failed to create input context' error.
call remote_send(name, ":call test_ignore_error('E285') | gui -f\<CR>")
else
call remote_send(name, ":gui -f\<CR>")
endif
let s:where = 8
sleep 500m
call remote_send(name, ":let @* = 'maybe'\<CR>")
let s:where = 9
call WaitFor('remote_expr("' . name . '", "@*") == "maybe"')
let s:where = 10
call assert_equal('maybe', remote_expr(name, "@*"))
let s:where = 11
call assert_equal('maybe', @*)
endif
call remote_send(name, ":qa!\<CR>")
let s:where = 12
call WaitFor('job_status(g:job) == "dead"')
let s:where = 13
if job_status(g:job) != 'dead'
call assert_report('Server did not exit')
call job_stop(g:job, 'kill')
endif
return ''
endfunc
func Test_quotestar()
let skipped = ''
let quotestar_saved = @*
if has('macunix')
let skipped = Do_test_quotestar_for_macunix()
elseif !empty("$DISPLAY")
let skipped = Do_test_quotestar_for_x11()
else
let skipped = "Test is not implemented yet for this platform."
endif
let @* = quotestar_saved
if !empty(skipped)
throw 'Skipped: ' . skipped
endif
endfunc

View File

@@ -450,13 +450,13 @@ func Test_viminfo_file_mark_tabclose()
let lnum = line('.')
while 1
if lnum == line('$')
call assert_false(1, 'mark not found in Xtestfileintab')
call assert_report('mark not found in Xtestfileintab')
break
endif
let lnum += 1
let line = getline(lnum)
if line == ''
call assert_false(1, 'mark not found in Xtestfileintab')
call assert_report('mark not found in Xtestfileintab')
break
endif
if line =~ "^\t\""

View File

@@ -1256,14 +1256,14 @@ func Test_script_lines()
\ '.',
\ ])
catch
call assert_false(1, "Can't define function")
call assert_report("Can't define function")
endtry
try
call DefineFunction('T_Append', [
\ 'append',
\ 'abc',
\ ])
call assert_false(1, "Shouldn't be able to define function")
call assert_report("Shouldn't be able to define function")
catch
call assert_exception('Vim(function):E126: Missing :endfunction')
endtry
@@ -1276,14 +1276,14 @@ func Test_script_lines()
\ '.',
\ ])
catch
call assert_false(1, "Can't define function")
call assert_report("Can't define function")
endtry
try
call DefineFunction('T_Change', [
\ 'change',
\ 'abc',
\ ])
call assert_false(1, "Shouldn't be able to define function")
call assert_report("Shouldn't be able to define function")
catch
call assert_exception('Vim(function):E126: Missing :endfunction')
endtry
@@ -1296,14 +1296,14 @@ func Test_script_lines()
\ '.',
\ ])
catch
call assert_false(1, "Can't define function")
call assert_report("Can't define function")
endtry
try
call DefineFunction('T_Insert', [
\ 'insert',
\ 'abc',
\ ])
call assert_false(1, "Shouldn't be able to define function")
call assert_report("Shouldn't be able to define function")
catch
call assert_exception('Vim(function):E126: Missing :endfunction')
endtry

View File

@@ -67,4 +67,309 @@ function Test_window_cmd_wincmd_gf()
augroup! test_window_cmd_wincmd_gf
endfunc
func Test_window_quit()
e Xa
split Xb
call assert_equal(2, winnr('$'))
call assert_equal('Xb', bufname(winbufnr(1)))
call assert_equal('Xa', bufname(winbufnr(2)))
wincmd q
call assert_equal(1, winnr('$'))
call assert_equal('Xa', bufname(winbufnr(1)))
bw Xa Xb
endfunc
func Test_window_horizontal_split()
call assert_equal(1, winnr('$'))
3wincmd s
call assert_equal(2, winnr('$'))
call assert_equal(3, winheight(0))
call assert_equal(winwidth(1), winwidth(2))
call assert_fails('botright topleft wincmd s', 'E442:')
bw
endfunc
func Test_window_vertical_split()
call assert_equal(1, winnr('$'))
3wincmd v
call assert_equal(2, winnr('$'))
call assert_equal(3, winwidth(0))
call assert_equal(winheight(1), winheight(2))
call assert_fails('botright topleft wincmd v', 'E442:')
bw
endfunc
func Test_window_split_edit_alternate()
e Xa
e Xb
wincmd ^
call assert_equal('Xa', bufname(winbufnr(1)))
call assert_equal('Xb', bufname(winbufnr(2)))
bw Xa Xb
endfunc
func Test_window_preview()
" Open a preview window
pedit Xa
call assert_equal(2, winnr('$'))
call assert_equal(0, &previewwindow)
" Go to the preview window
wincmd P
call assert_equal(1, &previewwindow)
" Close preview window
wincmd z
call assert_equal(1, winnr('$'))
call assert_equal(0, &previewwindow)
call assert_fails('wincmd P', 'E441:')
endfunc
func Test_window_exchange()
e Xa
" Nothing happens with window exchange when there is 1 window
wincmd x
call assert_equal(1, winnr('$'))
split Xb
split Xc
call assert_equal('Xc', bufname(winbufnr(1)))
call assert_equal('Xb', bufname(winbufnr(2)))
call assert_equal('Xa', bufname(winbufnr(3)))
" Exchange current window 1 with window 3
3wincmd x
call assert_equal('Xa', bufname(winbufnr(1)))
call assert_equal('Xb', bufname(winbufnr(2)))
call assert_equal('Xc', bufname(winbufnr(3)))
" Exchange window with next when at the top window
wincmd x
call assert_equal('Xb', bufname(winbufnr(1)))
call assert_equal('Xa', bufname(winbufnr(2)))
call assert_equal('Xc', bufname(winbufnr(3)))
" Exchange window with next when at the middle window
wincmd j
wincmd x
call assert_equal('Xb', bufname(winbufnr(1)))
call assert_equal('Xc', bufname(winbufnr(2)))
call assert_equal('Xa', bufname(winbufnr(3)))
" Exchange window with next when at the bottom window.
" When there is no next window, it exchanges with the previous window.
wincmd j
wincmd x
call assert_equal('Xb', bufname(winbufnr(1)))
call assert_equal('Xa', bufname(winbufnr(2)))
call assert_equal('Xc', bufname(winbufnr(3)))
bw Xa Xb Xc
endfunc
func Test_window_rotate()
e Xa
split Xb
split Xc
call assert_equal('Xc', bufname(winbufnr(1)))
call assert_equal('Xb', bufname(winbufnr(2)))
call assert_equal('Xa', bufname(winbufnr(3)))
" Rotate downwards
wincmd r
call assert_equal('Xa', bufname(winbufnr(1)))
call assert_equal('Xc', bufname(winbufnr(2)))
call assert_equal('Xb', bufname(winbufnr(3)))
2wincmd r
call assert_equal('Xc', bufname(winbufnr(1)))
call assert_equal('Xb', bufname(winbufnr(2)))
call assert_equal('Xa', bufname(winbufnr(3)))
" Rotate upwards
wincmd R
call assert_equal('Xb', bufname(winbufnr(1)))
call assert_equal('Xa', bufname(winbufnr(2)))
call assert_equal('Xc', bufname(winbufnr(3)))
2wincmd R
call assert_equal('Xc', bufname(winbufnr(1)))
call assert_equal('Xb', bufname(winbufnr(2)))
call assert_equal('Xa', bufname(winbufnr(3)))
bot vsplit
call assert_fails('wincmd R', 'E443:')
bw Xa Xb Xc
endfunc
func Test_window_height()
e Xa
split Xb
let [wh1, wh2] = [winheight(1), winheight(2)]
" Active window (1) should have the same height or 1 more
" than the other window.
call assert_inrange(wh2, wh2 + 1, wh1)
wincmd -
call assert_equal(wh1 - 1, winheight(1))
call assert_equal(wh2 + 1, winheight(2))
wincmd +
call assert_equal(wh1, winheight(1))
call assert_equal(wh2, winheight(2))
2wincmd _
call assert_equal(2, winheight(1))
call assert_equal(wh1 + wh2 - 2, winheight(2))
wincmd =
call assert_equal(wh1, winheight(1))
call assert_equal(wh2, winheight(2))
2wincmd _
set winfixheight
split Xc
let [wh1, wh2, wh3] = [winheight(1), winheight(2), winheight(3)]
call assert_equal(2, winheight(2))
call assert_inrange(wh3, wh3 + 1, wh1)
3wincmd +
call assert_equal(2, winheight(2))
call assert_equal(wh1 + 3, winheight(1))
call assert_equal(wh3 - 3, winheight(3))
wincmd =
call assert_equal(2, winheight(2))
call assert_equal(wh1, winheight(1))
call assert_equal(wh3, winheight(3))
wincmd j
set winfixheight&
wincmd =
let [wh1, wh2, wh3] = [winheight(1), winheight(2), winheight(3)]
" Current window (2) should have the same height or 1 more
" than the other windows.
call assert_inrange(wh1, wh1 + 1, wh2)
call assert_inrange(wh3, wh3 + 1, wh2)
bw Xa Xb Xc
endfunc
func Test_window_width()
e Xa
vsplit Xb
let [ww1, ww2] = [winwidth(1), winwidth(2)]
" Active window (1) should have the same width or 1 more
" than the other window.
call assert_inrange(ww2, ww2 + 1, ww1)
wincmd <
call assert_equal(ww1 - 1, winwidth(1))
call assert_equal(ww2 + 1, winwidth(2))
wincmd >
call assert_equal(ww1, winwidth(1))
call assert_equal(ww2, winwidth(2))
2wincmd |
call assert_equal(2, winwidth(1))
call assert_equal(ww1 + ww2 - 2, winwidth(2))
wincmd =
call assert_equal(ww1, winwidth(1))
call assert_equal(ww2, winwidth(2))
2wincmd |
set winfixwidth
vsplit Xc
let [ww1, ww2, ww3] = [winwidth(1), winwidth(2), winwidth(3)]
call assert_equal(2, winwidth(2))
call assert_inrange(ww3, ww3 + 1, ww1)
3wincmd >
call assert_equal(2, winwidth(2))
call assert_equal(ww1 + 3, winwidth(1))
call assert_equal(ww3 - 3, winwidth(3))
wincmd =
call assert_equal(2, winwidth(2))
call assert_equal(ww1, winwidth(1))
call assert_equal(ww3, winwidth(3))
wincmd l
set winfixwidth&
wincmd =
let [ww1, ww2, ww3] = [winwidth(1), winwidth(2), winwidth(3)]
" Current window (2) should have the same width or 1 more
" than the other windows.
call assert_inrange(ww1, ww1 + 1, ww2)
call assert_inrange(ww3, ww3 + 1, ww2)
bw Xa Xb Xc
endfunc
func Test_window_jump_tag()
help
/iccf
call assert_match('^|iccf|', getline('.'))
call assert_equal(2, winnr('$'))
2wincmd }
call assert_equal(3, winnr('$'))
call assert_match('^|iccf|', getline('.'))
wincmd k
call assert_match('\*iccf\*', getline('.'))
call assert_equal(2, winheight(0))
wincmd z
set previewheight=4
help
/bugs
wincmd }
wincmd k
call assert_match('\*bugs\*', getline('.'))
call assert_equal(4, winheight(0))
set previewheight&
%bw!
endfunc
func Test_window_newtab()
e Xa
call assert_equal(1, tabpagenr('$'))
call assert_equal("\nAlready only one window", execute('wincmd T'))
split Xb
split Xc
wincmd T
call assert_equal(2, tabpagenr('$'))
call assert_equal(['Xb', 'Xa'], map(tabpagebuflist(1), 'bufname(v:val)'))
call assert_equal(['Xc' ], map(tabpagebuflist(2), 'bufname(v:val)'))
%bw!
endfunc
func Test_next_split_all()
" This was causing an illegal memory access.
n x
norm axxx
split
split
s/x
s/x
all
bwipe!
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -764,6 +764,38 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
493,
/**/
492,
/**/
491,
/**/
490,
/**/
489,
/**/
488,
/**/
487,
/**/
486,
/**/
485,
/**/
484,
/**/
483,
/**/
482,
/**/
481,
/**/
480,
/**/
479,
/**/
478,
/**/
477,
/**/

View File

@@ -2506,7 +2506,9 @@ typedef enum {
# define ELAPSED_INIT(v) v = GetTickCount()
# define ELAPSED_FUNC(v) elapsed(v)
# define ELAPSED_TYPE DWORD
long elapsed(DWORD start_tick);
# ifndef PROTO
long elapsed(DWORD start_tick);
# endif
# endif
#endif

View File

@@ -870,9 +870,9 @@ win_split_ins(
/* We don't like to take lines for the new window from a
* 'winfixwidth' window. Take them from a window to the left or right
* instead, if possible. */
* instead, if possible. Add one for the separator. */
if (oldwin->w_p_wfw)
win_setwidth_win(oldwin->w_width + new_size, oldwin);
win_setwidth_win(oldwin->w_width + new_size + 1, oldwin);
/* Only make all windows the same width if one of them (except oldwin)
* is wider than one of the split windows. */
@@ -2107,7 +2107,7 @@ win_equal_rec(
}
/*
* close all windows for buffer 'buf'
* Close all windows for buffer "buf".
*/
void
close_windows(
@@ -2131,7 +2131,10 @@ close_windows(
#endif
)
{
win_close(wp, FALSE);
if (win_close(wp, FALSE) == FAIL)
/* If closing the window fails give up, to avoid looping
* forever. */
break;
/* Start all over, autocommands may change the window layout. */
wp = firstwin;
@@ -2450,6 +2453,10 @@ win_close(win_T *win, int free_buf)
#endif
curbuf = curwin->w_buffer;
close_curwin = TRUE;
/* The cursor position may be invalid if the buffer changed after last
* using the window. */
check_cursor();
}
if (p_ea && (*p_ead == 'b' || *p_ead == dir))
win_equal(curwin, TRUE, dir);
@@ -3754,6 +3761,58 @@ valid_tabpage(tabpage_T *tpc)
return FALSE;
}
/*
* Return TRUE when "tpc" points to a valid tab page and at least one window is
* valid.
*/
int
valid_tabpage_win(tabpage_T *tpc)
{
tabpage_T *tp;
win_T *wp;
FOR_ALL_TABPAGES(tp)
{
if (tp == tpc)
{
FOR_ALL_WINDOWS_IN_TAB(tp, wp)
{
if (win_valid_any_tab(wp))
return TRUE;
}
return FALSE;
}
}
/* shouldn't happen */
return FALSE;
}
/*
* Close tabpage "tab", assuming it has no windows in it.
* There must be another tabpage or this will crash.
*/
void
close_tabpage(tabpage_T *tab)
{
tabpage_T *ptp;
if (tab == first_tabpage)
{
first_tabpage = tab->tp_next;
ptp = first_tabpage;
}
else
{
for (ptp = first_tabpage; ptp != NULL && ptp->tp_next != tab;
ptp = ptp->tp_next)
;
ptp->tp_next = tab->tp_next;
}
goto_tabpage_tp(ptp, FALSE, FALSE);
free_tabpage(tab);
}
/*
* Find tab page "n" (first one is 1). Returns NULL when not found.
*/
@@ -6563,7 +6622,7 @@ check_snapshot_rec(frame_T *sn, frame_T *fr)
&& check_snapshot_rec(sn->fr_next, fr->fr_next) == FAIL)
|| (sn->fr_child != NULL
&& check_snapshot_rec(sn->fr_child, fr->fr_child) == FAIL)
|| !win_valid(sn->fr_win))
|| (sn->fr_win != NULL && !win_valid(sn->fr_win)))
return FAIL;
return OK;
}