vim-patch:8.1.1261: no error for quickfix commands with negative range

Problem:    No error for quickfix commands with negative range.
Solution:   Add ADDR_UNSIGNED and use it for quickfix commands.  Make
            assert_fails() show the command if the error doesn't match.
25190db225

N/A patches for version.c:

vim-patch:8.2.0113: "make cmdidxs" fails

Problem:    "make cmdidxs" fails.
Solution:   Allow address for ":cquit".  Add --not-a-term to avoid a delay.
9b24dfcb9f
This commit is contained in:
erw7 2020-10-13 10:02:36 +09:00 committed by Jan Edmund Lazo
parent a66d63f36e
commit 35dc6d6e87
No known key found for this signature in database
GPG Key ID: 64915E6E9F735B15
8 changed files with 165 additions and 69 deletions

View File

@ -74,7 +74,7 @@ processing a quickfix or location list command, it will be aborted.
*:cc* *:cc*
:cc[!] [nr] Display error [nr]. If [nr] is omitted, the same :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 work when jumping to another buffer, the current buffer
has been changed, there is the only window for the has been changed, there is the only window for the
buffer and both 'hidden' and 'autowrite' are off. 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. there is another window for this buffer.
The 'switchbuf' settings are respected when jumping The 'switchbuf' settings are respected when jumping
to a buffer. 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*
:ll[!] [nr] Same as ":cc", except the location list for the :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* *:cn* *:cne* *:cnext* *E553*
:[count]cn[ext][!] Display the [count] next error in the list that :[count]cn[ext][!] Display the [count] next error in the list that

View File

