0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 8.2.1519: Vim9: Ex command default range is not set

Problem:    Vim9: Ex command default range is not set.
Solution:   When range is not given use default. (closes #6779)
This commit is contained in:
Bram Moolenaar
2020-08-23 21:06:02 +02:00
parent 2e80095501
commit c2af0afff5
3 changed files with 138 additions and 98 deletions

View File

@@ -66,7 +66,9 @@ static int getargopt(exarg_T *eap);
# define ex_cexpr ex_ni
#endif
static linenr_T default_address(exarg_T *eap);
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 address_default_all(exarg_T *eap);
static void get_flags(exarg_T *eap);
#if !defined(FEAT_PERL) \
|| !defined(FEAT_PYTHON) || !defined(FEAT_PYTHON3) \
@@ -1880,7 +1882,9 @@ do_one_cmd(
ea.cmd = cmd;
#ifdef FEAT_EVAL
if (may_have_range)
if (!may_have_range)
ea.line1 = ea.line2 = default_address(&ea);
else
#endif
if (parse_cmd_address(&ea, &errormsg, FALSE) == FAIL)
goto doend;
@@ -2282,59 +2286,7 @@ do_one_cmd(
}
if ((ea.argt & EX_DFLALL) && ea.addr_count == 0)
{
buf_T *buf;
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:
buf = firstbuf;
while (buf->b_next != NULL && buf->b_ml.ml_mfp == NULL)
buf = buf->b_next;
ea.line1 = buf->b_fnum;
buf = lastbuf;
while (buf->b_prev != NULL && buf->b_ml.ml_mfp == NULL)
buf = buf->b_prev;
ea.line2 = buf->b_fnum;
break;
case ADDR_BUFFERS:
ea.line1 = firstbuf->b_fnum;
ea.line2 = lastbuf->b_fnum;
break;
case ADDR_WINDOWS:
ea.line2 = LAST_WIN_NR;
break;
case ADDR_TABS:
ea.line2 = LAST_TAB_NR;
break;
case ADDR_TABS_RELATIVE:
ea.line2 = 1;
break;
case ADDR_ARGUMENTS:
if (ARGCOUNT == 0)
ea.line1 = ea.line2 = 0;
else
ea.line2 = ARGCOUNT;
break;
case ADDR_QUICKFIX_VALID:
#ifdef FEAT_QUICKFIX
ea.line2 = qf_get_valid_size(&ea);
if (ea.line2 == 0)
ea.line2 = 1;
#endif
break;
case ADDR_NONE:
case ADDR_UNSIGNED:
case ADDR_QUICKFIX:
iemsg(_("INTERNAL: Cannot use EX_DFLALL with ADDR_NONE, ADDR_UNSIGNED or ADDR_QUICKFIX"));
break;
}
}
address_default_all(&ea);
// accept numbered register only when no count allowed (:put)
if ( (ea.argt & EX_REGSTR)
@@ -3011,50 +2963,7 @@ parse_cmd_address(exarg_T *eap, char **errormsg, int silent)
for (;;)
{
eap->line1 = eap->line2;
switch (eap->addr_type)
{
case ADDR_LINES:
case ADDR_OTHER:
// Default is the cursor line number. Avoid using an invalid
// line number though.
if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
eap->line2 = curbuf->b_ml.ml_line_count;
else
eap->line2 = curwin->w_cursor.lnum;
break;
case ADDR_WINDOWS:
eap->line2 = CURRENT_WIN_NR;
break;
case ADDR_ARGUMENTS:
eap->line2 = curwin->w_arg_idx + 1;
if (eap->line2 > ARGCOUNT)
eap->line2 = ARGCOUNT;
break;
case ADDR_LOADED_BUFFERS:
case ADDR_BUFFERS:
eap->line2 = curbuf->b_fnum;
break;
case ADDR_TABS:
eap->line2 = CURRENT_TAB_NR;
break;
case ADDR_TABS_RELATIVE:
case ADDR_UNSIGNED:
eap->line2 = 1;
break;
case ADDR_QUICKFIX:
#ifdef FEAT_QUICKFIX
eap->line2 = qf_get_cur_idx(eap);
#endif
break;
case ADDR_QUICKFIX_VALID:
#ifdef FEAT_QUICKFIX
eap->line2 = qf_get_cur_valid_idx(eap);
#endif
break;
case ADDR_NONE:
// Will give an error later if a range is found.
break;
}
eap->line2 = default_address(eap);
eap->cmd = skipwhite(eap->cmd);
lnum = get_address(eap, &eap->cmd, eap->addr_type, eap->skip, silent,
eap->addr_count == 0, address_count++);
@@ -3672,6 +3581,61 @@ addr_error(cmd_addr_T addr_type)
emsg(_(e_invrange));
}
/*
* Return the default address for an address type.
*/
static linenr_T
default_address(exarg_T *eap)
{
linenr_T lnum = 0;
switch (eap->addr_type)
{
case ADDR_LINES:
case ADDR_OTHER:
// Default is the cursor line number. Avoid using an invalid
// line number though.
if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
lnum = curbuf->b_ml.ml_line_count;
else
lnum = curwin->w_cursor.lnum;
break;
case ADDR_WINDOWS:
lnum = CURRENT_WIN_NR;
break;
case ADDR_ARGUMENTS:
lnum = curwin->w_arg_idx + 1;
if (lnum > ARGCOUNT)
lnum = ARGCOUNT;
break;
case ADDR_LOADED_BUFFERS:
case ADDR_BUFFERS:
lnum = curbuf->b_fnum;
break;
case ADDR_TABS:
lnum = CURRENT_TAB_NR;
break;
case ADDR_TABS_RELATIVE:
case ADDR_UNSIGNED:
lnum = 1;
break;
case ADDR_QUICKFIX:
#ifdef FEAT_QUICKFIX
lnum = qf_get_cur_idx(eap);
#endif
break;
case ADDR_QUICKFIX_VALID:
#ifdef FEAT_QUICKFIX
lnum = qf_get_cur_valid_idx(eap);
#endif
break;
case ADDR_NONE:
// Will give an error later if a range is found.
break;
}
return lnum;
}
/*
* Get a single EX address.
*
@@ -4033,6 +3997,68 @@ error:
return lnum;
}
/*
* Set eap->line1 and eap->line2 to the whole range.
* Used for commands with the EX_DFLALL flag and no range given.
*/
static void
address_default_all(exarg_T *eap)
{
eap->line1 = 1;
switch (eap->addr_type)
{
case ADDR_LINES:
case ADDR_OTHER:
eap->line2 = curbuf->b_ml.ml_line_count;
break;
case ADDR_LOADED_BUFFERS:
{
buf_T *buf = firstbuf;
while (buf->b_next != NULL && buf->b_ml.ml_mfp == NULL)
buf = buf->b_next;
eap->line1 = buf->b_fnum;
buf = lastbuf;
while (buf->b_prev != NULL && buf->b_ml.ml_mfp == NULL)
buf = buf->b_prev;
eap->line2 = buf->b_fnum;
}
break;
case ADDR_BUFFERS:
eap->line1 = firstbuf->b_fnum;
eap->line2 = lastbuf->b_fnum;
break;
case ADDR_WINDOWS:
eap->line2 = LAST_WIN_NR;
break;
case ADDR_TABS:
eap->line2 = LAST_TAB_NR;
break;
case ADDR_TABS_RELATIVE:
eap->line2 = 1;
break;
case ADDR_ARGUMENTS:
if (ARGCOUNT == 0)
eap->line1 = eap->line2 = 0;
else
eap->line2 = ARGCOUNT;
break;
case ADDR_QUICKFIX_VALID:
#ifdef FEAT_QUICKFIX
eap->line2 = qf_get_valid_size(eap);
if (eap->line2 == 0)
eap->line2 = 1;
#endif
break;
case ADDR_NONE:
case ADDR_UNSIGNED:
case ADDR_QUICKFIX:
iemsg(_("INTERNAL: Cannot use EX_DFLALL with ADDR_NONE, ADDR_UNSIGNED or ADDR_QUICKFIX"));
break;
}
}
/*
* Get flags from an Ex command argument.
*/

View File

@@ -15,6 +15,18 @@ def Test_range_only()
setline(1, ['blah', 'Blah'])
:/Blah/
assert_equal(2, getcurpos()[1])
bwipe!
# without range commands use current line
new
setline(1, ['one', 'two', 'three'])
:2
print
assert_equal('two', Screenline(&lines))
:3
list
assert_equal('three$', Screenline(&lines))
bwipe!
enddef
let s:appendToMe = 'xxx'

View File

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