Merge pull request #13655 from janlazo/vim-8.2.2255

vim-patch:8.1.{1241,1261,1275,1281,1549,1590,1881,2079,2322,2360,2411},8.2.{113,388,934,2255,2258,2260,2269}
This commit is contained in:
Jan Edmund Lazo 2021-01-01 17:40:26 -05:00 committed by GitHub
commit 5eccfd2b2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 1403 additions and 884 deletions

View File

@ -1173,9 +1173,11 @@ tag command action ~
|:caddbuffer| :cad[dbuffer] add errors from buffer
|:caddexpr| :cadde[xpr] add errors from expr
|:caddfile| :caddf[ile] add error message to current quickfix list
|:cafter| :caf[ter] go to error after current cursor
|:call| :cal[l] call a function
|:catch| :cat[ch] part of a :try command
|:cbelow| :cbe[low] go to error below current line
|:cbefore| :cbef[ore] go to error before current cursor
|:cbelow| :cbel[ow] go to error below current line
|:cbottom| :cbo[ttom] scroll to the bottom of the quickfix window
|:cbuffer| :cb[uffer] parse error messages and jump to first error
|:cc| :cc go to specific error
@ -1336,10 +1338,12 @@ tag command action ~
|:laddexpr| :lad[dexpr] add locations from expr
|:laddbuffer| :laddb[uffer] add locations from buffer
|:laddfile| :laddf[ile] add locations to current location list
|:lafter| :laf[ter] go to location after current cursor
|:last| :la[st] go to the last file in the argument list
|:language| :lan[guage] set the language (locale)
|:later| :lat[er] go to newer change, redo
|:lbelow| :lbe[low] go to location below current line
|:lbefore| :lbef[ore] go to location before current cursor
|:lbelow| :lbel[ow] go to location below current line
|:lbottom| :lbo[ttom] scroll to the bottom of the location window
|:lbuffer| :lb[uffer] parse locations and jump to first location
|:lcd| :lc[d] change directory locally

View File

@ -74,7 +74,7 @@ processing a quickfix or location list command, it will be aborted.
*:cc*
:cc[!] [nr] Display error [nr]. If [nr] is omitted, the same
error is displayed again. Without [!] this doesn't
:[nr]cc[!] error is displayed again. Without [!] this doesn't
work when jumping to another buffer, the current buffer
has been changed, there is the only window for the
buffer and both 'hidden' and 'autowrite' are off.
@ -83,10 +83,13 @@ processing a quickfix or location list command, it will be aborted.
there is another window for this buffer.
The 'switchbuf' settings are respected when jumping
to a buffer.
When used in the quickfix window the line number can
be used, including "." for the current line and "$"
for the last line.
*:ll*
:ll[!] [nr] Same as ":cc", except the location list for the
current window is used instead of the quickfix list.
:[nr]ll[!] current window is used instead of the quickfix list.
*:cn* *:cne* *:cnext* *E553*
:[count]cn[ext][!] Display the [count] next error in the list that
@ -125,8 +128,8 @@ processing a quickfix or location list command, it will be aborted.
:[count]lab[ove] Same as ":cabove", except the location list for the
current window is used instead of the quickfix list.
*:cbe* *:cbelow*
:[count]cbe[low] Go to the [count] error below the current line in the
*:cbel* *:cbelow*
:[count]cbel[ow] Go to the [count] error below the current line in the
current buffer. If [count] is omitted, then 1 is
used. If there are no errors, then an error message
is displayed. Assumes that the entries in a quickfix
@ -136,8 +139,36 @@ processing a quickfix or location list command, it will be aborted.
exceeds the number of entries below the current line,
then the last error in the file is selected.
*:lbe* *:lbelow*
:[count]lbe[low] Same as ":cbelow", except the location list for the
*:lbel* *:lbelow*
:[count]lbel[ow] Same as ":cbelow", except the location list for the
current window is used instead of the quickfix list.
*:cbe* *:cbefore*
:[count]cbe[fore] Go to the [count] error before the current cursor
position in the current buffer. If [count] is
omitted, then 1 is used. If there are no errors, then
an error message is displayed. Assumes that the
entries in a quickfix list are sorted by their buffer,
line and column numbers. If [count] exceeds the
number of entries before the current position, then
the first error in the file is selected.
*:lbe* *:lbefore*
:[count]lbe[fore] Same as ":cbefore", except the location list for the
current window is used instead of the quickfix list.
*:caf* *:cafter*
:[count]caf[ter] Go to the [count] error after the current cursor
position in the current buffer. If [count] is
omitted, then 1 is used. If there are no errors, then
an error message is displayed. Assumes that the
entries in a quickfix list are sorted by their buffer,
line and column numbers. If [count] exceeds the
number of entries after the current position, then
the last error in the file is selected.
*:laf* *:lafter*
:[count]laf[ter] Same as ":cafter", except the location list for the
current window is used instead of the quickfix list.
*:cnf* *:cnfile*
@ -805,14 +836,19 @@ lists. They set one of the existing error lists as the current one.
the current window instead of the quickfix list.
*:chistory* *:chi*
:chi[story] Show the list of error lists. The current list is
:[count]chi[story] Show the list of error lists. The current list is
marked with ">". The output looks like:
error list 1 of 3; 43 errors ~
> error list 2 of 3; 0 errors ~
error list 3 of 3; 15 errors ~
When [count] is given, then the count'th quickfix
list is made the current list. Example: >
" Make the 4th quickfix list current
:4chistory
<
*:lhistory* *:lhi*
:lhi[story] Show the list of location lists, otherwise like
:[count]lhi[story] Show the list of location lists, otherwise like
`:chistory`.
When adding a new error list, it becomes the current list.

View File

@ -495,6 +495,9 @@ au BufNewFile,BufRead *.com call dist#ft#BindzoneCheck('dcl')
" DOT
au BufNewFile,BufRead *.dot,*.gv setf dot
" Dune
au BufNewFile,BufRead jbuild,dune,dune-project,dune-workspace setf dune
" Dylan - lid files
au BufNewFile,BufRead *.lid setf dylanlid
@ -1121,8 +1124,8 @@ au BufNewFile,BufRead *.nse setf lua
" NSIS
au BufNewFile,BufRead *.nsi,*.nsh setf nsis
" OCAML
au BufNewFile,BufRead *.ml,*.mli,*.mll,*.mly,.ocamlinit setf ocaml
" OCaml
au BufNewFile,BufRead *.ml,*.mli,*.mll,*.mly,.ocamlinit,*.mlt,*.mlp,*.mlip,*.mli.cppo,*.ml.cppo setf ocaml
" Occam
au BufNewFile,BufRead *.occ setf occam
@ -1130,6 +1133,9 @@ au BufNewFile,BufRead *.occ setf occam
" Omnimark
au BufNewFile,BufRead *.xom,*.xin setf omnimark
" OPAM
au BufNewFile,BufRead opam,*.opam,*.opam.template setf opam
" OpenROAD
au BufNewFile,BufRead *.or setf openroad
@ -1549,6 +1555,9 @@ au BufNewFile,BufRead *.scm,*.ss,*.rkt setf scheme
" Screen RC
au BufNewFile,BufRead .screenrc,screenrc setf screen
" Sexplib
au BufNewFile,BufRead *.sexp setf sexplib
" Simula
au BufNewFile,BufRead *.sim setf simula

View File

@ -55,7 +55,7 @@ end
vimcmd_start = 'syn keyword vimCommand contained '
w(vimcmd_start)
local prev_cmd = nil
for _, cmd_desc in ipairs(ex_cmds) do
for _, cmd_desc in ipairs(ex_cmds.cmds) do
if lld.line_length > 850 then
w('\n' .. vimcmd_start)
end

View File

