patch 8.1.1241: Ex command info contains confusing information

Problem:    Ex command info contains confusing information.
Solution:   When using the NOTADR flag use ADDR_OTHER for the address type.
            Cleanup code using NOTADR.  Check for errors in
            create_cmdidxs.vim.  Adjust Makefile to see the errors.
This commit is contained in:
Bram Moolenaar
2019-05-01 18:08:42 +02:00
parent d96dbd6f95
commit b731689e85
9 changed files with 769 additions and 700 deletions

View File

@@ -1987,7 +1987,7 @@ autoconf:
# If this fails because you don't have Vim yet, first build and install Vim # If this fails because you don't have Vim yet, first build and install Vim
# without changes. # without changes.
cmdidxs: ex_cmds.h cmdidxs: ex_cmds.h
vim -u NONE -i NONE -X -S create_cmdidxs.vim vim --clean -X -u create_cmdidxs.vim
# The normal command to compile a .c file to its .o file. # The normal command to compile a .c file to its .o file.

View File

@@ -10,7 +10,10 @@
let cmds = [] let cmds = []
let skipped_cmds = 0 let skipped_cmds = 0
for line in readfile('ex_cmds.h') let lines = readfile('ex_cmds.h')
let idx = 0
while idx < len(lines)
let line = lines[idx]
if line =~ '^EX(CMD_' if line =~ '^EX(CMD_'
let m = matchlist(line, '^EX(CMD_\S*,\s*"\([a-z][^"]*\)"') let m = matchlist(line, '^EX(CMD_\S*,\s*"\([a-z][^"]*\)"')
if len(m) >= 2 if len(m) >= 2
@@ -18,8 +21,28 @@ for line in readfile('ex_cmds.h')
else else
let skipped_cmds += 1 let skipped_cmds += 1
endif endif
let idx += 1
let flags = lines[idx]
let idx += 1
let addr_type = lines[idx]
if flags =~ '\<RANGE\>'
if addr_type =~ 'ADDR_NONE'
echoerr 'ex_cmds.h:' .. (idx - 1) .. ': Using RANGE with ADDR_NONE: ' .. line
endif endif
endfor else
if addr_type !~ 'ADDR_NONE'
echoerr 'ex_cmds.h:' .. (idx - 1) .. ': Missing ADDR_NONE: ' .. line
endif
endif
if flags =~ '\<DFLALL\>' && (addr_type =~ 'ADDR_OTHER' || addr_type =~ 'ADDR_NONE')
echoerr 'ex_cmds.h:' .. (idx - 1) .. ': Missing misplaced DFLALL: ' .. line
endif
endif
let idx += 1
endwhile
let cmdidxs1 = {} let cmdidxs1 = {}
let cmdidxs2 = {} let cmdidxs2 = {}

View File

