Skip to content

Commit 73a0242

Browse files
nir9brammool
authored andcommitted
patch 8.2.3888: the argument list may contain duplicates
Problem: The argument list may contain duplicates. Solution: Add the :argdedeupe command. (Nir Lichtman, closes #6235)
1 parent 806da51 commit 73a0242

File tree

8 files changed

+99
-29
lines changed

8 files changed

+99
-29
lines changed

runtime/doc/editing.txt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -650,12 +650,19 @@ list of the current window.
650650
And after the last one:
651651
:+2argadd y a b c x y
652652
There is no check for duplicates, it is possible to
653-
add a file to the argument list twice.
654-
The currently edited file is not changed.
653+
add a file to the argument list twice. You can use
654+
|:argdedupe| to fix it afterwards: >
655+
:argadd *.txt | argdedupe
656+
< The currently edited file is not changed.
655657
Note: you can also use this method: >
656658
:args ## x
657659
< This will add the "x" item and sort the new list.
658660

661+
:argded[upe] *:argded* *:argdedupe*
662+
Remove duplicate filenames from the argument list.
663+
If your current file is a duplicate, your current file
664+
will change to the original file index.
665+
659666
:argd[elete] {pattern} .. *:argd* *:argdelete* *E480* *E610*
660667
Delete files from the argument list that match the
661668
{pattern}s. {pattern} is used like a file pattern,

runtime/doc/index.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,6 +1166,7 @@ tag command action ~
11661166
be remapped
11671167
|:args| :ar[gs] print the argument list
11681168
|:argadd| :arga[dd] add items to the argument list
1169+
:argdedupe :argdedupe remove duplicates from the argument list
11691170
|:argdelete| :argd[elete] delete items from the argument list
11701171
|:argedit| :arge[dit] add item to the argument list and edit it
11711172
|:argdo| :argdo do a command on all items in the argument list

src/arglist.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,33 @@ ex_next(exarg_T *eap)
758758
}
759759
}
760760

761+
/*
762+
* ":argdedupe"
763+
*/
764+
void
765+
ex_argdedupe(exarg_T *eap UNUSED)
766+
{
767+
int i;
768+
int j;
769+
770+
for (i = 0; i < ARGCOUNT; ++i)
771+
for (j = i + 1; j < ARGCOUNT; ++j)
772+
if (fnamecmp(ARGLIST[i].ae_fname, ARGLIST[j].ae_fname) == 0)
773+
{
774+
vim_free(ARGLIST[j].ae_fname);
775+
mch_memmove(ARGLIST + j, ARGLIST + j + 1,
776+
(ARGCOUNT - j - 1) * sizeof(aentry_T));
777+
--ARGCOUNT;
778+
779+
if (curwin->w_arg_idx == j)
780+
curwin->w_arg_idx = i;
781+
else if (curwin->w_arg_idx > j)
782+
--curwin->w_arg_idx;
783+
784+
--j;
785+
}
786+
}
787+
761788
/*
762789
* ":argedit"
763790
*/

src/ex_cmdidxs.h

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,31 @@
66
static const unsigned short cmdidxs1[26] =
77
{
88
/* a */ 0,
9-
/* b */ 20,
10-
/* c */ 44,
11-
/* d */ 111,
12-
/* e */ 136,
13-
/* f */ 164,
14-
/* g */ 181,
15-
/* h */ 187,
16-
/* i */ 196,
17-
/* j */ 216,
18-
/* k */ 218,
19-
/* l */ 223,
20-
/* m */ 286,
21-
/* n */ 304,
22-
/* o */ 324,
23-
/* p */ 336,
24-
/* q */ 375,
25-
/* r */ 378,
26-
/* s */ 398,
27-
/* t */ 468,
28-
/* u */ 514,
29-
/* v */ 525,
30-
/* w */ 546,
31-
/* x */ 560,
32-
/* y */ 570,
33-
/* z */ 571
9+
/* b */ 21,
10+
/* c */ 45,
11+
/* d */ 112,
12+
/* e */ 137,
13+
/* f */ 165,
14+
/* g */ 182,
15+
/* h */ 188,
16+
/* i */ 197,
17+
/* j */ 217,
18+
/* k */ 219,
19+
/* l */ 224,
20+
/* m */ 287,
21+
/* n */ 305,
22+
/* o */ 325,
23+
/* p */ 337,
24+
/* q */ 376,
25+
/* r */ 379,
26+
/* s */ 399,
27+
/* t */ 469,
28+
/* u */ 515,
29+
/* v */ 526,
30+
/* w */ 547,
31+
/* x */ 561,
32+
/* y */ 571,
33+
/* z */ 572
3434
};
3535

