]> granicus.if.org Git - vim/commitdiff
patch 8.2.3888: the argument list may contain duplicates v8.2.3888
authorNir Lichtman <nir_lichtman@hotmail.com>
Fri, 24 Dec 2021 20:28:03 +0000 (20:28 +0000)
committerBram Moolenaar <Bram@vim.org>
Fri, 24 Dec 2021 20:28:03 +0000 (20:28 +0000)
Problem:    The argument list may contain duplicates.
Solution:   Add the :argdedeupe command. (Nir Lichtman, closes #6235)

runtime/doc/editing.txt
runtime/doc/index.txt
src/arglist.c
src/ex_cmdidxs.h
src/ex_cmds.h
src/proto/arglist.pro
src/testdir/test_arglist.vim
src/version.c

index 9736d4c481f45988f8672a9a68f6d680de9b0fa5..fc4080cd8d9190f083d3c62f5a2f4d6192f09b8b 100644 (file)
@@ -650,12 +650,19 @@ list of the current window.
                        And after the last one:
                                :+2argadd y     a b c x y
                        There is no check for duplicates, it is possible to
-                       add a file to the argument list twice.
-                       The currently edited file is not changed.
+                       add a file to the argument list twice.  You can use
+                       |:argdedupe| to fix it afterwards: >
+                               :argadd *.txt | argdedupe
+<                      The currently edited file is not changed.
                        Note: you can also use this method: >
                                :args ## x
 <                      This will add the "x" item and sort the new list.
 
+:argded[upe]                                   *:argded* *:argdedupe*
+                       Remove duplicate filenames from the argument list.
+                       If your current file is a duplicate, your current file
+                       will change to the original file index.
+
 :argd[elete] {pattern} ..              *:argd* *:argdelete* *E480* *E610*
                        Delete files from the argument list that match the
                        {pattern}s.  {pattern} is used like a file pattern,
index 4af59c64a69c67a7ee3ae9bdb2c104bf0dff3db6..cbf363a77ce53757e001160026b1f16ebb6e5e76 100644 (file)
@@ -1166,6 +1166,7 @@ tag               command         action ~
                                be remapped
 |:args|                :ar[gs]         print the argument list
 |:argadd|      :arga[dd]       add items to the argument list
+:argdedupe     :argdedupe      remove duplicates from the argument list
 |:argdelete|   :argd[elete]    delete items from the argument list
 |:argedit|     :arge[dit]      add item to the argument list and edit it
 |:argdo|       :argdo          do a command on all items in the argument list
index af8ce740fcd7dfa17ba636304e9323f3bcf0d9e5..90ee4796b812900113d19c3a37d282c82d0333f4 100644 (file)
@@ -758,6 +758,33 @@ ex_next(exarg_T *eap)
     }
 }
 
+/*
+ * ":argdedupe"
+ */
+    void
+ex_argdedupe(exarg_T *eap UNUSED)
+{
+    int i;
+    int j;
+
+    for (i = 0; i < ARGCOUNT; ++i)
+       for (j = i + 1; j < ARGCOUNT; ++j)
+           if (fnamecmp(ARGLIST[i].ae_fname, ARGLIST[j].ae_fname) == 0)
+           {
+               vim_free(ARGLIST[j].ae_fname);
+               mch_memmove(ARGLIST + j, ARGLIST + j + 1,
+                                       (ARGCOUNT - j - 1) * sizeof(aentry_T));
+               --ARGCOUNT;
+
+               if (curwin->w_arg_idx == j)
+                   curwin->w_arg_idx = i;
+               else if (curwin->w_arg_idx > j)
+                   --curwin->w_arg_idx;
+
+               --j;
+           }
+}
+
 /*
  * ":argedit"
  */
