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[!] [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

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

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

@ -74,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;

View File

@ -1383,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;
@ -1730,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;
}
}
@ -2347,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:
@ -2403,6 +2414,8 @@ int parse_cmd_address(exarg_T *eap, char_u **errormsg, bool silent)
}
break;
case ADDR_TABS_RELATIVE:
case ADDR_UNSIGNED:
case ADDR_QUICKFIX:
*errormsg = (char_u *)_(e_invrange);
return FAIL;
case ADDR_ARGUMENTS:
@ -2413,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;
}
@ -2524,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;
@ -3761,11 +3773,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;
}
@ -3802,6 +3818,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;
@ -3812,6 +3829,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;
@ -3964,9 +3987,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;
}
}
@ -4115,7 +4143,19 @@ static char_u *invalid_range(exarg_T *eap)
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;

View File

@ -4269,9 +4269,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;

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>
@ -64,7 +64,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>
@ -4286,13 +4286,9 @@ func Xtest_below(cchar)
" 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:')
else
call assert_fails('-2lbelow', 'E553:')
" TODO: should go to first error in the current line?
0labove
call assert_fails('-2lbelow', 'E16:')
endif
call delete('X1')
@ -4306,6 +4302,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)