3636
/*
@@ -41,7 +41,7 @@ static const unsigned short cmdidxs1[26] =
4141
*/
4242
static const unsigned char cmdidxs2[26][26] =
4343
{ /* 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 */
44-
/* 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 },
44+
/* 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 },
4545
/* 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 },
4646
/* 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 },
4747
/* 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] =
6969
/* 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 }
7070
};
7171

72-
static const int command_count = 588;
72+
static const int command_count = 589;

src/ex_cmds.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ EXCMD(CMD_argdelete, "argdelete", ex_argdelete,
148148
EXCMD(CMD_argdo, "argdo", ex_listdo,
149149
EX_BANG|EX_NEEDARG|EX_EXTRA|EX_NOTRLCOM|EX_RANGE|EX_DFLALL|EX_EXPAND,
150150
ADDR_ARGUMENTS),
151+
EXCMD(CMD_argdedupe, "argdedupe", ex_argdedupe,
152+
EX_TRLBAR,
153+
ADDR_NONE),
151154
EXCMD(CMD_argedit, "argedit", ex_argedit,
152155
EX_BANG|EX_NEEDARG|EX_RANGE|EX_ZEROR|EX_FILES|EX_CMDARG|EX_ARGOPT|EX_TRLBAR,
153156
ADDR_ARGUMENTS),

src/proto/arglist.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ void ex_last(exarg_T *eap);
1818
void ex_argument(exarg_T *eap);
1919
void do_argfile(exarg_T *eap, int argn);
2020
void ex_next(exarg_T *eap);
21+
void ex_argdedupe(exarg_T *eap);
2122
void ex_argedit(exarg_T *eap);
2223
void ex_argadd(exarg_T *eap);
2324
void ex_argdelete(exarg_T *eap);

src/testdir/test_arglist.vim

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,35 @@ func Test_argedit()
416416
bw! x
417417
endfunc
418418

419+
" Test for the :argdedupe command
420+
func Test_argdedupe()
421+
call Reset_arglist()
422+
argdedupe
423+
call assert_equal([], argv())
424+
args a a a aa b b a b aa
425+
argdedupe
426+
call assert_equal(['a', 'aa', 'b'], argv())
427+
args a b c
428+
argdedupe
429+
call assert_equal(['a', 'b', 'c'], argv())
430+
args a
431+
argdedupe
432+
call assert_equal(['a'], argv())
433+
args a A b B
434+
argdedupe
435+
if has('fname_case')
436+
call assert_equal(['a', 'A', 'b', 'B'], argv())
437+
else
438+
call assert_equal(['a', 'b'], argv())
439+
endif
440+
args a b a c a b
441+
last
442+
argdedupe
443+
next
444+
call assert_equal('c', expand('%:t'))
445+
%argd
446+
endfunc
447+
419448
" Test for the :argdelete command
420449
func Test_argdelete()
421450
call Reset_arglist()

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,8 @@ static char *(features[]) =
749749

750750
static int included_patches[] =
751751
{ /* Add new patch number below this line */
752+
/**/
753+
3888,
752754
/**/
753755
3887,
754756
/**/

0 commit comments

Comments
 (0)