index 3ad1cd8ecfd74533b27eb99c37e4818001f296bf..b4743cd0e1f9b96ce35d51fa71edc433885b48be 100644 (file)
@@ -6,31 +6,31 @@
 static const unsigned short cmdidxs1[26] =
 {
   /* a */ 0,
-  /* b */ 20,
-  /* c */ 44,
-  /* d */ 111,
-  /* e */ 136,
-  /* f */ 164,
-  /* g */ 181,
-  /* h */ 187,
-  /* i */ 196,
-  /* j */ 216,
-  /* k */ 218,
-  /* l */ 223,
-  /* m */ 286,
-  /* n */ 304,
-  /* o */ 324,
-  /* p */ 336,
-  /* q */ 375,
-  /* r */ 378,
-  /* s */ 398,
-  /* t */ 468,
-  /* u */ 514,
-  /* v */ 525,
-  /* w */ 546,
-  /* x */ 560,
-  /* y */ 570,
-  /* z */ 571
+  /* b */ 21,
+  /* c */ 45,
+  /* d */ 112,
+  /* e */ 137,
+  /* f */ 165,
+  /* g */ 182,
+  /* h */ 188,
+  /* i */ 197,
+  /* j */ 217,
+  /* k */ 219,
+  /* l */ 224,
+  /* m */ 287,
+  /* n */ 305,
+  /* o */ 325,
+  /* p */ 337,
+  /* q */ 376,
+  /* r */ 379,
+  /* s */ 399,
+  /* t */ 469,
+  /* u */ 515,
+  /* v */ 526,
+  /* w */ 547,
+  /* x */ 561,
+  /* y */ 571,
+  /* z */ 572
 };
 
 /*
@@ -41,7 +41,7 @@ static const unsigned short cmdidxs1[26] =
  */
 static const unsigned char cmdidxs2[26][26] =
 { /*         a   b   c   d   e   f   g   h   i   j   k   l   m   n   o   p   q   r   s   t   u   v   w   x   y   z */
-  /* a */ {  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  6,  7,  0,  0,  0,  8, 16,  0, 17,  0,  0,  0,  0,  0 },
+  /* a */ {  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  6,  7,  0,  0,  0,  8, 17,  0, 18,  0,  0,  0,  0,  0 },
   /* b */ {  2,  0,  0,  5,  6,  8,  0,  0,  0,  0,  0,  9, 10, 11, 12, 13,  0, 14,  0,  0,  0,  0, 23,  0,  0,  0 },
   /* c */ {  3, 12, 16, 18, 20, 22, 25,  0,  0,  0,  0, 33, 38, 41, 47, 57, 59, 60, 61,  0, 63,  0, 66,  0,  0,  0 },
   /* d */ {  0,  0,  0,  0,  0,  0,  0,  0,  8, 18,  0, 19,  0,  0, 20,  0,  0, 22, 23,  0,  0,  0,  0,  0,  0,  0 },
@@ -69,4 +69,4 @@ static const unsigned char cmdidxs2[26][26] =
   /* z */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }
 };
 
-static const int command_count = 588;
+static const int command_count = 589;
index 044580a7c1d54dc850661c124687191c061d8c02..3cdb656c990eeed471b1b64269fbbaa82b7d2ce8 100644 (file)
@@ -148,6 +148,9 @@ EXCMD(CMD_argdelete,        "argdelete",    ex_argdelete,
 EXCMD(CMD_argdo,       "argdo",        ex_listdo,
        EX_BANG|EX_NEEDARG|EX_EXTRA|EX_NOTRLCOM|EX_RANGE|EX_DFLALL|EX_EXPAND,
        ADDR_ARGUMENTS),
+EXCMD(CMD_argdedupe,   "argdedupe",    ex_argdedupe,
+       EX_TRLBAR,
+       ADDR_NONE),
 EXCMD(CMD_argedit,     "argedit",      ex_argedit,
        EX_BANG|EX_NEEDARG|EX_RANGE|EX_ZEROR|EX_FILES|EX_CMDARG|EX_ARGOPT|EX_TRLBAR,
        ADDR_ARGUMENTS),
index d3ccf2dfbaeda77c6ec7da52be1fff4204acd5c6..aeb839992f701cf5540801a91f24b0624b85b1e6 100644 (file)
@@ -18,6 +18,7 @@ void ex_last(exarg_T *eap);
 void ex_argument(exarg_T *eap);
 void do_argfile(exarg_T *eap, int argn);
 void ex_next(exarg_T *eap);
+void ex_argdedupe(exarg_T *eap);
 void ex_argedit(exarg_T *eap);
 void ex_argadd(exarg_T *eap);
 void ex_argdelete(exarg_T *eap);
index 9f9957ae1b076548c10c4c994a856a64fcdf5434..a7d707ca8eb5153a013a6d08bd3e854aa94c76f3 100644 (file)
@@ -416,6 +416,35 @@ func Test_argedit()
   bw! x
 endfunc
 
+" Test for the :argdedupe command
+func Test_argdedupe()
+  call Reset_arglist()
+  argdedupe
+  call assert_equal([], argv())
+  args a a a aa b b a b aa
+  argdedupe
+  call assert_equal(['a', 'aa', 'b'], argv())
+  args a b c
+  argdedupe
+  call assert_equal(['a', 'b', 'c'], argv())
+  args a
+  argdedupe
+  call assert_equal(['a'], argv())
+  args a A b B
+  argdedupe
+  if has('fname_case')
+    call assert_equal(['a', 'A', 'b', 'B'], argv())
+  else
+    call assert_equal(['a', 'b'], argv())
+  endif
+  args a b a c a b
+  last
+  argdedupe
+  next
+  call assert_equal('c', expand('%:t'))
+  %argd
+endfunc
+
 " Test for the :argdelete command
 func Test_argdelete()
   call Reset_arglist()
index 0809436d20a4fa11476031211dc62c75b1172b9f..78baffdec88d4c3779ec9c0dfe2aa61dd01ca419 100644 (file)
@@ -749,6 +749,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3888,
 /**/
     3887,
 /**/