]> granicus.if.org Git - vim/commitdiff
patch 8.2.1519: Vim9: Ex command default range is not set v8.2.1519
authorBram Moolenaar <Bram@vim.org>
Sun, 23 Aug 2020 19:06:02 +0000 (21:06 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 23 Aug 2020 19:06:02 +0000 (21:06 +0200)
Problem:    Vim9: Ex command default range is not set.
Solution:   When range is not given use default. (closes #6779)

src/ex_docmd.c
src/testdir/test_vim9_script.vim
src/version.c

index e252b05794571cb3456baa06458d0080a7af4f43..3dee01d281f39ed141fbea5c2201e383753c3c2c 100644 (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.
  */
index 45384d1d8b84d8aa2549d2fa165da61b5fc9bfc0..245817b998ade3a208a7850e72eb1916f7eeae48 100644 (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'
index 7b52e0546afae144187de3b5a0d33068e5471be0..421e4a68cfa5cc63132d0e5c245e6d742fc85d46 100644 (file)
@@ -754,6 +754,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1519,
 /**/
     1518,
 /**/