aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/editing.txt11
-rw-r--r--runtime/doc/index.txt1
-rw-r--r--src/nvim/arglist.c23
-rw-r--r--src/nvim/ex_cmds.lua6
-rw-r--r--src/nvim/testdir/test_arglist.vim29
5 files changed, 68 insertions, 2 deletions
diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt
index c19d9f482b..dcb0bf8a2e 100644
--- a/runtime/doc/editing.txt
+++ b/runtime/doc/editing.txt
@@ -613,12 +613,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 7d8a89887a..7f3ef20762 100644
--- a/runtime/doc/index.txt
+++ b/runtime/doc/index.txt
@@ -1143,6 +1143,7 @@ tag command action ~
be remapped
|:args| :ar[gs] print the argument list
|:argadd| :arga[dd] add items to the argument list
+|:argdedupe| :argded[upe] 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/nvim/arglist.c b/src/nvim/arglist.c
index d19f6ed623..7d8917cc73 100644
--- a/src/nvim/arglist.c
+++ b/src/nvim/arglist.c
@@ -620,6 +620,29 @@ void ex_next(exarg_T *eap)
}
}
+/// ":argdedupe"
+void ex_argdedupe(exarg_T *eap FUNC_ATTR_UNUSED)
+{
+ for (int i = 0; i < ARGCOUNT; i++) {
+ for (int j = i + 1; j < ARGCOUNT; j++) {
+ if (FNAMECMP(ARGLIST[i].ae_fname, ARGLIST[j].ae_fname) == 0) {
+ xfree(ARGLIST[j].ae_fname);
+ memmove(ARGLIST + j, ARGLIST + j + 1,
+ (size_t)(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 ex_argedit(exarg_T *eap)
{
diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua
index a5ba5e0b30..37f12a7600 100644
--- a/src/nvim/ex_cmds.lua
+++ b/src/nvim/ex_cmds.lua
@@ -107,6 +107,12 @@ module.cmds = {
func='ex_listdo',
},
{
+ command='argdedupe',
+ flags=TRLBAR,
+ addr_type='ADDR_NONE',
+ func='ex_argdedupe',
+ },
+ {
command='argedit',
flags=bit.bor(BANG, NEEDARG, RANGE, ZEROR, FILES, CMDARG, ARGOPT, TRLBAR),
addr_type='ADDR_ARGUMENTS',
diff --git a/src/nvim/testdir/test_arglist.vim b/src/nvim/testdir/test_arglist.vim
index 0a72e38755..521c3fcd57 100644
--- a/src/nvim/testdir/test_arglist.vim
+++ b/src/nvim/testdir/test_arglist.vim
@@ -412,6 +412,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()