mirror of
https://github.com/zoriya/vim.git
synced 2025-12-09 08:46:17 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5409f5d8c9 | ||
|
|
b7e2483655 | ||
|
|
67fbdfefd2 | ||
|
|
ef6d86c173 | ||
|
|
4014e2ceb0 | ||
|
|
df069eec3b | ||
|
|
7eaafe65ee | ||
|
|
bdd2c290d3 | ||
|
|
25fd267287 | ||
|
|
b2b218d89b | ||
|
|
acd4c5e914 |
@@ -1,4 +1,4 @@
|
||||
*vim9.txt* For Vim version 8.2. Last change: 2020 Jun 21
|
||||
*vim9.txt* For Vim version 8.2. Last change: 2020 Jun 22
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -257,27 +257,32 @@ Function call: >
|
||||
arg2
|
||||
)
|
||||
|
||||
For binary operators iin expressions not in [], {} or () a line break is
|
||||
possible AFTER the operators. For example: >
|
||||
let text = lead ..
|
||||
middle ..
|
||||
end
|
||||
For binary operators in expressions not in [], {} or () a line break is
|
||||
possible just before or after the operator. For example: >
|
||||
let text = lead
|
||||
.. middle
|
||||
.. end
|
||||
let total = start +
|
||||
end -
|
||||
correction
|
||||
let result = positive ?
|
||||
PosFunc(arg) :
|
||||
NegFunc(arg)
|
||||
let result = positive
|
||||
? PosFunc(arg)
|
||||
: NegFunc(arg)
|
||||
|
||||
A special case is "->" for function call chains, it can appear in the next
|
||||
line: >
|
||||
let result = GetBuilder()
|
||||
->BuilderSetWidth(333)
|
||||
->BuilderSetHeight(777)
|
||||
->BuilderBuild()
|
||||
|
||||
Note that "enddef" cannot be used at the start of a continuation line, it ends
|
||||
the current function.
|
||||
< *E1050*
|
||||
To make it possible for the operator at the start of the line to be
|
||||
recognized, it is required to put a colon before a range. This will adde
|
||||
"start" and print: >
|
||||
let result = start
|
||||
+ print
|
||||
This will assign "start" and print a line: >
|
||||
let result = start
|
||||
:+ print
|
||||
|
||||
It is also possible to split a function header over multiple lines, in between
|
||||
arguments: >
|
||||
@@ -286,6 +291,9 @@ arguments: >
|
||||
separator = '-'
|
||||
): string
|
||||
|
||||
Note that "enddef" cannot be used at the start of a continuation line, it ends
|
||||
the current function.
|
||||
|
||||
|
||||
No curly braces expansion ~
|
||||
|
||||
|
||||
@@ -1655,8 +1655,9 @@ au BufNewFile,BufRead *.sil setf sil
|
||||
au BufNewFile,BufRead */etc/sysctl.conf,*/etc/sysctl.d/*.conf setf sysctl
|
||||
|
||||
" Systemd unit files
|
||||
au BufNewFile,BufRead */systemd/*.{automount,mount,path,service,socket,swap,target,timer} setf systemd
|
||||
au BufNewFile,BufRead */systemd/*.{automount,dnssd,link,mount,netdev,network,nspawn,path,service,slice,socket,swap,target,timer} setf systemd
|
||||
" Systemd overrides
|
||||
au BufNewFile,BufRead */etc/systemd/*.conf.d/*.conf setf systemd
|
||||
au BufNewFile,BufRead */etc/systemd/system/*.d/*.conf setf systemd
|
||||
au BufNewFile,BufRead */.config/systemd/user/*.d/*.conf setf systemd
|
||||
" Systemd temp files
|
||||
|
||||
11
src/dict.c
11
src/dict.c
@@ -788,12 +788,14 @@ get_literal_key(char_u **arg, typval_T *tv)
|
||||
/*
|
||||
* Allocate a variable for a Dictionary and fill it from "*arg".
|
||||
* "literal" is TRUE for #{key: val}
|
||||
* "flags" can have EVAL_EVALUATE and other EVAL_ flags.
|
||||
* Return OK or FAIL. Returns NOTDONE for {expr}.
|
||||
*/
|
||||
int
|
||||
eval_dict(char_u **arg, typval_T *rettv, int flags, int literal)
|
||||
{
|
||||
int evaluate = flags & EVAL_EVALUATE;
|
||||
evalarg_T evalarg;
|
||||
dict_T *d = NULL;
|
||||
typval_T tvkey;
|
||||
typval_T tv;
|
||||
@@ -803,6 +805,9 @@ eval_dict(char_u **arg, typval_T *rettv, int flags, int literal)
|
||||
char_u buf[NUMBUFLEN];
|
||||
int vim9script = current_sctx.sc_version == SCRIPT_VERSION_VIM9;
|
||||
|
||||
CLEAR_FIELD(evalarg);
|
||||
evalarg.eval_flags = flags;
|
||||
|
||||
/*
|
||||
* First check if it's not a curly-braces thing: {expr}.
|
||||
* Must do this without evaluating, otherwise a function may be called
|
||||
@@ -812,7 +817,7 @@ eval_dict(char_u **arg, typval_T *rettv, int flags, int literal)
|
||||
*/
|
||||
if (!vim9script && *start != '}')
|
||||
{
|
||||
if (eval1(&start, &tv, 0) == FAIL) // recursive!
|
||||
if (eval1(&start, &tv, NULL) == FAIL) // recursive!
|
||||
return FAIL;
|
||||
if (*start == '}')
|
||||
return NOTDONE;
|
||||
@@ -832,7 +837,7 @@ eval_dict(char_u **arg, typval_T *rettv, int flags, int literal)
|
||||
{
|
||||
if ((literal
|
||||
? get_literal_key(arg, &tvkey)
|
||||
: eval1(arg, &tvkey, flags)) == FAIL) // recursive!
|
||||
: eval1(arg, &tvkey, &evalarg)) == FAIL) // recursive!
|
||||
goto failret;
|
||||
|
||||
if (**arg != ':')
|
||||
@@ -854,7 +859,7 @@ eval_dict(char_u **arg, typval_T *rettv, int flags, int literal)
|
||||
}
|
||||
|
||||
*arg = skipwhite(*arg + 1);
|
||||
if (eval1(arg, &tv, flags) == FAIL) // recursive!
|
||||
if (eval1(arg, &tv, &evalarg) == FAIL) // recursive!
|
||||
{
|
||||
if (evaluate)
|
||||
clear_tv(&tvkey);
|
||||
|
||||
274
src/eval.c
274
src/eval.c
@@ -45,12 +45,12 @@ typedef struct
|
||||
} forinfo_T;
|
||||
|
||||
static int tv_op(typval_T *tv1, typval_T *tv2, char_u *op);
|
||||
static int eval2(char_u **arg, typval_T *rettv, int flags);
|
||||
static int eval3(char_u **arg, typval_T *rettv, int flags);
|
||||
static int eval4(char_u **arg, typval_T *rettv, int flags);
|
||||
static int eval5(char_u **arg, typval_T *rettv, int flags);
|
||||
static int eval6(char_u **arg, typval_T *rettv, int flags, int want_string);
|
||||
static int eval7(char_u **arg, typval_T *rettv, int flags, int want_string);
|
||||
static int eval2(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
|
||||
static int eval3(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
|
||||
static int eval4(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
|
||||
static int eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
|
||||
static int eval6(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_string);
|
||||
static int eval7(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_string);
|
||||
static int eval7_leader(typval_T *rettv, char_u *start_leader, char_u **end_leaderp);
|
||||
|
||||
static int free_unref_items(int copyID);
|
||||
@@ -169,7 +169,7 @@ eval_to_bool(
|
||||
|
||||
if (skip)
|
||||
++emsg_skip;
|
||||
if (eval0(arg, &tv, nextcmd, skip ? 0 : EVAL_EVALUATE) == FAIL)
|
||||
if (eval0(arg, &tv, nextcmd, skip ? NULL : &EVALARG_EVALUATE) == FAIL)
|
||||
*error = TRUE;
|
||||
else
|
||||
{
|
||||
@@ -197,7 +197,7 @@ eval1_emsg(char_u **arg, typval_T *rettv, int evaluate)
|
||||
int did_emsg_before = did_emsg;
|
||||
int called_emsg_before = called_emsg;
|
||||
|
||||
ret = eval1(arg, rettv, evaluate ? EVAL_EVALUATE : 0);
|
||||
ret = eval1(arg, rettv, evaluate ? &EVALARG_EVALUATE : NULL);
|
||||
if (ret == FAIL)
|
||||
{
|
||||
// Report the invalid expression unless the expression evaluation has
|
||||
@@ -325,7 +325,8 @@ eval_to_string_skip(
|
||||
|
||||
if (skip)
|
||||
++emsg_skip;
|
||||
if (eval0(arg, &tv, nextcmd, skip ? 0 : EVAL_EVALUATE) == FAIL || skip)
|
||||
if (eval0(arg, &tv, nextcmd, skip ? NULL : &EVALARG_EVALUATE)
|
||||
== FAIL || skip)
|
||||
retval = NULL;
|
||||
else
|
||||
{
|
||||
@@ -348,7 +349,7 @@ skip_expr(char_u **pp)
|
||||
typval_T rettv;
|
||||
|
||||
*pp = skipwhite(*pp);
|
||||
return eval1(pp, &rettv, 0);
|
||||
return eval1(pp, &rettv, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -370,7 +371,7 @@ eval_to_string(
|
||||
char_u numbuf[NUMBUFLEN];
|
||||
#endif
|
||||
|
||||
if (eval0(arg, &tv, nextcmd, EVAL_EVALUATE) == FAIL)
|
||||
if (eval0(arg, &tv, nextcmd, &EVALARG_EVALUATE) == FAIL)
|
||||
retval = NULL;
|
||||
else
|
||||
{
|
||||
@@ -440,7 +441,7 @@ eval_to_number(char_u *expr)
|
||||
|
||||
++emsg_off;
|
||||
|
||||
if (eval1(&p, &rettv, EVAL_EVALUATE) == FAIL)
|
||||
if (eval1(&p, &rettv, &EVALARG_EVALUATE) == FAIL)
|
||||
retval = -1;
|
||||
else
|
||||
{
|
||||
@@ -463,7 +464,7 @@ eval_expr(char_u *arg, char_u **nextcmd)
|
||||
typval_T *tv;
|
||||
|
||||
tv = ALLOC_ONE(typval_T);
|
||||
if (tv != NULL && eval0(arg, tv, nextcmd, EVAL_EVALUATE) == FAIL)
|
||||
if (tv != NULL && eval0(arg, tv, nextcmd, &EVALARG_EVALUATE) == FAIL)
|
||||
VIM_CLEAR(tv);
|
||||
|
||||
return tv;
|
||||
@@ -588,7 +589,7 @@ eval_foldexpr(char_u *arg, int *cp)
|
||||
++sandbox;
|
||||
++textwinlock;
|
||||
*cp = NUL;
|
||||
if (eval0(arg, &tv, NULL, EVAL_EVALUATE) == FAIL)
|
||||
if (eval0(arg, &tv, NULL, &EVALARG_EVALUATE) == FAIL)
|
||||
retval = 0;
|
||||
else
|
||||
{
|
||||
@@ -776,7 +777,7 @@ get_lval(
|
||||
else
|
||||
{
|
||||
empty1 = FALSE;
|
||||
if (eval1(&p, &var1, EVAL_EVALUATE) == FAIL) // recursive!
|
||||
if (eval1(&p, &var1, &EVALARG_EVALUATE) == FAIL) // recursive!
|
||||
return NULL;
|
||||
if (tv_get_string_chk(&var1) == NULL)
|
||||
{
|
||||
@@ -814,7 +815,7 @@ get_lval(
|
||||
{
|
||||
lp->ll_empty2 = FALSE;
|
||||
// recursive!
|
||||
if (eval1(&p, &var2, EVAL_EVALUATE) == FAIL)
|
||||
if (eval1(&p, &var2, &EVALARG_EVALUATE) == FAIL)
|
||||
{
|
||||
clear_tv(&var1);
|
||||
return NULL;
|
||||
@@ -1424,7 +1425,10 @@ eval_for_line(
|
||||
char_u *expr;
|
||||
typval_T tv;
|
||||
list_T *l;
|
||||
evalarg_T evalarg;
|
||||
|
||||
CLEAR_FIELD(evalarg);
|
||||
evalarg.eval_flags = skip ? 0 : EVAL_EVALUATE;
|
||||
*errp = TRUE; // default: there is an error
|
||||
|
||||
fi = ALLOC_CLEAR_ONE(forinfo_T);
|
||||
@@ -1444,8 +1448,7 @@ eval_for_line(
|
||||
|
||||
if (skip)
|
||||
++emsg_skip;
|
||||
if (eval0(skipwhite(expr + 2), &tv, nextcmdp, skip ? 0 : EVAL_EVALUATE)
|
||||
== OK)
|
||||
if (eval0(skipwhite(expr + 2), &tv, nextcmdp, &evalarg) == OK)
|
||||
{
|
||||
*errp = FALSE;
|
||||
if (!skip)
|
||||
@@ -1763,6 +1766,35 @@ eval_func(
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* If inside Vim9 script, "arg" points to the end of a line (ignoring comments)
|
||||
* and there is a next line, return the next line (skipping blanks) and set
|
||||
* "getnext".
|
||||
* Otherwise just return "arg" unmodified and set "getnext" to FALSE.
|
||||
* "arg" must point somewhere inside a line, not at the start.
|
||||
*/
|
||||
static char_u *
|
||||
eval_next_non_blank(char_u *arg, evalarg_T *evalarg, int *getnext)
|
||||
{
|
||||
*getnext = FALSE;
|
||||
if (current_sctx.sc_version == SCRIPT_VERSION_VIM9
|
||||
&& evalarg != NULL
|
||||
&& evalarg->eval_cookie != NULL
|
||||
&& (*arg == NUL || (VIM_ISWHITE(arg[-1])
|
||||
&& (*arg == '"' || *arg == '#')))
|
||||
&& source_nextline(evalarg->eval_cookie) != NULL)
|
||||
{
|
||||
char_u *p = source_nextline(evalarg->eval_cookie);
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
*getnext = TRUE;
|
||||
return skipwhite(p);
|
||||
}
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
||||
/*
|
||||
* The "evaluate" argument: When FALSE, the argument is only parsed but not
|
||||
* executed. The function may return OK, but the rettv will be of type
|
||||
@@ -1774,7 +1806,7 @@ eval_func(
|
||||
* This calls eval1() and handles error message and nextcmd.
|
||||
* Put the result in "rettv" when returning OK and "evaluate" is TRUE.
|
||||
* Note: "rettv.v_lock" is not set.
|
||||
* "flags" has EVAL_EVALUATE and similar flags.
|
||||
* "evalarg" can be NULL, EVALARG_EVALUATE or a pointer.
|
||||
* Return OK or FAIL.
|
||||
*/
|
||||
int
|
||||
@@ -1782,15 +1814,16 @@ eval0(
|
||||
char_u *arg,
|
||||
typval_T *rettv,
|
||||
char_u **nextcmd,
|
||||
int flags)
|
||||
evalarg_T *evalarg)
|
||||
{
|
||||
int ret;
|
||||
char_u *p;
|
||||
int did_emsg_before = did_emsg;
|
||||
int called_emsg_before = called_emsg;
|
||||
int flags = evalarg == NULL ? 0 : evalarg->eval_flags;
|
||||
|
||||
p = skipwhite(arg);
|
||||
ret = eval1(&p, rettv, flags);
|
||||
ret = eval1(&p, rettv, evalarg);
|
||||
if (ret == FAIL || !ends_excmd2(arg, p))
|
||||
{
|
||||
if (ret != FAIL)
|
||||
@@ -1826,23 +1859,36 @@ eval0(
|
||||
* Return OK or FAIL.
|
||||
*/
|
||||
int
|
||||
eval1(char_u **arg, typval_T *rettv, int flags)
|
||||
eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
|
||||
{
|
||||
int result;
|
||||
typval_T var2;
|
||||
|
||||
/*
|
||||
* Get the first variable.
|
||||
*/
|
||||
if (eval2(arg, rettv, flags) == FAIL)
|
||||
if (eval2(arg, rettv, evalarg) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
if ((*arg)[0] == '?')
|
||||
{
|
||||
int evaluate = flags & EVAL_EVALUATE;
|
||||
int result;
|
||||
typval_T var2;
|
||||
evalarg_T nested_evalarg;
|
||||
int orig_flags;
|
||||
|
||||
if (evalarg == NULL)
|
||||
{
|
||||
CLEAR_FIELD(nested_evalarg);
|
||||
orig_flags = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
nested_evalarg = *evalarg;
|
||||
orig_flags = evalarg->eval_flags;
|
||||
}
|
||||
|
||||
int evaluate = nested_evalarg.eval_flags & EVAL_EVALUATE;
|
||||
|
||||
result = FALSE;
|
||||
if (flags & EVAL_EVALUATE)
|
||||
if (evaluate)
|
||||
{
|
||||
int error = FALSE;
|
||||
|
||||
@@ -1857,7 +1903,9 @@ eval1(char_u **arg, typval_T *rettv, int flags)
|
||||
* Get the second variable. Recursive!
|
||||
*/
|
||||
*arg = skipwhite(*arg + 1);
|
||||
if (eval1(arg, rettv, result ? flags : flags & ~EVAL_EVALUATE) == FAIL)
|
||||
nested_evalarg.eval_flags = result ? orig_flags
|
||||
: orig_flags & ~EVAL_EVALUATE;
|
||||
if (eval1(arg, rettv, &nested_evalarg) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
/*
|
||||
@@ -1875,7 +1923,9 @@ eval1(char_u **arg, typval_T *rettv, int flags)
|
||||
* Get the third variable. Recursive!
|
||||
*/
|
||||
*arg = skipwhite(*arg + 1);
|
||||
if (eval1(arg, &var2, !result ? flags : flags & ~EVAL_EVALUATE) == FAIL)
|
||||
nested_evalarg.eval_flags = !result ? orig_flags
|
||||
: orig_flags & ~EVAL_EVALUATE;
|
||||
if (eval1(arg, &var2, &nested_evalarg) == FAIL)
|
||||
{
|
||||
if (evaluate && result)
|
||||
clear_tv(rettv);
|
||||
@@ -1898,7 +1948,7 @@ eval1(char_u **arg, typval_T *rettv, int flags)
|
||||
* Return OK or FAIL.
|
||||
*/
|
||||
static int
|
||||
eval2(char_u **arg, typval_T *rettv, int flags)
|
||||
eval2(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
|
||||
{
|
||||
typval_T var2;
|
||||
long result;
|
||||
@@ -1908,7 +1958,7 @@ eval2(char_u **arg, typval_T *rettv, int flags)
|
||||
/*
|
||||
* Get the first variable.
|
||||
*/
|
||||
if (eval3(arg, rettv, flags) == FAIL)
|
||||
if (eval3(arg, rettv, evalarg) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
/*
|
||||
@@ -1918,7 +1968,22 @@ eval2(char_u **arg, typval_T *rettv, int flags)
|
||||
result = FALSE;
|
||||
while ((*arg)[0] == '|' && (*arg)[1] == '|')
|
||||
{
|
||||
int evaluate = flags & EVAL_EVALUATE;
|
||||
evalarg_T nested_evalarg;
|
||||
int evaluate;
|
||||
int orig_flags;
|
||||
|
||||
if (evalarg == NULL)
|
||||
{
|
||||
CLEAR_FIELD(nested_evalarg);
|
||||
orig_flags = 0;
|
||||
evaluate = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
nested_evalarg = *evalarg;
|
||||
orig_flags = evalarg->eval_flags;
|
||||
evaluate = orig_flags & EVAL_EVALUATE;
|
||||
}
|
||||
|
||||
if (evaluate && first)
|
||||
{
|
||||
@@ -1934,8 +1999,9 @@ eval2(char_u **arg, typval_T *rettv, int flags)
|
||||
* Get the second variable.
|
||||
*/
|
||||
*arg = skipwhite(*arg + 2);
|
||||
if (eval3(arg, &var2, !result ? flags : flags & ~EVAL_EVALUATE)
|
||||
== FAIL)
|
||||
nested_evalarg.eval_flags = !result ? orig_flags
|
||||
: orig_flags & ~EVAL_EVALUATE;
|
||||
if (eval3(arg, &var2, &nested_evalarg) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
/*
|
||||
@@ -1969,7 +2035,7 @@ eval2(char_u **arg, typval_T *rettv, int flags)
|
||||
* Return OK or FAIL.
|
||||
*/
|
||||
static int
|
||||
eval3(char_u **arg, typval_T *rettv, int flags)
|
||||
eval3(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
|
||||
{
|
||||
typval_T var2;
|
||||
long result;
|
||||
@@ -1979,7 +2045,7 @@ eval3(char_u **arg, typval_T *rettv, int flags)
|
||||
/*
|
||||
* Get the first variable.
|
||||
*/
|
||||
if (eval4(arg, rettv, flags) == FAIL)
|
||||
if (eval4(arg, rettv, evalarg) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
/*
|
||||
@@ -1989,8 +2055,22 @@ eval3(char_u **arg, typval_T *rettv, int flags)
|
||||
result = TRUE;
|
||||
while ((*arg)[0] == '&' && (*arg)[1] == '&')
|
||||
{
|
||||
int evaluate = flags & EVAL_EVALUATE;
|
||||
evalarg_T nested_evalarg;
|
||||
int orig_flags;
|
||||
int evaluate;
|
||||
|
||||
if (evalarg == NULL)
|
||||
{
|
||||
CLEAR_FIELD(nested_evalarg);
|
||||
orig_flags = 0;
|
||||
evaluate = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
nested_evalarg = *evalarg;
|
||||
orig_flags = evalarg->eval_flags;
|
||||
evaluate = orig_flags & EVAL_EVALUATE;
|
||||
}
|
||||
if (evaluate && first)
|
||||
{
|
||||
if (tv_get_number_chk(rettv, &error) == 0)
|
||||
@@ -2005,7 +2085,9 @@ eval3(char_u **arg, typval_T *rettv, int flags)
|
||||
* Get the second variable.
|
||||
*/
|
||||
*arg = skipwhite(*arg + 2);
|
||||
if (eval4(arg, &var2, result ? flags : flags & ~EVAL_EVALUATE) == FAIL)
|
||||
nested_evalarg.eval_flags = result ? orig_flags
|
||||
: orig_flags & ~EVAL_EVALUATE;
|
||||
if (eval4(arg, &var2, &nested_evalarg) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
/*
|
||||
@@ -2048,7 +2130,7 @@ eval3(char_u **arg, typval_T *rettv, int flags)
|
||||
* Return OK or FAIL.
|
||||
*/
|
||||
static int
|
||||
eval4(char_u **arg, typval_T *rettv, int flags)
|
||||
eval4(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
|
||||
{
|
||||
typval_T var2;
|
||||
char_u *p;
|
||||
@@ -2060,7 +2142,7 @@ eval4(char_u **arg, typval_T *rettv, int flags)
|
||||
/*
|
||||
* Get the first variable.
|
||||
*/
|
||||
if (eval5(arg, rettv, flags) == FAIL)
|
||||
if (eval5(arg, rettv, evalarg) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
p = *arg;
|
||||
@@ -2128,12 +2210,12 @@ eval4(char_u **arg, typval_T *rettv, int flags)
|
||||
* Get the second variable.
|
||||
*/
|
||||
*arg = skipwhite(p + len);
|
||||
if (eval5(arg, &var2, flags) == FAIL)
|
||||
if (eval5(arg, &var2, evalarg) == FAIL)
|
||||
{
|
||||
clear_tv(rettv);
|
||||
return FAIL;
|
||||
}
|
||||
if (flags & EVAL_EVALUATE)
|
||||
if (evalarg != NULL && (evalarg->eval_flags & EVAL_EVALUATE))
|
||||
{
|
||||
int ret = typval_compare(rettv, &var2, type, ic);
|
||||
|
||||
@@ -2195,23 +2277,14 @@ eval_addlist(typval_T *tv1, typval_T *tv2)
|
||||
* Return OK or FAIL.
|
||||
*/
|
||||
static int
|
||||
eval5(char_u **arg, typval_T *rettv, int flags)
|
||||
eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
|
||||
{
|
||||
typval_T var2;
|
||||
int op;
|
||||
varnumber_T n1, n2;
|
||||
#ifdef FEAT_FLOAT
|
||||
float_T f1 = 0, f2 = 0;
|
||||
#endif
|
||||
char_u *s1, *s2;
|
||||
char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
|
||||
char_u *p;
|
||||
int concat;
|
||||
int evaluate = evalarg == NULL ? 0 : (evalarg->eval_flags & EVAL_EVALUATE);
|
||||
|
||||
/*
|
||||
* Get the first variable.
|
||||
*/
|
||||
if (eval6(arg, rettv, flags, FALSE) == FAIL)
|
||||
if (eval6(arg, rettv, evalarg, FALSE) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
/*
|
||||
@@ -2219,12 +2292,20 @@ eval5(char_u **arg, typval_T *rettv, int flags)
|
||||
*/
|
||||
for (;;)
|
||||
{
|
||||
int getnext;
|
||||
char_u *p;
|
||||
int op;
|
||||
int concat;
|
||||
typval_T var2;
|
||||
|
||||
// "." is only string concatenation when scriptversion is 1
|
||||
op = **arg;
|
||||
concat = op == '.'
|
||||
&& (*(*arg + 1) == '.' || current_sctx.sc_version < 2);
|
||||
p = eval_next_non_blank(*arg, evalarg, &getnext);
|
||||
op = *p;
|
||||
concat = op == '.' && (*(p + 1) == '.' || current_sctx.sc_version < 2);
|
||||
if (op != '+' && op != '-' && !concat)
|
||||
break;
|
||||
if (getnext)
|
||||
*arg = skipwhite(getsourceline(0, evalarg->eval_cookie, 0, TRUE));
|
||||
|
||||
if ((op != '+' || (rettv->v_type != VAR_LIST
|
||||
&& rettv->v_type != VAR_BLOB))
|
||||
@@ -2240,7 +2321,7 @@ eval5(char_u **arg, typval_T *rettv, int flags)
|
||||
// we know that the first operand needs to be a string or number
|
||||
// without evaluating the 2nd operand. So check before to avoid
|
||||
// side effects after an error.
|
||||
if ((flags & EVAL_EVALUATE) && tv_get_string_chk(rettv) == NULL)
|
||||
if (evaluate && tv_get_string_chk(rettv) == NULL)
|
||||
{
|
||||
clear_tv(rettv);
|
||||
return FAIL;
|
||||
@@ -2253,21 +2334,23 @@ eval5(char_u **arg, typval_T *rettv, int flags)
|
||||
if (op == '.' && *(*arg + 1) == '.') // .. string concatenation
|
||||
++*arg;
|
||||
*arg = skipwhite(*arg + 1);
|
||||
if (eval6(arg, &var2, flags, op == '.') == FAIL)
|
||||
if (eval6(arg, &var2, evalarg, op == '.') == FAIL)
|
||||
{
|
||||
clear_tv(rettv);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (flags & EVAL_EVALUATE)
|
||||
if (evaluate)
|
||||
{
|
||||
/*
|
||||
* Compute the result.
|
||||
*/
|
||||
if (op == '.')
|
||||
{
|
||||
s1 = tv_get_string_buf(rettv, buf1); // already checked
|
||||
s2 = tv_get_string_buf_chk(&var2, buf2);
|
||||
char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
|
||||
char_u *s1 = tv_get_string_buf(rettv, buf1);
|
||||
char_u *s2 = tv_get_string_buf_chk(&var2, buf2);
|
||||
|
||||
if (s2 == NULL) // type error ?
|
||||
{
|
||||
clear_tv(rettv);
|
||||
@@ -2290,9 +2373,11 @@ eval5(char_u **arg, typval_T *rettv, int flags)
|
||||
}
|
||||
else
|
||||
{
|
||||
int error = FALSE;
|
||||
|
||||
int error = FALSE;
|
||||
varnumber_T n1, n2;
|
||||
#ifdef FEAT_FLOAT
|
||||
float_T f1 = 0, f2 = 0;
|
||||
|
||||
if (rettv->v_type == VAR_FLOAT)
|
||||
{
|
||||
f1 = rettv->vval.v_float;
|
||||
@@ -2381,7 +2466,7 @@ eval5(char_u **arg, typval_T *rettv, int flags)
|
||||
eval6(
|
||||
char_u **arg,
|
||||
typval_T *rettv,
|
||||
int flags,
|
||||
evalarg_T *evalarg,
|
||||
int want_string) // after "." operator
|
||||
{
|
||||
typval_T var2;
|
||||
@@ -2396,7 +2481,7 @@ eval6(
|
||||
/*
|
||||
* Get the first variable.
|
||||
*/
|
||||
if (eval7(arg, rettv, flags, want_string) == FAIL)
|
||||
if (eval7(arg, rettv, evalarg, want_string) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
/*
|
||||
@@ -2404,11 +2489,17 @@ eval6(
|
||||
*/
|
||||
for (;;)
|
||||
{
|
||||
op = **arg;
|
||||
int evaluate = evalarg == NULL ? 0
|
||||
: (evalarg->eval_flags & EVAL_EVALUATE);
|
||||
int getnext;
|
||||
|
||||
op = *eval_next_non_blank(*arg, evalarg, &getnext);
|
||||
if (op != '*' && op != '/' && op != '%')
|
||||
break;
|
||||
if (getnext)
|
||||
*arg = skipwhite(getsourceline(0, evalarg->eval_cookie, 0, TRUE));
|
||||
|
||||
if (flags & EVAL_EVALUATE)
|
||||
if (evaluate)
|
||||
{
|
||||
#ifdef FEAT_FLOAT
|
||||
if (rettv->v_type == VAR_FLOAT)
|
||||
@@ -2431,10 +2522,10 @@ eval6(
|
||||
* Get the second variable.
|
||||
*/
|
||||
*arg = skipwhite(*arg + 1);
|
||||
if (eval7(arg, &var2, flags, FALSE) == FAIL)
|
||||
if (eval7(arg, &var2, evalarg, FALSE) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
if (flags & EVAL_EVALUATE)
|
||||
if (evaluate)
|
||||
{
|
||||
#ifdef FEAT_FLOAT
|
||||
if (var2.v_type == VAR_FLOAT)
|
||||
@@ -2551,10 +2642,12 @@ eval6(
|
||||
eval7(
|
||||
char_u **arg,
|
||||
typval_T *rettv,
|
||||
int flags,
|
||||
evalarg_T *evalarg,
|
||||
int want_string) // after "." operator
|
||||
{
|
||||
int evaluate = flags & EVAL_EVALUATE;
|
||||
int flags = evalarg == NULL ? 0 : evalarg->eval_flags;
|
||||
int evaluate = evalarg != NULL
|
||||
&& (evalarg->eval_flags & EVAL_EVALUATE);
|
||||
int len;
|
||||
char_u *s;
|
||||
char_u *start_leader, *end_leader;
|
||||
@@ -2672,15 +2765,17 @@ eval7(
|
||||
/*
|
||||
* nested expression: (expression).
|
||||
*/
|
||||
case '(': *arg = skipwhite(*arg + 1);
|
||||
ret = eval1(arg, rettv, flags); // recursive!
|
||||
if (**arg == ')')
|
||||
++*arg;
|
||||
else if (ret == OK)
|
||||
{
|
||||
emsg(_(e_missing_close));
|
||||
clear_tv(rettv);
|
||||
ret = FAIL;
|
||||
case '(': {
|
||||
*arg = skipwhite(*arg + 1);
|
||||
ret = eval1(arg, rettv, evalarg); // recursive!
|
||||
if (**arg == ')')
|
||||
++*arg;
|
||||
else if (ret == OK)
|
||||
{
|
||||
emsg(_(e_missing_close));
|
||||
clear_tv(rettv);
|
||||
ret = FAIL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -3030,6 +3125,11 @@ eval_index(
|
||||
}
|
||||
else
|
||||
{
|
||||
evalarg_T evalarg;
|
||||
|
||||
CLEAR_FIELD(evalarg);
|
||||
evalarg.eval_flags = flags;
|
||||
|
||||
/*
|
||||
* something[idx]
|
||||
*
|
||||
@@ -3038,7 +3138,7 @@ eval_index(
|
||||
*arg = skipwhite(*arg + 1);
|
||||
if (**arg == ':')
|
||||
empty1 = TRUE;
|
||||
else if (eval1(arg, &var1, flags) == FAIL) // recursive!
|
||||
else if (eval1(arg, &var1, &evalarg) == FAIL) // recursive!
|
||||
return FAIL;
|
||||
else if (evaluate && tv_get_string_chk(&var1) == NULL)
|
||||
{
|
||||
@@ -3056,7 +3156,7 @@ eval_index(
|
||||
*arg = skipwhite(*arg + 1);
|
||||
if (**arg == ']')
|
||||
empty2 = TRUE;
|
||||
else if (eval1(arg, &var2, flags) == FAIL) // recursive!
|
||||
else if (eval1(arg, &var2, &evalarg) == FAIL) // recursive!
|
||||
{
|
||||
if (!empty1)
|
||||
clear_tv(&var1);
|
||||
@@ -4947,6 +5047,10 @@ ex_echo(exarg_T *eap)
|
||||
int atstart = TRUE;
|
||||
int did_emsg_before = did_emsg;
|
||||
int called_emsg_before = called_emsg;
|
||||
evalarg_T evalarg;
|
||||
|
||||
CLEAR_FIELD(evalarg);
|
||||
evalarg.eval_flags = eap->skip ? 0 : EVAL_EVALUATE;
|
||||
|
||||
if (eap->skip)
|
||||
++emsg_skip;
|
||||
@@ -4957,7 +5061,7 @@ ex_echo(exarg_T *eap)
|
||||
need_clr_eos = needclr;
|
||||
|
||||
p = arg;
|
||||
if (eval1(&arg, &rettv, eap->skip ? 0 : EVAL_EVALUATE) == FAIL)
|
||||
if (eval1(&arg, &rettv, &evalarg) == FAIL)
|
||||
{
|
||||
/*
|
||||
* Report the invalid expression unless the expression evaluation
|
||||
|
||||
@@ -2084,7 +2084,7 @@ f_eval(typval_T *argvars, typval_T *rettv)
|
||||
s = skipwhite(s);
|
||||
|
||||
p = s;
|
||||
if (s == NULL || eval1(&s, rettv, EVAL_EVALUATE) == FAIL)
|
||||
if (s == NULL || eval1(&s, rettv, &EVALARG_EVALUATE) == FAIL)
|
||||
{
|
||||
if (p != NULL && !aborting())
|
||||
semsg(_(e_invexpr2), p);
|
||||
|
||||
@@ -435,7 +435,7 @@ eval_spell_expr(char_u *badword, char_u *expr)
|
||||
if (p_verbose == 0)
|
||||
++emsg_off;
|
||||
|
||||
if (eval1(&p, &rettv, EVAL_EVALUATE) == OK)
|
||||
if (eval1(&p, &rettv, &EVALARG_EVALUATE) == OK)
|
||||
{
|
||||
if (rettv.v_type != VAR_LIST)
|
||||
clear_tv(&rettv);
|
||||
@@ -774,7 +774,7 @@ ex_let(exarg_T *eap)
|
||||
}
|
||||
else
|
||||
{
|
||||
int eval_flags;
|
||||
evalarg_T evalarg;
|
||||
|
||||
rettv.v_type = VAR_UNKNOWN;
|
||||
i = FAIL;
|
||||
@@ -797,14 +797,17 @@ ex_let(exarg_T *eap)
|
||||
|
||||
if (eap->skip)
|
||||
++emsg_skip;
|
||||
eval_flags = eap->skip ? 0 : EVAL_EVALUATE;
|
||||
i = eval0(expr, &rettv, &eap->nextcmd, eval_flags);
|
||||
evalarg.eval_flags = eap->skip ? 0 : EVAL_EVALUATE;
|
||||
evalarg.eval_cookie = eap->getline == getsourceline
|
||||
? eap->cookie : NULL;
|
||||
i = eval0(expr, &rettv, &eap->nextcmd, &evalarg);
|
||||
if (eap->skip)
|
||||
--emsg_skip;
|
||||
}
|
||||
if (eap->skip)
|
||||
{
|
||||
if (i != FAIL)
|
||||
clear_tv(&rettv);
|
||||
--emsg_skip;
|
||||
}
|
||||
else if (i != FAIL)
|
||||
{
|
||||
|
||||
@@ -1729,7 +1729,14 @@ do_one_cmd(
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
if (current_sctx.sc_version == SCRIPT_VERSION_VIM9 && !starts_with_colon)
|
||||
{
|
||||
if (ea.cmd > cmd)
|
||||
{
|
||||
emsg(_(e_colon_required));
|
||||
goto doend;
|
||||
}
|
||||
p = find_ex_command(&ea, NULL, lookup_scriptvar, NULL);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
p = find_ex_command(&ea, NULL, NULL, NULL);
|
||||
@@ -3446,7 +3453,7 @@ excmd_get_argt(cmdidx_T idx)
|
||||
* Backslashed delimiters after / or ? will be skipped, and commands will
|
||||
* not be expanded between /'s and ?'s or after "'".
|
||||
*
|
||||
* Also skip white space and ":" characters.
|
||||
* Also skip white space and ":" characters after the range.
|
||||
* Returns the "cmd" pointer advanced to beyond the range.
|
||||
*/
|
||||
char_u *
|
||||
|
||||
@@ -895,9 +895,12 @@ report_discard_pending(int pending, void *value)
|
||||
ex_eval(exarg_T *eap)
|
||||
{
|
||||
typval_T tv;
|
||||
evalarg_T evalarg;
|
||||
|
||||
if (eval0(eap->arg, &tv, &eap->nextcmd, eap->skip ? 0 : EVAL_EVALUATE)
|
||||
== OK)
|
||||
evalarg.eval_flags = eap->skip ? 0 : EVAL_EVALUATE;
|
||||
evalarg.eval_cookie = eap->getline == getsourceline ? eap->cookie : NULL;
|
||||
|
||||
if (eval0(eap->arg, &tv, &eap->nextcmd, &evalarg) == OK)
|
||||
clear_tv(&tv);
|
||||
}
|
||||
|
||||
|
||||
@@ -1790,6 +1790,7 @@ EXTERN char e_const_req_value[] INIT(= N_("E1021: const requires a value"));
|
||||
EXTERN char e_type_req[] INIT(= N_("E1022: type or initialization required"));
|
||||
EXTERN char e_declare_var[] INIT(= N_("E1016: Cannot declare a %s variable: %s"));
|
||||
EXTERN char e_declare_env_var[] INIT(= N_("E1016: Cannot declare an environment variable: %s"));
|
||||
EXTERN char e_colon_required[] INIT(= N_("E1050: Colon required before a range"));
|
||||
#endif
|
||||
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
|
||||
EXTERN char e_alloc_color[] INIT(= N_("E254: Cannot allocate color %s"));
|
||||
@@ -1879,6 +1880,9 @@ EXTERN char windowsVersion[20] INIT(= {0});
|
||||
|
||||
// Used for lv_first in a non-materialized range() list.
|
||||
EXTERN listitem_T range_list_item;
|
||||
|
||||
// Passed to an eval() function to enable evaluation.
|
||||
EXTERN evalarg_T EVALARG_EVALUATE INIT2(EVAL_EVALUATE, NULL);
|
||||
#endif
|
||||
|
||||
#ifdef MSWIN
|
||||
|
||||
@@ -1165,6 +1165,10 @@ get_list_tv(char_u **arg, typval_T *rettv, int flags, int do_error)
|
||||
list_T *l = NULL;
|
||||
typval_T tv;
|
||||
listitem_T *item;
|
||||
evalarg_T evalarg;
|
||||
|
||||
CLEAR_FIELD(evalarg);
|
||||
evalarg.eval_flags = flags;
|
||||
|
||||
if (evaluate)
|
||||
{
|
||||
@@ -1176,7 +1180,7 @@ get_list_tv(char_u **arg, typval_T *rettv, int flags, int do_error)
|
||||
*arg = skipwhite(*arg + 1);
|
||||
while (**arg != ']' && **arg != NUL)
|
||||
{
|
||||
if (eval1(arg, &tv, flags) == FAIL) // recursive!
|
||||
if (eval1(arg, &tv, &evalarg) == FAIL) // recursive!
|
||||
goto failret;
|
||||
if (evaluate)
|
||||
{
|
||||
|
||||
@@ -26,8 +26,8 @@ int next_for_item(void *fi_void, char_u *arg);
|
||||
void free_for_info(void *fi_void);
|
||||
void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx);
|
||||
int pattern_match(char_u *pat, char_u *text, int ic);
|
||||
int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int flags);
|
||||
int eval1(char_u **arg, typval_T *rettv, int flags);
|
||||
int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, evalarg_T *evalarg);
|
||||
int eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg_in);
|
||||
void eval_addblob(typval_T *tv1, typval_T *tv2);
|
||||
int eval_addlist(typval_T *tv1, typval_T *tv2);
|
||||
char_u *partial_name(partial_T *pt);
|
||||
|
||||
@@ -22,6 +22,7 @@ void ex_options(exarg_T *eap);
|
||||
linenr_T *source_breakpoint(void *cookie);
|
||||
int *source_dbg_tick(void *cookie);
|
||||
int source_level(void *cookie);
|
||||
char_u *source_nextline(void *cookie);
|
||||
int do_source(char_u *fname, int check_other, int is_vimrc, int *ret_sid);
|
||||
void ex_scriptnames(exarg_T *eap);
|
||||
void scriptnames_slash_adjust(void);
|
||||
|
||||
@@ -1050,6 +1050,15 @@ source_level(void *cookie)
|
||||
{
|
||||
return ((struct source_cookie *)cookie)->level;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the readahead line.
|
||||
*/
|
||||
char_u *
|
||||
source_nextline(void *cookie)
|
||||
{
|
||||
return ((struct source_cookie *)cookie)->nextline;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined(MSWIN) && defined(FEAT_CSCOPE)) || defined(HAVE_FD_CLOEXEC)
|
||||
|
||||
@@ -1746,6 +1746,19 @@ typedef struct
|
||||
# endif
|
||||
} scriptitem_T;
|
||||
|
||||
// Struct passed through eval() functions.
|
||||
// See EVALARG_EVALUATE for a fixed value with eval_flags set to EVAL_EVALUATE.
|
||||
typedef struct {
|
||||
int eval_flags; // EVAL_ flag values below
|
||||
|
||||
// copied from exarg_T when "getline" is "getsourceline". Can be NULL.
|
||||
void *eval_cookie; // argument for getline()
|
||||
} evalarg_T;
|
||||
|
||||
// Flags for expression evaluation.
|
||||
#define EVAL_EVALUATE 1 // when missing don't actually evaluate
|
||||
#define EVAL_CONSTANT 2 // when not a constant return FAIL
|
||||
|
||||
# ifdef FEAT_PROFILE
|
||||
/*
|
||||
* Struct used in sn_prl_ga for every line of a script.
|
||||
|
||||
@@ -90,6 +90,7 @@ NEW_TESTS = \
|
||||
test_close_count \
|
||||
test_cmdline \
|
||||
test_command_count \
|
||||
test_comments \
|
||||
test_comparators \
|
||||
test_compiler \
|
||||
test_conceal \
|
||||
@@ -341,6 +342,7 @@ NEW_TESTS_RES = \
|
||||
test_close_count.res \
|
||||
test_cmdline.res \
|
||||
test_command_count.res \
|
||||
test_comments.res \
|
||||
test_comparators.res \
|
||||
test_conceal.res \
|
||||
test_const.res \
|
||||
|
||||
@@ -28,7 +28,7 @@ if 1
|
||||
" This uses the :s command to just fetch and process the output of the
|
||||
" tests, it doesn't actually replace anything.
|
||||
" And it uses "silent" to avoid reporting the number of matches.
|
||||
silent %s/^Executed\s\+\zs\d\+\ze\s\+tests\?/\=Count(submatch(0),'executed')/egn
|
||||
silent %s/Executed\s\+\zs\d\+\ze\s\+tests\?/\=Count(submatch(0),'executed')/egn
|
||||
silent %s/^SKIPPED \zs.*/\=Count(submatch(0), 'skipped')/egn
|
||||
silent %s/^\(\d\+\)\s\+FAILED:/\=Count(submatch(1), 'failed')/egn
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
" Tests for Vim buffer
|
||||
|
||||
source check.vim
|
||||
|
||||
" Test for the :bunload command with an offset
|
||||
func Test_bunload_with_offset()
|
||||
%bwipe!
|
||||
@@ -152,6 +154,24 @@ func Test_bdelete_cmd()
|
||||
set nobuflisted
|
||||
enew
|
||||
call assert_fails('bdelete ' .. bnr, 'E516:')
|
||||
|
||||
" Deleting more than one buffer
|
||||
new Xbuf1
|
||||
new Xbuf2
|
||||
exe 'bdel ' .. bufnr('Xbuf2') .. ' ' .. bufnr('Xbuf1')
|
||||
call assert_equal(1, winnr('$'))
|
||||
call assert_equal(0, getbufinfo('Xbuf1')[0].loaded)
|
||||
call assert_equal(0, getbufinfo('Xbuf2')[0].loaded)
|
||||
|
||||
" Deleting more than one buffer and an invalid buffer
|
||||
new Xbuf1
|
||||
new Xbuf2
|
||||
let cmd = "exe 'bdel ' .. bufnr('Xbuf2') .. ' xxx ' .. bufnr('Xbuf1')"
|
||||
call assert_fails(cmd, 'E94:')
|
||||
call assert_equal(2, winnr('$'))
|
||||
call assert_equal(1, getbufinfo('Xbuf1')[0].loaded)
|
||||
call assert_equal(0, getbufinfo('Xbuf2')[0].loaded)
|
||||
|
||||
%bwipe!
|
||||
endfunc
|
||||
|
||||
@@ -166,4 +186,188 @@ func Test_buffer_error()
|
||||
%bwipe
|
||||
endfunc
|
||||
|
||||
" Test for the status messages displayed when unloading, deleting or wiping
|
||||
" out buffers
|
||||
func Test_buffer_statusmsg()
|
||||
CheckEnglish
|
||||
set report=1
|
||||
new Xbuf1
|
||||
new Xbuf2
|
||||
let bnr = bufnr()
|
||||
exe "normal 2\<C-G>"
|
||||
call assert_match('buf ' .. bnr .. ':', v:statusmsg)
|
||||
bunload Xbuf1 Xbuf2
|
||||
call assert_equal('2 buffers unloaded', v:statusmsg)
|
||||
bdel Xbuf1 Xbuf2
|
||||
call assert_equal('2 buffers deleted', v:statusmsg)
|
||||
bwipe Xbuf1 Xbuf2
|
||||
call assert_equal('2 buffers wiped out', v:statusmsg)
|
||||
set report&
|
||||
endfunc
|
||||
|
||||
" Test for quitting the 'swapfile exists' dialog with the split buffer
|
||||
" command.
|
||||
func Test_buffer_sbuf_cleanup()
|
||||
call writefile([], 'Xfile')
|
||||
" first open the file in a buffer
|
||||
new Xfile
|
||||
let bnr = bufnr()
|
||||
close
|
||||
" create the swap file
|
||||
call writefile([], '.Xfile.swp')
|
||||
" Remove the catch-all that runtest.vim adds
|
||||
au! SwapExists
|
||||
augroup BufTest
|
||||
au!
|
||||
autocmd SwapExists Xfile let v:swapchoice='q'
|
||||
augroup END
|
||||
exe 'sbuf ' . bnr
|
||||
call assert_equal(1, winnr('$'))
|
||||
call assert_equal(0, getbufinfo('Xfile')[0].loaded)
|
||||
|
||||
" test for :sball
|
||||
sball
|
||||
call assert_equal(1, winnr('$'))
|
||||
call assert_equal(0, getbufinfo('Xfile')[0].loaded)
|
||||
|
||||
%bw!
|
||||
set shortmess+=F
|
||||
let v:statusmsg = ''
|
||||
edit Xfile
|
||||
call assert_equal('', v:statusmsg)
|
||||
call assert_equal(1, winnr('$'))
|
||||
call assert_equal(0, getbufinfo('Xfile')[0].loaded)
|
||||
set shortmess&
|
||||
|
||||
call delete('Xfile')
|
||||
call delete('.Xfile.swp')
|
||||
augroup BufTest
|
||||
au!
|
||||
augroup END
|
||||
augroup! BufTest
|
||||
endfunc
|
||||
|
||||
" Test for deleting a modified buffer with :confirm
|
||||
func Test_bdel_with_confirm()
|
||||
CheckUnix
|
||||
CheckNotGui
|
||||
CheckFeature dialog_con
|
||||
new
|
||||
call setline(1, 'test')
|
||||
call assert_fails('bdel', 'E89:')
|
||||
call feedkeys('c', 'L')
|
||||
confirm bdel
|
||||
call assert_equal(2, winnr('$'))
|
||||
call assert_equal(1, &modified)
|
||||
call feedkeys('n', 'L')
|
||||
confirm bdel
|
||||
call assert_equal(1, winnr('$'))
|
||||
endfunc
|
||||
|
||||
" Test for editing another buffer from a modified buffer with :confirm
|
||||
func Test_goto_buf_with_confirm()
|
||||
CheckUnix
|
||||
CheckNotGui
|
||||
CheckFeature dialog_con
|
||||
new Xfile
|
||||
enew
|
||||
call setline(1, 'test')
|
||||
call assert_fails('b Xfile', 'E37:')
|
||||
call feedkeys('c', 'L')
|
||||
call assert_fails('confirm b Xfile', 'E37:')
|
||||
call assert_equal(1, &modified)
|
||||
call assert_equal('', @%)
|
||||
call feedkeys('y', 'L')
|
||||
call assert_fails('confirm b Xfile', 'E37:')
|
||||
call assert_equal(1, &modified)
|
||||
call assert_equal('', @%)
|
||||
call feedkeys('n', 'L')
|
||||
confirm b Xfile
|
||||
call assert_equal('Xfile', @%)
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for splitting buffer with 'switchbuf'
|
||||
func Test_buffer_switchbuf()
|
||||
new Xfile
|
||||
wincmd w
|
||||
set switchbuf=useopen
|
||||
sbuf Xfile
|
||||
call assert_equal(1, winnr())
|
||||
call assert_equal(2, winnr('$'))
|
||||
set switchbuf=usetab
|
||||
tabnew
|
||||
sbuf Xfile
|
||||
call assert_equal(1, tabpagenr())
|
||||
call assert_equal(2, tabpagenr('$'))
|
||||
set switchbuf&
|
||||
%bw
|
||||
endfunc
|
||||
|
||||
" Test for BufAdd autocommand wiping out the buffer
|
||||
func Test_bufadd_autocmd_bwipe()
|
||||
%bw!
|
||||
augroup BufAdd_Wipe
|
||||
au!
|
||||
autocmd BufAdd Xfile %bw!
|
||||
augroup END
|
||||
edit Xfile
|
||||
call assert_equal('', @%)
|
||||
call assert_equal(0, bufexists('Xfile'))
|
||||
augroup BufAdd_Wipe
|
||||
au!
|
||||
augroup END
|
||||
augroup! BufAdd_Wipe
|
||||
endfunc
|
||||
|
||||
" Test for trying to load a buffer with text locked
|
||||
" <C-\>e in the command line is used to lock the text
|
||||
func Test_load_buf_with_text_locked()
|
||||
new Xfile1
|
||||
edit Xfile2
|
||||
let cmd = ":\<C-\>eexecute(\"normal \<C-O>\")\<CR>\<C-C>"
|
||||
call assert_fails("call feedkeys(cmd, 'xt')", 'E565:')
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" Test for using CTRL-^ to edit the alternative file keeping the cursor
|
||||
" position with 'nostartofline'. Also test using the 'buf' command.
|
||||
func Test_buffer_edit_altfile()
|
||||
call writefile(repeat(['one two'], 50), 'Xfile1')
|
||||
call writefile(repeat(['five six'], 50), 'Xfile2')
|
||||
set nosol
|
||||
edit Xfile1
|
||||
call cursor(25, 5)
|
||||
edit Xfile2
|
||||
call cursor(30, 4)
|
||||
exe "normal \<C-^>"
|
||||
call assert_equal([0, 25, 5, 0], getpos('.'))
|
||||
exe "normal \<C-^>"
|
||||
call assert_equal([0, 30, 4, 0], getpos('.'))
|
||||
buf Xfile1
|
||||
call assert_equal([0, 25, 5, 0], getpos('.'))
|
||||
buf Xfile2
|
||||
call assert_equal([0, 30, 4, 0], getpos('.'))
|
||||
set sol&
|
||||
call delete('Xfile1')
|
||||
call delete('Xfile2')
|
||||
endfunc
|
||||
|
||||
" Test for running the :sball command with a maximum window count and a
|
||||
" modified buffer
|
||||
func Test_sball_with_count()
|
||||
%bw!
|
||||
edit Xfile1
|
||||
call setline(1, ['abc'])
|
||||
new Xfile2
|
||||
new Xfile3
|
||||
new Xfile4
|
||||
2sball
|
||||
call assert_equal(bufnr('Xfile4'), winbufnr(1))
|
||||
call assert_equal(bufnr('Xfile1'), winbufnr(2))
|
||||
call assert_equal(0, getbufinfo('Xfile2')[0].loaded)
|
||||
call assert_equal(0, getbufinfo('Xfile3')[0].loaded)
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -392,6 +392,7 @@ func Test_getcompletion()
|
||||
call delete('Xtags')
|
||||
set tags&
|
||||
|
||||
call assert_fails("call getcompletion('\\\\@!\\\\@=', 'buffer')", 'E871:')
|
||||
call assert_fails('call getcompletion("", "burp")', 'E475:')
|
||||
call assert_fails('call getcompletion("abc", [])', 'E475:')
|
||||
endfunc
|
||||
|
||||
277
src/testdir/test_comments.vim
Normal file
277
src/testdir/test_comments.vim
Normal file
@@ -0,0 +1,277 @@
|
||||
" Tests for the various flags in the 'comments' option
|
||||
|
||||
" Test for the 'n' flag in 'comments'
|
||||
func Test_comment_nested()
|
||||
new
|
||||
setlocal comments=n:> fo+=ro
|
||||
exe "normal i> B\nD\<C-C>ggOA\<C-C>joC\<C-C>Go\<BS>>>> F\nH"
|
||||
exe "normal 5GOE\<C-C>6GoG"
|
||||
let expected =<< trim END
|
||||
> A
|
||||
> B
|
||||
> C
|
||||
> D
|
||||
>>>> E
|
||||
>>>> F
|
||||
>>>> G
|
||||
>>>> H
|
||||
END
|
||||
call assert_equal(expected, getline(1, '$'))
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for the 'b' flag in 'comments'
|
||||
func Test_comment_blank()
|
||||
new
|
||||
setlocal comments=b:* fo+=ro
|
||||
exe "normal i* E\nF\n\<BS>G\nH\<C-C>ggOC\<C-C>O\<BS>B\<C-C>OA\<C-C>2joD"
|
||||
let expected =<< trim END
|
||||
A
|
||||
*B
|
||||
* C
|
||||
* D
|
||||
* E
|
||||
* F
|
||||
*G
|
||||
H
|
||||
END
|
||||
call assert_equal(expected, getline(1, '$'))
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for the 'f' flag in 'comments' (only the first line has a comment
|
||||
" string)
|
||||
func Test_comment_firstline()
|
||||
new
|
||||
setlocal comments=f:- fo+=ro
|
||||
exe "normal i- B\nD\<C-C>ggoC\<C-C>ggOA\<C-C>"
|
||||
call assert_equal(['A', '- B', ' C', ' D'], getline(1, '$'))
|
||||
%d
|
||||
setlocal comments=:-
|
||||
exe "normal i- B\nD\<C-C>ggoC\<C-C>ggOA\<C-C>"
|
||||
call assert_equal(['- A', '- B', '- C', '- D'], getline(1, '$'))
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for the 's', 'm' and 'e' flags in 'comments'
|
||||
" Test for automatically adding comment leaders in insert mode
|
||||
func Test_comment_threepiece()
|
||||
new
|
||||
setlocal expandtab
|
||||
call setline(1, ["\t/*"])
|
||||
setlocal formatoptions=croql
|
||||
call cursor(1, 3)
|
||||
call feedkeys("A\<cr>\<cr>/", 'tnix')
|
||||
call assert_equal(["\t/*", " *", " */"], getline(1, '$'))
|
||||
|
||||
" If a comment ends in a single line, then don't add it in the next line
|
||||
%d
|
||||
call setline(1, '/* line1 */')
|
||||
call feedkeys("A\<CR>next line", 'xt')
|
||||
call assert_equal(['/* line1 */', 'next line'], getline(1, '$'))
|
||||
|
||||
%d
|
||||
" Copy the trailing indentation from the leader comment to a new line
|
||||
setlocal autoindent noexpandtab
|
||||
call feedkeys("a\t/*\tone\ntwo\n/", 'xt')
|
||||
call assert_equal(["\t/*\tone", "\t *\ttwo", "\t */"], getline(1, '$'))
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for the 'r' flag in 'comments' (right align comment)
|
||||
func Test_comment_rightalign()
|
||||
new
|
||||
setlocal comments=sr:/***,m:**,ex-2:******/ fo+=ro
|
||||
exe "normal i=\<C-C>o\t /***\nD\n/"
|
||||
exe "normal 2GOA\<C-C>joB\<C-C>jOC\<C-C>joE\<C-C>GOF\<C-C>joG"
|
||||
let expected =<< trim END
|
||||
=
|
||||
A
|
||||
/***
|
||||
** B
|
||||
** C
|
||||
** D
|
||||
** E
|
||||
** F
|
||||
******/
|
||||
G
|
||||
END
|
||||
call assert_equal(expected, getline(1, '$'))
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for the 'O' flag in 'comments'
|
||||
func Test_comment_O()
|
||||
new
|
||||
setlocal comments=Ob:* fo+=ro
|
||||
exe "normal i* B\nD\<C-C>kOA\<C-C>joC"
|
||||
let expected =<< trim END
|
||||
A
|
||||
* B
|
||||
* C
|
||||
* D
|
||||
END
|
||||
call assert_equal(expected, getline(1, '$'))
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for using a multibyte character as a comment leader
|
||||
func Test_comment_multibyte_leader()
|
||||
new
|
||||
let t =<< trim END
|
||||
{
|
||||
X
|
||||
Xa
|
||||
XaY
|
||||
XY
|
||||
XYZ
|
||||
X Y
|
||||
X YZ
|
||||
XX
|
||||
XXa
|
||||
XXY
|
||||
}
|
||||
END
|
||||
call setline(1, t)
|
||||
call cursor(2, 1)
|
||||
|
||||
set tw=2 fo=cqm comments=n:X
|
||||
exe "normal gqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgq"
|
||||
let t =<< trim END
|
||||
X
|
||||
Xa
|
||||
XaY
|
||||
XY
|
||||
XYZ
|
||||
X Y
|
||||
X YZ
|
||||
XX
|
||||
XXa
|
||||
XXY
|
||||
END
|
||||
exe "normal o\n" . join(t, "\n")
|
||||
|
||||
let expected =<< trim END
|
||||
{
|
||||
X
|
||||
Xa
|
||||
Xa
|
||||
XY
|
||||
XY
|
||||
XY
|
||||
XZ
|
||||
X Y
|
||||
X Y
|
||||
X Z
|
||||
XX
|
||||
XXa
|
||||
XXY
|
||||
|
||||
X
|
||||
Xa
|
||||
Xa
|
||||
XY
|
||||
XY
|
||||
XY
|
||||
XZ
|
||||
X Y
|
||||
X Y
|
||||
X Z
|
||||
XX
|
||||
XXa
|
||||
XXY
|
||||
}
|
||||
END
|
||||
call assert_equal(expected, getline(1, '$'))
|
||||
|
||||
set tw& fo& comments&
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for a space character in 'comments' setting
|
||||
func Test_comment_space()
|
||||
new
|
||||
setlocal comments=b:\ > fo+=ro
|
||||
exe "normal i> B\nD\<C-C>ggOA\<C-C>joC"
|
||||
exe "normal Go > F\nH\<C-C>kOE\<C-C>joG"
|
||||
let expected =<< trim END
|
||||
A
|
||||
> B
|
||||
C
|
||||
D
|
||||
> E
|
||||
> F
|
||||
> G
|
||||
> H
|
||||
END
|
||||
call assert_equal(expected, getline(1, '$'))
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for formatting lines with and without comments
|
||||
func Test_comment_format_lines()
|
||||
new
|
||||
call setline(1, ['one', '/* two */', 'three'])
|
||||
normal gggqG
|
||||
call assert_equal(['one', '/* two */', 'three'], getline(1, '$'))
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for using 'a' in 'formatoptions' with comments
|
||||
func Test_comment_autoformat()
|
||||
new
|
||||
setlocal formatoptions+=a
|
||||
call feedkeys("a- one\n- two\n", 'xt')
|
||||
call assert_equal(['- one', '- two', ''], getline(1, '$'))
|
||||
|
||||
%d
|
||||
call feedkeys("a\none\n", 'xt')
|
||||
call assert_equal(['', 'one', ''], getline(1, '$'))
|
||||
|
||||
setlocal formatoptions+=aw
|
||||
%d
|
||||
call feedkeys("aone \ntwo\n", 'xt')
|
||||
call assert_equal(['one two', ''], getline(1, '$'))
|
||||
|
||||
%d
|
||||
call feedkeys("aone\ntwo\n", 'xt')
|
||||
call assert_equal(['one', 'two', ''], getline(1, '$'))
|
||||
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for joining lines with comments ('j' flag in 'formatoptions')
|
||||
func Test_comment_join_lines_fo_j()
|
||||
new
|
||||
setlocal fo+=j comments=://
|
||||
call setline(1, ['i++; // comment1', ' // comment2'])
|
||||
normal J
|
||||
call assert_equal('i++; // comment1 comment2', getline(1))
|
||||
setlocal fo-=j
|
||||
call setline(1, ['i++; // comment1', ' // comment2'])
|
||||
normal J
|
||||
call assert_equal('i++; // comment1 // comment2', getline(1))
|
||||
" Test with nested comments
|
||||
setlocal fo+=j comments=n:>,n:)
|
||||
call setline(1, ['i++; > ) > ) comment1', ' > ) comment2'])
|
||||
normal J
|
||||
call assert_equal('i++; > ) > ) comment1 comment2', getline(1))
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for formatting lines where only the first line has a comment.
|
||||
func Test_comment_format_firstline_comment()
|
||||
new
|
||||
setlocal formatoptions=tcq
|
||||
call setline(1, ['- one two', 'three'])
|
||||
normal gggqG
|
||||
call assert_equal(['- one two three'], getline(1, '$'))
|
||||
|
||||
%d
|
||||
call setline(1, ['- one', '- two'])
|
||||
normal gggqG
|
||||
call assert_equal(['- one', '- two'], getline(1, '$'))
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
@@ -99,6 +99,7 @@ func Test_screenpos()
|
||||
\ 'curscol': wincol + 9,
|
||||
\ 'endcol': wincol + 9}, screenpos(winid, 2, 22))
|
||||
close
|
||||
call assert_equal({}, screenpos(999, 1, 1))
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
|
||||
@@ -440,7 +440,7 @@ let s:filename_checks = {
|
||||
\ 'swiftgyb': ['file.swift.gyb'],
|
||||
\ 'sil': ['file.sil'],
|
||||
\ 'sysctl': ['/etc/sysctl.conf', '/etc/sysctl.d/file.conf'],
|
||||
\ 'systemd': ['any/systemd/file.automount', 'any/systemd/file.mount', 'any/systemd/file.path', 'any/systemd/file.service', 'any/systemd/file.socket', 'any/systemd/file.swap', 'any/systemd/file.target', 'any/systemd/file.timer', '/etc/systemd/system/some.d/file.conf', '/etc/systemd/system/some.d/.#file', '/etc/systemd/system/.#otherfile', '/home/user/.config/systemd/user/some.d/mine.conf', '/home/user/.config/systemd/user/some.d/.#file', '/home/user/.config/systemd/user/.#otherfile'],
|
||||
\ 'systemd': ['any/systemd/file.automount', 'any/systemd/file.dnssd', 'any/systemd/file.link', 'any/systemd/file.mount', 'any/systemd/file.netdev', 'any/systemd/file.network', 'any/systemd/file.nspawn', 'any/systemd/file.path', 'any/systemd/file.service', 'any/systemd/file.slice', 'any/systemd/file.socket', 'any/systemd/file.swap', 'any/systemd/file.target', 'any/systemd/file.timer', '/etc/systemd/some.conf.d/file.conf', '/etc/systemd/system/some.d/file.conf', '/etc/systemd/system/some.d/.#file', '/etc/systemd/system/.#otherfile', '/home/user/.config/systemd/user/some.d/mine.conf', '/home/user/.config/systemd/user/some.d/.#file', '/home/user/.config/systemd/user/.#otherfile'],
|
||||
\ 'systemverilog': ['file.sv', 'file.svh'],
|
||||
\ 'tags': ['tags'],
|
||||
\ 'tak': ['file.tak'],
|
||||
|
||||
@@ -475,6 +475,11 @@ func Test_simplify()
|
||||
call assert_equal('./file', simplify('./dir/../file'))
|
||||
call assert_equal('../dir/file', simplify('dir/../../dir/file'))
|
||||
call assert_equal('./file', simplify('dir/.././file'))
|
||||
call assert_equal('../dir', simplify('./../dir'))
|
||||
call assert_equal('..', simplify('../testdir/..'))
|
||||
call mkdir('Xdir')
|
||||
call assert_equal('.', simplify('Xdir/../.'))
|
||||
call delete('Xdir', 'd')
|
||||
|
||||
call assert_fails('call simplify({->0})', 'E729:')
|
||||
call assert_fails('call simplify([])', 'E730:')
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
" Test for the gf and gF (goto file) commands
|
||||
|
||||
" This is a test if a URL is recognized by "gf", with the cursor before and
|
||||
" after the "://". Also test ":\\".
|
||||
@@ -38,6 +39,13 @@ func Test_gf_url()
|
||||
call search("URL")
|
||||
call assert_equal("URL://machine.name:1234?q=vim", expand("<cfile>"))
|
||||
|
||||
%d
|
||||
call setline(1, "demo://remote_file")
|
||||
wincmd f
|
||||
call assert_equal('demo://remote_file', @%)
|
||||
call assert_equal(2, winnr('$'))
|
||||
close!
|
||||
|
||||
set isf&vim
|
||||
enew!
|
||||
endfunc
|
||||
@@ -118,6 +126,11 @@ func Test_gf_visual()
|
||||
norm! ttvtXgf
|
||||
call assert_equal('Xtest_gf_visual', bufname('%'))
|
||||
|
||||
" if multiple lines are selected, then gf should fail
|
||||
call setline(1, ["one", "two"])
|
||||
normal VGgf
|
||||
call assert_equal('Xtest_gf_visual', @%)
|
||||
|
||||
bwipe!
|
||||
call delete('Xtest_gf_visual')
|
||||
set hidden&
|
||||
@@ -146,4 +159,21 @@ func Test_gf_error()
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" If a file is not found by 'gf', then 'includeexpr' should be used to locate
|
||||
" the file.
|
||||
func Test_gf_includeexpr()
|
||||
new
|
||||
let g:Inc_fname = ''
|
||||
func IncFunc()
|
||||
let g:Inc_fname = v:fname
|
||||
return v:fname
|
||||
endfunc
|
||||
setlocal includeexpr=IncFunc()
|
||||
call setline(1, 'somefile.java')
|
||||
call assert_fails('normal gf', 'E447:')
|
||||
call assert_equal('somefile.java', g:Inc_fname)
|
||||
close!
|
||||
delfunc IncFunc
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -754,8 +754,9 @@ func Test_normal17_z_scroll_hor2()
|
||||
bw!
|
||||
endfunc
|
||||
|
||||
" Test for H, M and L commands with folds
|
||||
func Test_scroll_cmds()
|
||||
" Test for commands that scroll the window horizontally. Test with folds.
|
||||
" H, M, L, CTRL-E, CTRL-Y, CTRL-U, CTRL-D, PageUp, PageDown commands
|
||||
func Test_vert_scroll_cmds()
|
||||
15new
|
||||
call setline(1, range(1, 100))
|
||||
exe "normal! 30ggz\<CR>"
|
||||
@@ -764,6 +765,8 @@ func Test_scroll_cmds()
|
||||
40,43fold
|
||||
46,49fold
|
||||
let h = winheight(0)
|
||||
|
||||
" Test for H, M and L commands
|
||||
" Top of the screen = 30
|
||||
" Folded lines = 9
|
||||
" Bottom of the screen = 30 + h + 9 - 1
|
||||
@@ -771,10 +774,104 @@ func Test_scroll_cmds()
|
||||
call assert_equal(35 + h, line('.'))
|
||||
normal! 4H
|
||||
call assert_equal(33, line('.'))
|
||||
|
||||
" Test for the CTRL-E and CTRL-Y commands with folds
|
||||
%d
|
||||
call setline(1, range(1, 10))
|
||||
3,5fold
|
||||
exe "normal 6G3\<C-E>"
|
||||
call assert_equal(6, line('w0'))
|
||||
exe "normal 2\<C-Y>"
|
||||
call assert_equal(2, line('w0'))
|
||||
|
||||
" Test for CTRL-Y on a folded line
|
||||
%d
|
||||
call setline(1, range(1, 100))
|
||||
exe (h + 2) .. "," .. (h + 4) .. "fold"
|
||||
exe h + 5
|
||||
normal z-
|
||||
exe "normal \<C-Y>\<C-Y>"
|
||||
call assert_equal(h + 1, line('w$'))
|
||||
|
||||
" Using <PageUp> and <PageDown> in an empty buffer should beep
|
||||
%d
|
||||
call assert_beeps('exe "normal \<PageUp>"')
|
||||
call assert_beeps('exe "normal \<C-B>"')
|
||||
call assert_beeps('exe "normal \<PageDown>"')
|
||||
call assert_beeps('exe "normal \<C-F>"')
|
||||
|
||||
" Test for <C-U> and <C-D> with fold
|
||||
%d
|
||||
call setline(1, range(1, 100))
|
||||
10,35fold
|
||||
set scroll=10
|
||||
exe "normal \<C-D>"
|
||||
call assert_equal(36, line('.'))
|
||||
exe "normal \<C-D>"
|
||||
call assert_equal(46, line('.'))
|
||||
exe "normal \<C-U>"
|
||||
call assert_equal(36, line('.'))
|
||||
exe "normal \<C-U>"
|
||||
call assert_equal(10, line('.'))
|
||||
exe "normal \<C-U>"
|
||||
call assert_equal(1, line('.'))
|
||||
set scroll&
|
||||
|
||||
" Test for scrolling to the top of the file with <C-U> and a fold
|
||||
10
|
||||
normal ztL
|
||||
exe "normal \<C-U>\<C-U>"
|
||||
call assert_equal(1, line('w0'))
|
||||
|
||||
" Test for CTRL-D on a folded line
|
||||
%d
|
||||
call setline(1, range(1, 100))
|
||||
50,100fold
|
||||
75
|
||||
normal z-
|
||||
exe "normal \<C-D>"
|
||||
call assert_equal(50, line('.'))
|
||||
call assert_equal(100, line('w$'))
|
||||
normal z.
|
||||
let lnum = winline()
|
||||
exe "normal \<C-D>"
|
||||
call assert_equal(lnum, winline())
|
||||
call assert_equal(50, line('.'))
|
||||
normal zt
|
||||
exe "normal \<C-D>"
|
||||
call assert_equal(50, line('w0'))
|
||||
|
||||
set foldenable&
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for the 'sidescroll' option
|
||||
func Test_sidescroll_opt()
|
||||
new
|
||||
20vnew
|
||||
|
||||
" scroll by 2 characters horizontally
|
||||
set sidescroll=2 nowrap
|
||||
call setline(1, repeat('a', 40))
|
||||
normal g$l
|
||||
call assert_equal(19, screenpos(0, 1, 21).col)
|
||||
normal l
|
||||
call assert_equal(20, screenpos(0, 1, 22).col)
|
||||
normal g0h
|
||||
call assert_equal(2, screenpos(0, 1, 2).col)
|
||||
call assert_equal(20, screenpos(0, 1, 20).col)
|
||||
|
||||
" when 'sidescroll' is 0, cursor positioned at the center
|
||||
set sidescroll=0
|
||||
normal g$l
|
||||
call assert_equal(11, screenpos(0, 1, 21).col)
|
||||
normal g0h
|
||||
call assert_equal(10, screenpos(0, 1, 10).col)
|
||||
|
||||
%bw!
|
||||
set wrap& sidescroll&
|
||||
endfunc
|
||||
|
||||
" basic tests for foldopen/folddelete
|
||||
func Test_normal18_z_fold()
|
||||
CheckFeature folding
|
||||
@@ -1170,6 +1267,7 @@ func Test_normal21_nv_hat()
|
||||
edit Xfoo | %bw
|
||||
call assert_fails(':buffer #', 'E86')
|
||||
call assert_fails(':execute "normal! \<C-^>"', 'E23')
|
||||
call assert_fails("normal i\<C-R>#", 'E23:')
|
||||
|
||||
" Test for the expected behavior when switching between two named buffers.
|
||||
edit Xfoo | edit Xbar
|
||||
@@ -2962,4 +3060,40 @@ func Test_normal_word_move()
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for 'scrolloff' with a long line that doesn't fit in the screen
|
||||
func Test_normal_scroloff()
|
||||
10new
|
||||
80vnew
|
||||
call setline(1, repeat('a', 1000))
|
||||
set scrolloff=10
|
||||
normal gg10gj
|
||||
call assert_equal(8, winline())
|
||||
normal 10gj
|
||||
call assert_equal(10, winline())
|
||||
normal 10gk
|
||||
call assert_equal(3, winline())
|
||||
set scrolloff&
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for vertical scrolling with CTRL-F and CTRL-B with a long line
|
||||
func Test_normal_vert_scroll_longline()
|
||||
10new
|
||||
80vnew
|
||||
call setline(1, range(1, 10))
|
||||
call append(5, repeat('a', 1000))
|
||||
exe "normal gg\<C-F>"
|
||||
call assert_equal(6, line('.'))
|
||||
exe "normal \<C-F>\<C-F>"
|
||||
call assert_equal(11, line('.'))
|
||||
call assert_equal(1, winline())
|
||||
exe "normal \<C-B>"
|
||||
call assert_equal(10, line('.'))
|
||||
call assert_equal(3, winline())
|
||||
exe "normal \<C-B>\<C-B>"
|
||||
call assert_equal(5, line('.'))
|
||||
call assert_equal(5, winline())
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -513,6 +513,7 @@ func Test_set_one_column()
|
||||
endfunc
|
||||
|
||||
func Test_set_values()
|
||||
" opt_test.vim is generated from ../optiondefs.h using gen_opt_test.vim
|
||||
if filereadable('opt_test.vim')
|
||||
source opt_test.vim
|
||||
else
|
||||
@@ -921,4 +922,35 @@ func Test_opt_boolean()
|
||||
set number&
|
||||
endfunc
|
||||
|
||||
" Test for the 'window' option
|
||||
func Test_window_opt()
|
||||
" Needs only one open widow
|
||||
%bw!
|
||||
call setline(1, range(1, 8))
|
||||
set window=5
|
||||
exe "normal \<C-F>"
|
||||
call assert_equal(4, line('w0'))
|
||||
exe "normal \<C-F>"
|
||||
call assert_equal(7, line('w0'))
|
||||
exe "normal \<C-F>"
|
||||
call assert_equal(8, line('w0'))
|
||||
exe "normal \<C-B>"
|
||||
call assert_equal(5, line('w0'))
|
||||
exe "normal \<C-B>"
|
||||
call assert_equal(2, line('w0'))
|
||||
exe "normal \<C-B>"
|
||||
call assert_equal(1, line('w0'))
|
||||
set window=1
|
||||
exe "normal gg\<C-F>"
|
||||
call assert_equal(2, line('w0'))
|
||||
exe "normal \<C-F>"
|
||||
call assert_equal(3, line('w0'))
|
||||
exe "normal \<C-B>"
|
||||
call assert_equal(2, line('w0'))
|
||||
exe "normal \<C-B>"
|
||||
call assert_equal(1, line('w0'))
|
||||
enew!
|
||||
set window&
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -2454,10 +2454,9 @@ func Test_popupwin_terminal_buffer()
|
||||
call term_sendkeys(termbuf2, "exit\<CR>")
|
||||
|
||||
" Exiting shell closes popup window
|
||||
let pupwin = win_getid()
|
||||
call feedkeys("exit\<CR>", 'xt')
|
||||
" Wait for shell to exit
|
||||
call WaitForAssert({-> assert_notequal(pupwin, win_getid())})
|
||||
call WaitForAssert({-> assert_equal("dead", job_status(term_getjob(termbuf)))})
|
||||
|
||||
call feedkeys(":quit\<CR>", 'xt')
|
||||
call assert_equal(origwin, win_getid())
|
||||
|
||||
@@ -488,10 +488,10 @@ func Xtest_browse(cchar)
|
||||
call assert_fails('Xprev', 'E553')
|
||||
call assert_fails('Xpfile', 'E553')
|
||||
Xnfile
|
||||
call assert_equal('Xqftestfile2', bufname('%'))
|
||||
call assert_equal('Xqftestfile2', @%)
|
||||
call assert_equal(10, line('.'))
|
||||
Xpfile
|
||||
call assert_equal('Xqftestfile1', bufname('%'))
|
||||
call assert_equal('Xqftestfile1', @%)
|
||||
call assert_equal(6, line('.'))
|
||||
5Xcc
|
||||
call assert_equal(5, g:Xgetlist({'idx':0}).idx)
|
||||
@@ -507,7 +507,7 @@ func Xtest_browse(cchar)
|
||||
call assert_equal(6, g:Xgetlist({'idx':0}).idx)
|
||||
Xlast
|
||||
Xprev
|
||||
call assert_equal('Xqftestfile2', bufname('%'))
|
||||
call assert_equal('Xqftestfile2', @%)
|
||||
call assert_equal(11, line('.'))
|
||||
call assert_fails('Xnext', 'E553')
|
||||
call assert_fails('Xnfile', 'E553')
|
||||
@@ -520,14 +520,14 @@ func Xtest_browse(cchar)
|
||||
endif
|
||||
call assert_equal(6, g:Xgetlist({'idx':0}).idx)
|
||||
Xrewind
|
||||
call assert_equal('Xqftestfile1', bufname('%'))
|
||||
call assert_equal('Xqftestfile1', @%)
|
||||
call assert_equal(5, line('.'))
|
||||
|
||||
10Xnext
|
||||
call assert_equal('Xqftestfile2', bufname('%'))
|
||||
call assert_equal('Xqftestfile2', @%)
|
||||
call assert_equal(11, line('.'))
|
||||
10Xprev
|
||||
call assert_equal('Xqftestfile1', bufname('%'))
|
||||
call assert_equal('Xqftestfile1', @%)
|
||||
call assert_equal(5, line('.'))
|
||||
|
||||
" Jumping to an error from the error window using cc command
|
||||
@@ -538,7 +538,7 @@ func Xtest_browse(cchar)
|
||||
Xopen
|
||||
10Xcc
|
||||
call assert_equal(11, line('.'))
|
||||
call assert_equal('Xqftestfile2', bufname('%'))
|
||||
call assert_equal('Xqftestfile2', @%)
|
||||
Xopen
|
||||
call cursor(2, 1)
|
||||
if a:cchar == 'c'
|
||||
@@ -547,14 +547,14 @@ func Xtest_browse(cchar)
|
||||
.ll
|
||||
endif
|
||||
call assert_equal(6, line('.'))
|
||||
call assert_equal('Xqftestfile1', bufname('%'))
|
||||
call assert_equal('Xqftestfile1', @%)
|
||||
|
||||
" Jumping to an error from the error window (when only the error window is
|
||||
" present)
|
||||
Xopen | only
|
||||
Xlast 1
|
||||
call assert_equal(5, line('.'))
|
||||
call assert_equal('Xqftestfile1', bufname('%'))
|
||||
call assert_equal('Xqftestfile1', @%)
|
||||
|
||||
Xexpr ""
|
||||
call assert_fails('Xnext', 'E42:')
|
||||
@@ -1859,7 +1859,7 @@ func Test_switchbuf()
|
||||
copen | only
|
||||
cfirst
|
||||
call assert_equal(1, tabpagenr())
|
||||
call assert_equal('Xqftestfile1', bufname(''))
|
||||
call assert_equal('Xqftestfile1', @%)
|
||||
|
||||
" If opening a file changes 'switchbuf', then the new value should be
|
||||
" retained.
|
||||
@@ -2679,7 +2679,7 @@ func Test_cwindow_jump()
|
||||
wincmd b
|
||||
cfirst
|
||||
call assert_equal(2, winnr())
|
||||
call assert_equal('F1', bufname(''))
|
||||
call assert_equal('F1', @%)
|
||||
enew | only
|
||||
exe 'sb' bnum
|
||||
exe 'botright sb' bnum
|
||||
@@ -2768,7 +2768,7 @@ func XvimgrepTests(cchar)
|
||||
edit +3 Xtestfile2
|
||||
Xvimgrep +\cemacs+j Xtestfile1
|
||||
let l = g:Xgetlist()
|
||||
call assert_equal('Xtestfile2', bufname(''))
|
||||
call assert_equal('Xtestfile2', @%)
|
||||
call assert_equal('Editor:Emacs EmAcS', l[0].text)
|
||||
|
||||
" Test for unloading a buffer after vimgrep searched the buffer
|
||||
@@ -3394,7 +3394,7 @@ func Xqfjump_tests(cchar)
|
||||
Xopen | only
|
||||
2Xnext
|
||||
call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
|
||||
call assert_equal('F3', bufname('%'))
|
||||
call assert_equal('F3', @%)
|
||||
Xnext
|
||||
call assert_equal(7, col('.'))
|
||||
Xnext
|
||||
@@ -4043,20 +4043,20 @@ func Xjumpto_first_error_test(cchar)
|
||||
" Test for cexpr/lexpr
|
||||
enew
|
||||
Xexpr l
|
||||
call assert_equal('Xtestfile1', bufname(''))
|
||||
call assert_equal('Xtestfile1', @%)
|
||||
call assert_equal(2, line('.'))
|
||||
|
||||
" Test for cfile/lfile
|
||||
enew
|
||||
call writefile(l, 'Xerr')
|
||||
Xfile Xerr
|
||||
call assert_equal('Xtestfile1', bufname(''))
|
||||
call assert_equal('Xtestfile1', @%)
|
||||
call assert_equal(2, line('.'))
|
||||
|
||||
" Test for cbuffer/lbuffer
|
||||
edit Xerr
|
||||
Xbuffer
|
||||
call assert_equal('Xtestfile1', bufname(''))
|
||||
call assert_equal('Xtestfile1', @%)
|
||||
call assert_equal(2, line('.'))
|
||||
|
||||
call delete('Xerr')
|
||||
@@ -4081,7 +4081,7 @@ func Xautocmd_changelist(cchar)
|
||||
autocmd QuickFixCmdPost * Xolder
|
||||
call writefile(['Xtestfile2:4:Line4'], 'Xerr')
|
||||
Xfile Xerr
|
||||
call assert_equal('Xtestfile2', bufname(''))
|
||||
call assert_equal('Xtestfile2', @%)
|
||||
call assert_equal(4, line('.'))
|
||||
autocmd! QuickFixCmdPost
|
||||
|
||||
@@ -4092,7 +4092,7 @@ func Xautocmd_changelist(cchar)
|
||||
call writefile(['Xtestfile2:4:Line4'], 'Xerr')
|
||||
edit Xerr
|
||||
Xbuffer
|
||||
call assert_equal('Xtestfile2', bufname(''))
|
||||
call assert_equal('Xtestfile2', @%)
|
||||
call assert_equal(4, line('.'))
|
||||
autocmd! QuickFixCmdPost
|
||||
|
||||
@@ -4101,7 +4101,7 @@ func Xautocmd_changelist(cchar)
|
||||
Xexpr 'Xtestfile1:2:Line2'
|
||||
autocmd QuickFixCmdPost * Xolder
|
||||
Xexpr 'Xtestfile2:4:Line4'
|
||||
call assert_equal('Xtestfile2', bufname(''))
|
||||
call assert_equal('Xtestfile2', @%)
|
||||
call assert_equal(4, line('.'))
|
||||
autocmd! QuickFixCmdPost
|
||||
|
||||
@@ -4112,7 +4112,7 @@ func Xautocmd_changelist(cchar)
|
||||
Xexpr 'Xtestfile1:2:Line2'
|
||||
autocmd QuickFixCmdPost * Xolder
|
||||
silent Xgrep Line5 Xtestfile2
|
||||
call assert_equal('Xtestfile2', bufname(''))
|
||||
call assert_equal('Xtestfile2', @%)
|
||||
call assert_equal(5, line('.'))
|
||||
autocmd! QuickFixCmdPost
|
||||
endif
|
||||
@@ -4122,7 +4122,7 @@ func Xautocmd_changelist(cchar)
|
||||
Xexpr 'Xtestfile1:2:Line2'
|
||||
autocmd QuickFixCmdPost * Xolder
|
||||
silent Xvimgrep Line5 Xtestfile2
|
||||
call assert_equal('Xtestfile2', bufname(''))
|
||||
call assert_equal('Xtestfile2', @%)
|
||||
call assert_equal(5, line('.'))
|
||||
autocmd! QuickFixCmdPost
|
||||
|
||||
@@ -4415,7 +4415,7 @@ func Test_winonly_autocmd()
|
||||
" positioned correctly.
|
||||
ll 3
|
||||
call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
|
||||
call assert_equal('Xtest1', bufname(''))
|
||||
call assert_equal('Xtest1', @%)
|
||||
call assert_equal(15, line('.'))
|
||||
" Cleanup
|
||||
autocmd! WinEnter
|
||||
@@ -4476,51 +4476,51 @@ func Xtest_below(cchar)
|
||||
Xexpr ["X1:5:3:L5", "X2:5:2:L5", "X2:10:3:L10", "X2:15:4:L15", "X3:3:5:L3"]
|
||||
edit +7 X2
|
||||
Xabove
|
||||
call assert_equal(['X2', 5], [bufname(''), line('.')])
|
||||
call assert_equal(['X2', 5], [@%, line('.')])
|
||||
call assert_fails('Xabove', 'E553:')
|
||||
normal 7G
|
||||
Xbefore
|
||||
call assert_equal(['X2', 5, 2], [bufname(''), line('.'), col('.')])
|
||||
call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
|
||||
call assert_fails('Xbefore', 'E553:')
|
||||
|
||||
normal 2j
|
||||
Xbelow
|
||||
call assert_equal(['X2', 10], [bufname(''), line('.')])
|
||||
call assert_equal(['X2', 10], [@%, line('.')])
|
||||
normal 7G
|
||||
Xafter
|
||||
call assert_equal(['X2', 10, 3], [bufname(''), line('.'), col('.')])
|
||||
call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
|
||||
|
||||
" Last error in this file
|
||||
Xbelow 99
|
||||
call assert_equal(['X2', 15], [bufname(''), line('.')])
|
||||
call assert_equal(['X2', 15], [@%, line('.')])
|
||||
call assert_fails('Xbelow', 'E553:')
|
||||
normal gg
|
||||
Xafter 99
|
||||
call assert_equal(['X2', 15, 4], [bufname(''), line('.'), col('.')])
|
||||
call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
|
||||
call assert_fails('Xafter', 'E553:')
|
||||
|
||||
" First error in this file
|
||||
Xabove 99
|
||||
call assert_equal(['X2', 5], [bufname(''), line('.')])
|
||||
call assert_equal(['X2', 5], [@%, line('.')])
|
||||
call assert_fails('Xabove', 'E553:')
|
||||
normal G
|
||||
Xbefore 99
|
||||
call assert_equal(['X2', 5, 2], [bufname(''), line('.'), col('.')])
|
||||
call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
|
||||
call assert_fails('Xbefore', 'E553:')
|
||||
|
||||
normal gg
|
||||
Xbelow 2
|
||||
call assert_equal(['X2', 10], [bufname(''), line('.')])
|
||||
call assert_equal(['X2', 10], [@%, line('.')])
|
||||
normal gg
|
||||
Xafter 2
|
||||
call assert_equal(['X2', 10, 3], [bufname(''), line('.'), col('.')])
|
||||
call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
|
||||
|
||||
normal G
|
||||
Xabove 2
|
||||
call assert_equal(['X2', 10], [bufname(''), line('.')])
|
||||
call assert_equal(['X2', 10], [@%, line('.')])
|
||||
normal G
|
||||
Xbefore 2
|
||||
call assert_equal(['X2', 10, 3], [bufname(''), line('.'), col('.')])
|
||||
call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
|
||||
|
||||
edit X4
|
||||
call assert_fails('Xabove', 'E42:')
|
||||
@@ -4544,45 +4544,45 @@ func Xtest_below(cchar)
|
||||
\ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"]
|
||||
edit +1 X2
|
||||
Xbelow 2
|
||||
call assert_equal(['X2', 10, 1], [bufname(''), line('.'), col('.')])
|
||||
call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
|
||||
normal 1G
|
||||
Xafter 2
|
||||
call assert_equal(['X2', 5, 2], [bufname(''), line('.'), col('.')])
|
||||
call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
|
||||
|
||||
normal gg
|
||||
Xbelow 99
|
||||
call assert_equal(['X2', 15, 1], [bufname(''), line('.'), col('.')])
|
||||
call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
|
||||
normal gg
|
||||
Xafter 99
|
||||
call assert_equal(['X2', 15, 3], [bufname(''), line('.'), col('.')])
|
||||
call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
|
||||
|
||||
normal G
|
||||
Xabove 2
|
||||
call assert_equal(['X2', 10, 1], [bufname(''), line('.'), col('.')])
|
||||
call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
|
||||
normal G
|
||||
Xbefore 2
|
||||
call assert_equal(['X2', 15, 2], [bufname(''), line('.'), col('.')])
|
||||
call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
|
||||
|
||||
normal G
|
||||
Xabove 99
|
||||
call assert_equal(['X2', 5, 1], [bufname(''), line('.'), col('.')])
|
||||
call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
|
||||
normal G
|
||||
Xbefore 99
|
||||
call assert_equal(['X2', 5, 1], [bufname(''), line('.'), col('.')])
|
||||
call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
|
||||
|
||||
normal 10G
|
||||
Xabove
|
||||
call assert_equal(['X2', 5, 1], [bufname(''), line('.'), col('.')])
|
||||
call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
|
||||
normal 10G$
|
||||
2Xbefore
|
||||
call assert_equal(['X2', 10, 2], [bufname(''), line('.'), col('.')])
|
||||
call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
|
||||
|
||||
normal 10G
|
||||
Xbelow
|
||||
call assert_equal(['X2', 15, 1], [bufname(''), line('.'), col('.')])
|
||||
call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
|
||||
normal 9G
|
||||
5Xafter
|
||||
call assert_equal(['X2', 15, 2], [bufname(''), line('.'), col('.')])
|
||||
call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
|
||||
|
||||
" Invalid range
|
||||
if a:cchar == 'c'
|
||||
|
||||
@@ -641,4 +641,22 @@ func Test_execute_reg_as_ex_cmd()
|
||||
call assert_equal(repeat('abcdefghijklmnopqrstuvwxyz', 312), str)
|
||||
endfunc
|
||||
|
||||
" Test for clipboard registers with ASCII NUL
|
||||
func Test_clipboard_nul()
|
||||
CheckFeature clipboard_working
|
||||
new
|
||||
|
||||
" Test for putting ASCII NUL into the clipboard
|
||||
set clipboard=unnamed
|
||||
call append(0, "\ntest")
|
||||
normal ggyyp
|
||||
call assert_equal("^@test^@", strtrans(getreg('*')))
|
||||
call assert_equal(getline(1), getline(2))
|
||||
let b = split(execute(":reg *"), "\n")
|
||||
call assert_match('"\*\s*\^@test\^J',b[1])
|
||||
|
||||
set clipboard&vim
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -64,7 +64,17 @@ endfunc
|
||||
func Test_statusline()
|
||||
CheckFeature quickfix
|
||||
|
||||
new Xstatusline
|
||||
" %a: Argument list ({current} of {max})
|
||||
set statusline=%a
|
||||
call assert_match('^\s*$', s:get_statusline())
|
||||
arglocal a1 a2
|
||||
rewind
|
||||
call assert_match('^ (1 of 2)\s*$', s:get_statusline())
|
||||
next
|
||||
call assert_match('^ (2 of 2)\s*$', s:get_statusline())
|
||||
e Xstatusline
|
||||
call assert_match('^ ((2) of 2)\s*$', s:get_statusline())
|
||||
|
||||
only
|
||||
set laststatus=2
|
||||
set splitbelow
|
||||
|
||||
@@ -784,78 +784,6 @@ func Test_tw_2_fo_tm_noai()
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_tw_2_fo_cqm_com()
|
||||
new
|
||||
let t =<< trim END
|
||||
{
|
||||
X
|
||||
Xa
|
||||
XaY
|
||||
XY
|
||||
XYZ
|
||||
X Y
|
||||
X YZ
|
||||
XX
|
||||
XXa
|
||||
XXY
|
||||
}
|
||||
END
|
||||
call setline(1, t)
|
||||
call cursor(2, 1)
|
||||
|
||||
set tw=2 fo=cqm comments=n:X
|
||||
exe "normal gqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgq"
|
||||
let t =<< trim END
|
||||
X
|
||||
Xa
|
||||
XaY
|
||||
XY
|
||||
XYZ
|
||||
X Y
|
||||
X YZ
|
||||
XX
|
||||
XXa
|
||||
XXY
|
||||
END
|
||||
exe "normal o\n" . join(t, "\n")
|
||||
|
||||
let expected =<< trim END
|
||||
{
|
||||
X
|
||||
Xa
|
||||
Xa
|
||||
XY
|
||||
XY
|
||||
XY
|
||||
XZ
|
||||
X Y
|
||||
X Y
|
||||
X Z
|
||||
XX
|
||||
XXa
|
||||
XXY
|
||||
|
||||
X
|
||||
Xa
|
||||
Xa
|
||||
XY
|
||||
XY
|
||||
XY
|
||||
XZ
|
||||
X Y
|
||||
X Y
|
||||
X Z
|
||||
XX
|
||||
XXa
|
||||
XXY
|
||||
}
|
||||
END
|
||||
call assert_equal(expected, getline(1, '$'))
|
||||
|
||||
set tw& fo& comments&
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_tw_2_fo_tm_replace()
|
||||
new
|
||||
let t =<< trim END
|
||||
@@ -975,140 +903,6 @@ func Test_whichwrap_multi_byte()
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Test for automatically adding comment leaders in insert mode
|
||||
func Test_threepiece_comment()
|
||||
new
|
||||
setlocal expandtab
|
||||
call setline(1, ["\t/*"])
|
||||
setlocal formatoptions=croql
|
||||
call cursor(1, 3)
|
||||
call feedkeys("A\<cr>\<cr>/", 'tnix')
|
||||
call assert_equal(["\t/*", " *", " */"], getline(1, '$'))
|
||||
|
||||
" If a comment ends in a single line, then don't add it in the next line
|
||||
%d
|
||||
call setline(1, '/* line1 */')
|
||||
call feedkeys("A\<CR>next line", 'xt')
|
||||
call assert_equal(['/* line1 */', 'next line'], getline(1, '$'))
|
||||
|
||||
%d
|
||||
" Copy the trailing indentation from the leader comment to a new line
|
||||
setlocal autoindent noexpandtab
|
||||
call feedkeys("a\t/*\tone\ntwo\n/", 'xt')
|
||||
call assert_equal(["\t/*\tone", "\t *\ttwo", "\t */"], getline(1, '$'))
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for the 'f' flag in 'comments' (only the first line has the comment
|
||||
" string)
|
||||
func Test_firstline_comment()
|
||||
new
|
||||
setlocal comments=f:- fo+=ro
|
||||
exe "normal i- B\nD\<C-C>ggoC\<C-C>ggOA\<C-C>"
|
||||
call assert_equal(['A', '- B', ' C', ' D'], getline(1, '$'))
|
||||
%d
|
||||
setlocal comments=:-
|
||||
exe "normal i- B\nD\<C-C>ggoC\<C-C>ggOA\<C-C>"
|
||||
call assert_equal(['- A', '- B', '- C', '- D'], getline(1, '$'))
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" Test for the 'r' flag in 'comments' (right align comment)
|
||||
func Test_comment_rightalign()
|
||||
new
|
||||
setlocal comments=sr:/***,m:**,ex-2:******/ fo+=ro
|
||||
exe "normal i=\<C-C>o\t /***\nD\n/"
|
||||
exe "normal 2GOA\<C-C>joB\<C-C>jOC\<C-C>joE\<C-C>GOF\<C-C>joG"
|
||||
let expected =<< trim END
|
||||
=
|
||||
A
|
||||
/***
|
||||
** B
|
||||
** C
|
||||
** D
|
||||
** E
|
||||
** F
|
||||
******/
|
||||
G
|
||||
END
|
||||
call assert_equal(expected, getline(1, '$'))
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" Test for the 'b' flag in 'comments'
|
||||
func Test_comment_blank()
|
||||
new
|
||||
setlocal comments=b:* fo+=ro
|
||||
exe "normal i* E\nF\n\<BS>G\nH\<C-C>ggOC\<C-C>O\<BS>B\<C-C>OA\<C-C>2joD"
|
||||
let expected =<< trim END
|
||||
A
|
||||
*B
|
||||
* C
|
||||
* D
|
||||
* E
|
||||
* F
|
||||
*G
|
||||
H
|
||||
END
|
||||
call assert_equal(expected, getline(1, '$'))
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" Test for the 'n' flag in comments
|
||||
func Test_comment_nested()
|
||||
new
|
||||
setlocal comments=n:> fo+=ro
|
||||
exe "normal i> B\nD\<C-C>ggOA\<C-C>joC\<C-C>Go\<BS>>>> F\nH"
|
||||
exe "normal 5GOE\<C-C>6GoG"
|
||||
let expected =<< trim END
|
||||
> A
|
||||
> B
|
||||
> C
|
||||
> D
|
||||
>>>> E
|
||||
>>>> F
|
||||
>>>> G
|
||||
>>>> H
|
||||
END
|
||||
call assert_equal(expected, getline(1, '$'))
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" Test for a space character in 'comments' setting
|
||||
func Test_comment_space()
|
||||
new
|
||||
setlocal comments=b:\ > fo+=ro
|
||||
exe "normal i> B\nD\<C-C>ggOA\<C-C>joC"
|
||||
exe "normal Go > F\nH\<C-C>kOE\<C-C>joG"
|
||||
let expected =<< trim END
|
||||
A
|
||||
> B
|
||||
C
|
||||
D
|
||||
> E
|
||||
> F
|
||||
> G
|
||||
> H
|
||||
END
|
||||
call assert_equal(expected, getline(1, '$'))
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" Test for the 'O' flag in 'comments'
|
||||
func Test_comment_O()
|
||||
new
|
||||
setlocal comments=Ob:* fo+=ro
|
||||
exe "normal i* B\nD\<C-C>kOA\<C-C>joC"
|
||||
let expected =<< trim END
|
||||
A
|
||||
* B
|
||||
* C
|
||||
* D
|
||||
END
|
||||
call assert_equal(expected, getline(1, '$'))
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" Test for 'a' and 'w' flags in 'formatoptions'
|
||||
func Test_fo_a_w()
|
||||
new
|
||||
@@ -1143,25 +937,6 @@ func Test_fo_a_w()
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" Test for 'j' flag in 'formatoptions'
|
||||
func Test_fo_j()
|
||||
new
|
||||
setlocal fo+=j comments=://
|
||||
call setline(1, ['i++; // comment1', ' // comment2'])
|
||||
normal J
|
||||
call assert_equal('i++; // comment1 comment2', getline(1))
|
||||
setlocal fo-=j
|
||||
call setline(1, ['i++; // comment1', ' // comment2'])
|
||||
normal J
|
||||
call assert_equal('i++; // comment1 // comment2', getline(1))
|
||||
" Test with nested comments
|
||||
setlocal fo+=j comments=n:>,n:)
|
||||
call setline(1, ['i++; > ) > ) comment1', ' > ) comment2'])
|
||||
normal J
|
||||
call assert_equal('i++; > ) > ) comment1 comment2', getline(1))
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" Test for formatting lines using gq in visual mode
|
||||
func Test_visual_gq_format()
|
||||
new
|
||||
@@ -1296,51 +1071,4 @@ func Test_fo_2()
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for formatting lines where only the first line has a comment.
|
||||
func Test_fo_gq_with_firstline_comment()
|
||||
new
|
||||
setlocal formatoptions=tcq
|
||||
call setline(1, ['- one two', 'three'])
|
||||
normal gggqG
|
||||
call assert_equal(['- one two three'], getline(1, '$'))
|
||||
|
||||
%d
|
||||
call setline(1, ['- one', '- two'])
|
||||
normal gggqG
|
||||
call assert_equal(['- one', '- two'], getline(1, '$'))
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for trying to join a comment line with a non-comment line
|
||||
func Test_join_comments()
|
||||
new
|
||||
call setline(1, ['one', '/* two */', 'three'])
|
||||
normal gggqG
|
||||
call assert_equal(['one', '/* two */', 'three'], getline(1, '$'))
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for using 'a' in 'formatoptions' with comments
|
||||
func Test_autoformat_comments()
|
||||
new
|
||||
setlocal formatoptions+=a
|
||||
call feedkeys("a- one\n- two\n", 'xt')
|
||||
call assert_equal(['- one', '- two', ''], getline(1, '$'))
|
||||
|
||||
%d
|
||||
call feedkeys("a\none\n", 'xt')
|
||||
call assert_equal(['', 'one', ''], getline(1, '$'))
|
||||
|
||||
setlocal formatoptions+=aw
|
||||
%d
|
||||
call feedkeys("aone \ntwo\n", 'xt')
|
||||
call assert_equal(['one two', ''], getline(1, '$'))
|
||||
|
||||
%d
|
||||
call feedkeys("aone\ntwo\n", 'xt')
|
||||
call assert_equal(['one', 'two', ''], getline(1, '$'))
|
||||
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -13,6 +13,9 @@ def Test_expr1()
|
||||
assert_equal('one', 0.1 ? 'one' : 'two')
|
||||
endif
|
||||
assert_equal('one', 'x' ? 'one' : 'two')
|
||||
assert_equal('one', 'x'
|
||||
? 'one'
|
||||
: 'two')
|
||||
assert_equal('one', 0z1234 ? 'one' : 'two')
|
||||
assert_equal('one', [0] ? 'one' : 'two')
|
||||
assert_equal('one', #{x: 0} ? 'one' : 'two')
|
||||
@@ -70,6 +73,8 @@ def Test_expr2()
|
||||
0 ||
|
||||
7)
|
||||
assert_equal(0, 0 || 0)
|
||||
assert_equal(0, 0
|
||||
|| 0)
|
||||
assert_equal('', 0 || '')
|
||||
|
||||
g:vals = []
|
||||
@@ -81,7 +86,9 @@ def Test_expr2()
|
||||
assert_equal([0, 5], g:vals)
|
||||
|
||||
g:vals = []
|
||||
assert_equal(4, Record(0) || Record(4) || Record(0))
|
||||
assert_equal(4, Record(0)
|
||||
|| Record(4)
|
||||
|| Record(0))
|
||||
assert_equal([0, 4], g:vals)
|
||||
|
||||
g:vals = []
|
||||
@@ -104,7 +111,9 @@ def Test_expr3()
|
||||
assert_equal(0, 0 &&
|
||||
0 &&
|
||||
7)
|
||||
assert_equal(7, 2 && 3 && 7)
|
||||
assert_equal(7, 2
|
||||
&& 3
|
||||
&& 7)
|
||||
assert_equal(0, 0 && 0)
|
||||
assert_equal(0, 0 && '')
|
||||
assert_equal('', 8 && '')
|
||||
@@ -158,7 +167,8 @@ def Test_expr4_equal()
|
||||
assert_equal(true, true == true)
|
||||
assert_equal(false, true ==
|
||||
false)
|
||||
assert_equal(true, true == trueVar)
|
||||
assert_equal(true, true
|
||||
== trueVar)
|
||||
assert_equal(false, true == falseVar)
|
||||
assert_equal(true, true == g:atrue)
|
||||
assert_equal(false, g:atrue == false)
|
||||
@@ -250,7 +260,8 @@ def Test_expr4_notequal()
|
||||
assert_equal(false, true != true)
|
||||
assert_equal(true, true !=
|
||||
false)
|
||||
assert_equal(false, true != trueVar)
|
||||
assert_equal(false, true
|
||||
!= trueVar)
|
||||
assert_equal(true, true != falseVar)
|
||||
assert_equal(false, true != g:atrue)
|
||||
assert_equal(true, g:atrue != false)
|
||||
@@ -334,7 +345,8 @@ def Test_expr4_greater()
|
||||
assert_true(nr2 >
|
||||
1)
|
||||
assert_false(nr2 > 2)
|
||||
assert_false(nr2 > 3)
|
||||
assert_false(nr2
|
||||
> 3)
|
||||
if has('float')
|
||||
let ff = 2.0
|
||||
assert_true(ff > 0.0)
|
||||
@@ -367,7 +379,8 @@ def Test_expr4_smaller()
|
||||
assert_false(2 < 0)
|
||||
assert_false(2 <
|
||||
2)
|
||||
assert_true(2 < 3)
|
||||
assert_true(2
|
||||
< 3)
|
||||
let nr2 = 2
|
||||
assert_false(nr2 < 0)
|
||||
assert_false(nr2 < 2)
|
||||
@@ -385,7 +398,8 @@ def Test_expr4_smallerequal()
|
||||
assert_false(2 <= 0)
|
||||
assert_false(2 <=
|
||||
1)
|
||||
assert_true(2 <= 2)
|
||||
assert_true(2
|
||||
<= 2)
|
||||
assert_true(2 <= 3)
|
||||
let nr2 = 2
|
||||
assert_false(nr2 <= 0)
|
||||
@@ -404,6 +418,8 @@ enddef
|
||||
" test =~ comperator
|
||||
def Test_expr4_match()
|
||||
assert_equal(false, '2' =~ '0')
|
||||
assert_equal(false, ''
|
||||
=~ '0')
|
||||
assert_equal(true, '2' =~
|
||||
'[0-9]')
|
||||
enddef
|
||||
@@ -411,6 +427,8 @@ enddef
|
||||
" test !~ comperator
|
||||
def Test_expr4_nomatch()
|
||||
assert_equal(true, '2' !~ '0')
|
||||
assert_equal(true, ''
|
||||
!~ '0')
|
||||
assert_equal(false, '2' !~
|
||||
'[0-9]')
|
||||
enddef
|
||||
@@ -424,7 +442,8 @@ def Test_expr4_is()
|
||||
other)
|
||||
|
||||
let myblob = 0z1234
|
||||
assert_false(myblob is 0z1234)
|
||||
assert_false(myblob
|
||||
is 0z1234)
|
||||
let otherblob = myblob
|
||||
assert_true(myblob is otherblob)
|
||||
enddef
|
||||
@@ -439,7 +458,8 @@ def Test_expr4_isnot()
|
||||
other)
|
||||
|
||||
let myblob = 0z1234
|
||||
assert_true(myblob isnot 0z1234)
|
||||
assert_true(myblob
|
||||
isnot 0z1234)
|
||||
let otherblob = myblob
|
||||
assert_false(myblob isnot otherblob)
|
||||
enddef
|
||||
@@ -522,30 +542,54 @@ def Test_expr5()
|
||||
assert_equal(66, 60 + 6)
|
||||
assert_equal(70, 60 +
|
||||
g:anint)
|
||||
assert_equal(9, g:alsoint + 5)
|
||||
assert_equal(9, g:alsoint
|
||||
+ 5)
|
||||
assert_equal(14, g:alsoint + g:anint)
|
||||
assert_equal([1, 2, 3, 4], [1] + g:alist)
|
||||
|
||||
assert_equal(54, 60 - 6)
|
||||
assert_equal(50, 60 -
|
||||
g:anint)
|
||||
assert_equal(-1, g:alsoint - 5)
|
||||
assert_equal(-1, g:alsoint
|
||||
- 5)
|
||||
assert_equal(-6, g:alsoint - g:anint)
|
||||
|
||||
assert_equal('hello', 'hel' .. 'lo')
|
||||
assert_equal('hello 123', 'hello ' ..
|
||||
123)
|
||||
assert_equal('hello 123', 'hello ' .. 123)
|
||||
assert_equal('hello 123', 'hello '
|
||||
.. 123)
|
||||
assert_equal('123 hello', 123 .. ' hello')
|
||||
assert_equal('123456', 123 .. 456)
|
||||
|
||||
assert_equal([1, 2, 3, 4], [1, 2] + [3, 4])
|
||||
assert_equal(0z11223344, 0z1122 + 0z3344)
|
||||
assert_equal(0z112201ab, 0z1122 + g:ablob)
|
||||
assert_equal(0z112201ab, 0z1122
|
||||
+ g:ablob)
|
||||
assert_equal(0z01ab3344, g:ablob + 0z3344)
|
||||
assert_equal(0z01ab01ab, g:ablob + g:ablob)
|
||||
enddef
|
||||
|
||||
def Test_expr5_vim9script()
|
||||
" only checks line continuation
|
||||
let lines =<< trim END
|
||||
vim9script
|
||||
let var = 11
|
||||
+ 77
|
||||
- 22
|
||||
assert_equal(66, var)
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
let var = 'one'
|
||||
.. 'two'
|
||||
assert_equal('onetwo', var)
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
def Test_expr5_float()
|
||||
if !has('float')
|
||||
MissingFeature 'float'
|
||||
@@ -554,13 +598,15 @@ def Test_expr5_float()
|
||||
assert_equal(66.0, 60.0 + 6)
|
||||
assert_equal(66.0, 60 +
|
||||
6.0)
|
||||
assert_equal(5.1, g:afloat + 5)
|
||||
assert_equal(5.1, g:afloat
|
||||
+ 5)
|
||||
assert_equal(8.1, 8 + g:afloat)
|
||||
assert_equal(10.1, g:anint + g:afloat)
|
||||
assert_equal(10.1, g:afloat + g:anint)
|
||||
|
||||
assert_equal(54.0, 60.0 - 6.0)
|
||||
assert_equal(54.0, 60.0 - 6)
|
||||
assert_equal(54.0, 60.0
|
||||
- 6)
|
||||
assert_equal(54.0, 60 - 6.0)
|
||||
assert_equal(-4.9, g:afloat - 5)
|
||||
assert_equal(7.9, 8 - g:afloat)
|
||||
@@ -585,12 +631,12 @@ func Test_expr5_fails()
|
||||
call CheckDefFailure(["let x = '1' ..'2'"], msg)
|
||||
call CheckDefFailure(["let x = '1'.. '2'"], msg)
|
||||
|
||||
call CheckDefFailure(["let x = 0z1122 + 33"], 'E1035')
|
||||
call CheckDefFailure(["let x = 0z1122 + [3]"], 'E1035')
|
||||
call CheckDefFailure(["let x = 0z1122 + 'asd'"], 'E1035')
|
||||
call CheckDefFailure(["let x = 33 + 0z1122"], 'E1035')
|
||||
call CheckDefFailure(["let x = [3] + 0z1122"], 'E1035')
|
||||
call CheckDefFailure(["let x = 'asdf' + 0z1122"], 'E1035')
|
||||
call CheckDefFailure(["let x = 0z1122 + 33"], 'E1051')
|
||||
call CheckDefFailure(["let x = 0z1122 + [3]"], 'E1051')
|
||||
call CheckDefFailure(["let x = 0z1122 + 'asd'"], 'E1051')
|
||||
call CheckDefFailure(["let x = 33 + 0z1122"], 'E1051')
|
||||
call CheckDefFailure(["let x = [3] + 0z1122"], 'E1051')
|
||||
call CheckDefFailure(["let x = 'asdf' + 0z1122"], 'E1051')
|
||||
call CheckDefFailure(["let x = 6 + xxx"], 'E1001')
|
||||
endfunc
|
||||
|
||||
@@ -599,20 +645,23 @@ def Test_expr6()
|
||||
assert_equal(36, 6 * 6)
|
||||
assert_equal(24, 6 *
|
||||
g:alsoint)
|
||||
assert_equal(24, g:alsoint * 6)
|
||||
assert_equal(24, g:alsoint
|
||||
* 6)
|
||||
assert_equal(40, g:anint * g:alsoint)
|
||||
|
||||
assert_equal(10, 60 / 6)
|
||||
assert_equal(6, 60 /
|
||||
g:anint)
|
||||
assert_equal(1, g:anint / 6)
|
||||
assert_equal(2, g:anint / g:alsoint)
|
||||
assert_equal(2, g:anint
|
||||
/ g:alsoint)
|
||||
|
||||
assert_equal(5, 11 % 6)
|
||||
assert_equal(4, g:anint % 6)
|
||||
assert_equal(3, 13 %
|
||||
g:anint)
|
||||
assert_equal(2, g:anint % g:alsoint)
|
||||
assert_equal(2, g:anint
|
||||
% g:alsoint)
|
||||
|
||||
assert_equal(4, 6 * 4 / 6)
|
||||
|
||||
@@ -623,13 +672,35 @@ def Test_expr6()
|
||||
if has('float')
|
||||
let xf = [2.0]
|
||||
let yf = [3.0]
|
||||
assert_equal(5.0, xf[0] + yf[0])
|
||||
assert_equal(6.0, xf[0] * yf[0])
|
||||
assert_equal(5.0, xf[0]
|
||||
+ yf[0])
|
||||
assert_equal(6.0, xf[0]
|
||||
* yf[0])
|
||||
endif
|
||||
|
||||
call CheckDefFailure(["let x = 6 * xxx"], 'E1001')
|
||||
enddef
|
||||
|
||||
def Test_expr6_vim9script()
|
||||
" only checks line continuation
|
||||
let lines =<< trim END
|
||||
vim9script
|
||||
let var = 11
|
||||
* 22
|
||||
/ 3
|
||||
assert_equal(80, var)
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
let var = 25
|
||||
% 10
|
||||
assert_equal(5, var)
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
def Test_expr6_float()
|
||||
if !has('float')
|
||||
MissingFeature 'float'
|
||||
|
||||
@@ -837,5 +837,16 @@ def Test_sort_return_type()
|
||||
res = [1, 2, 3]->sort()
|
||||
enddef
|
||||
|
||||
def Line_continuation_in_def(dir: string = ''): string
|
||||
let path: string = empty(dir)
|
||||
\ ? 'empty'
|
||||
\ : 'full'
|
||||
return path
|
||||
enddef
|
||||
|
||||
def Test_line_continuation_in_def()
|
||||
assert_equal('full', Line_continuation_in_def('.'))
|
||||
enddef
|
||||
|
||||
|
||||
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
||||
|
||||
@@ -468,6 +468,14 @@ func Test_const()
|
||||
call CheckDefFailure(['const &option'], 'E996:')
|
||||
endfunc
|
||||
|
||||
def Test_range_no_colon()
|
||||
call CheckDefFailure(['%s/a/b/'], 'E1050:')
|
||||
call CheckDefFailure(['+ s/a/b/'], 'E1050:')
|
||||
call CheckDefFailure(['- s/a/b/'], 'E1050:')
|
||||
call CheckDefFailure(['. s/a/b/'], 'E1050:')
|
||||
enddef
|
||||
|
||||
|
||||
def Test_block()
|
||||
let outer = 1
|
||||
{
|
||||
@@ -1279,7 +1287,7 @@ def Test_echomsg_cmd()
|
||||
echomsg 'some' 'more' # comment
|
||||
assert_match('^some more$', Screenline(&lines))
|
||||
echo 'clear'
|
||||
1messages
|
||||
:1messages
|
||||
assert_match('^some more$', Screenline(&lines))
|
||||
|
||||
call CheckDefFailure(['echomsg "xxx"# comment'], 'E488:')
|
||||
@@ -1898,7 +1906,7 @@ def Test_vim9_comment_not_compiled()
|
||||
'vim9script',
|
||||
'new'
|
||||
'call setline(1, ["# define pat", "last"])',
|
||||
'$',
|
||||
':$',
|
||||
'dsearch /pat/ #comment',
|
||||
'bwipe!',
|
||||
])
|
||||
@@ -1907,7 +1915,7 @@ def Test_vim9_comment_not_compiled()
|
||||
'vim9script',
|
||||
'new'
|
||||
'call setline(1, ["# define pat", "last"])',
|
||||
'$',
|
||||
':$',
|
||||
'dsearch /pat/#comment',
|
||||
'bwipe!',
|
||||
], 'E488:')
|
||||
|
||||
@@ -239,7 +239,7 @@ get_function_args(
|
||||
whitep = p;
|
||||
p = skipwhite(p);
|
||||
expr = p;
|
||||
if (eval1(&p, &rettv, 0) != FAIL)
|
||||
if (eval1(&p, &rettv, NULL) != FAIL)
|
||||
{
|
||||
if (ga_grow(default_args, 1) == FAIL)
|
||||
goto err_ret;
|
||||
@@ -561,6 +561,10 @@ get_func_tv(
|
||||
int ret = OK;
|
||||
typval_T argvars[MAX_FUNC_ARGS + 1]; // vars for arguments
|
||||
int argcount = 0; // number of arguments found
|
||||
evalarg_T evalarg;
|
||||
|
||||
CLEAR_FIELD(evalarg);
|
||||
evalarg.eval_flags = funcexe->evaluate ? EVAL_EVALUATE : 0;
|
||||
|
||||
/*
|
||||
* Get the arguments.
|
||||
@@ -572,8 +576,7 @@ get_func_tv(
|
||||
argp = skipwhite(argp + 1); // skip the '(' or ','
|
||||
if (*argp == ')' || *argp == ',' || *argp == NUL)
|
||||
break;
|
||||
if (eval1(&argp, &argvars[argcount],
|
||||
funcexe->evaluate ? EVAL_EVALUATE : 0) == FAIL)
|
||||
if (eval1(&argp, &argvars[argcount], &evalarg) == FAIL)
|
||||
{
|
||||
ret = FAIL;
|
||||
break;
|
||||
@@ -1249,7 +1252,7 @@ call_user_func(
|
||||
|
||||
default_expr = ((char_u **)(fp->uf_def_args.ga_data))
|
||||
[ai + fp->uf_def_args.ga_len];
|
||||
if (eval1(&default_expr, &def_rettv, EVAL_EVALUATE) == FAIL)
|
||||
if (eval1(&default_expr, &def_rettv, &EVALARG_EVALUATE) == FAIL)
|
||||
{
|
||||
default_arg_err = 1;
|
||||
break;
|
||||
@@ -1394,7 +1397,7 @@ call_user_func(
|
||||
// A Lambda always has the command "return {expr}". It is much faster
|
||||
// to evaluate {expr} directly.
|
||||
++ex_nesting_level;
|
||||
(void)eval1(&p, rettv, EVAL_EVALUATE);
|
||||
(void)eval1(&p, rettv, &EVALARG_EVALUATE);
|
||||
--ex_nesting_level;
|
||||
}
|
||||
else
|
||||
@@ -3697,6 +3700,7 @@ ex_return(exarg_T *eap)
|
||||
char_u *arg = eap->arg;
|
||||
typval_T rettv;
|
||||
int returning = FALSE;
|
||||
evalarg_T evalarg;
|
||||
|
||||
if (current_funccal == NULL)
|
||||
{
|
||||
@@ -3704,13 +3708,15 @@ ex_return(exarg_T *eap)
|
||||
return;
|
||||
}
|
||||
|
||||
CLEAR_FIELD(evalarg);
|
||||
evalarg.eval_flags = eap->skip ? 0 : EVAL_EVALUATE;
|
||||
|
||||
if (eap->skip)
|
||||
++emsg_skip;
|
||||
|
||||
eap->nextcmd = NULL;
|
||||
if ((*arg != NUL && *arg != '|' && *arg != '\n')
|
||||
&& eval0(arg, &rettv, &eap->nextcmd, eap->skip ? 0 : EVAL_EVALUATE)
|
||||
!= FAIL)
|
||||
&& eval0(arg, &rettv, &eap->nextcmd, &evalarg) != FAIL)
|
||||
{
|
||||
if (!eap->skip)
|
||||
returning = do_return(eap, FALSE, TRUE, &rettv);
|
||||
@@ -3767,7 +3773,7 @@ ex_call(exarg_T *eap)
|
||||
// instead to skip to any following command, e.g. for:
|
||||
// :if 0 | call dict.foo().bar() | endif
|
||||
++emsg_skip;
|
||||
if (eval0(eap->arg, &rettv, &eap->nextcmd, 0) != FAIL)
|
||||
if (eval0(eap->arg, &rettv, &eap->nextcmd, NULL) != FAIL)
|
||||
clear_tv(&rettv);
|
||||
--emsg_skip;
|
||||
return;
|
||||
|
||||
@@ -754,6 +754,28 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1047,
|
||||
/**/
|
||||
1046,
|
||||
/**/
|
||||
1045,
|
||||
/**/
|
||||
1044,
|
||||
/**/
|
||||
1043,
|
||||
/**/
|
||||
1042,
|
||||
/**/
|
||||
1041,
|
||||
/**/
|
||||
1040,
|
||||
/**/
|
||||
1039,
|
||||
/**/
|
||||
1038,
|
||||
/**/
|
||||
1037,
|
||||
/**/
|
||||
1036,
|
||||
/**/
|
||||
|
||||
@@ -2665,10 +2665,6 @@ long elapsed(DWORD start_tick);
|
||||
#define REPTERM_SPECIAL 4
|
||||
#define REPTERM_NO_SIMPLIFY 8
|
||||
|
||||
// Flags for expression evaluation.
|
||||
#define EVAL_EVALUATE 1 // when missing don't actually evaluate
|
||||
#define EVAL_CONSTANT 2 // when not a constant return FAIL
|
||||
|
||||
// Flags for find_special_key()
|
||||
#define FSK_KEYCODE 0x01 // prefer key code, e.g. K_DEL instead of DEL
|
||||
#define FSK_KEEP_X_KEY 0x02 // don't translate xHome to Home key
|
||||
|
||||
@@ -643,7 +643,7 @@ check_number_or_float(vartype_T type1, vartype_T type2, char_u *op)
|
||||
|| type2 == VAR_ANY)))
|
||||
{
|
||||
if (*op == '+')
|
||||
emsg(_("E1035: wrong argument type for +"));
|
||||
emsg(_("E1051: wrong argument type for +"));
|
||||
else
|
||||
semsg(_("E1036: %c requires number or float arguments"), *op);
|
||||
return FAIL;
|
||||
@@ -2402,14 +2402,38 @@ peek_next_line(cctx_T *cctx)
|
||||
while (++lnum < cctx->ctx_ufunc->uf_lines.ga_len)
|
||||
{
|
||||
char_u *line = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[lnum];
|
||||
char_u *p = skipwhite(line);
|
||||
char_u *p;
|
||||
|
||||
if (line == NULL)
|
||||
break;
|
||||
p = skipwhite(line);
|
||||
if (*p != NUL && !comment_start(p))
|
||||
return p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when checking for a following operator at "arg". When the rest of
|
||||
* the line is empty or only a comment, peek the next line. If there is a next
|
||||
* line return a pointer to it and set "nextp".
|
||||
* Otherwise skip over white space.
|
||||
*/
|
||||
static char_u *
|
||||
may_peek_next_line(cctx_T *cctx, char_u *arg, char_u **nextp)
|
||||
{
|
||||
char_u *p = skipwhite(arg);
|
||||
|
||||
*nextp = NULL;
|
||||
if (*p == NUL || (VIM_ISWHITE(*arg) && comment_start(p)))
|
||||
{
|
||||
*nextp = peek_next_line(cctx);
|
||||
if (*nextp != NULL)
|
||||
return *nextp;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the next line of the function from "cctx".
|
||||
* Skips over empty lines. Skips over comment lines if "skip_comment" is TRUE.
|
||||
@@ -3944,6 +3968,7 @@ compile_expr7(
|
||||
compile_expr6(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
||||
{
|
||||
char_u *op;
|
||||
char_u *next;
|
||||
int ppconst_used = ppconst->pp_used;
|
||||
|
||||
// get the first expression
|
||||
@@ -3955,9 +3980,14 @@ compile_expr6(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
||||
*/
|
||||
for (;;)
|
||||
{
|
||||
op = skipwhite(*arg);
|
||||
op = may_peek_next_line(cctx, *arg, &next);
|
||||
if (*op != '*' && *op != '/' && *op != '%')
|
||||
break;
|
||||
if (next != NULL)
|
||||
{
|
||||
*arg = next_line_from_context(cctx, TRUE);
|
||||
op = skipwhite(*arg);
|
||||
}
|
||||
|
||||
if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[1]))
|
||||
{
|
||||
@@ -4015,6 +4045,7 @@ compile_expr6(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
||||
compile_expr5(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
||||
{
|
||||
char_u *op;
|
||||
char_u *next;
|
||||
int oplen;
|
||||
int ppconst_used = ppconst->pp_used;
|
||||
|
||||
@@ -4027,10 +4058,15 @@ compile_expr5(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
||||
*/
|
||||
for (;;)
|
||||
{
|
||||
op = skipwhite(*arg);
|
||||
if (*op != '+' && *op != '-' && !(*op == '.' && (*(*arg + 1) == '.')))
|
||||
op = may_peek_next_line(cctx, *arg, &next);
|
||||
if (*op != '+' && *op != '-' && !(*op == '.' && *(op + 1) == '.'))
|
||||
break;
|
||||
oplen = (*op == '.' ? 2 : 1);
|
||||
if (next != NULL)
|
||||
{
|
||||
*arg = next_line_from_context(cctx, TRUE);
|
||||
op = skipwhite(*arg);
|
||||
}
|
||||
|
||||
if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[oplen]))
|
||||
{
|
||||
@@ -4124,6 +4160,7 @@ compile_expr4(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
||||
{
|
||||
exptype_T type = EXPR_UNKNOWN;
|
||||
char_u *p;
|
||||
char_u *next;
|
||||
int len = 2;
|
||||
int type_is = FALSE;
|
||||
int ppconst_used = ppconst->pp_used;
|
||||
@@ -4132,7 +4169,7 @@ compile_expr4(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
||||
if (compile_expr5(arg, cctx, ppconst) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
p = skipwhite(*arg);
|
||||
p = may_peek_next_line(cctx, *arg, &next);
|
||||
type = get_compare_type(p, &len, &type_is);
|
||||
|
||||
/*
|
||||
@@ -4142,6 +4179,11 @@ compile_expr4(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
||||
{
|
||||
int ic = FALSE; // Default: do not ignore case
|
||||
|
||||
if (next != NULL)
|
||||
{
|
||||
*arg = next_line_from_context(cctx, TRUE);
|
||||
p = skipwhite(*arg);
|
||||
}
|
||||
if (type_is && (p[len] == '?' || p[len] == '#'))
|
||||
{
|
||||
semsg(_(e_invexpr2), *arg);
|
||||
@@ -4218,7 +4260,8 @@ compile_and_or(
|
||||
ppconst_T *ppconst,
|
||||
int ppconst_used UNUSED)
|
||||
{
|
||||
char_u *p = skipwhite(*arg);
|
||||
char_u *next;
|
||||
char_u *p = may_peek_next_line(cctx, *arg, &next);
|
||||
int opchar = *op;
|
||||
|
||||
if (p[0] == opchar && p[1] == opchar)
|
||||
@@ -4232,6 +4275,12 @@ compile_and_or(
|
||||
ga_init2(&end_ga, sizeof(int), 10);
|
||||
while (p[0] == opchar && p[1] == opchar)
|
||||
{
|
||||
if (next != NULL)
|
||||
{
|
||||
*arg = next_line_from_context(cctx, TRUE);
|
||||
p = skipwhite(*arg);
|
||||
}
|
||||
|
||||
if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[2]))
|
||||
{
|
||||
semsg(_(e_white_both), op);
|
||||
@@ -4262,7 +4311,8 @@ compile_and_or(
|
||||
ga_clear(&end_ga);
|
||||
return FAIL;
|
||||
}
|
||||
p = skipwhite(*arg);
|
||||
|
||||
p = may_peek_next_line(cctx, *arg, &next);
|
||||
}
|
||||
generate_ppconst(cctx, ppconst);
|
||||
|
||||
@@ -4346,12 +4396,13 @@ compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
||||
{
|
||||
char_u *p;
|
||||
int ppconst_used = ppconst->pp_used;
|
||||
char_u *next;
|
||||
|
||||
// Evaluate the first expression.
|
||||
if (compile_expr2(arg, cctx, ppconst) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
p = skipwhite(*arg);
|
||||
p = may_peek_next_line(cctx, *arg, &next);
|
||||
if (*p == '?')
|
||||
{
|
||||
garray_T *instr = &cctx->ctx_instr;
|
||||
@@ -4365,6 +4416,12 @@ compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
||||
int const_value = FALSE;
|
||||
int save_skip = cctx->ctx_skip;
|
||||
|
||||
if (next != NULL)
|
||||
{
|
||||
*arg = next_line_from_context(cctx, TRUE);
|
||||
p = skipwhite(*arg);
|
||||
}
|
||||
|
||||
if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1]))
|
||||
{
|
||||
semsg(_(e_white_both), "?");
|
||||
@@ -4412,12 +4469,18 @@ compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
||||
}
|
||||
|
||||
// Check for the ":".
|
||||
p = skipwhite(*arg);
|
||||
p = may_peek_next_line(cctx, *arg, &next);
|
||||
if (*p != ':')
|
||||
{
|
||||
emsg(_(e_missing_colon));
|
||||
return FAIL;
|
||||
}
|
||||
if (next != NULL)
|
||||
{
|
||||
*arg = next_line_from_context(cctx, TRUE);
|
||||
p = skipwhite(*arg);
|
||||
}
|
||||
|
||||
if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1]))
|
||||
{
|
||||
semsg(_(e_white_both), ":");
|
||||
@@ -6692,6 +6755,7 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
|
||||
{
|
||||
exarg_T ea;
|
||||
int starts_with_colon = FALSE;
|
||||
char_u *cmd;
|
||||
|
||||
// Bail out on the first error to avoid a flood of errors and report
|
||||
// the right line number when inside try/catch.
|
||||
@@ -6850,7 +6914,13 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
|
||||
/*
|
||||
* COMMAND after range
|
||||
*/
|
||||
cmd = ea.cmd;
|
||||
ea.cmd = skip_range(ea.cmd, NULL);
|
||||
if (ea.cmd > cmd && !starts_with_colon)
|
||||
{
|
||||
emsg(_(e_colon_required));
|
||||
goto erret;
|
||||
}
|
||||
p = find_ex_command(&ea, NULL, starts_with_colon ? NULL
|
||||
: (void *(*)(char_u *, size_t, cctx_T *))lookup_local,
|
||||
&cctx);
|
||||
@@ -7005,8 +7075,9 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
|
||||
line = compile_mult_expr(p, ea.cmdidx, &cctx);
|
||||
break;
|
||||
|
||||
// TODO: other commands with an expression argument
|
||||
|
||||
default:
|
||||
// TODO: other commands with an expression argument
|
||||
// Not recognized, execute with do_cmdline_cmd().
|
||||
ea.arg = p;
|
||||
line = compile_exec(line, &ea, &cctx);
|
||||
|
||||
@@ -422,7 +422,7 @@ clip_mch_request_selection(Clipboard_T *cbd)
|
||||
}
|
||||
}
|
||||
|
||||
if (str != NULL && *str != NUL)
|
||||
if (str != NULL && metadata.txtlen != 0)
|
||||
{
|
||||
char_u *temp_clipboard;
|
||||
|
||||
@@ -543,7 +543,7 @@ clip_mch_set_selection(Clipboard_T *cbd)
|
||||
|
||||
if (lpszMem)
|
||||
{
|
||||
vim_strncpy((char_u *)lpszMem, str, metadata.txtlen);
|
||||
mch_memmove((char_u *)lpszMem, str, metadata.txtlen);
|
||||
GlobalUnlock(hMem);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user