@@ -3157,6 +3157,13 @@ ex_update(exarg_T *eap)
void void
ex_write(exarg_T *eap) ex_write(exarg_T *eap)
{ {
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 */ if (eap->usefilter) /* input lines to shell command */
do_bang(1, eap, FALSE, TRUE, FALSE); do_bang(1, eap, FALSE, TRUE, FALSE);
else else

File diff suppressed because it is too large Load Diff

View File

@@ -73,7 +73,7 @@ static int getargopt(exarg_T *eap);
# define ex_cexpr ex_ni # define ex_cexpr ex_ni
#endif #endif
static linenr_T get_address(exarg_T *, char_u **, int addr_type, int skip, int silent, int to_other_file, int address_count); static linenr_T get_address(exarg_T *, char_u **, cmd_addr_T addr_type, int skip, int silent, int to_other_file, int address_count);
static void get_flags(exarg_T *eap); static void get_flags(exarg_T *eap);
#if !defined(FEAT_PERL) \ #if !defined(FEAT_PERL) \
|| !defined(FEAT_PYTHON) || !defined(FEAT_PYTHON3) \ || !defined(FEAT_PYTHON) || !defined(FEAT_PYTHON3) \
@@ -1577,6 +1577,10 @@ compute_buffer_local_count(int addr_type, int lnum, int offset)
return buf->b_fnum; return buf->b_fnum;
} }
/*
* Return the window number of "win".
* When "win" is NULL return the number of windows.
*/
static int static int
current_win_nr(win_T *win) current_win_nr(win_T *win)
{ {
@@ -1951,7 +1955,7 @@ do_one_cmd(
ea.forceit = FALSE; ea.forceit = FALSE;
/* /*
* 6. Parse arguments. * 6. Parse arguments. Then check for errors.
*/ */
if (!IS_USER_CMDIDX(ea.cmdidx)) if (!IS_USER_CMDIDX(ea.cmdidx))
ea.argt = (long)cmdnames[(int)ea.cmdidx].cmd_argt; ea.argt = (long)cmdnames[(int)ea.cmdidx].cmd_argt;
@@ -2016,7 +2020,7 @@ do_one_cmd(
* Don't complain about the range if it is not used * Don't complain about the range if it is not used
* (could happen if line_count is accidentally set to 0). * (could happen if line_count is accidentally set to 0).
*/ */
if (!ea.skip && !ni) if (!ea.skip && !ni && (ea.argt & RANGE))
{ {
/* /*
* If the range is backwards, ask for confirmation and, if given, swap * If the range is backwards, ask for confirmation and, if given, swap
@@ -2044,7 +2048,8 @@ do_one_cmd(
goto doend; 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; ea.line2 = 1;
correct_range(&ea); correct_range(&ea);
@@ -2191,6 +2196,7 @@ do_one_cmd(
switch (ea.addr_type) switch (ea.addr_type)
{ {
case ADDR_LINES: case ADDR_LINES:
case ADDR_OTHER:
ea.line2 = curbuf->b_ml.ml_line_count; ea.line2 = curbuf->b_ml.ml_line_count;
break; break;
case ADDR_LOADED_BUFFERS: case ADDR_LOADED_BUFFERS:
@@ -2229,6 +2235,9 @@ do_one_cmd(
ea.line2 = 1; ea.line2 = 1;
break; break;
#endif #endif
case ADDR_NONE:
iemsg(_("INTERNAL: Cannot use DFLALL with ADDR_NONE"));
break;
} }
} }
@@ -2278,7 +2287,7 @@ do_one_cmd(
errormsg = _(e_zerocount); errormsg = _(e_zerocount);
goto doend; 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; ea.line2 = n;
if (ea.addr_count == 0) if (ea.addr_count == 0)
@@ -2292,8 +2301,7 @@ do_one_cmd(
/* /*
* Be vi compatible: no error message for out of range. * Be vi compatible: no error message for out of range.
*/ */
if (ea.addr_type == ADDR_LINES if (ea.line2 > curbuf->b_ml.ml_line_count)
&& ea.line2 > curbuf->b_ml.ml_line_count)
ea.line2 = curbuf->b_ml.ml_line_count; ea.line2 = curbuf->b_ml.ml_line_count;
} }
} }
@@ -2876,6 +2884,7 @@ parse_cmd_address(exarg_T *eap, char **errormsg, int silent)
switch (eap->addr_type) switch (eap->addr_type)
{ {
case ADDR_LINES: case ADDR_LINES:
case ADDR_OTHER:
// default is current line number // default is current line number
eap->line2 = curwin->w_cursor.lnum; eap->line2 = curwin->w_cursor.lnum;
break; break;
@@ -2902,6 +2911,9 @@ parse_cmd_address(exarg_T *eap, char **errormsg, int silent)
eap->line2 = qf_get_cur_valid_idx(eap); eap->line2 = qf_get_cur_valid_idx(eap);
break; break;
#endif #endif
case ADDR_NONE:
// Will give an error later if a range is found.
break;
} }
eap->cmd = skipwhite(eap->cmd); eap->cmd = skipwhite(eap->cmd);
lnum = get_address(eap, &eap->cmd, eap->addr_type, eap->skip, silent, lnum = get_address(eap, &eap->cmd, eap->addr_type, eap->skip, silent,
@@ -2916,6 +2928,7 @@ parse_cmd_address(exarg_T *eap, char **errormsg, int silent)
switch (eap->addr_type) switch (eap->addr_type)
{ {
case ADDR_LINES: case ADDR_LINES:
case ADDR_OTHER:
eap->line1 = 1; eap->line1 = 1;
eap->line2 = curbuf->b_ml.ml_line_count; eap->line2 = curbuf->b_ml.ml_line_count;
break; break;
@@ -2955,7 +2968,6 @@ parse_cmd_address(exarg_T *eap, char **errormsg, int silent)
} }
break; break;
case ADDR_TABS_RELATIVE: case ADDR_TABS_RELATIVE:
case ADDR_OTHER:
*errormsg = _(e_invrange); *errormsg = _(e_invrange);
return FAIL; return FAIL;
case ADDR_ARGUMENTS: case ADDR_ARGUMENTS:
@@ -2975,6 +2987,9 @@ parse_cmd_address(exarg_T *eap, char **errormsg, int silent)
eap->line2 = 1; eap->line2 = 1;
break; break;
#endif #endif
case ADDR_NONE:
// Will give an error later if a range is found.
break;
} }
++eap->addr_count; ++eap->addr_count;
} }
@@ -4207,12 +4222,13 @@ skip_range(
get_address( get_address(
exarg_T *eap UNUSED, exarg_T *eap UNUSED,
char_u **ptr, char_u **ptr,
int addr_type, // flag: one of ADDR_LINES, ... cmd_addr_T addr_type_arg,
int skip, // only skip the address, don't use it int skip, // only skip the address, don't use it
int silent, // no errors or side effects int silent, // no errors or side effects
int to_other_file, // flag: may jump to other file int to_other_file, // flag: may jump to other file
int address_count UNUSED) // 1 for first address, >1 after comma int address_count UNUSED) // 1 for first address, >1 after comma
{ {
cmd_addr_T addr_type = addr_type_arg;
int c; int c;
int i; int i;
long n; long n;
@@ -4233,6 +4249,7 @@ get_address(
switch (addr_type) switch (addr_type)
{ {
case ADDR_LINES: case ADDR_LINES:
case ADDR_OTHER:
lnum = curwin->w_cursor.lnum; lnum = curwin->w_cursor.lnum;
break; break;
case ADDR_WINDOWS: case ADDR_WINDOWS:
@@ -4249,6 +4266,7 @@ get_address(
lnum = CURRENT_TAB_NR; lnum = CURRENT_TAB_NR;
break; break;
case ADDR_TABS_RELATIVE: case ADDR_TABS_RELATIVE:
case ADDR_NONE:
emsg(_(e_invrange)); emsg(_(e_invrange));
cmd = NULL; cmd = NULL;
goto error; goto error;
@@ -4266,6 +4284,7 @@ get_address(
switch (addr_type) switch (addr_type)
{ {
case ADDR_LINES: case ADDR_LINES:
case ADDR_OTHER:
lnum = curbuf->b_ml.ml_line_count; lnum = curbuf->b_ml.ml_line_count;
break; break;
case ADDR_WINDOWS: case ADDR_WINDOWS:
@@ -4291,6 +4310,7 @@ get_address(
lnum = LAST_TAB_NR; lnum = LAST_TAB_NR;
break; break;
case ADDR_TABS_RELATIVE: case ADDR_TABS_RELATIVE:
case ADDR_NONE:
emsg(_(e_invrange)); emsg(_(e_invrange));
cmd = NULL; cmd = NULL;
goto error; goto error;
@@ -4460,7 +4480,8 @@ get_address(
switch (addr_type) switch (addr_type)
{ {
case ADDR_LINES: case ADDR_LINES:
/* "+1" is same as ".+1" */ case ADDR_OTHER:
// "+1" is same as ".+1"
lnum = curwin->w_cursor.lnum; lnum = curwin->w_cursor.lnum;
break; break;
case ADDR_WINDOWS: case ADDR_WINDOWS:
@@ -4484,6 +4505,8 @@ get_address(
lnum = qf_get_cur_valid_idx(eap); lnum = qf_get_cur_valid_idx(eap);
break; break;
#endif #endif
case ADDR_NONE:
break;
} }
} }
@@ -4586,11 +4609,10 @@ invalid_range(exarg_T *eap)
if (eap->argt & RANGE) if (eap->argt & RANGE)
{ {
switch(eap->addr_type) switch (eap->addr_type)
{ {
case ADDR_LINES: case ADDR_LINES:
if (!(eap->argt & NOTADR) if (eap->line2 > curbuf->b_ml.ml_line_count
&& eap->line2 > curbuf->b_ml.ml_line_count
#ifdef FEAT_DIFF #ifdef FEAT_DIFF
+ (eap->cmdidx == CMD_diffget) + (eap->cmdidx == CMD_diffget)
#endif #endif
@@ -4636,7 +4658,8 @@ invalid_range(exarg_T *eap)
return _(e_invrange); return _(e_invrange);
break; break;
case ADDR_TABS_RELATIVE: case ADDR_TABS_RELATIVE:
/* Do nothing */ case ADDR_OTHER:
// Any range is OK.
break; break;
#ifdef FEAT_QUICKFIX #ifdef FEAT_QUICKFIX
case ADDR_QUICKFIX: case ADDR_QUICKFIX:
@@ -4644,6 +4667,9 @@ invalid_range(exarg_T *eap)
return _(e_invrange); return _(e_invrange);
break; break;
#endif #endif
case ADDR_NONE:
// Will give an error elsewhere.
break;
} }
} }
return NULL; return NULL;

View File

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

View File

@@ -20,7 +20,7 @@ typedef struct ucmd
char_u *uc_rep; // The command's replacement string char_u *uc_rep; // The command's replacement string
long uc_def; // The default value for a range/count long uc_def; // The default value for a range/count
int uc_compl; // completion type int uc_compl; // completion type
int uc_addr_type; // The command's address type cmd_addr_T uc_addr_type; // The command's address type
# ifdef FEAT_EVAL # ifdef FEAT_EVAL
sctx_T uc_script_ctx; // SCTX where the command was defined sctx_T uc_script_ctx; // SCTX where the command was defined
# ifdef FEAT_CMDL_COMPL # ifdef FEAT_CMDL_COMPL
@@ -101,7 +101,7 @@ static struct
*/ */
static struct static struct
{ {
int expand; cmd_addr_T expand;
char *name; char *name;
char *shortname; char *shortname;
} addr_type_complete[] = } addr_type_complete[] =
@@ -114,7 +114,7 @@ static struct
{ADDR_WINDOWS, "windows", "win"}, {ADDR_WINDOWS, "windows", "win"},
{ADDR_QUICKFIX, "quickfix", "qf"}, {ADDR_QUICKFIX, "quickfix", "qf"},
{ADDR_OTHER, "other", "?"}, {ADDR_OTHER, "other", "?"},
{-1, NULL, NULL} {ADDR_NONE, NULL, NULL}
}; };
#define UC_BUFFER 1 // -buffer: local to current buffer #define UC_BUFFER 1 // -buffer: local to current buffer
@@ -495,7 +495,7 @@ uc_list(char_u *name, size_t name_len)
} while (len < 8 - over); } while (len < 8 - over);
// Address Type // Address Type
for (j = 0; addr_type_complete[j].expand != -1; ++j) for (j = 0; addr_type_complete[j].expand != ADDR_NONE; ++j)
if (addr_type_complete[j].expand != ADDR_LINES if (addr_type_complete[j].expand != ADDR_LINES
&& addr_type_complete[j].expand == cmd->uc_addr_type) && addr_type_complete[j].expand == cmd->uc_addr_type)
{ {
@@ -566,12 +566,11 @@ uc_fun_cmd(void)
parse_addr_type_arg( parse_addr_type_arg(
char_u *value, char_u *value,
int vallen, int vallen,
long *argt, cmd_addr_T *addr_type_arg)
int *addr_type_arg)
{ {
int i, a, b; int i, a, b;
for (i = 0; addr_type_complete[i].expand != -1; ++i) for (i = 0; addr_type_complete[i].expand != ADDR_NONE; ++i)
{ {
a = (int)STRLEN(addr_type_complete[i].name) == vallen; a = (int)STRLEN(addr_type_complete[i].name) == vallen;
b = STRNCMP(value, addr_type_complete[i].name, vallen) == 0; b = STRNCMP(value, addr_type_complete[i].name, vallen) == 0;
@@ -582,7 +581,7 @@ parse_addr_type_arg(
} }
} }
if (addr_type_complete[i].expand == -1) if (addr_type_complete[i].expand == ADDR_NONE)
{ {
char_u *err = value; char_u *err = value;
@@ -593,9 +592,6 @@ parse_addr_type_arg(
return FAIL; return FAIL;
} }
if (*addr_type_arg != ADDR_LINES)
*argt |= NOTADR;
return OK; return OK;
} }
@@ -694,7 +690,7 @@ uc_scan_attr(
int *flags, int *flags,
int *complp, int *complp,
char_u **compl_arg, char_u **compl_arg,
int *addr_type_arg) cmd_addr_T *addr_type_arg)
{ {
char_u *p; char_u *p;
@@ -773,7 +769,7 @@ two_count:
} }
*def = getdigits(&p); *def = getdigits(&p);
*argt |= (ZEROR | NOTADR); *argt |= ZEROR;
if (p != val + vallen || vallen == 0) if (p != val + vallen || vallen == 0)
{ {
@@ -782,10 +778,16 @@ invalid_count:
return FAIL; 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) 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) if (val != NULL)
{ {
@@ -822,11 +824,10 @@ invalid_count:
emsg(_("E179: argument required for -addr")); emsg(_("E179: argument required for -addr"));
return FAIL; return FAIL;
} }
if (parse_addr_type_arg(val, (int)vallen, argt, addr_type_arg) if (parse_addr_type_arg(val, (int)vallen, addr_type_arg) == FAIL)
== FAIL)
return FAIL; return FAIL;
if (addr_type_arg != ADDR_LINES) if (addr_type_arg != ADDR_LINES)
*argt |= (ZEROR | NOTADR) ; *argt |= (ZEROR) ;
} }
else else
{ {
@@ -854,7 +855,7 @@ uc_add_command(
int flags, int flags,
int compl, int compl,
char_u *compl_arg UNUSED, char_u *compl_arg UNUSED,
int addr_type, cmd_addr_T addr_type,
int force) int force)
{ {
ucmd_T *cmd = NULL; ucmd_T *cmd = NULL;
@@ -982,7 +983,7 @@ ex_command(exarg_T *eap)
int flags = 0; int flags = 0;
int compl = EXPAND_NOTHING; int compl = EXPAND_NOTHING;
char_u *compl_arg = NULL; char_u *compl_arg = NULL;
int addr_type_arg = ADDR_LINES; cmd_addr_T addr_type_arg = ADDR_NONE;
int has_attr = (eap->arg[0] == '-'); int has_attr = (eap->arg[0] == '-');
int name_len; int name_len;

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 */
/**/
1241,
/**/ /**/
1240, 1240,
/**/ /**/

View File

@@ -601,7 +601,7 @@ wingotofile:
} }
/* /*
* Figure out the address type for ":wnncmd". * Figure out the address type for ":wincmd".
*/ */
void void
get_wincmd_addr_type(char_u *arg, exarg_T *eap) get_wincmd_addr_type(char_u *arg, exarg_T *eap)
@@ -656,13 +656,13 @@ get_wincmd_addr_type(char_u *arg, exarg_T *eap)
case 'd': case 'd':
case Ctrl_D: case Ctrl_D:
#endif #endif
/* window size or any count */ // window size or any count
eap->addr_type = ADDR_LINES; eap->addr_type = ADDR_OTHER;
break; break;
case Ctrl_HAT: case Ctrl_HAT:
case '^': case '^':
/* buffer number */ // buffer number
eap->addr_type = ADDR_BUFFERS; eap->addr_type = ADDR_BUFFERS;
break; break;
@@ -677,7 +677,7 @@ get_wincmd_addr_type(char_u *arg, exarg_T *eap)
case 'W': case 'W':
case 'x': case 'x':
case Ctrl_X: case Ctrl_X:
/* window number */ // window number
eap->addr_type = ADDR_WINDOWS; eap->addr_type = ADDR_WINDOWS;
break; break;
@@ -694,8 +694,8 @@ get_wincmd_addr_type(char_u *arg, exarg_T *eap)
case Ctrl_P: case Ctrl_P:
case '=': case '=':
case CAR: case CAR:
/* no count */ // no count
eap->addr_type = 0; eap->addr_type = ADDR_NONE;
break; break;
} }
} }