Compare commits

...

21 Commits

Author SHA1 Message Date
Bram Moolenaar
3ff2f09525 patch 8.0.0497: arabic support is not fully tested
Problem:    Arabic support is not fully tested.
Solution:   Add more tests for the untested functions.  Comment out
            unreachable code.
2017-03-21 13:22:44 +01:00
Bram Moolenaar
518c9b133b patch 8.0.0496: insufficient testing for folding
Problem:    Insufficient testing for folding.
Solution:   Add a couple more fold tests. (Dominique Pelle, closes #1579)
2017-03-21 11:48:39 +01:00
Bram Moolenaar
f5610da7a8 patch 8.0.0495: quotestar test uses timer instead of timeout
Problem:    The quotestar test uses a timer instead of a timeout, thus it
            cannot be rerun like a flaky test.
Solution:   Remove the timer and add a timeout. (Kazunobu Kuriyama)
2017-03-20 21:47:16 +01:00
Bram Moolenaar
1662ce104e patch 8.0.0494: build failure with older compiler on MS-Windows
Problem:    Build failure with older compiler on MS-Windows.
Solution:   Move declaration to start of block.
2017-03-19 21:47:50 +01:00
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
Bram Moolenaar
42205551b1 patch 8.0.0477: the client-server test may hang when failing
Problem:    The client-server test may hang when failing.
Solution:   Set a timer.  Add assert_report()
2017-03-18 19:42:22 +01:00
45 changed files with 1383 additions and 250 deletions

View File

@@ -1,4 +1,4 @@
*eval.txt* For Vim version 8.0. Last change: 2017 Mar 09
*eval.txt* For Vim version 8.0. Last change: 2017 Mar 18
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -1986,16 +1986,23 @@ argidx() Number current index in the argument list
arglistid([{winnr} [, {tabnr}]]) Number argument list id
argv({nr}) String {nr} entry of the argument list
argv() List the argument list
assert_equal({exp}, {act} [, {msg}]) none assert {exp} is equal to {act}
assert_exception({error} [, {msg}]) none assert {error} is in v:exception
assert_fails({cmd} [, {error}]) none assert {cmd} fails
assert_false({actual} [, {msg}]) none assert {actual} is false
assert_equal({exp}, {act} [, {msg}])
none assert {exp} is equal to {act}
assert_exception({error} [, {msg}])
none assert {error} is in v:exception
assert_fails({cmd} [, {error}]) none assert {cmd} fails
assert_false({actual} [, {msg}])
none assert {actual} is false
assert_inrange({lower}, {upper}, {actual} [, {msg}])
none assert {actual} is inside the range
assert_match({pat}, {text} [, {msg}]) none assert {pat} matches {text}
assert_notequal({exp}, {act} [, {msg}]) none assert {exp} is not equal {act}
assert_notmatch({pat}, {text} [, {msg}]) none assert {pat} not matches {text}
assert_true({actual} [, {msg}]) none assert {actual} is true
assert_match({pat}, {text} [, {msg}])
none assert {pat} matches {text}
assert_notequal({exp}, {act} [, {msg}])
none assert {exp} is not equal {act}
assert_notmatch({pat}, {text} [, {msg}])
none assert {pat} not matches {text}
assert_report({msg}) none report a test failure
assert_true({actual} [, {msg}]) none assert {actual} is true
asin({expr}) Float arc sine of {expr}
atan({expr}) Float arc tangent of {expr}
atan2({expr1}, {expr2}) Float arc tangent of {expr1} / {expr2}
@@ -2583,7 +2590,10 @@ assert_notmatch({pattern}, {actual} [, {msg}])
The opposite of `assert_match()`: add an error message to
|v:errors| when {pattern} matches {actual}.
assert_true({actual} [, {msg}]) *assert_true()*
assert_report({msg}) *assert_report()*
Report a test failure directly, using {msg}.
assert_true({actual} [, {msg}]) *assert_true()*
When {actual} is not true an error message is added to
|v:errors|, like with |assert_equal()|.
A value is TRUE when it is a non-zero number. When {actual}
@@ -3925,11 +3935,14 @@ foldtext() Returns a String, to be displayed for a closed fold. This is
|v:foldstart|, |v:foldend| and |v:folddashes| variables.
The returned string looks like this: >
+-- 45 lines: abcdef
< The number of dashes depends on the foldlevel. The "45" is
the number of lines in the fold. "abcdef" is the text in the
first non-blank line of the fold. Leading white space, "//"
or "/*" and the text from the 'foldmarker' and 'commentstring'
options is removed.
< The number of leading dashes depends on the foldlevel. The
"45" is the number of lines in the fold. "abcdef" is the text
in the first non-blank line of the fold. Leading white space,
"//" or "/*" and the text from the 'foldmarker' and
'commentstring' options is removed.
When used to draw the actual foldtext, the rest of the line
will be filled with the fold char from the 'fillchars'
setting.
{not available when compiled without the |+folding| feature}
foldtextresult({lnum}) *foldtextresult()*
@@ -6307,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}
@@ -6354,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

