summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNir Lichtman <nir_lichtman@hotmail.com>2021-12-24 20:28:03 +0000
committerBram Moolenaar <Bram@vim.org>2021-12-24 20:28:03 +0000
commit73a024209cbfbd5b39a2e974084d807c6131e2ed (patch)
tree3fc4d2207a59fd3b0bb04e92d1a282e64e61c4a2
parent806da5176e9e9ab011d927c4ca33a8dde1769539 (diff)
patch 8.2.3888: the argument list may contain duplicatesv8.2.3888
Problem: The argument list may contain duplicates. Solution: Add the :argdedeupe command. (Nir Lichtman, closes #6235)
-rw-r--r--runtime/doc/editing.txt11
-rw-r--r--runtime/doc/index.txt1
-rw-r--r--src/arglist.c27
-rw-r--r--src/ex_cmdidxs.h54
-rw-r--r--src/ex_cmds.h3
-rw-r--r--src/proto/arglist.pro1
-rw-r--r--src/testdir/test_arglist.vim29
-rw-r--r--src/version.c2
8 files changed, 99 insertions, 29 deletions
diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt
index 9736d4c481..fc4080cd8d 100644
--- a/runtime/doc/editing.txt
+++ b/runtime/doc/editing.txt
@@ -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,
diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt
index 4af59c64a6..cbf363a77c 100644
--- a/runtime/doc/index.txt
+++ b/runtime/doc/index.txt
@@ -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
diff --git a/src/arglist.c b/src/arglist.c
index af8ce740fc..90ee4796b8 100644
--- a/src/arglist.c
+++ b/src/arglist.c
@@ -759,6 +759,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"
*/
void
diff --git a/src/ex_cmdidxs.h b/src/ex_cmdidxs.h
index 3ad1cd8ecf..b4743cd0e1 100644
--- a/src/ex_cmdidxs.h
+++ b/src/ex_cmdidxs.h
@@ -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;
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index 044580a7c1..3cdb656c99 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -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),
diff --git a/src/proto/arglist.pro b/src/proto/arglist.pro
index d3ccf2dfba..aeb839992f 100644
--- a/src/proto/arglist.pro
+++ b/src/proto/arglist.pro
@@ -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);
diff --git a/src/testdir/test_arglist.vim b/src/testdir/test_arglist.vim
index 9f9957ae1b..a7d707ca8e 100644
--- a/src/testdir/test_arglist.vim
+++ b/src/testdir/test_arglist.vim
@@ -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()
diff --git a/src/version.c b/src/version.c
index 0809436d20..78baffdec8 100644
--- a/src/version.c
+++ b/src/version.c
@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3888,
+/**/
3887,
/**/
3886,