# HG changeset patch # User Bram Moolenaar # Date 1598210104 -7200 # Node ID 8350bdbdbb28822bddcb2a76ee0a8bfa1c485e08 # Parent 9131ebc53d38990fae7fce76ea2f6f52f00f3095 patch 8.2.1519: Vim9: Ex command default range is not set Commit: https://github.com/vim/vim/commit/c2af0afff5c44969ad7611ec2d47d0f52087fa7f Author: Bram Moolenaar Date: Sun Aug 23 21:06:02 2020 +0200 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 https://github.com/vim/vim/issues/6779) diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -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 **e 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++); @@ -3673,6 +3582,61 @@ addr_error(cmd_addr_T addr_type) } /* + * 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. * * Set ptr to the next character after the part that was interpreted. @@ -4034,6 +3998,68 @@ error: } /* + * 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. */ static void diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -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' diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1519, +/**/ 1518, /**/ 1517,