0
0
mirror of https://github.com/vim/vim.git synced 2025-09-25 03:54:15 -04:00

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.
This commit is contained in:
Bram Moolenaar
2019-05-04 15:05:28 +02:00
parent e4f5f3aa3d
commit 25190db225
9 changed files with 177 additions and 67 deletions

View File

@@ -87,7 +87,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.
@@ -96,10 +96,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* *:cnext* *E553* *:cn* *: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

@@ -9595,14 +9595,27 @@ assert_beeps(typval_T *argvars)
return ret; return ret;
} }
static void
assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars, char_u *cmd)
{
char_u *tofree;
char_u numbuf[NUMBUFLEN];
if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN)
{
ga_concat(gap, echo_string(&argvars[2], &tofree, numbuf, 0));
vim_free(tofree);
}
else
ga_concat(gap, cmd);
}
int int
assert_fails(typval_T *argvars) assert_fails(typval_T *argvars)
{ {
char_u *cmd = tv_get_string_chk(&argvars[0]); char_u *cmd = tv_get_string_chk(&argvars[0]);
garray_T ga; garray_T ga;
int ret = 0; int ret = 0;
char_u numbuf[NUMBUFLEN];
char_u *tofree;
called_emsg = FALSE; called_emsg = FALSE;
suppress_errthrow = TRUE; suppress_errthrow = TRUE;
@@ -9612,14 +9625,7 @@ assert_fails(typval_T *argvars)
{ {
prepare_assert_error(&ga); prepare_assert_error(&ga);
ga_concat(&ga, (char_u *)"command did not fail: "); ga_concat(&ga, (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)
{
ga_concat(&ga, echo_string(&argvars[2], &tofree, numbuf, 0));
vim_free(tofree);
}
else
ga_concat(&ga, cmd);
assert_error(&ga); assert_error(&ga);
ga_clear(&ga); ga_clear(&ga);
ret = 1; ret = 1;
@@ -9635,6 +9641,8 @@ 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

@@ -73,8 +73,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;
#endif #endif
@@ -92,7 +94,7 @@ typedef struct exarg exarg_T;
* Not supported commands are included to avoid ambiguities. * Not supported commands are included to avoid ambiguities.
*/ */
#ifdef EX #ifdef EX
# undef EX /* just in case */ # undef EX // just in case
#endif #endif
#ifdef DO_DECLARE_EXCMD #ifdef DO_DECLARE_EXCMD
# define EX(a, b, c, d, e) {(char_u *)b, c, (long_u)(d), e} # define EX(a, b, c, d, e) {(char_u *)b, c, (long_u)(d), e}
@@ -242,10 +244,10 @@ EX(CMD_change, "change", ex_change,
ADDR_LINES), ADDR_LINES),
EX(CMD_cNext, "cNext", ex_cnext, EX(CMD_cNext, "cNext", ex_cnext,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_cNfile, "cNfile", ex_cnext, EX(CMD_cNfile, "cNfile", ex_cnext,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_cabbrev, "cabbrev", ex_abbreviate, EX(CMD_cabbrev, "cabbrev", ex_abbreviate,
EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN, EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN,
ADDR_NONE), ADDR_NONE),
@@ -253,8 +255,8 @@ EX(CMD_cabclear, "cabclear", ex_abclear,
EXTRA|TRLBAR|CMDWIN, EXTRA|TRLBAR|CMDWIN,
ADDR_NONE), ADDR_NONE),
EX(CMD_cabove, "cabove", ex_cbelow, EX(CMD_cabove, "cabove", ex_cbelow,
RANGE|TRLBAR, RANGE|COUNT|TRLBAR,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_caddbuffer, "caddbuffer", ex_cbuffer, EX(CMD_caddbuffer, "caddbuffer", ex_cbuffer,
RANGE|WORD1|TRLBAR, RANGE|WORD1|TRLBAR,
ADDR_OTHER), ADDR_OTHER),
@@ -274,14 +276,14 @@ EX(CMD_cbuffer, "cbuffer", ex_cbuffer,
BANG|RANGE|WORD1|TRLBAR, BANG|RANGE|WORD1|TRLBAR,
ADDR_OTHER), ADDR_OTHER),
EX(CMD_cbelow, "cbelow", ex_cbelow, EX(CMD_cbelow, "cbelow", ex_cbelow,
RANGE|TRLBAR, RANGE|COUNT|TRLBAR,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_cbottom, "cbottom", ex_cbottom, EX(CMD_cbottom, "cbottom", ex_cbottom,
TRLBAR, TRLBAR,
ADDR_NONE), ADDR_NONE),
EX(CMD_cc, "cc", ex_cc, EX(CMD_cc, "cc", ex_cc,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_QUICKFIX),
EX(CMD_cclose, "cclose", ex_cclose, EX(CMD_cclose, "cclose", ex_cclose,
TRLBAR, TRLBAR,
ADDR_NONE), ADDR_NONE),
@@ -290,7 +292,7 @@ EX(CMD_cd, "cd", ex_cd,
ADDR_NONE), ADDR_NONE),
EX(CMD_cdo, "cdo", ex_listdo, EX(CMD_cdo, "cdo", ex_listdo,
BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL, BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL,
ADDR_QUICKFIX), ADDR_QUICKFIX_VALID),
EX(CMD_center, "center", ex_align, EX(CMD_center, "center", ex_align,
TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY, TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY,
ADDR_LINES), ADDR_LINES),
@@ -302,10 +304,10 @@ EX(CMD_cfile, "cfile", ex_cfile,
ADDR_NONE), ADDR_NONE),
EX(CMD_cfdo, "cfdo", ex_listdo, EX(CMD_cfdo, "cfdo", ex_listdo,
BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL, BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL,
ADDR_QUICKFIX), ADDR_QUICKFIX_VALID),
EX(CMD_cfirst, "cfirst", ex_cc, EX(CMD_cfirst, "cfirst", ex_cc,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_cgetfile, "cgetfile", ex_cfile, EX(CMD_cgetfile, "cgetfile", ex_cfile,
TRLBAR|FILE1, TRLBAR|FILE1,
ADDR_NONE), ADDR_NONE),
@@ -335,7 +337,7 @@ EX(CMD_clist, "clist", qf_list,
ADDR_NONE), ADDR_NONE),
EX(CMD_clast, "clast", ex_cc, EX(CMD_clast, "clast", ex_cc,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_close, "close", ex_close, EX(CMD_close, "close", ex_close,
BANG|RANGE|COUNT|TRLBAR|CMDWIN, BANG|RANGE|COUNT|TRLBAR|CMDWIN,
ADDR_WINDOWS), ADDR_WINDOWS),
@@ -353,13 +355,13 @@ EX(CMD_cmenu, "cmenu", ex_menu,
ADDR_OTHER), ADDR_OTHER),
EX(CMD_cnext, "cnext", ex_cnext, EX(CMD_cnext, "cnext", ex_cnext,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_cnewer, "cnewer", qf_age, EX(CMD_cnewer, "cnewer", qf_age,
RANGE|COUNT|TRLBAR, RANGE|COUNT|TRLBAR,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_cnfile, "cnfile", ex_cnext, EX(CMD_cnfile, "cnfile", ex_cnext,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_cnoremap, "cnoremap", ex_map, EX(CMD_cnoremap, "cnoremap", ex_map,
EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN, EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN,
ADDR_NONE), ADDR_NONE),
@@ -374,7 +376,7 @@ EX(CMD_copy, "copy", ex_copymove,
ADDR_LINES), ADDR_LINES),
EX(CMD_colder, "colder", qf_age, EX(CMD_colder, "colder", qf_age,
RANGE|COUNT|TRLBAR, RANGE|COUNT|TRLBAR,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_colorscheme, "colorscheme", ex_colorscheme, EX(CMD_colorscheme, "colorscheme", ex_colorscheme,
WORD1|TRLBAR|CMDWIN, WORD1|TRLBAR|CMDWIN,
ADDR_NONE), ADDR_NONE),
@@ -398,7 +400,7 @@ EX(CMD_copen, "copen", ex_copen,
ADDR_OTHER), ADDR_OTHER),
EX(CMD_cprevious, "cprevious", ex_cnext, EX(CMD_cprevious, "cprevious", ex_cnext,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_cpfile, "cpfile", ex_cnext, EX(CMD_cpfile, "cpfile", ex_cnext,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_OTHER),
@@ -407,7 +409,7 @@ EX(CMD_cquit, "cquit", ex_cquit,
ADDR_NONE), ADDR_NONE),
EX(CMD_crewind, "crewind", ex_cc, EX(CMD_crewind, "crewind", ex_cc,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_cscope, "cscope", ex_cscope, EX(CMD_cscope, "cscope", ex_cscope,
EXTRA|NOTRLCOM|XFILE, EXTRA|NOTRLCOM|XFILE,
ADDR_NONE), ADDR_NONE),
@@ -725,16 +727,16 @@ EX(CMD_list, "list", ex_print,
ADDR_LINES), ADDR_LINES),
EX(CMD_lNext, "lNext", ex_cnext, EX(CMD_lNext, "lNext", ex_cnext,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_lNfile, "lNfile", ex_cnext, EX(CMD_lNfile, "lNfile", ex_cnext,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_last, "last", ex_last, EX(CMD_last, "last", ex_last,
EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR, EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR,
ADDR_NONE), ADDR_NONE),
EX(CMD_labove, "labove", ex_cbelow, EX(CMD_labove, "labove", ex_cbelow,
RANGE|TRLBAR, RANGE|COUNT|TRLBAR,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_language, "language", ex_language, EX(CMD_language, "language", ex_language,
EXTRA|TRLBAR|CMDWIN, EXTRA|TRLBAR|CMDWIN,
ADDR_NONE), ADDR_NONE),
@@ -754,8 +756,8 @@ EX(CMD_lbuffer, "lbuffer", ex_cbuffer,
BANG|RANGE|WORD1|TRLBAR, BANG|RANGE|WORD1|TRLBAR,
ADDR_OTHER), ADDR_OTHER),
EX(CMD_lbelow, "lbelow", ex_cbelow, EX(CMD_lbelow, "lbelow", ex_cbelow,
RANGE|TRLBAR, RANGE|COUNT|TRLBAR,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_lbottom, "lbottom", ex_cbottom, EX(CMD_lbottom, "lbottom", ex_cbottom,
TRLBAR, TRLBAR,
ADDR_NONE), ADDR_NONE),
@@ -773,7 +775,7 @@ EX(CMD_lcscope, "lcscope", ex_cscope,
ADDR_NONE), ADDR_NONE),
EX(CMD_ldo, "ldo", ex_listdo, EX(CMD_ldo, "ldo", ex_listdo,
BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL, BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL,
ADDR_QUICKFIX), ADDR_QUICKFIX_VALID),
EX(CMD_left, "left", ex_align, EX(CMD_left, "left", ex_align,
TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY, TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY,
ADDR_LINES), ADDR_LINES),
@@ -791,10 +793,10 @@ EX(CMD_lfile, "lfile", ex_cfile,
ADDR_NONE), ADDR_NONE),
EX(CMD_lfdo, "lfdo", ex_listdo, EX(CMD_lfdo, "lfdo", ex_listdo,
BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL, BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL,
ADDR_QUICKFIX), ADDR_QUICKFIX_VALID),
EX(CMD_lfirst, "lfirst", ex_cc, EX(CMD_lfirst, "lfirst", ex_cc,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_lgetfile, "lgetfile", ex_cfile, EX(CMD_lgetfile, "lgetfile", ex_cfile,
TRLBAR|FILE1, TRLBAR|FILE1,
ADDR_NONE), ADDR_NONE),
@@ -818,10 +820,10 @@ EX(CMD_lhistory, "lhistory", qf_history,
ADDR_NONE), ADDR_NONE),
EX(CMD_ll, "ll", ex_cc, EX(CMD_ll, "ll", ex_cc,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_QUICKFIX),
EX(CMD_llast, "llast", ex_cc, EX(CMD_llast, "llast", ex_cc,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_llist, "llist", qf_list, EX(CMD_llist, "llist", qf_list,
BANG|EXTRA|TRLBAR|CMDWIN, BANG|EXTRA|TRLBAR|CMDWIN,
ADDR_NONE), ADDR_NONE),
@@ -839,13 +841,13 @@ EX(CMD_lnoremap, "lnoremap", ex_map,
ADDR_NONE), ADDR_NONE),
EX(CMD_lnext, "lnext", ex_cnext, EX(CMD_lnext, "lnext", ex_cnext,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_lnewer, "lnewer", qf_age, EX(CMD_lnewer, "lnewer", qf_age,
RANGE|COUNT|TRLBAR, RANGE|COUNT|TRLBAR,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_lnfile, "lnfile", ex_cnext, EX(CMD_lnfile, "lnfile", ex_cnext,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_loadview, "loadview", ex_loadview, EX(CMD_loadview, "loadview", ex_loadview,
FILE1|TRLBAR, FILE1|TRLBAR,
ADDR_NONE), ADDR_NONE),
@@ -860,19 +862,19 @@ EX(CMD_lockvar, "lockvar", ex_lockvar,
ADDR_NONE), ADDR_NONE),
EX(CMD_lolder, "lolder", qf_age, EX(CMD_lolder, "lolder", qf_age,
RANGE|COUNT|TRLBAR, RANGE|COUNT|TRLBAR,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_lopen, "lopen", ex_copen, EX(CMD_lopen, "lopen", ex_copen,
RANGE|COUNT|TRLBAR, RANGE|COUNT|TRLBAR,
ADDR_OTHER), ADDR_OTHER),
EX(CMD_lprevious, "lprevious", ex_cnext, EX(CMD_lprevious, "lprevious", ex_cnext,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_lpfile, "lpfile", ex_cnext, EX(CMD_lpfile, "lpfile", ex_cnext,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_OTHER),
EX(CMD_lrewind, "lrewind", ex_cc, EX(CMD_lrewind, "lrewind", ex_cc,
RANGE|COUNT|TRLBAR|BANG, RANGE|COUNT|TRLBAR|BANG,
ADDR_OTHER), ADDR_UNSIGNED),
EX(CMD_ltag, "ltag", ex_tag, EX(CMD_ltag, "ltag", ex_tag,
TRLBAR|BANG|WORD1, TRLBAR|BANG|WORD1,
ADDR_NONE), ADDR_NONE),

View File

@@ -2132,7 +2132,7 @@ 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);
if (qf_size <= 0 || eap->line1 > qf_size) if (qf_size <= 0 || eap->line1 > qf_size)
buf = NULL; buf = NULL;
else else

View File

@@ -1786,7 +1786,7 @@ do_one_cmd(
* is equal to the lower. * is equal to the lower.
*/ */
/* ea.addr_type for user commands is set by find_ucmd */ // ea.addr_type for user commands is set by find_ucmd
if (!IS_USER_CMDIDX(ea.cmdidx)) if (!IS_USER_CMDIDX(ea.cmdidx))
{ {
if (ea.cmdidx != CMD_SIZE) if (ea.cmdidx != CMD_SIZE)
@@ -1794,9 +1794,14 @@ do_one_cmd(
else else
ea.addr_type = ADDR_LINES; ea.addr_type = ADDR_LINES;
/* :wincmd range depends on the argument. */ // :wincmd range depends on the argument.
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);
#ifdef FEAT_QUICKFIX
// :.cc in quickfix window uses line number
if ((ea.cmdidx == CMD_cc || ea.cmdidx == CMD_ll) && bt_quickfix(curbuf))
ea.addr_type = ADDR_OTHER;
#endif
} }
ea.cmd = cmd; ea.cmd = cmd;
@@ -2229,15 +2234,17 @@ do_one_cmd(
else else
ea.line2 = ARGCOUNT; ea.line2 = ARGCOUNT;
break; break;
case ADDR_QUICKFIX: case ADDR_QUICKFIX_VALID:
#ifdef FEAT_QUICKFIX #ifdef FEAT_QUICKFIX
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;
#endif #endif
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;
} }
} }
@@ -2905,9 +2912,15 @@ parse_cmd_address(exarg_T *eap, char **errormsg, int 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:
#ifdef FEAT_QUICKFIX
eap->line2 = qf_get_cur_idx(eap);
#endif
break;
case ADDR_QUICKFIX_VALID:
#ifdef FEAT_QUICKFIX #ifdef FEAT_QUICKFIX
eap->line2 = qf_get_cur_valid_idx(eap); eap->line2 = qf_get_cur_valid_idx(eap);
#endif #endif
@@ -2969,6 +2982,8 @@ parse_cmd_address(exarg_T *eap, char **errormsg, int silent)
} }
break; break;
case ADDR_TABS_RELATIVE: case ADDR_TABS_RELATIVE:
case ADDR_UNSIGNED:
case ADDR_QUICKFIX:
*errormsg = _(e_invrange); *errormsg = _(e_invrange);
return FAIL; return FAIL;
case ADDR_ARGUMENTS: case ADDR_ARGUMENTS:
@@ -2980,10 +2995,10 @@ parse_cmd_address(exarg_T *eap, char **errormsg, int silent)
eap->line2 = ARGCOUNT; eap->line2 = ARGCOUNT;
} }
break; break;
case ADDR_QUICKFIX: case ADDR_QUICKFIX_VALID:
#ifdef FEAT_QUICKFIX #ifdef FEAT_QUICKFIX
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;
#endif #endif
@@ -3102,7 +3117,7 @@ append_command(char_u *cmd)
/* /*
* 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.
* Returns pointer to char after the command name. * Sets eap->cmdidx and returns a 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.
*/ */
@@ -4268,11 +4283,17 @@ get_address(
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:
#ifdef FEAT_QUICKFIX
lnum = qf_get_cur_idx(eap);
#endif
break;
case ADDR_QUICKFIX_VALID:
#ifdef FEAT_QUICKFIX #ifdef FEAT_QUICKFIX
lnum = qf_get_cur_valid_idx(eap); lnum = qf_get_cur_valid_idx(eap);
#endif #endif
@@ -4312,6 +4333,7 @@ get_address(
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;
@@ -4321,6 +4343,13 @@ get_address(
lnum = qf_get_size(eap); lnum = qf_get_size(eap);
if (lnum == 0) if (lnum == 0)
lnum = 1; lnum = 1;
#endif
break;
case ADDR_QUICKFIX_VALID:
#ifdef FEAT_QUICKFIX
lnum = qf_get_valid_size(eap);
if (lnum == 0)
lnum = 1;
#endif #endif
break; break;
} }
@@ -4502,11 +4531,18 @@ get_address(
lnum = 1; lnum = 1;
break; break;
case ADDR_QUICKFIX: case ADDR_QUICKFIX:
#ifdef FEAT_QUICKFIX
lnum = qf_get_cur_idx(eap);
#endif
break;
case ADDR_QUICKFIX_VALID:
#ifdef FEAT_QUICKFIX #ifdef FEAT_QUICKFIX
lnum = qf_get_cur_valid_idx(eap); lnum = qf_get_cur_valid_idx(eap);
#endif #endif
break; break;
case ADDR_NONE: case ADDR_NONE:
case ADDR_UNSIGNED:
lnum = 0;
break; break;
} }
} }
@@ -4603,6 +4639,7 @@ ex_script_ni(exarg_T *eap)
invalid_range(exarg_T *eap) invalid_range(exarg_T *eap)
{ {
buf_T *buf; buf_T *buf;
if ( eap->line1 < 0 if ( eap->line1 < 0
|| eap->line2 < 0 || eap->line2 < 0
|| eap->line1 > eap->line2) || eap->line1 > eap->line2)
@@ -4664,10 +4701,22 @@ invalid_range(exarg_T *eap)
break; break;
case ADDR_QUICKFIX: case ADDR_QUICKFIX:
#ifdef FEAT_QUICKFIX #ifdef FEAT_QUICKFIX
if (eap->line2 != 1 && eap->line2 > qf_get_size(eap)) // No error for value that is too big, will use the last entry.
if (eap->line2 <= 0)
return _(e_invrange); return _(e_invrange);
#endif #endif
break; break;
case ADDR_QUICKFIX_VALID:
#ifdef FEAT_QUICKFIX
if ((eap->line2 != 1 && eap->line2 > qf_get_valid_size(eap))
|| eap->line2 < 0)
return _(e_invrange);
#endif
break;
case ADDR_UNSIGNED:
if (eap->line2 < 0)
return _(e_invrange);
break;
case ADDR_NONE: case ADDR_NONE:
// Will give an error elsewhere. // Will give an error elsewhere.
break; break;

View File

@@ -19,6 +19,7 @@ linenr_T qf_current_entry(win_T *wp);
int grep_internal(cmdidx_T cmdidx); int grep_internal(cmdidx_T cmdidx);
void ex_make(exarg_T *eap); void ex_make(exarg_T *eap);
int qf_get_size(exarg_T *eap); int qf_get_size(exarg_T *eap);
int qf_get_valid_size(exarg_T *eap);
int qf_get_cur_idx(exarg_T *eap); int qf_get_cur_idx(exarg_T *eap);
int qf_get_cur_valid_idx(exarg_T *eap); int qf_get_cur_valid_idx(exarg_T *eap);
void ex_cc(exarg_T *eap); void ex_cc(exarg_T *eap);

View File

@@ -4828,10 +4828,23 @@ cleanup:
} }
/* /*
* Returns the number of valid entries in the current quickfix/location list. * Returns the number of entries in the current quickfix/location list.
*/ */
int int
qf_get_size(exarg_T *eap) qf_get_size(exarg_T *eap)
{
qf_info_T *qi;
if ((qi = qf_cmd_get_stack(eap, FALSE)) == NULL)
return 0;
return qf_get_curlist(qi)->qf_count;
}
/*
* Returns the number of valid entries in the current quickfix/location list.
*/
int
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

@@ -28,7 +28,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>
@@ -63,7 +63,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>
@@ -4126,13 +4126,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')
@@ -4145,3 +4141,39 @@ func Test_cbelow()
call Xtest_below('c') call Xtest_below('c')
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

View File

@@ -767,6 +767,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1261,
/**/ /**/
1260, 1260,
/**/ /**/