@ -5948,6 +5948,19 @@ int assert_exception(typval_T *argvars)
return 0;
}
static void assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars,
const char *cmd)
FUNC_ATTR_NONNULL_ALL
{
if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) {
char *const tofree = encode_tv2echo(&argvars[2], NULL);
ga_concat(gap, (char_u *)tofree);
xfree(tofree);
} else {
ga_concat(gap, (char_u *)cmd);
}
}
int assert_fails(typval_T *argvars)
FUNC_ATTR_NONNULL_ALL
{
@ -5966,14 +5979,7 @@ int assert_fails(typval_T *argvars)
if (!called_emsg) {
prepare_assert_error(&ga);
ga_concat(&ga, (const char_u *)"command did not fail: ");
if (argvars[1].v_type != VAR_UNKNOWN
&& argvars[2].v_type != VAR_UNKNOWN) {
char *const tofree = encode_tv2echo(&argvars[2], NULL);
ga_concat(&ga, (char_u *)tofree);
xfree(tofree);
} else {
ga_concat(&ga, (const char_u *)cmd);
}
assert_append_cmd_or_arg(&ga, argvars, cmd);
assert_error(&ga);
ga_clear(&ga);
ret = 1;
@ -5986,6 +5992,8 @@ int assert_fails(typval_T *argvars)
prepare_assert_error(&ga);
fill_assert_error(&ga, &argvars[2], NULL, &argvars[1],
&vimvars[VV_ERRMSG].vv_tv, ASSERT_OTHER);
ga_concat(&ga, (char_u *)": ");
assert_append_cmd_or_arg(&ga, argvars, cmd);
assert_error(&ga);
ga_clear(&ga);
ret = 1;

View File

@ -1032,14 +1032,15 @@ void free_prev_shellcmd(void)
* Bangs in the argument are replaced with the previously entered command.
* Remember the argument.
*/
void do_bang(int addr_count, exarg_T *eap, int forceit, int do_in, int do_out)
void do_bang(int addr_count, exarg_T *eap, bool forceit,
bool do_in, bool do_out)
FUNC_ATTR_NONNULL_ALL
{
char_u *arg = eap->arg; /* command */
linenr_T line1 = eap->line1; /* start of range */
linenr_T line2 = eap->line2; /* end of range */
char_u *newcmd = NULL; /* the new command */
int free_newcmd = FALSE; /* need to free() newcmd */
int ins_prevcmd;
char_u *arg = eap->arg; // command
linenr_T line1 = eap->line1; // start of range
linenr_T line2 = eap->line2; // end of range
char_u *newcmd = NULL; // the new command
bool free_newcmd = false; // need to free() newcmd
char_u *t;
char_u *p;
char_u *trailarg;
@ -1064,7 +1065,7 @@ void do_bang(int addr_count, exarg_T *eap, int forceit, int do_in, int do_out)
* Try to find an embedded bang, like in :!<cmd> ! [args]
* (:!! is indicated by the 'forceit' variable)
*/
ins_prevcmd = forceit;
bool ins_prevcmd = forceit;
trailarg = arg;
do {
len = (int)STRLEN(trailarg) + 1;
@ -1101,7 +1102,7 @@ void do_bang(int addr_count, exarg_T *eap, int forceit, int do_in, int do_out)
else {
trailarg = p;
*trailarg++ = NUL;
ins_prevcmd = TRUE;
ins_prevcmd = true;
break;
}
}
@ -1131,7 +1132,7 @@ void do_bang(int addr_count, exarg_T *eap, int forceit, int do_in, int do_out)
STRCPY(newcmd, p_shq);
STRCAT(newcmd, prevcmd);
STRCAT(newcmd, p_shq);
free_newcmd = TRUE;
free_newcmd = true;
}
if (addr_count == 0) { /* :! */
/* echo the command */
@ -1164,15 +1165,15 @@ void do_bang(int addr_count, exarg_T *eap, int forceit, int do_in, int do_out)
// do this.
// Alternatively, if on Unix and redirecting input or output, but not both,
// and the 'shelltemp' option isn't set, use pipes.
// We use input redirection if do_in is TRUE.
// We use output redirection if do_out is TRUE.
// We use input redirection if do_in is true.
// We use output redirection if do_out is true.
static void do_filter(
linenr_T line1,
linenr_T line2,
exarg_T *eap, /* for forced 'ff' and 'fenc' */
char_u *cmd,
int do_in,
int do_out)
bool do_in,
bool do_out)
{
char_u *itmp = NULL;
char_u *otmp = NULL;
@ -1669,10 +1670,17 @@ void ex_update(exarg_T *eap)
*/
void ex_write(exarg_T *eap)
{
if (eap->usefilter) /* input lines to shell command */
do_bang(1, eap, FALSE, TRUE, FALSE);
else
if (eap->cmdidx == CMD_saveas) {
// :saveas does not take a range, uses all lines.
eap->line1 = 1;
eap->line2 = curbuf->b_ml.ml_line_count;
}
if (eap->usefilter) { // input lines to shell command
do_bang(1, eap, false, true, false);
} else {
(void)do_write(eap);
}
}
/*

File diff suppressed because it is too large Load Diff

View File

@ -2113,7 +2113,7 @@ void ex_listdo(exarg_T *eap)
}
} else if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo
|| eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo) {
qf_size = qf_get_size(eap);
qf_size = qf_get_valid_size(eap);
assert(eap->line1 >= 0);
if (qf_size == 0 || (size_t)eap->line1 > qf_size) {
buf = NULL;

View File

@ -51,17 +51,16 @@
#define NOTRLCOM 0x800 // no trailing comment allowed
#define ZEROR 0x1000 // zero line number allowed
#define USECTRLV 0x2000 // do not remove CTRL-V from argument
#define NOTADR 0x4000 // number before command is not an address
#define EDITCMD 0x8000 // allow "+command" argument
#define BUFNAME 0x10000 // accepts buffer name
#define BUFUNL 0x20000 // accepts unlisted buffer too
#define ARGOPT 0x40000 // allow "++opt=val" argument
#define SBOXOK 0x80000 // allowed in the sandbox
#define CMDWIN 0x100000 // allowed in cmdline window; when missing
#define EDITCMD 0x4000 // allow "+command" argument
#define BUFNAME 0x8000 // accepts buffer name
#define BUFUNL 0x10000L // accepts unlisted buffer too
#define ARGOPT 0x20000L // allow "++opt=val" argument
#define SBOXOK 0x40000L // allowed in the sandbox
#define CMDWIN 0x80000L // allowed in cmdline window; when missing
// disallows editing another buffer when
// curbuf_lock is set
#define MODIFY 0x200000 // forbidden in non-'modifiable' buffer
#define EXFLAGS 0x400000 // allow flags after count in argument
#define MODIFY 0x100000L // forbidden in non-'modifiable' buffer
#define EXFLAGS 0x200000L // allow flags after count in argument
#define FILES (XFILE | EXTRA) // multiple extra files allowed
#define WORD1 (EXTRA | NOSPC) // one extra word allowed
#define FILE1 (FILES | NOSPC) // 1 file allowed, defaults to current file
@ -75,8 +74,10 @@ typedef enum {
ADDR_BUFFERS, // buffer number
ADDR_TABS, // tab page number
ADDR_TABS_RELATIVE, // Tab page that only relative
ADDR_QUICKFIX_VALID, // quickfix list valid entry number
ADDR_QUICKFIX, // quickfix list entry number
ADDR_OTHER, // something else
ADDR_UNSIGNED, // positive count or zero, defaults to 1
ADDR_OTHER, // something else, use line number for '$', '%', etc.
ADDR_NONE // no range used
} cmd_addr_T;
@ -153,7 +154,7 @@ struct exarg {
int addr_count; ///< the number of addresses given
linenr_T line1; ///< the first line number
linenr_T line2; ///< the second line number or count
int addr_type; ///< type of the count/range
cmd_addr_T addr_type; ///< type of the count/range
int flags; ///< extra flags after count: EXFLAG_
char_u *do_ecmd_cmd; ///< +command arg to be used in edited file
linenr_T do_ecmd_lnum; ///< the line number in an edited file

View File

@ -1086,7 +1086,10 @@ static int compute_buffer_local_count(int addr_type, int lnum, int offset)
return buf->b_fnum;
}
static int current_win_nr(win_T *win)
// Return the window number of "win".
// When "win" is NULL return the number of windows.
static int current_win_nr(const win_T *win)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
int nr = 0;
@ -1163,7 +1166,7 @@ static void get_wincmd_addr_type(char_u *arg, exarg_T *eap)
case 'd':
case Ctrl_D:
// window size or any count
eap->addr_type = ADDR_LINES; // -V1037
eap->addr_type = ADDR_OTHER; // -V1037
break;
case Ctrl_HAT:
@ -1199,7 +1202,7 @@ static void get_wincmd_addr_type(char_u *arg, exarg_T *eap)
case '=':
case CAR:
// no count
eap->addr_type = 0;
eap->addr_type = ADDR_NONE;
break;
}
}
@ -1380,6 +1383,10 @@ static char_u * do_one_cmd(char_u **cmdlinep,
if (ea.cmdidx == CMD_wincmd && p != NULL) {
get_wincmd_addr_type(skipwhite(p), &ea);
}
// :.cc in quickfix window uses line number
if ((ea.cmdidx == CMD_cc || ea.cmdidx == CMD_ll) && bt_quickfix(curbuf)) {
ea.addr_type = ADDR_OTHER;
}
}
ea.cmd = cmd;
@ -1490,9 +1497,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.forceit = false;
}
/*
* 6. Parse arguments.
*/
// 6. Parse arguments. Then check for errors.
if (!IS_USER_CMDIDX(ea.cmdidx)) {
ea.argt = cmdnames[(int)ea.cmdidx].cmd_argt;
}
@ -1547,12 +1552,10 @@ static char_u * do_one_cmd(char_u **cmdlinep,
* Don't complain about the range if it is not used
* (could happen if line_count is accidentally set to 0).
*/
if (!ea.skip && !ni) {
/*
* If the range is backwards, ask for confirmation and, if given, swap
* ea.line1 & ea.line2 so it's forwards again.
* When global command is busy, don't ask, will fail below.
*/
if (!ea.skip && !ni && (ea.argt & RANGE)) {
// If the range is backwards, ask for confirmation and, if given, swap
// ea.line1 & ea.line2 so it's forwards again.
// When global command is busy, don't ask, will fail below.
if (!global_busy && ea.line1 > ea.line2) {
if (msg_silent == 0) {
if ((flags & DOCMD_VERBOSE) || exmode_active) {
@ -1571,8 +1574,10 @@ static char_u * do_one_cmd(char_u **cmdlinep,
goto doend;
}
if ((ea.argt & NOTADR) && ea.addr_count == 0) /* default is 1, not cursor */
if ((ea.addr_type == ADDR_OTHER) && ea.addr_count == 0) {
// default is 1, not cursor
ea.line2 = 1;
}
correct_range(&ea);
@ -1694,6 +1699,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.line1 = 1;
switch (ea.addr_type) {
case ADDR_LINES:
case ADDR_OTHER:
ea.line2 = curbuf->b_ml.ml_line_count;
break;
case ADDR_LOADED_BUFFERS:
@ -1728,14 +1734,17 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.line2 = ARGCOUNT;
}
break;
case ADDR_QUICKFIX:
ea.line2 = qf_get_size(&ea);
case ADDR_QUICKFIX_VALID:
ea.line2 = qf_get_valid_size(&ea);
if (ea.line2 == 0) {
ea.line2 = 1;
}
break;
case ADDR_NONE:
IEMSG(_("INTERNAL: Cannot use DFLALL with ADDR_NONE"));
case ADDR_UNSIGNED:
case ADDR_QUICKFIX:
IEMSG(_("INTERNAL: Cannot use DFLALL "
"with ADDR_NONE, ADDR_UNSIGNED or ADDR_QUICKFIX"));
break;
}
}
@ -1771,7 +1780,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
errormsg = (char_u *)_(e_zerocount);
goto doend;
}
if (ea.argt & NOTADR) { /* e.g. :buffer 2, :sleep 3 */
if (ea.addr_type != ADDR_LINES) { // e.g. :buffer 2, :sleep 3
ea.line2 = n;
if (ea.addr_count == 0)
ea.addr_count = 1;
@ -1780,8 +1789,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.line2 += n - 1;
++ea.addr_count;
// Be vi compatible: no error message for out of range.
if (ea.addr_type == ADDR_LINES
&& ea.line2 > curbuf->b_ml.ml_line_count) {
if (ea.line2 > curbuf->b_ml.ml_line_count) {
ea.line2 = curbuf->b_ml.ml_line_count;
}
}
@ -2325,6 +2333,7 @@ int parse_cmd_address(exarg_T *eap, char_u **errormsg, bool silent)
eap->line1 = eap->line2;
switch (eap->addr_type) {
case ADDR_LINES:
case ADDR_OTHER:
// default is current line number
eap->line2 = curwin->w_cursor.lnum;
break;
@ -2345,9 +2354,13 @@ int parse_cmd_address(exarg_T *eap, char_u **errormsg, bool silent)
eap->line2 = CURRENT_TAB_NR;
break;
case ADDR_TABS_RELATIVE:
case ADDR_UNSIGNED:
eap->line2 = 1;
break;
case ADDR_QUICKFIX:
eap->line2 = qf_get_cur_idx(eap);
break;
case ADDR_QUICKFIX_VALID:
eap->line2 = qf_get_cur_valid_idx(eap);
break;
case ADDR_NONE:
@ -2365,6 +2378,7 @@ int parse_cmd_address(exarg_T *eap, char_u **errormsg, bool silent)
eap->cmd++;
switch (eap->addr_type) {
case ADDR_LINES:
case ADDR_OTHER:
eap->line1 = 1;
eap->line2 = curbuf->b_ml.ml_line_count;
break;
@ -2400,7 +2414,8 @@ int parse_cmd_address(exarg_T *eap, char_u **errormsg, bool silent)
}
break;
case ADDR_TABS_RELATIVE:
case ADDR_OTHER:
case ADDR_UNSIGNED:
case ADDR_QUICKFIX:
*errormsg = (char_u *)_(e_invrange);
return FAIL;
case ADDR_ARGUMENTS:
@ -2411,9 +2426,9 @@ int parse_cmd_address(exarg_T *eap, char_u **errormsg, bool silent)
eap->line2 = ARGCOUNT;
}
break;
case ADDR_QUICKFIX:
case ADDR_QUICKFIX_VALID:
eap->line1 = 1;
eap->line2 = qf_get_size(eap);
eap->line2 = qf_get_valid_size(eap);
if (eap->line2 == 0) {
eap->line2 = 1;
}
@ -2522,14 +2537,13 @@ static void append_command(char_u *cmd)
*d = NUL;
}
/*
* Find an Ex command by its name, either built-in or user.
* Start of the name can be found at eap->cmd.
* Returns pointer to char after the command name.
* "full" is set to TRUE if the whole command name matched.
* Returns NULL for an ambiguous user command.
*/
// Find an Ex command by its name, either built-in or user.
// Start of the name can be found at eap->cmd.
// Sets eap->cmdidx and returns a pointer to char after the command name.
// "full" is set to TRUE if the whole command name matched.
// Returns NULL for an ambiguous user command.
static char_u *find_command(exarg_T *eap, int *full)
FUNC_ATTR_NONNULL_ARG(1)
{
int len;
char_u *p;
@ -3716,14 +3730,13 @@ char_u *skip_range(
// Return MAXLNUM when no Ex address was found.
static linenr_T get_address(exarg_T *eap,
char_u **ptr,
cmd_addr_T addr_type_arg,
cmd_addr_T addr_type,
int skip, // only skip the address, don't use it
bool silent, // no errors or side effects
int to_other_file, // flag: may jump to other file
int address_count) // 1 for first, >1 after comma
FUNC_ATTR_NONNULL_ALL
{
const int addr_type = addr_type_arg;
int c;
int i;
long n;
@ -3741,6 +3754,7 @@ static linenr_T get_address(exarg_T *eap,
++cmd;
switch (addr_type) {
case ADDR_LINES:
case ADDR_OTHER:
lnum = curwin->w_cursor.lnum;
break;
case ADDR_WINDOWS:
@ -3758,11 +3772,15 @@ static linenr_T get_address(exarg_T *eap,
break;
case ADDR_TABS_RELATIVE:
case ADDR_NONE:
case ADDR_UNSIGNED:
EMSG(_(e_invrange));
cmd = NULL;
goto error;
break;
case ADDR_QUICKFIX:
lnum = qf_get_cur_idx(eap);
break;
case ADDR_QUICKFIX_VALID:
lnum = qf_get_cur_valid_idx(eap);
break;
}
@ -3772,6 +3790,7 @@ static linenr_T get_address(exarg_T *eap,
++cmd;
switch (addr_type) {
case ADDR_LINES:
case ADDR_OTHER:
lnum = curbuf->b_ml.ml_line_count;
break;
case ADDR_WINDOWS:
@ -3798,6 +3817,7 @@ static linenr_T get_address(exarg_T *eap,
break;
case ADDR_TABS_RELATIVE:
case ADDR_NONE:
case ADDR_UNSIGNED:
EMSG(_(e_invrange));
cmd = NULL;
goto error;
@ -3808,6 +3828,12 @@ static linenr_T get_address(exarg_T *eap,
lnum = 1;
}
break;
case ADDR_QUICKFIX_VALID:
lnum = qf_get_valid_size(eap);
if (lnum == 0) {
lnum = 1;
}
break;
}
break;
@ -3939,7 +3965,9 @@ static linenr_T get_address(exarg_T *eap,
if (lnum == MAXLNUM) {
switch (addr_type) {
case ADDR_LINES:
lnum = curwin->w_cursor.lnum; /* "+1" is same as ".+1" */
case ADDR_OTHER:
// "+1" is same as ".+1"
lnum = curwin->w_cursor.lnum;
break;
case ADDR_WINDOWS:
lnum = CURRENT_WIN_NR;
@ -3958,9 +3986,14 @@ static linenr_T get_address(exarg_T *eap,
lnum = 1;
break;
case ADDR_QUICKFIX:
lnum = qf_get_cur_idx(eap);
break;
case ADDR_QUICKFIX_VALID:
lnum = qf_get_cur_valid_idx(eap);
break;
case ADDR_NONE:
case ADDR_UNSIGNED:
lnum = 0;
break;
}
}
@ -4052,11 +4085,10 @@ static char_u *invalid_range(exarg_T *eap)
}
if (eap->argt & RANGE) {
switch(eap->addr_type) {
switch (eap->addr_type) {
case ADDR_LINES:
if (!(eap->argt & NOTADR)
&& eap->line2 > curbuf->b_ml.ml_line_count
+ (eap->cmdidx == CMD_diffget)) {
if (eap->line2 > (curbuf->b_ml.ml_line_count
+ (eap->cmdidx == CMD_diffget))) {
return (char_u *)_(e_invrange);
}
break;
@ -4105,11 +4137,24 @@ static char_u *invalid_range(exarg_T *eap)
}
break;
case ADDR_TABS_RELATIVE:
// Do nothing
case ADDR_OTHER:
// Any range is OK.
break;
case ADDR_QUICKFIX:
assert(eap->line2 >= 0);
if (eap->line2 != 1 && (size_t)eap->line2 > qf_get_size(eap)) {
// No error for value that is too big, will use the last entry.
if (eap->line2 <= 0) {
return (char_u *)_(e_invrange);
}
break;
case ADDR_QUICKFIX_VALID:
if ((eap->line2 != 1 && (size_t)eap->line2 > qf_get_valid_size(eap))
|| eap->line2 < 0) {
return (char_u *)_(e_invrange);
}
break;
case ADDR_UNSIGNED:
if (eap->line2 < 0) {
return (char_u *)_(e_invrange);
}
break;
@ -5376,7 +5421,7 @@ two_count:
}
*def = getdigits_long(&p, true, 0);
*argt |= (ZEROR | NOTADR);
*argt |= ZEROR;
if (p != val + vallen || vallen == 0) {
invalid_count:
@ -5384,8 +5429,16 @@ invalid_count:
return FAIL;
}
}
// default for -range is using buffer lines
if (*addr_type_arg == ADDR_NONE) {
*addr_type_arg = ADDR_LINES;
}
} else if (STRNICMP(attr, "count", attrlen) == 0) {
*argt |= (COUNT | ZEROR | RANGE | NOTADR);
*argt |= (COUNT | ZEROR | RANGE);
// default for -count is using any number
if (*addr_type_arg == ADDR_NONE) {
*addr_type_arg = ADDR_OTHER;
}
if (val != NULL) {
p = val;
@ -5416,11 +5469,11 @@ invalid_count:
EMSG(_("E179: argument required for -addr"));
return FAIL;
}
if (parse_addr_type_arg(val, (int)vallen, argt, addr_type_arg) == FAIL) {
if (parse_addr_type_arg(val, (int)vallen, addr_type_arg) == FAIL) {
return FAIL;
}
if (*addr_type_arg != ADDR_LINES) {
*argt |= (ZEROR | NOTADR);
*argt |= ZEROR;
}
} else {
char_u ch = attr[len];
@ -5447,7 +5500,7 @@ static void ex_command(exarg_T *eap)
int flags = 0;
int compl = EXPAND_NOTHING;
char_u *compl_arg = NULL;
cmd_addr_T addr_type_arg = ADDR_LINES;
cmd_addr_T addr_type_arg = ADDR_NONE;
int has_attr = (eap->arg[0] == '-');
int name_len;
@ -6105,8 +6158,7 @@ char_u *get_user_cmd_complete(expand_T *xp, int idx)
/*
* Parse address type argument
*/
int parse_addr_type_arg(char_u *value, int vallen, uint32_t *argt,
cmd_addr_T *addr_type_arg)
int parse_addr_type_arg(char_u *value, int vallen, cmd_addr_T *addr_type_arg)
FUNC_ATTR_NONNULL_ALL
{
int i, a, b;
@ -6129,9 +6181,6 @@ int parse_addr_type_arg(char_u *value, int vallen, uint32_t *argt,
return FAIL;
}
if (*addr_type_arg != ADDR_LINES)
*argt |= NOTADR;
return OK;
}
@ -7423,11 +7472,12 @@ static void ex_read(exarg_T *eap)
int empty = (curbuf->b_ml.ml_flags & ML_EMPTY);
linenr_T lnum;
if (eap->usefilter) /* :r!cmd */
do_bang(1, eap, FALSE, FALSE, TRUE);
else {
if (u_save(eap->line2, (linenr_T)(eap->line2 + 1)) == FAIL)
if (eap->usefilter) { // :r!cmd
do_bang(1, eap, false, false, true);
} else {
if (u_save(eap->line2, (linenr_T)(eap->line2 + 1)) == FAIL) {
return;
}
if (*eap->arg == NUL) {
if (check_fname() == FAIL) /* check for no file name */
@ -7897,7 +7947,7 @@ static void ex_at(exarg_T *eap)
*/
static void ex_bang(exarg_T *eap)
{
do_bang(eap->addr_count, eap, eap->forceit, TRUE, TRUE);
do_bang(eap->addr_count, eap, eap->forceit, true, true);
}
/*

View File

@ -22,7 +22,10 @@ local defsfname = autodir .. '/ex_cmds_defs.generated.h'
local enumfile = io.open(enumfname, 'w')
local defsfile = io.open(defsfname, 'w')
local defs = require('ex_cmds')
local bit = require 'bit'
local ex_cmds = require('ex_cmds')
local defs = ex_cmds.cmds
local flags = ex_cmds.flags
local byte_a = string.byte('a')
local byte_z = string.byte('z')
@ -51,6 +54,17 @@ static CommandDefinition cmdnames[%u] = {
]], #defs, #defs))
local cmds, cmdidxs1, cmdidxs2 = {}, {}, {}
for _, cmd in ipairs(defs) do
if bit.band(cmd.flags, flags.RANGE) == flags.RANGE then
assert(cmd.addr_type ~= 'ADDR_NONE',
string.format('ex_cmds.lua:%s: Using RANGE with ADDR_NONE\n', cmd.command))
else
assert(cmd.addr_type == 'ADDR_NONE',
string.format('ex_cmds.lua:%s: Missing ADDR_NONE\n', cmd.command))
end
if bit.band(cmd.flags, flags.DFLALL) == flags.DFLALL then
assert(cmd.addr_type ~= 'ADDR_OTHER' and cmd.addr_type ~= 'ADDR_NONE',
string.format('ex_cmds.lua:%s: Missing misplaced DFLALL\n', cmd.command))
end
local enumname = cmd.enum or ('CMD_' .. cmd.command)
local byte_cmd = cmd.command:sub(1, 1):byte()
if byte_a <= byte_cmd and byte_cmd <= byte_z then

View File

@ -3300,6 +3300,24 @@ void qf_history(exarg_T *eap)
qf_info_T *qi = qf_cmd_get_stack(eap, false);
int i;
if (eap->addr_count > 0) {
if (qi == NULL) {
EMSG(_(e_loclist));
return;
}
// Jump to the specified quickfix list
if (eap->line2 > 0 && eap->line2 <= qi->qf_listcount) {
qi->qf_curlist = (int)(eap->line2 - 1);
qf_msg(qi, qi->qf_curlist, "");
qf_update_buffer(qi, NULL);
} else {
EMSG(_(e_invrange));
}
return;
}
if (qf_stack_empty(qi)) {
MSG(_("No entries"));
} else {
@ -3622,7 +3640,7 @@ static int qf_open_new_cwindow(qf_info_T *qi, int height)
// Set the options for the quickfix buffer/window (if not already done)
// Do this even if the quickfix buffer was already present, as an autocmd
// might have previously deleted (:bdelete) the quickfix buffer.
if (curbuf->b_p_bt[0] != 'q') {
if (!bt_quickfix(curbuf)) {
qf_set_cwindow_options();
}
@ -4269,9 +4287,20 @@ static char_u *get_mef_name(void)
return name;
}
/// Returns the number of valid entries in the current quickfix/location list.
/// Returns the number of entries in the current quickfix/location list.
size_t qf_get_size(exarg_T *eap)
FUNC_ATTR_NONNULL_ALL
{
qf_info_T *qi;
if ((qi = qf_cmd_get_stack(eap, false)) == NULL) {
return 0;
}
return (size_t)qf_get_curlist(qi)->qf_count;
}
/// Returns the number of valid entries in the current quickfix/location list.
size_t qf_get_valid_size(exarg_T *eap)
{
qf_info_T *qi;
qf_list_T *qfl;
@ -4562,74 +4591,150 @@ static qfline_T * qf_find_last_entry_on_line(qfline_T *entry, int *errornr)
return entry;
}
/// Find the first quickfix entry below line 'lnum' in buffer 'bnr'.
// Returns true if the specified quickfix entry is
// after the given line (linewise is true)
// or after the line and column.
static bool qf_entry_after_pos(const qfline_T *qfp, const pos_T *pos,
bool linewise)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (linewise) {
return qfp->qf_lnum > pos->lnum;
}
return qfp->qf_lnum > pos->lnum
|| (qfp->qf_lnum == pos->lnum && qfp->qf_col > pos->col);
}
// Returns true if the specified quickfix entry is
// before the given line (linewise is true)
// or before the line and column.
static bool qf_entry_before_pos(const qfline_T *qfp, const pos_T *pos,
bool linewise)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (linewise) {
return qfp->qf_lnum < pos->lnum;
}
return qfp->qf_lnum < pos->lnum
|| (qfp->qf_lnum == pos->lnum && qfp->qf_col < pos->col);
}
// Returns true if the specified quickfix entry is
// on or after the given line (linewise is true)
// or on or after the line and column.
static bool qf_entry_on_or_after_pos(const qfline_T *qfp, const pos_T *pos,
bool linewise)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (linewise) {
return qfp->qf_lnum >= pos->lnum;
}
return qfp->qf_lnum > pos->lnum
|| (qfp->qf_lnum == pos->lnum && qfp->qf_col >= pos->col);
}
// Returns true if the specified quickfix entry is
// on or before the given line (linewise is true)
// or on or before the line and column.
static bool qf_entry_on_or_before_pos(const qfline_T *qfp, const pos_T *pos,
bool linewise)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (linewise) {
return qfp->qf_lnum <= pos->lnum;
}
return qfp->qf_lnum < pos->lnum
|| (qfp->qf_lnum == pos->lnum && qfp->qf_col <= pos->col);
}
/// Find the first quickfix entry after position 'pos' in buffer 'bnr'.
/// If 'linewise' is true, returns the entry after the specified line and treats
/// multiple entries on a single line as one. Otherwise returns the entry after
/// the specified line and column.
/// 'qfp' points to the very first entry in the buffer and 'errornr' is the
/// index of the very first entry in the quickfix list.
/// Returns NULL if an entry is not found after 'lnum'.
static qfline_T *qf_find_entry_on_next_line(int bnr,
linenr_T lnum,
/// Returns NULL if an entry is not found after 'pos'.
static qfline_T *qf_find_entry_after_pos(
int bnr,
const pos_T *pos,
bool linewise,
qfline_T *qfp,
int *errornr)
int *errornr
)
FUNC_ATTR_NONNULL_ALL
{
if (qfp->qf_lnum > lnum) {
// First entry is after line 'lnum'
if (qf_entry_after_pos(qfp, pos, linewise)) {
// First entry is after postion 'pos'
return qfp;
}
// Find the entry just before or at the line 'lnum'
// Find the entry just before or at the position 'pos'
while (qfp->qf_next != NULL
&& qfp->qf_next->qf_fnum == bnr
&& qfp->qf_next->qf_lnum <= lnum) {
&& qf_entry_on_or_before_pos(qfp->qf_next, pos, linewise)) {
qfp = qfp->qf_next;
(*errornr)++;
}
if (qfp->qf_next == NULL || qfp->qf_next->qf_fnum != bnr) {
// No entries found after 'lnum'
// No entries found after position 'pos'
return NULL;
}
// Use the entry just after line 'lnum'
// Use the entry just after position 'pos'
qfp = qfp->qf_next;
(*errornr)++;
return qfp;
}
/// Find the first quickfix entry before line 'lnum' in buffer 'bnr'.
/// Find the first quickfix entry before position 'pos' in buffer 'bnr'.
/// If 'linewise' is true, returns the entry before the specified line and
/// treats multiple entries on a single line as one. Otherwise returns the entry
/// before the specified line and column.
/// 'qfp' points to the very first entry in the buffer and 'errornr' is the
/// index of the very first entry in the quickfix list.
/// Returns NULL if an entry is not found before 'lnum'.
static qfline_T *qf_find_entry_on_prev_line(int bnr,
linenr_T lnum,
/// Returns NULL if an entry is not found before 'pos'.
static qfline_T *qf_find_entry_before_pos(
int bnr,
const pos_T *pos,
bool linewise,
qfline_T *qfp,
int *errornr)
int *errornr
)
FUNC_ATTR_NONNULL_ALL
{
// Find the entry just before the line 'lnum'
// Find the entry just before the position 'pos'
while (qfp->qf_next != NULL
&& qfp->qf_next->qf_fnum == bnr
&& qfp->qf_next->qf_lnum < lnum) {
&& qf_entry_before_pos(qfp->qf_next, pos, linewise)) {
qfp = qfp->qf_next;
(*errornr)++;
}
if (qfp->qf_lnum >= lnum) { // entry is after 'lnum'
if (qf_entry_on_or_after_pos(qfp, pos, linewise)) {
return NULL;
}
if (linewise) {
// If multiple entries are on the same line, then use the first entry
qfp = qf_find_first_entry_on_line(qfp, errornr);
}
return qfp;
}
/// Find a quickfix entry in 'qfl' closest to line 'lnum' in buffer 'bnr' in
/// Find a quickfix entry in 'qfl' closest to position 'pos' in buffer 'bnr' in
/// the direction 'dir'.
static qfline_T *qf_find_closest_entry(qf_list_T *qfl,
static qfline_T *qf_find_closest_entry(
qf_list_T *qfl,
int bnr,
linenr_T lnum,
int dir,
int *errornr)
const pos_T *pos,
Direction dir,
bool linewise,
int *errornr
)
FUNC_ATTR_NONNULL_ALL
{
qfline_T *qfp;
@ -4642,33 +4747,38 @@ static qfline_T *qf_find_closest_entry(qf_list_T *qfl,
}
if (dir == FORWARD) {
qfp = qf_find_entry_on_next_line(bnr, lnum, qfp, errornr);
qfp = qf_find_entry_after_pos(bnr, pos, linewise, qfp, errornr);
} else {
qfp = qf_find_entry_on_prev_line(bnr, lnum, qfp, errornr);
qfp = qf_find_entry_before_pos(bnr, pos, linewise, qfp, errornr);
}
return qfp;
}
/// Get the nth quickfix entry below the specified entry treating multiple
/// entries on a single line as one. Searches forward in the list.
static void qf_get_nth_below_entry(qfline_T *entry,
int *errornr,
linenr_T n)
/// Get the nth quickfix entry below the specified entry. Searches forward in
/// the list. If linewise is true, then treat multiple entries on a single line
/// as one.
static void qf_get_nth_below_entry(qfline_T *entry, linenr_T n,
bool linewise, int *errornr)
FUNC_ATTR_NONNULL_ALL
{
while (n-- > 0 && !got_int) {
// qfline_T *first_entry = entry;
int first_errornr = *errornr;
if (linewise) {
// Treat all the entries on the same line in this file as one
entry = qf_find_last_entry_on_line(entry, errornr);
}
if (entry->qf_next == NULL
|| entry->qf_next->qf_fnum != entry->qf_fnum) {
if (linewise) {
// If multiple entries are on the same line, then use the first
// entry
// entry = first_entry;
*errornr = first_errornr;
}
break;
}
@ -4677,11 +4787,12 @@ static void qf_get_nth_below_entry(qfline_T *entry,
}
}
/// Get the nth quickfix entry above the specified entry treating multiple
/// entries on a single line as one. Searches backwards in the list.
static void qf_get_nth_above_entry(qfline_T *entry,
int *errornr,
linenr_T n)
/// Get the nth quickfix entry above the specified entry. Searches backwards in
/// the list. If linewise is TRUE, then treat multiple entries on a single line
/// as one.
static void qf_get_nth_above_entry(qfline_T *entry, linenr_T n,
bool linewise, int *errornr)
FUNC_ATTR_NONNULL_ALL
{
while (n-- > 0 && !got_int) {
if (entry->qf_prev == NULL
@ -4692,25 +4803,30 @@ static void qf_get_nth_above_entry(qfline_T *entry,
entry = entry->qf_prev;
(*errornr)--;
// If multiple entries are on the same line, then use the first entry
if (linewise) {
entry = qf_find_first_entry_on_line(entry, errornr);
}
}
}
/// Find the n'th quickfix entry adjacent to line 'lnum' in buffer 'bnr' in the
/// specified direction.
/// Returns the error number in the quickfix list or 0 if an entry is not found.
static int qf_find_nth_adj_entry(qf_list_T *qfl,
/// Find the n'th quickfix entry adjacent to position 'pos' in buffer 'bnr' in
/// the specified direction. Returns the error number in the quickfix list or 0
/// if an entry is not found.
static int qf_find_nth_adj_entry(
qf_list_T *qfl,
int bnr,
linenr_T lnum,
pos_T *pos,
linenr_T n,
int dir)
Direction dir,
bool linewise
)
FUNC_ATTR_NONNULL_ALL
{
qfline_T *adj_entry;
int errornr;
// Find an entry closest to the specified line
adj_entry = qf_find_closest_entry(qfl, bnr, lnum, dir, &errornr);
// Find an entry closest to the specified position
qfline_T *const adj_entry = qf_find_closest_entry(qfl, bnr, pos, dir,
linewise, &errornr);
if (adj_entry == NULL) {
return 0;
}
@ -4718,24 +4834,25 @@ static int qf_find_nth_adj_entry(qf_list_T *qfl,
if (--n > 0) {
// Go to the n'th entry in the current buffer
if (dir == FORWARD) {
qf_get_nth_below_entry(adj_entry, &errornr, n);
qf_get_nth_below_entry(adj_entry, n, linewise, &errornr);
} else {
qf_get_nth_above_entry(adj_entry, &errornr, n);
qf_get_nth_above_entry(adj_entry, n, linewise, &errornr);
}
}
return errornr;
}
/// Jump to a quickfix entry in the current file nearest to the current line.
/// ":cabove", ":cbelow", ":labove" and ":lbelow" commands
/// Jump to a quickfix entry in the current file nearest to the current line or
/// current line/col.
/// ":cabove", ":cbelow", ":labove", ":lbelow", ":cafter", ":cbefore",
/// ":lafter" and ":lbefore" commands
void ex_cbelow(exarg_T *eap)
{
qf_info_T *qi;
qf_list_T *qfl;
int dir;
int buf_has_flag;
int errornr = 0;
if (eap->addr_count > 0 && eap->line2 <= 0) {
EMSG(_(e_invrange));
@ -4743,7 +4860,8 @@ void ex_cbelow(exarg_T *eap)
}
// Check whether the current buffer has any quickfix entries
if (eap->cmdidx == CMD_cabove || eap->cmdidx == CMD_cbelow) {
if (eap->cmdidx == CMD_cabove || eap->cmdidx == CMD_cbelow
|| eap->cmdidx == CMD_cbefore || eap->cmdidx == CMD_cafter) {
buf_has_flag = BUF_HAS_QF_ENTRY;
} else {
buf_has_flag = BUF_HAS_LL_ENTRY;
@ -4764,14 +4882,30 @@ void ex_cbelow(exarg_T *eap)
return;
}
if (eap->cmdidx == CMD_cbelow || eap->cmdidx == CMD_lbelow) {
if (eap->cmdidx == CMD_cbelow
|| eap->cmdidx == CMD_lbelow
|| eap->cmdidx == CMD_cafter
|| eap->cmdidx == CMD_lafter) {
// Forward motion commands
dir = FORWARD;
} else {
dir = BACKWARD;
}
errornr = qf_find_nth_adj_entry(qfl, curbuf->b_fnum, curwin->w_cursor.lnum,
eap->addr_count > 0 ? eap->line2 : 0, dir);
pos_T pos = curwin->w_cursor;
// A quickfix entry column number is 1 based whereas cursor column
// number is 0 based. Adjust the column number.
pos.col++;
const int errornr = qf_find_nth_adj_entry(
qfl,
curbuf->b_fnum,
&pos,
eap->addr_count > 0 ? eap->line2 : 0,
dir,
eap->cmdidx == CMD_cbelow
|| eap->cmdidx == CMD_lbelow
|| eap->cmdidx == CMD_cabove
|| eap->cmdidx == CMD_labove);
if (errornr > 0) {
qf_jump(qi, 0, errornr, false);
@ -6818,8 +6952,9 @@ void ex_helpgrep(exarg_T *eap)
if (au_name != NULL) {
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
curbuf->b_fname, true, curbuf);
if (!new_qi && IS_LL_STACK(qi) && qf_find_buf(qi) == NULL) {
// autocommands made "qi" invalid
// When adding a location list to an existing location list stack,
// if the autocmd made the stack invalid, then just return.
if (!new_qi && IS_LL_STACK(qi) && qf_find_win_with_loclist(qi) == NULL) {
decr_quickfix_busy();
return;
}

View File

@ -150,6 +150,7 @@ let s:filename_checks = {
\ 'dsl': ['file.dsl'],
\ 'dtd': ['file.dtd'],
\ 'dts': ['file.dts', 'file.dtsi'],
\ 'dune': ['jbuild', 'dune', 'dune-project', 'dune-workspace'],
\ 'dylan': ['file.dylan'],
\ 'dylanintr': ['file.intr'],
\ 'dylanlid': ['file.lid'],
@ -322,9 +323,10 @@ let s:filename_checks = {
\ 'nroff': ['file.tr', 'file.nr', 'file.roff', 'file.tmac', 'file.mom'],
\ 'nsis': ['file.nsi', 'file.nsh'],
\ 'obj': ['file.obj'],
\ 'ocaml': ['file.ml', 'file.mli', 'file.mll', 'file.mly', '.ocamlinit'],
\ 'ocaml': ['file.ml', 'file.mli', 'file.mll', 'file.mly', '.ocamlinit', 'file.mlt', 'file.mlp', 'file.mlip', 'file.mli.cppo', 'file.ml.cppo'],
\ 'occam': ['file.occ'],
\ 'omnimark': ['file.xom', 'file.xin'],
\ 'opam': ['opam', 'file.opam', 'file.opam.template'],
\ 'openroad': ['file.or'],
\ 'ora': ['file.ora'],
\ 'pamconf': ['/etc/pam.conf'],
@ -398,6 +400,7 @@ let s:filename_checks = {
\ 'scheme': ['file.scm', 'file.ss', 'file.rkt'],
\ 'scilab': ['file.sci', 'file.sce'],
\ 'screen': ['.screenrc', 'screenrc'],
\ 'sexplib': ['file.sexp'],
\ 'scss': ['file.scss'],
\ 'sd': ['file.sd'],
\ 'sdc': ['file.sdc'],

View File

@ -1,5 +1,7 @@
" Test :hardcopy
source check.vim
func Test_printoptions()
edit test_hardcopy.vim
syn on
@ -8,8 +10,10 @@ func Test_printoptions()
\ 'left:2in,top:30pt,right:16mm,bottom:3pc',
\ 'header:3,syntax:y,number:y,wrap:n',
\ 'header:3,syntax:n,number:y,wrap:y',
\ 'header:0,syntax:a,number:y,wrap:y',
\ 'duplex:short,collate:n,jobsplit:y,portrait:n',
\ 'duplex:long,collate:y,jobsplit:n,portrait:y',
\ 'duplex:off,collate:y,jobsplit:y,portrait:y',
\ 'paper:10x14',
\ 'paper:A3',
\ 'paper:A4',
@ -28,7 +32,7 @@ func Test_printoptions()
\ '']
exe 'set printoptions=' .. opt
if has('postscript')
hardcopy > Xhardcopy_printoptions
1,50hardcopy > Xhardcopy_printoptions
let lines = readfile('Xhardcopy_printoptions')
call assert_true(len(lines) > 20, opt)
call assert_true(lines[0] =~ 'PS-Adobe', opt)
@ -44,8 +48,8 @@ func Test_printoptions()
endfunc
func Test_printmbfont()
" Print a small help page which contains tabs to cover code that expands tabs to spaces.
help help
" Print a help page which contains tabs, underlines (etc) to recover more code.
help syntax.txt
syn on
for opt in [':WadaMin-Regular,b:WadaMin-Bold,i:WadaMin-Italic,o:WadaMin-Bold-Italic,c:yes,a:no',
@ -63,10 +67,39 @@ func Test_printmbfont()
bwipe
endfunc
func Test_printmbcharset()
CheckFeature postscript
" digraph.txt has plenty of non-latin1 characters.
help digraph.txt
set printmbcharset=ISO10646 printencoding=utf-8
for courier in ['yes', 'no']
for ascii in ['yes', 'no']
exe 'set printmbfont=r:WadaMin-Regular,b:WadaMin-Bold,i:WadaMin-Italic,o:WadaMin-BoldItalic'
\ .. ',c:' .. courier .. ',a:' .. ascii
hardcopy > Xhardcopy_printmbcharset
let lines = readfile('Xhardcopy_printmbcharset')
call assert_true(len(lines) > 20)
call assert_true(lines[0] =~ 'PS-Adobe')
endfor
endfor
set printmbcharset=does-not-exist printencoding=utf-8 printmbfont=r:WadaMin-Regular
call assert_fails('hardcopy > Xhardcopy_printmbcharset', 'E456:')
set printmbcharset=GB_2312-80 printencoding=utf-8 printmbfont=r:WadaMin-Regular
call assert_fails('hardcopy > Xhardcopy_printmbcharset', 'E673:')
set printmbcharset=ISO10646 printencoding=utf-8 printmbfont=
call assert_fails('hardcopy > Xhardcopy_printmbcharset', 'E675:')
call delete('Xhardcopy_printmbcharset')
set printmbcharset& printencoding& printmbfont&
bwipe
endfunc
func Test_printexpr()
if !has('unix')
return
endif
CheckFeature postscript
" Not a very useful printexpr value, but enough to test
" hardcopy with 'printexpr'.
@ -84,7 +117,7 @@ func Test_printexpr()
\ readfile('Xhardcopy_printexpr'))
call delete('Xhardcopy_printexpr')
" Function return 1 to test print failure.
" Function returns 1 to test print failure.
function PrintFails(fname)
call delete(a:fname)
return 1
@ -97,12 +130,11 @@ func Test_printexpr()
endfunc
func Test_errors()
" FIXME: Windows fails differently than Unix.
if has('unix')
CheckFeature postscript
edit test_hardcopy.vim
call assert_fails('hardcopy >', 'E324:')
bwipe
endif
endfunc
func Test_dark_background()
@ -126,12 +158,11 @@ func Test_dark_background()
endfun
func Test_empty_buffer()
" FIXME: Unclear why this fails on Windows.
if has('unix')
CheckFeature postscript
new
call assert_equal("\nNo text to be printed", execute('hardcopy'))
bwipe
endif
endfunc
func Test_printheader_parsing()
@ -145,9 +176,8 @@ func Test_printheader_parsing()
endfunc
func Test_fname_with_spaces()
if !has('postscript')
return
endif
CheckFeature postscript
split t\ e\ s\ t.txt
call setline(1, ['just', 'some', 'text'])
hardcopy > %.ps
@ -157,9 +187,11 @@ func Test_fname_with_spaces()
endfunc
func Test_illegal_byte()
if !has('postscript') || &enc != 'utf-8'
CheckFeature postscript
if &enc != 'utf-8'
return
endif
new
" conversion of 0xff will fail, this used to cause a crash
call setline(1, "\xff")
@ -168,3 +200,5 @@ func Test_illegal_byte()
bwipe!
call delete('Xpstest')
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@ -29,7 +29,7 @@ func s:setup_commands(cchar)
command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args>
command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args>
command! -nargs=* -bang Xlast <mods>clast<bang> <args>
command! -nargs=* -bang -range Xnfile <mods><count>cnfile<bang> <args>
command! -count -nargs=* -bang Xnfile <mods><count>cnfile<bang> <args>
command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args>
command! -nargs=* Xexpr <mods>cexpr <args>
command! -range -nargs=* Xvimgrep <mods><count>vimgrep <args>
@ -40,6 +40,8 @@ func s:setup_commands(cchar)
command! -nargs=0 -count Xcc <count>cc
command! -count=1 -nargs=0 Xbelow <mods><count>cbelow
command! -count=1 -nargs=0 Xabove <mods><count>cabove
command! -count=1 -nargs=0 Xbefore <mods><count>cbefore
command! -count=1 -nargs=0 Xafter <mods><count>cafter
let g:Xgetlist = function('getqflist')
let g:Xsetlist = function('setqflist')
call setqflist([], 'f')
@ -64,7 +66,7 @@ func s:setup_commands(cchar)
command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args>
command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
command! -nargs=* -bang Xlast <mods>llast<bang> <args>
command! -nargs=* -bang -range Xnfile <mods><count>lnfile<bang> <args>
command! -count -nargs=* -bang Xnfile <mods><count>lnfile<bang> <args>
command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
command! -nargs=* Xexpr <mods>lexpr <args>
command! -range -nargs=* Xvimgrep <mods><count>lvimgrep <args>
@ -75,6 +77,8 @@ func s:setup_commands(cchar)
command! -nargs=0 -count Xcc <count>ll
command! -count=1 -nargs=0 Xbelow <mods><count>lbelow
command! -count=1 -nargs=0 Xabove <mods><count>labove
command! -count=1 -nargs=0 Xbefore <mods><count>lbefore
command! -count=1 -nargs=0 Xafter <mods><count>lafter
let g:Xgetlist = function('getloclist', [0])
let g:Xsetlist = function('setloclist', [0])
call setloclist(0, [], 'f')
@ -260,6 +264,9 @@ func XwindowTests(cchar)
\ winheight('.') == 7 &&
\ getline('.') ==# '|| non-error 1')
" :cnext in quickfix window should move to the next entry
Xnext
call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
" Calling cwindow should close the quickfix window with no valid errors
Xwindow
@ -431,13 +438,19 @@ func Xtest_browse(cchar)
" result in failure
if a:cchar == 'c'
let err = 'E42:'
let cmd = '$cc'
else
let err = 'E776:'
let cmd = '$ll'
endif
call assert_fails('Xnext', err)
call assert_fails('Xprev', err)
call assert_fails('Xnfile', err)
call assert_fails('Xpfile', err)
call assert_fails(cmd, err)
Xexpr ''
call assert_fails(cmd, 'E42:')
call s:create_test_file('Xqftestfile1')
call s:create_test_file('Xqftestfile2')
@ -1810,14 +1823,27 @@ func s:test_xgrep(cchar)
enew! | only
set makeef&vim
silent Xgrep Grep_Test_Text: test_quickfix.vim
call assert_true(len(g:Xgetlist()) == 3)
call assert_true(len(g:Xgetlist()) == 5)
Xopen
call assert_true(w:quickfix_title =~ '^:grep')
Xclose
enew
set makeef=Temp_File_##
silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
call assert_true(len(g:Xgetlist()) == 6)
" Try with 'grepprg' set to 'internal'
set grepprg=internal
silent Xgrep Grep_Test_Text: test_quickfix.vim
silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
call assert_true(len(g:Xgetlist()) == 9)
set grepprg&vim
call writefile(['Vim'], 'XtestTempFile')
set makeef=XtestTempFile
silent Xgrep Grep_Test_Text: test_quickfix.vim
call assert_equal(5, len(g:Xgetlist()))
call assert_false(filereadable('XtestTempFile'))
set makeef&vim
endfunc
func Test_grep()
@ -1914,9 +1940,23 @@ func HistoryTest(cchar)
call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
" Test for changing the quickfix lists
call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
exe '1' . a:cchar . 'hist'
call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
exe '3' . a:cchar . 'hist'
call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
call assert_fails('-2' . a:cchar . 'hist', 'E16:')
call assert_fails('4' . a:cchar . 'hist', 'E16:')
call g:Xsetlist([], 'f')
let l = split(execute(a:cchar . 'hist'), "\n")
call assert_equal('No entries', l[0])
if a:cchar == 'c'
call assert_fails('4chist', 'E16:')
else
call assert_fails('4lhist', 'E776:')
endif
" An empty list should still show the stack history
call g:Xsetlist([])
@ -2365,6 +2405,12 @@ func Test_Autocmd()
silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
silent grep abc123def Xtest
silent grepadd abc123def Xtest
set grepprg=internal
silent grep Grep_Autocmd_Text test_quickfix.vim
silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
silent lgrep Grep_Autocmd_Text test_quickfix.vim
silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
set grepprg&vim
let l = ['pregrep',
\ 'postgrep',
\ 'pregrepadd',
@ -2372,7 +2418,15 @@ func Test_Autocmd()
\ 'pregrep',
\ 'postgrep',
\ 'pregrepadd',
\ 'postgrepadd']
\ 'postgrepadd',
\ 'pregrep',
\ 'postgrep',
\ 'pregrepadd',
\ 'postgrepadd',
\ 'prelgrep',
\ 'postlgrep',
\ 'prelgrepadd',
\ 'postlgrepadd']
call assert_equal(l, g:acmds)
endif
@ -2491,6 +2545,19 @@ func Test_cwindow_jump()
call assert_true(winnr('$') == 2)
call assert_true(winnr() == 1)
" Jumping to a file from the location list window should find a usuable
" window by wrapping around the window list.
enew | only
call setloclist(0, [], 'f')
new | new
lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
lopen
1close
call assert_equal(0, getloclist(3, {'id' : 0}).id)
lnext
call assert_equal(3, winnr())
call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
enew | only
set efm&vim
endfunc
@ -4201,17 +4268,22 @@ func Test_empty_qfbuf()
endfunc
" Test for the :cbelow, :cabove, :lbelow and :labove commands.
" And for the :cafter, :cbefore, :lafter and :lbefore commands.
func Xtest_below(cchar)
call s:setup_commands(a:cchar)
" No quickfix/location list
call assert_fails('Xbelow', 'E42:')
call assert_fails('Xabove', 'E42:')
call assert_fails('Xbefore', 'E42:')
call assert_fails('Xafter', 'E42:')
" Empty quickfix/location list
call g:Xsetlist([])
call assert_fails('Xbelow', 'E42:')
call assert_fails('Xabove', 'E42:')
call assert_fails('Xbefore', 'E42:')
call assert_fails('Xafter', 'E42:')
call s:create_test_file('X1')
call s:create_test_file('X2')
@ -4225,39 +4297,74 @@ func Xtest_below(cchar)
call assert_fails('Xabove', 'E42:')
call assert_fails('3Xbelow', 'E42:')
call assert_fails('4Xabove', 'E42:')
call assert_fails('Xbefore', 'E42:')
call assert_fails('Xafter', 'E42:')
call assert_fails('3Xbefore', 'E42:')
call assert_fails('4Xafter', 'E42:')
" Test the commands with various arguments
Xexpr ["X1:5:L5", "X2:5:L5", "X2:10:L10", "X2:15:L15", "X3:3:L3"]
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_fails('Xabove', 'E553:')
normal 7G
Xbefore
call assert_equal(['X2', 5, 2], [bufname(''), line('.'), col('.')])
call assert_fails('Xbefore', 'E553:')
normal 2j
Xbelow
call assert_equal(['X2', 10], [bufname(''), line('.')])
normal 7G
Xafter
call assert_equal(['X2', 10, 3], [bufname(''), line('.'), col('.')])
" Last error in this file
Xbelow 99
call assert_equal(['X2', 15], [bufname(''), line('.')])
call assert_fails('Xbelow', 'E553:')
normal gg
Xafter 99
call assert_equal(['X2', 15, 4], [bufname(''), line('.'), col('.')])
call assert_fails('Xafter', 'E553:')
" First error in this file
Xabove 99
call assert_equal(['X2', 5], [bufname(''), line('.')])
call assert_fails('Xabove', 'E553:')
normal G
Xbefore 99
call assert_equal(['X2', 5, 2], [bufname(''), line('.'), col('.')])
call assert_fails('Xbefore', 'E553:')
normal gg
Xbelow 2
call assert_equal(['X2', 10], [bufname(''), line('.')])
normal gg
Xafter 2
call assert_equal(['X2', 10, 3], [bufname(''), line('.'), col('.')])
normal G
Xabove 2
call assert_equal(['X2', 10], [bufname(''), line('.')])
normal G
Xbefore 2
call assert_equal(['X2', 10, 3], [bufname(''), line('.'), col('.')])
edit X4
call assert_fails('Xabove', 'E42:')
call assert_fails('Xbelow', 'E42:')
call assert_fails('Xbefore', 'E42:')
call assert_fails('Xafter', 'E42:')
if a:cchar == 'l'
" If a buffer has location list entries from some other window but not
" from the current window, then the commands should fail.
edit X1 | split | call setloclist(0, [], 'f')
call assert_fails('Xabove', 'E776:')
call assert_fails('Xbelow', 'E776:')
call assert_fails('Xbefore', 'E776:')
call assert_fails('Xafter', 'E776:')
close
endif
@ -4268,31 +4375,52 @@ func Xtest_below(cchar)
edit +1 X2
Xbelow 2
call assert_equal(['X2', 10, 1], [bufname(''), line('.'), col('.')])
normal 1G
Xafter 2
call assert_equal(['X2', 5, 2], [bufname(''), line('.'), col('.')])
normal gg
Xbelow 99
call assert_equal(['X2', 15, 1], [bufname(''), line('.'), col('.')])
normal gg
Xafter 99
call assert_equal(['X2', 15, 3], [bufname(''), line('.'), col('.')])
normal G
Xabove 2
call assert_equal(['X2', 10, 1], [bufname(''), line('.'), col('.')])
normal G
Xbefore 2
call assert_equal(['X2', 15, 2], [bufname(''), line('.'), col('.')])
normal G
Xabove 99
call assert_equal(['X2', 5, 1], [bufname(''), line('.'), col('.')])
normal G
Xbefore 99
call assert_equal(['X2', 5, 1], [bufname(''), line('.'), col('.')])
normal 10G
Xabove
call assert_equal(['X2', 5, 1], [bufname(''), line('.'), col('.')])
normal 10G$
2Xbefore
call assert_equal(['X2', 10, 2], [bufname(''), line('.'), col('.')])
normal 10G
Xbelow
call assert_equal(['X2', 15, 1], [bufname(''), line('.'), col('.')])
normal 9G
5Xafter
call assert_equal(['X2', 15, 2], [bufname(''), line('.'), col('.')])
" Invalid range
if a:cchar == 'c'
call assert_fails('-2cbelow', 'E553:')
" TODO: should go to first error in the current line?
0cabove
call assert_fails('-2cbelow', 'E16:')
call assert_fails('-2cafter', 'E16:')
else
call assert_fails('-2lbelow', 'E553:')
" TODO: should go to first error in the current line?
0labove
call assert_fails('-2lbelow', 'E16:')
call assert_fails('-2lafter', 'E16:')
endif
call delete('X1')
@ -4306,6 +4434,42 @@ func Test_cbelow()
call Xtest_below('l')
endfunc
func Test_quickfix_count()
let commands = [
\ 'cNext',
\ 'cNfile',
\ 'cabove',
\ 'cbelow',
\ 'cfirst',
\ 'clast',
\ 'cnewer',
\ 'cnext',
\ 'cnfile',
\ 'colder',
\ 'cprevious',
\ 'crewind',
\
\ 'lNext',
\ 'lNfile',
\ 'labove',
\ 'lbelow',
\ 'lfirst',
\ 'llast',
\ 'lnewer',
\ 'lnext',
\ 'lnfile',
\ 'lolder',
\ 'lprevious',
\ 'lrewind',
\ ]
for cmd in commands
call assert_fails('-1' .. cmd, 'E16:')
call assert_fails('.' .. cmd, 'E16:')
call assert_fails('%' .. cmd, 'E16:')
call assert_fails('$' .. cmd, 'E16:')
endfor
endfunc
" Test for aborting quickfix commands using QuickFixCmdPre
func Xtest_qfcmd_abort(cchar)
call s:setup_commands(a:cchar)
@ -4461,6 +4625,24 @@ func Test_cquit()
call assert_fails('-3cquit', 'E16:')
endfunc
" Running :lhelpgrep command more than once in a help window, doesn't jump to
" the help topic
func Test_lhelpgrep_from_help_window()
call mkdir('Xtestdir/doc', 'p')
call writefile(['window'], 'Xtestdir/doc/a.txt')
call writefile(['buffer'], 'Xtestdir/doc/b.txt')
let save_rtp = &rtp
let &rtp = 'Xtestdir'
lhelpgrep window
lhelpgrep buffer
call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
lhelpgrep window
call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
let &rtp = save_rtp
call delete('Xtestdir', 'rf')
new | only!
endfunc
" Test for adding an invalid entry with the quickfix window open and making
" sure that the window contents are not changed
func Test_add_invalid_entry_with_qf_window()

View File

@ -393,9 +393,13 @@ func Test_addr_all()
call assert_equal(len(gettabinfo()), g:a2)
bwipe
command! -addr=other DoSomething echo 'nothing'
command! -addr=other DoSomething let g:a1 = <line1> | let g:a2 = <line2>
DoSomething
call assert_fails('%DoSomething')
call assert_equal(line('.'), g:a1)
call assert_equal(line('.'), g:a2)
%DoSomething
call assert_equal(1, g:a1)
call assert_equal(line('$'), g:a2)
delcommand DoSomething
endfunc
@ -421,7 +425,7 @@ func Test_command_list()
\ execute('command DoCmd'))
command! -count=2 DoCmd :
call assert_equal("\n Name Args Address Complete Definition"
\ .. "\n DoCmd 0 2c :",
\ .. "\n DoCmd 0 2c ? :",
\ execute('command DoCmd'))
" Test with various -addr= argument values.

View File

@ -856,7 +856,7 @@ func Test_window_resize()
wincmd l
let other_winnr = winnr('h')
call assert_notequal(winnr(), other_winnr)
exe 'vert ' .. other_winnr .. 'resize -100'
exe 'vert ' .. other_winnr .. 'resize -' .. &columns
call assert_equal(0, winwidth(other_winnr))
%bwipe!

View File

@ -242,9 +242,9 @@ describe('assert function:', function()
-- assert_fails({cmd}, [, {error}])
describe('assert_fails', function()
it('should change v:errors when error does not match v:errmsg', function()
eq(1, eval([[assert_fails('xxx', {})]]))
command([[call assert_match("Expected {} but got 'E731:", v:errors[0])]])
expected_errors({"Expected {} but got 'E731: using Dictionary as a String'"})
eq(1, eval([[assert_fails('xxx', 'E12345')]]))
command([[call assert_match("Expected 'E12345' but got 'E492:", v:errors[0])]])
expected_errors({"Expected 'E12345' but got 'E492: Not an editor command: xxx': xxx"})
end)
it('should not change v:errors when cmd errors', function()
@ -258,9 +258,9 @@ describe('assert function:', function()
end)
it('can specify and get a message about what failed', function()
eq(1, eval([[assert_fails('xxx', {}, 'stupid')]]))
command([[call assert_match("stupid: Expected {} but got 'E731:", v:errors[0])]])
expected_errors({"stupid: Expected {} but got 'E731: using Dictionary as a String'"})
eq(1, eval([[assert_fails('xxx', 'E9876', 'stupid')]]))
command([[call assert_match("stupid: Expected 'E9876' but got 'E492:", v:errors[0])]])
expected_errors({"stupid: Expected 'E9876' but got 'E492: Not an editor command: xxx': stupid"})
end)
it('can specify and get a message even when cmd succeeds', function()

View File

@ -10,6 +10,29 @@ local source = helpers.source
local poke_eventloop = helpers.poke_eventloop
local uname = helpers.uname
local load_adjust = helpers.load_adjust
local isCI = helpers.isCI
local function isasan()
local version = eval('execute("version")')
return version:match('-fsanitize=[a-z,]*address')
end
clear()
if isasan() then
pending('ASAN build is difficult to estimate memory usage', function() end)
return
elseif iswin() then
if isCI('github') then
pending('Windows runners in Github Actions do not have a stable environment to estimate memory usage', function() end)
return
elseif eval("executable('wmic')") == 0 then
pending('missing "wmic" command', function() end)
return
end
elseif eval("executable('ps')") == 0 then
pending('missing "ps" command', function() end)
return
end
local monitor_memory_usage = {
memory_usage = function(self)
@ -71,11 +94,6 @@ describe('memory usage', function()
end
end
local function isasan()
local version = eval('execute("version")')
return version:match('-fsanitize=[a-z,]*address')
end
before_each(clear)
--[[
@ -83,15 +101,6 @@ describe('memory usage', function()
just after it finishes.
]]--
it('function capture vargs', function()
if isasan() then
pending('ASAN build is difficult to estimate memory usage')
end
if iswin() and eval("executable('wmic')") == 0 then
pending('missing "wmic" command')
elseif eval("executable('ps')") == 0 then
pending('missing "ps" command')
end
local pid = eval('getpid()')
local before = monitor_memory_usage(pid)
source([[
@ -125,15 +134,6 @@ describe('memory usage', function()
increase so much even when rerun Xtest.vim since system memory caches.
]]--
it('function capture lvars', function()
if isasan() then
pending('ASAN build is difficult to estimate memory usage')
end
if iswin() and eval("executable('wmic')") == 0 then
pending('missing "wmic" command')
elseif eval("executable('ps')") == 0 then
pending('missing "ps" command')
end
local pid = eval('getpid()')
local before = monitor_memory_usage(pid)
local fname = source([[

View File

@ -136,7 +136,7 @@ local function command_specs_for(fn, sync, first_arg_factory, init)
end)
it('with nargs/count', function()
call(fn, args..', {"nargs": "1", "range": "5"}')
call(fn, args..', {"nargs": "1", "count": "5"}')
local function on_setup()
command('5RpcCommand arg')
end
@ -152,7 +152,7 @@ local function command_specs_for(fn, sync, first_arg_factory, init)
end)
it('with nargs/count/bang', function()
call(fn, args..', {"nargs": "1", "range": "5", "bang": ""}')
call(fn, args..', {"nargs": "1", "count": "5", "bang": ""}')
local function on_setup()
command('5RpcCommand! arg')
end
@ -169,7 +169,7 @@ local function command_specs_for(fn, sync, first_arg_factory, init)
end)
it('with nargs/count/bang/register', function()
call(fn, args..', {"nargs": "1", "range": "5", "bang": "",'..
call(fn, args..', {"nargs": "1", "count": "5", "bang": "",'..
' "register": ""}')
local function on_setup()
command('5RpcCommand! b arg')
@ -188,7 +188,7 @@ local function command_specs_for(fn, sync, first_arg_factory, init)
end)
it('with nargs/count/bang/register/eval', function()
call(fn, args..', {"nargs": "1", "range": "5", "bang": "",'..
call(fn, args..', {"nargs": "1", "count": "5", "bang": "",'..
' "register": "", "eval": "@<reg>"}')
local function on_setup()
command('let @b = "regb"')