@@ -24,7 +24,9 @@ static int chg_c_a2s(int cur_c);
static int chg_c_a2i(int cur_c);
static int chg_c_a2m(int cur_c);
static int chg_c_a2f(int cur_c);
#if 0
static int chg_c_i2m(int cur_c);
#endif
static int chg_c_f2m(int cur_c);
static int chg_c_laa2i(int hid_c);
static int chg_c_laa2f(int hid_c);
@@ -418,7 +420,10 @@ chg_c_a2f(int cur_c)
/*
* Change shape - from Initial to Medial
* This code is unreachable, because for the relevant characters ARABIC_CHAR()
* is FALSE;
*/
#if 0
static int
chg_c_i2m(int cur_c)
{
@@ -450,6 +455,7 @@ chg_c_i2m(int cur_c)
}
return 0;
}
#endif
/*
@@ -608,7 +614,11 @@ arabic_shape(
else if (!shape_c || A_is_f(shape_c) || A_is_s(shape_c) || prev_laa)
curr_c = A_is_valid(next_c) ? chg_c_a2i(c) : chg_c_a2s(c);
else if (A_is_valid(next_c))
#if 0
curr_c = A_is_iso(c) ? chg_c_a2m(c) : chg_c_i2m(c);
#else
curr_c = A_is_iso(c) ? chg_c_a2m(c) : 0;
#endif
else if (A_is_valid(prev_c))
curr_c = chg_c_a2f(c);
else

View File

@@ -9083,6 +9083,17 @@ assert_bool(typval_T *argvars, int isTrue)
}
}
void
assert_report(typval_T *argvars)
{
garray_T ga;
prepare_assert_error(&ga);
ga_concat(&ga, get_tv_string(&argvars[0]));
assert_error(&ga);
ga_clear(&ga);
}
void
assert_exception(typval_T *argvars)
{

View File

@@ -52,6 +52,7 @@ static void f_assert_inrange(typval_T *argvars, typval_T *rettv);
static void f_assert_match(typval_T *argvars, typval_T *rettv);
static void f_assert_notequal(typval_T *argvars, typval_T *rettv);
static void f_assert_notmatch(typval_T *argvars, typval_T *rettv);
static void f_assert_report(typval_T *argvars, typval_T *rettv);
static void f_assert_true(typval_T *argvars, typval_T *rettv);
#ifdef FEAT_FLOAT
static void f_asin(typval_T *argvars, typval_T *rettv);
@@ -483,6 +484,7 @@ static struct fst
{"assert_match", 2, 3, f_assert_match},
{"assert_notequal", 2, 3, f_assert_notequal},
{"assert_notmatch", 2, 3, f_assert_notmatch},
{"assert_report", 1, 1, f_assert_report},
{"assert_true", 1, 2, f_assert_true},
#ifdef FEAT_FLOAT
{"atan", 1, 1, f_atan},
@@ -737,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},
@@ -1313,6 +1315,15 @@ f_assert_notmatch(typval_T *argvars, typval_T *rettv UNUSED)
assert_match_common(argvars, ASSERT_NOTMATCH);
}
/*
* "assert_report(msg)" function
*/
static void
f_assert_report(typval_T *argvars, typval_T *rettv UNUSED)
{
assert_report(argvars);
}
/*
* "assert_true(actual[, msg])" function
*/
@@ -8504,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
@@ -8517,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)
@@ -8544,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
@@ -8622,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
@@ -8659,17 +8676,24 @@ f_remote_read(typval_T *argvars UNUSED, typval_T *rettv)
if (serverid != NULL && !check_restricted() && !check_secure())
{
int timeout = 0;
# ifdef WIN32
/* The server's HWND is encoded in the 'id' parameter */
long_u n = 0;
# endif
if (argvars[1].v_type != VAR_UNKNOWN)
timeout = get_tv_number(&argvars[1]);
# ifdef WIN32
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
@@ -596,6 +598,10 @@ ServerWait(
if (seconds >= 0 && (now - start) >= seconds)
break;
#ifdef FEAT_TIMERS
check_due_timer();
#endif
/* Just look out for the answer without calling back into Vim */
if (localLoop)
{
@@ -786,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.
*/
@@ -794,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)
@@ -4194,7 +4194,7 @@ sendToLocalVim(char_u *cmd, int asExpr, char_u **result)
size_t len = STRLEN(cmd) + STRLEN(err) + 5;
char_u *msg;
msg = alloc(len);
msg = alloc((unsigned)len);
if (msg != NULL)
vim_snprintf((char *)msg, len, "%s: \"%s\"", err, cmd);
*result = msg;

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

@@ -2111,7 +2111,7 @@ Messaging_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
char *err = _(e_invexprmsg);
size_t len = STRLEN(str) + STRLEN(err) + 5;
res = alloc(len);
res = alloc((unsigned)len);
if (res != NULL)
vim_snprintf((char *)res, len, "%s: \"%s\"", err, str);
reply.dwData = COPYDATA_ERROR_RESULT;
@@ -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. */
@@ -2570,6 +2585,13 @@ serverGetReply(HWND server, int *expr_res, int remove, int wait)
/* Loop until we receive a reply */
while (reply_received == 0)
{
#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

@@ -123,6 +123,7 @@ void assert_equal_common(typval_T *argvars, assert_type_T atype);
void assert_match_common(typval_T *argvars, assert_type_T atype);
void assert_inrange(typval_T *argvars);
void assert_bool(typval_T *argvars, int isTrue);
void assert_report(typval_T *argvars);
void assert_exception(typval_T *argvars);
void assert_fails(typval_T *argvars);
void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, char_u *exp_str, typval_T *exp_tv, typval_T *got_tv, assert_type_T atype);

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

@@ -86,7 +86,7 @@ function GetAllocId(name)
return lnum - top - 1
endfunc
function RunTheTest(test)
func RunTheTest(test)
echo 'Executing ' . a:test
" Avoid stopping at the "hit enter" prompt
@@ -142,6 +142,60 @@ function RunTheTest(test)
set nomodified
endfunc
func AfterTheTest()
if len(v:errors) > 0
let s:fail += 1
call add(s:errors, 'Found errors in ' . s:test . ':')
call extend(s:errors, v:errors)
let v:errors = []
endif
endfunc
" This function can be called by a test if it wants to abort testing.
func FinishTesting()
call AfterTheTest()
" Don't write viminfo on exit.
set viminfo=
if s:fail == 0
" Success, create the .res file so that make knows it's done.
exe 'split ' . fnamemodify(g:testname, ':r') . '.res'
write
endif
if len(s:errors) > 0
" Append errors to test.log
split test.log
call append(line('$'), '')
call append(line('$'), 'From ' . g:testname . ':')
call append(line('$'), s:errors)
write
endif
let message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test')
echo message
call add(s:messages, message)
if s:fail > 0
let message = s:fail . ' FAILED:'
echo message
call add(s:messages, message)
call extend(s:messages, s:errors)
endif
" Add SKIPPED messages
call extend(s:messages, s:skipped)
" Append messages to the file "messages"
split messages
call append(line('$'), '')
call append(line('$'), 'From ' . g:testname . ':')
call append(line('$'), s:messages)
write
qall!
endfunc
" Source the test script. First grab the file name, in case the script
" navigates away. g:testname can be used by the tests.
let g:testname = expand('%')
@@ -164,6 +218,7 @@ endif
" Names of flaky tests.
let s:flaky = [
\ 'Test_client_server()',
\ 'Test_close_and_exit_cb()',
\ 'Test_collapse_buffers()',
\ 'Test_communicate()',
@@ -173,6 +228,7 @@ let s:flaky = [
\ 'Test_pipe_through_sort_all()',
\ 'Test_pipe_through_sort_some()',
\ 'Test_quoteplus()',
\ 'Test_quotestar()',
\ 'Test_reltime()',
\ ]
@@ -192,57 +248,25 @@ 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
if len(v:errors) > 0
let s:fail += 1
call add(s:errors, 'Found errors in ' . s:test . ':')
call extend(s:errors, v:errors)
let v:errors = []
endif
call AfterTheTest()
endfor
" Don't write viminfo on exit.
set viminfo=
if s:fail == 0
" Success, create the .res file so that make knows it's done.
exe 'split ' . fnamemodify(g:testname, ':r') . '.res'
write
endif
if len(s:errors) > 0
" Append errors to test.log
split test.log
call append(line('$'), '')
call append(line('$'), 'From ' . g:testname . ':')
call append(line('$'), s:errors)
write
endif
let message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test')
echo message
call add(s:messages, message)
if s:fail > 0
let message = s:fail . ' FAILED:'
echo message
call add(s:messages, message)
call extend(s:messages, s:errors)
endif
" Add SKIPPED messages
call extend(s:messages, s:skipped)
" Append messages to the file "messages"
split messages
call append(line('$'), '')
call append(line('$'), 'From ' . g:testname . ':')
call append(line('$'), s:messages)
write
qall!
call FinishTesting()
" vim: shiftwidth=2 sts=2 expandtab

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

@@ -1,4 +1,6 @@
" Simplistic testing of Arabic mode.
" NOTE: This just checks if the code works. If you know Arabic please add
" functional tests that check the shaping works with real text.
if !has('arabic') || !has('multi_byte')
finish
@@ -417,7 +419,7 @@ func Test_shape_isolated()
bwipe!
endfunc
func Test_shape_medial()
func Test_shape_iso_to_medial()
new
set arabicshape
@@ -470,3 +472,142 @@ func Test_shape_medial()
bwipe!
endfunc
func Test_shape_final()
new
set arabicshape
" Shaping arabic {testchar} arabic Tests chg_c_a2f().
" pair[0] = testchar, pair[1] = current-result, pair[2] = previous-result
for pair in [[s:a_HAMZA, s:a_s_HAMZA, s:a_s_BEH],
\[s:a_ALEF_MADDA, s:a_f_ALEF_MADDA, s:a_i_BEH],
\[s:a_ALEF_HAMZA_ABOVE, s:a_f_ALEF_HAMZA_ABOVE, s:a_i_BEH],
\[s:a_WAW_HAMZA, s:a_f_WAW_HAMZA, s:a_i_BEH],
\[s:a_ALEF_HAMZA_BELOW, s:a_f_ALEF_HAMZA_BELOW, s:a_i_BEH],
\[s:a_YEH_HAMZA, s:a_f_YEH_HAMZA, s:a_i_BEH],
\[s:a_ALEF, s:a_f_ALEF, s:a_i_BEH],
\[s:a_BEH, s:a_f_BEH, s:a_i_BEH],
\[s:a_TEH_MARBUTA, s:a_f_TEH_MARBUTA, s:a_i_BEH],
\[s:a_TEH, s:a_f_TEH, s:a_i_BEH],
\[s:a_THEH, s:a_f_THEH, s:a_i_BEH],
\[s:a_JEEM, s:a_f_JEEM, s:a_i_BEH],
\[s:a_HAH, s:a_f_HAH, s:a_i_BEH],
\[s:a_KHAH, s:a_f_KHAH, s:a_i_BEH],
\[s:a_DAL, s:a_f_DAL, s:a_i_BEH],
\[s:a_THAL, s:a_f_THAL, s:a_i_BEH],
\[s:a_REH, s:a_f_REH, s:a_i_BEH],
\[s:a_ZAIN, s:a_f_ZAIN, s:a_i_BEH],
\[s:a_SEEN, s:a_f_SEEN, s:a_i_BEH],
\[s:a_SHEEN, s:a_f_SHEEN, s:a_i_BEH],
\[s:a_SAD, s:a_f_SAD, s:a_i_BEH],
\[s:a_DAD, s:a_f_DAD, s:a_i_BEH],
\[s:a_TAH, s:a_f_TAH, s:a_i_BEH],
\[s:a_ZAH, s:a_f_ZAH, s:a_i_BEH],
\[s:a_AIN, s:a_f_AIN, s:a_i_BEH],
\[s:a_GHAIN, s:a_f_GHAIN, s:a_i_BEH],
\[s:a_TATWEEL, s:a_TATWEEL, s:a_i_BEH],
\[s:a_FEH, s:a_f_FEH, s:a_i_BEH],
\[s:a_QAF, s:a_f_QAF, s:a_i_BEH],
\[s:a_KAF, s:a_f_KAF, s:a_i_BEH],
\[s:a_LAM, s:a_f_LAM, s:a_i_BEH],
\[s:a_MEEM, s:a_f_MEEM, s:a_i_BEH],
\[s:a_NOON, s:a_f_NOON, s:a_i_BEH],
\[s:a_HEH, s:a_f_HEH, s:a_i_BEH],
\[s:a_WAW, s:a_f_WAW, s:a_i_BEH],
\[s:a_ALEF_MAKSURA, s:a_f_ALEF_MAKSURA, s:a_i_BEH],
\[s:a_YEH, s:a_f_YEH, s:a_i_BEH],
\ ]
call setline(1, ' ' . pair[0] . s:a_BEH)
call assert_equal([' ' . pair[1] . pair[2]], ScreenLines(1, 3))
endfor
set arabicshape&
bwipe!
endfunc
func Test_shape_final_to_medial()
new
set arabicshape
" Shaping arabic {testchar} arabic Tests chg_c_f2m().
" This does not test much...
" pair[0] = testchar, pair[1] = current-result
for pair in [[s:a_f_YEH_HAMZA, s:a_f_BEH],
\[s:a_f_WAW_HAMZA, s:a_s_BEH],
\[s:a_f_ALEF, s:a_s_BEH],
\[s:a_f_TEH_MARBUTA, s:a_s_BEH],
\[s:a_f_DAL, s:a_s_BEH],
\[s:a_f_THAL, s:a_s_BEH],
\[s:a_f_REH, s:a_s_BEH],
\[s:a_f_ZAIN, s:a_s_BEH],
\[s:a_f_WAW, s:a_s_BEH],
\[s:a_f_ALEF_MAKSURA, s:a_s_BEH],
\[s:a_f_BEH, s:a_f_BEH],
\[s:a_f_TEH, s:a_f_BEH],
\[s:a_f_THEH, s:a_f_BEH],
\[s:a_f_JEEM, s:a_f_BEH],
\[s:a_f_HAH, s:a_f_BEH],
\[s:a_f_KHAH, s:a_f_BEH],
\[s:a_f_SEEN, s:a_f_BEH],
\[s:a_f_SHEEN, s:a_f_BEH],
\[s:a_f_SAD, s:a_f_BEH],
\[s:a_f_DAD, s:a_f_BEH],
\[s:a_f_TAH, s:a_f_BEH],
\[s:a_f_ZAH, s:a_f_BEH],
\[s:a_f_AIN, s:a_f_BEH],
\[s:a_f_GHAIN, s:a_f_BEH],
\[s:a_f_FEH, s:a_f_BEH],
\[s:a_f_QAF, s:a_f_BEH],
\[s:a_f_KAF, s:a_f_BEH],
\[s:a_f_LAM, s:a_f_BEH],
\[s:a_f_MEEM, s:a_f_BEH],
\[s:a_f_NOON, s:a_f_BEH],
\[s:a_f_HEH, s:a_f_BEH],
\[s:a_f_YEH, s:a_f_BEH],
\ ]
call setline(1, ' ' . s:a_BEH . pair[0])
call assert_equal([' ' . pair[1] . pair[0]], ScreenLines(1, 3))
endfor
set arabicshape&
bwipe!
endfunc
func Test_shape_combination_final()
new
set arabicshape
" Shaping arabic {testchar} arabic Tests chg_c_laa2f().
" pair[0] = testchar, pair[1] = current-result
for pair in [[s:a_ALEF_MADDA, s:a_f_LAM_ALEF_MADDA_ABOVE],
\ [s:a_ALEF_HAMZA_ABOVE, s:a_f_LAM_ALEF_HAMZA_ABOVE],
\ [s:a_ALEF_HAMZA_BELOW, s:a_f_LAM_ALEF_HAMZA_BELOW],
\ [s:a_ALEF, s:a_f_LAM_ALEF],
\ ]
" The test char is a composing char, put on s:a_LAM.
call setline(1, ' ' . s:a_LAM . pair[0] . s:a_BEH)
call assert_equal([' ' . pair[1] . s:a_i_BEH], ScreenLines(1, 3))
endfor
set arabicshape&
bwipe!
endfunc
func Test_shape_combination_isolated()
new
set arabicshape
" Shaping arabic {testchar} arabic Tests chg_c_laa2i().
" pair[0] = testchar, pair[1] = current-result
for pair in [[s:a_ALEF_MADDA, s:a_s_LAM_ALEF_MADDA_ABOVE],
\ [s:a_ALEF_HAMZA_ABOVE, s:a_s_LAM_ALEF_HAMZA_ABOVE],
\ [s:a_ALEF_HAMZA_BELOW, s:a_s_LAM_ALEF_HAMZA_BELOW],
\ [s:a_ALEF, s:a_s_LAM_ALEF],
\ ]
" The test char is a composing char, put on s:a_LAM.
call setline(1, ' ' . s:a_LAM . pair[0] . ' ')
call assert_equal([' ' . pair[1] . ' '], ScreenLines(1, 3))
endfor
set arabicshape&
bwipe!
endfunc

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

@@ -11,12 +11,13 @@ func Test_client_server()
if cmd == ''
return
endif
let name = 'XVIMTEXT'
let name = 'XVIMTEST'
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_true(0, 'Cannot run the Vim server')
call assert_report('Cannot run the Vim server')
return
endif
@@ -27,19 +28,26 @@ func Test_client_server()
call remote_foreground(name)
call remote_send(name, ":let testvar = 'yes'\<CR>")
call WaitFor('remote_expr("' . name . '", "testvar") == "yes"')
call assert_equal('yes', remote_expr(name, "testvar"))
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>")
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>")
call WaitFor('remote_expr("' . name . '", "testvar") == "maybe"')
call assert_equal('maybe', remote_expr(name, "testvar"))
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')
@@ -47,18 +55,35 @@ func Test_client_server()
" Expression evaluated locally.
if v:servername == ''
call remote_startserver('MYSELF')
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'))
call remote_send(name, ":call server2client(expand('<client>'), 'got it')\<CR>", 'g:myserverid')
call assert_equal('got it', remote_read(g:myserverid))
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>")
call WaitFor('job_status(g:job) == "dead"')
if job_status(g:job) != 'dead'
call assert_true(0, 'Server did not exit')
call assert_report('Server did not exit')
call job_stop(g:job, 'kill')
endif
endfunc

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

@@ -9,8 +9,8 @@ func! Test_address_fold()
call setline(1, ['int FuncName() {/*{{{*/', 1, 2, 3, 4, 5, '}/*}}}*/',
\ 'after fold 1', 'after fold 2', 'after fold 3'])
setl fen fdm=marker
" The next ccommands should all copy the same part of the buffer,
" regardless of the adressing type, since the part to be copied
" The next commands should all copy the same part of the buffer,
" regardless of the addressing type, since the part to be copied
" is folded away
:1y
call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
@@ -360,3 +360,56 @@ func! Test_move_folds_around_indent()
call assert_equal([0, 1, 1, 1, 1, 0, 0, 0, 1, 1], map(range(1, line('$')), 'foldlevel(v:val)'))
bw!
endfunc
func Test_folddoopen_folddoclosed()
new
call setline(1, range(1, 9))
set foldmethod=manual
1,3 fold
6,8 fold
" Test without range.
folddoopen s/$/o/
folddoclosed s/$/c/
call assert_equal(['1c', '2c', '3c',
\ '4o', '5o',
\ '6c', '7c', '8c',
\ '9o'], getline(1, '$'))
" Test with range.
call setline(1, range(1, 9))
1,8 folddoopen s/$/o/
4,$ folddoclosed s/$/c/
call assert_equal(['1', '2', '3',
\ '4o', '5o',
\ '6c', '7c', '8c',
\ '9'], getline(1, '$'))
set foldmethod&
bw!
endfunc
func Test_fold_error()
new
call setline(1, [1, 2])
for fm in ['indent', 'expr', 'syntax', 'diff']
exe 'set foldmethod=' . fm
call assert_fails('norm zf', 'E350:')
call assert_fails('norm zd', 'E351:')
call assert_fails('norm zE', 'E352:')
endfor
set foldmethod=manual
call assert_fails('norm zd', 'E490:')
call assert_fails('norm zo', 'E490:')
call assert_fails('3fold', 'E16:')
set foldmethod=marker
set nomodifiable
call assert_fails('1,2fold', 'E21:')
set modifiable&
set foldmethod&
bw!
endfunc

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,119 @@
" *-register (quotestar) tests
if !has('clipboard')
finish
endif
source shared.vim
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
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
" Takes a short while for the server to be active.
call WaitFor('serverlist() =~ "' . name . '"')
call assert_match(name, serverlist())
" Clear the *-register of this vim instance.
let @* = ''
" Try to change the *-register of the server.
call remote_foreground(name)
call remote_send(name, ":let @* = 'yes'\<CR>")
call WaitFor('remote_expr("' . name . '", "@*", "", 1) == "yes"')
call assert_equal('yes', remote_expr(name, "@*", "", 2))
" 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
" Wait for the server to be up and answering requests.
call WaitFor('remote_expr("' . name . '", "v:version", "", 1) != ""')
call remote_send(name, ":let @* = 'maybe'\<CR>")
call WaitFor('remote_expr("' . name . '", "@*", "", 1) == "maybe"')
call assert_equal('maybe', remote_expr(name, "@*", "", 2))
call assert_equal('maybe', @*)
endif
call remote_send(name, ":qa!\<CR>")
call WaitFor('job_status(g:job) == "dead"')
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,48 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
497,
/**/
496,
/**/
495,
/**/
494,
/**/
493,
/**/
492,
/**/
491,
/**/
490,
/**/
489,
/**/
488,
/**/
487,
/**/
486,
/**/
485,
/**/
484,
/**/
483,
/**/
482,
/**/
481,
/**/
480,
/**/
479,
/**/
478,
/**/
477,
/**/
476,
/**/

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;
}