@ -5948,6 +5948,19 @@ int assert_exception(typval_T *argvars)
return 0; 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) int assert_fails(typval_T *argvars)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
@ -5966,14 +5979,7 @@ int assert_fails(typval_T *argvars)
if (!called_emsg) { if (!called_emsg) {
prepare_assert_error(&ga); prepare_assert_error(&ga);
ga_concat(&ga, (const char_u *)"command did not fail: "); ga_concat(&ga, (const char_u *)"command did not fail: ");
if (argvars[1].v_type != VAR_UNKNOWN assert_append_cmd_or_arg(&ga, argvars, cmd);
&& 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_error(&ga); assert_error(&ga);
ga_clear(&ga); ga_clear(&ga);
ret = 1; ret = 1;
@ -5986,6 +5992,8 @@ int assert_fails(typval_T *argvars)
prepare_assert_error(&ga); prepare_assert_error(&ga);
fill_assert_error(&ga, &argvars[2], NULL, &argvars[1], fill_assert_error(&ga, &argvars[2], NULL, &argvars[1],
&vimvars[VV_ERRMSG].vv_tv, ASSERT_OTHER); &vimvars[VV_ERRMSG].vv_tv, ASSERT_OTHER);
ga_concat(&ga, (char_u *)": ");
assert_append_cmd_or_arg(&ga, argvars, cmd);
assert_error(&ga); assert_error(&ga);
ga_clear(&ga); ga_clear(&ga);
ret = 1; ret = 1;

View File

@ -297,13 +297,13 @@ module.cmds = {
{ {
command='cNext', command='cNext',
flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), flags=bit.bor(RANGE, COUNT, TRLBAR, BANG),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cnext', func='ex_cnext',
}, },
{ {
command='cNfile', command='cNfile',
flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), flags=bit.bor(RANGE, COUNT, TRLBAR, BANG),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cnext', func='ex_cnext',
}, },
{ {
@ -320,8 +320,8 @@ module.cmds = {
}, },
{ {
command='cabove', command='cabove',
flags=bit.bor(RANGE, TRLBAR), flags=bit.bor(RANGE, COUNT, TRLBAR),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cbelow', func='ex_cbelow',
}, },
{ {
@ -362,8 +362,8 @@ module.cmds = {
}, },
{ {
command='cbelow', command='cbelow',
flags=bit.bor(RANGE, TRLBAR), flags=bit.bor(RANGE, COUNT, TRLBAR),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cbelow', func='ex_cbelow',
}, },
{ {
@ -375,7 +375,7 @@ module.cmds = {
{ {
command='cc', command='cc',
flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), flags=bit.bor(RANGE, COUNT, TRLBAR, BANG),
addr_type='ADDR_OTHER', addr_type='ADDR_QUICKFIX',
func='ex_cc', func='ex_cc',
}, },
{ {
@ -393,7 +393,7 @@ module.cmds = {
{ {
command='cdo', command='cdo',
flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL),
addr_type='ADDR_QUICKFIX', addr_type='ADDR_QUICKFIX_VALID',
func='ex_listdo', func='ex_listdo',
}, },
{ {
@ -419,13 +419,13 @@ module.cmds = {
{ {
command='cfdo', command='cfdo',
flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL),
addr_type='ADDR_QUICKFIX', addr_type='ADDR_QUICKFIX_VALID',
func='ex_listdo', func='ex_listdo',
}, },
{ {
command='cfirst', command='cfirst',
flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), flags=bit.bor(RANGE, COUNT, TRLBAR, BANG),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cc', func='ex_cc',
}, },
{ {
@ -491,7 +491,7 @@ module.cmds = {
{ {
command='clast', command='clast',
flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), flags=bit.bor(RANGE, COUNT, TRLBAR, BANG),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cc', func='ex_cc',
}, },
{ {
@ -527,19 +527,19 @@ module.cmds = {
{ {
command='cnext', command='cnext',
flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), flags=bit.bor(RANGE, COUNT, TRLBAR, BANG),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cnext', func='ex_cnext',
}, },
{ {
command='cnewer', command='cnewer',
flags=bit.bor(RANGE, COUNT, TRLBAR), flags=bit.bor(RANGE, COUNT, TRLBAR),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='qf_age', func='qf_age',
}, },
{ {
command='cnfile', command='cnfile',
flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), flags=bit.bor(RANGE, COUNT, TRLBAR, BANG),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cnext', func='ex_cnext',
}, },
{ {
@ -569,7 +569,7 @@ module.cmds = {
{ {
command='colder', command='colder',
flags=bit.bor(RANGE, COUNT, TRLBAR), flags=bit.bor(RANGE, COUNT, TRLBAR),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='qf_age', func='qf_age',
}, },
{ {
@ -623,7 +623,7 @@ module.cmds = {
{ {
command='cprevious', command='cprevious',
flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), flags=bit.bor(RANGE, COUNT, TRLBAR, BANG),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cnext', func='ex_cnext',
}, },
{ {
@ -635,13 +635,13 @@ module.cmds = {
{ {
command='cquit', command='cquit',
flags=bit.bor(RANGE, COUNT, ZEROR, TRLBAR, BANG), flags=bit.bor(RANGE, COUNT, ZEROR, TRLBAR, BANG),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cquit', func='ex_cquit',
}, },
{ {
command='crewind', command='crewind',
flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), flags=bit.bor(RANGE, COUNT, TRLBAR, BANG),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cc', func='ex_cc',
}, },
{ {
@ -1265,13 +1265,13 @@ module.cmds = {
{ {
command='lNext', command='lNext',
flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), flags=bit.bor(RANGE, COUNT, TRLBAR, BANG),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cnext', func='ex_cnext',
}, },
{ {
command='lNfile', command='lNfile',
flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), flags=bit.bor(RANGE, COUNT, TRLBAR, BANG),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cnext', func='ex_cnext',
}, },
{ {
@ -1282,8 +1282,8 @@ module.cmds = {
}, },
{ {
command='labove', command='labove',
flags=bit.bor(RANGE, TRLBAR), flags=bit.bor(RANGE, COUNT, TRLBAR),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cbelow', func='ex_cbelow',
}, },
{ {
@ -1324,8 +1324,8 @@ module.cmds = {
}, },
{ {
command='lbelow', command='lbelow',
flags=bit.bor(RANGE, TRLBAR), flags=bit.bor(RANGE, COUNT, TRLBAR),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cbelow', func='ex_cbelow',
}, },
{ {
@ -1361,7 +1361,7 @@ module.cmds = {
{ {
command='ldo', command='ldo',
flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL),
addr_type='ADDR_QUICKFIX', addr_type='ADDR_QUICKFIX_VALID',
func='ex_listdo', func='ex_listdo',
}, },
{ {
@ -1399,13 +1399,13 @@ module.cmds = {
{ {
command='lfdo', command='lfdo',
flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL), flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL),
addr_type='ADDR_QUICKFIX', addr_type='ADDR_QUICKFIX_VALID',
func='ex_listdo', func='ex_listdo',
}, },
{ {
command='lfirst', command='lfirst',
flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), flags=bit.bor(RANGE, COUNT, TRLBAR, BANG),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cc', func='ex_cc',
}, },
{ {
@ -1453,13 +1453,13 @@ module.cmds = {
{ {
command='ll', command='ll',
flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), flags=bit.bor(RANGE, COUNT, TRLBAR, BANG),
addr_type='ADDR_OTHER', addr_type='ADDR_QUICKFIX',
func='ex_cc', func='ex_cc',
}, },
{ {
command='llast', command='llast',
flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), flags=bit.bor(RANGE, COUNT, TRLBAR, BANG),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cc', func='ex_cc',
}, },
{ {
@ -1495,19 +1495,19 @@ module.cmds = {
{ {
command='lnext', command='lnext',
flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), flags=bit.bor(RANGE, COUNT, TRLBAR, BANG),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cnext', func='ex_cnext',
}, },
{ {
command='lnewer', command='lnewer',
flags=bit.bor(RANGE, COUNT, TRLBAR), flags=bit.bor(RANGE, COUNT, TRLBAR),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='qf_age', func='qf_age',
}, },
{ {
command='lnfile', command='lnfile',
flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), flags=bit.bor(RANGE, COUNT, TRLBAR, BANG),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cnext', func='ex_cnext',
}, },
{ {
@ -1537,7 +1537,7 @@ module.cmds = {
{ {
command='lolder', command='lolder',
flags=bit.bor(RANGE, COUNT, TRLBAR), flags=bit.bor(RANGE, COUNT, TRLBAR),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='qf_age', func='qf_age',
}, },
{ {
@ -1549,7 +1549,7 @@ module.cmds = {
{ {
command='lprevious', command='lprevious',
flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), flags=bit.bor(RANGE, COUNT, TRLBAR, BANG),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cnext', func='ex_cnext',
}, },
{ {
@ -1561,7 +1561,7 @@ module.cmds = {
{ {
command='lrewind', command='lrewind',
flags=bit.bor(RANGE, COUNT, TRLBAR, BANG), flags=bit.bor(RANGE, COUNT, TRLBAR, BANG),
addr_type='ADDR_OTHER', addr_type='ADDR_UNSIGNED',
func='ex_cc', func='ex_cc',
}, },
{ {

View File

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

View File

@ -74,8 +74,10 @@ typedef enum {
ADDR_BUFFERS, // buffer number ADDR_BUFFERS, // buffer number
ADDR_TABS, // tab page number ADDR_TABS, // tab page number
ADDR_TABS_RELATIVE, // Tab page that only relative ADDR_TABS_RELATIVE, // Tab page that only relative
ADDR_QUICKFIX_VALID, // quickfix list valid entry number
ADDR_QUICKFIX, // quickfix list 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 ADDR_NONE // no range used
} cmd_addr_T; } cmd_addr_T;

View File

@ -1383,6 +1383,10 @@ static char_u * do_one_cmd(char_u **cmdlinep,
if (ea.cmdidx == CMD_wincmd && p != NULL) { if (ea.cmdidx == CMD_wincmd && p != NULL) {
get_wincmd_addr_type(skipwhite(p), &ea); 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; ea.cmd = cmd;
@ -1730,14 +1734,17 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.line2 = ARGCOUNT; ea.line2 = ARGCOUNT;
} }
break; break;
case ADDR_QUICKFIX: case ADDR_QUICKFIX_VALID:
ea.line2 = qf_get_size(&ea); ea.line2 = qf_get_valid_size(&ea);
if (ea.line2 == 0) { if (ea.line2 == 0) {
ea.line2 = 1; ea.line2 = 1;
} }
break; break;
case ADDR_NONE: 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; break;
} }
} }
@ -2347,9 +2354,13 @@ int parse_cmd_address(exarg_T *eap, char_u **errormsg, bool silent)
eap->line2 = CURRENT_TAB_NR; eap->line2 = CURRENT_TAB_NR;
break; break;
case ADDR_TABS_RELATIVE: case ADDR_TABS_RELATIVE:
case ADDR_UNSIGNED:
eap->line2 = 1; eap->line2 = 1;
break; break;
case ADDR_QUICKFIX: case ADDR_QUICKFIX:
eap->line2 = qf_get_cur_idx(eap);
break;
case ADDR_QUICKFIX_VALID:
eap->line2 = qf_get_cur_valid_idx(eap); eap->line2 = qf_get_cur_valid_idx(eap);
break; break;
case ADDR_NONE: case ADDR_NONE:
@ -2403,6 +2414,8 @@ int parse_cmd_address(exarg_T *eap, char_u **errormsg, bool silent)
} }
break; break;
case ADDR_TABS_RELATIVE: case ADDR_TABS_RELATIVE:
case ADDR_UNSIGNED:
case ADDR_QUICKFIX:
*errormsg = (char_u *)_(e_invrange); *errormsg = (char_u *)_(e_invrange);
return FAIL; return FAIL;
case ADDR_ARGUMENTS: case ADDR_ARGUMENTS:
@ -2413,9 +2426,9 @@ int parse_cmd_address(exarg_T *eap, char_u **errormsg, bool silent)
eap->line2 = ARGCOUNT; eap->line2 = ARGCOUNT;
} }
break; break;
case ADDR_QUICKFIX: case ADDR_QUICKFIX_VALID:
eap->line1 = 1; eap->line1 = 1;
eap->line2 = qf_get_size(eap); eap->line2 = qf_get_valid_size(eap);
if (eap->line2 == 0) { if (eap->line2 == 0) {
eap->line2 = 1; eap->line2 = 1;
} }
@ -2524,14 +2537,13 @@ static void append_command(char_u *cmd)
*d = NUL; *d = NUL;
} }
/* // Find an Ex command by its name, either built-in or user.
* Find an Ex command by its name, either built-in or user. // Start of the name can be found at eap->cmd.
* Start of the name can be found at eap->cmd. // Sets eap->cmdidx and returns a pointer to char after the command name.
* Returns pointer to char after the command name. // "full" is set to TRUE if the whole command name matched.
* "full" is set to TRUE if the whole command name matched. // Returns NULL for an ambiguous user command.
* Returns NULL for an ambiguous user command.
*/
static char_u *find_command(exarg_T *eap, int *full) static char_u *find_command(exarg_T *eap, int *full)
FUNC_ATTR_NONNULL_ARG(1)
{ {
int len; int len;
char_u *p; char_u *p;
@ -3761,11 +3773,15 @@ static linenr_T get_address(exarg_T *eap,
break; break;
case ADDR_TABS_RELATIVE: case ADDR_TABS_RELATIVE:
case ADDR_NONE: case ADDR_NONE:
case ADDR_UNSIGNED:
EMSG(_(e_invrange)); EMSG(_(e_invrange));
cmd = NULL; cmd = NULL;
goto error; goto error;
break; break;
case ADDR_QUICKFIX: case ADDR_QUICKFIX:
lnum = qf_get_cur_idx(eap);
break;
case ADDR_QUICKFIX_VALID:
lnum = qf_get_cur_valid_idx(eap); lnum = qf_get_cur_valid_idx(eap);
break; break;
} }
@ -3802,6 +3818,7 @@ static linenr_T get_address(exarg_T *eap,
break; break;
case ADDR_TABS_RELATIVE: case ADDR_TABS_RELATIVE:
case ADDR_NONE: case ADDR_NONE:
case ADDR_UNSIGNED:
EMSG(_(e_invrange)); EMSG(_(e_invrange));
cmd = NULL; cmd = NULL;
goto error; goto error;
@ -3812,6 +3829,12 @@ static linenr_T get_address(exarg_T *eap,
lnum = 1; lnum = 1;
} }
break; break;
case ADDR_QUICKFIX_VALID:
lnum = qf_get_valid_size(eap);
if (lnum == 0) {
lnum = 1;
}
break;
} }
break; break;
@ -3964,9 +3987,14 @@ static linenr_T get_address(exarg_T *eap,
lnum = 1; lnum = 1;
break; break;
case ADDR_QUICKFIX: case ADDR_QUICKFIX:
lnum = qf_get_cur_idx(eap);
break;
case ADDR_QUICKFIX_VALID:
lnum = qf_get_cur_valid_idx(eap); lnum = qf_get_cur_valid_idx(eap);
break; break;
case ADDR_NONE: case ADDR_NONE:
case ADDR_UNSIGNED:
lnum = 0;
break; break;
} }
} }
@ -4115,7 +4143,19 @@ static char_u *invalid_range(exarg_T *eap)
break; break;
case ADDR_QUICKFIX: case ADDR_QUICKFIX:
assert(eap->line2 >= 0); 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); return (char_u *)_(e_invrange);
} }
break; break;

View File

@ -4269,9 +4269,20 @@ static char_u *get_mef_name(void)
return name; 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) size_t qf_get_size(exarg_T *eap)
FUNC_ATTR_NONNULL_ALL 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_info_T *qi;
qf_list_T *qfl; qf_list_T *qfl;

View File

@ -29,7 +29,7 @@ func s:setup_commands(cchar)
command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args> command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args>
command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args> command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args>
command! -nargs=* -bang Xlast <mods>clast<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=* -bang Xpfile <mods>cpfile<bang> <args>
command! -nargs=* Xexpr <mods>cexpr <args> command! -nargs=* Xexpr <mods>cexpr <args>
command! -range -nargs=* Xvimgrep <mods><count>vimgrep <args> command! -range -nargs=* Xvimgrep <mods><count>vimgrep <args>
@ -64,7 +64,7 @@ func s:setup_commands(cchar)
command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args> command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args>
command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args> command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
command! -nargs=* -bang Xlast <mods>llast<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=* -bang Xpfile <mods>lpfile<bang> <args>
command! -nargs=* Xexpr <mods>lexpr <args> command! -nargs=* Xexpr <mods>lexpr <args>
command! -range -nargs=* Xvimgrep <mods><count>lvimgrep <args> command! -range -nargs=* Xvimgrep <mods><count>lvimgrep <args>
@ -4286,13 +4286,9 @@ func Xtest_below(cchar)
" Invalid range " Invalid range
if a:cchar == 'c' if a:cchar == 'c'
call assert_fails('-2cbelow', 'E553:') call assert_fails('-2cbelow', 'E16:')
" TODO: should go to first error in the current line?
0cabove
else else
call assert_fails('-2lbelow', 'E553:') call assert_fails('-2lbelow', 'E16:')
" TODO: should go to first error in the current line?
0labove
endif endif
call delete('X1') call delete('X1')
@ -4306,6 +4302,42 @@ func Test_cbelow()
call Xtest_below('l') call Xtest_below('l')
endfunc 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 " Test for aborting quickfix commands using QuickFixCmdPre
func Xtest_qfcmd_abort(cchar) func Xtest_qfcmd_abort(cchar)
call s:setup_commands(a:cchar) call s:setup_commands(a:cchar)