diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-08-16 15:29:36 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-16 15:29:36 +0800 |
commit | da13ed43cb3593f6d50e08fc6e5f26760da63f84 (patch) | |
tree | e210a95266c01861b206479bcda6e3835d2ca4c7 | |
parent | cf3b871fa940c42e9c94257118f7d1131ebd362a (diff) | |
download | rneovim-da13ed43cb3593f6d50e08fc6e5f26760da63f84.tar.gz rneovim-da13ed43cb3593f6d50e08fc6e5f26760da63f84.tar.bz2 rneovim-da13ed43cb3593f6d50e08fc6e5f26760da63f84.zip |
vim-patch:8.2.3888: the argument list may contain duplicates (#19795)
Problem: The argument list may contain duplicates.
Solution: Add the :argdedeupe command. (Nir Lichtman, closes vim/vim#6235)
https://github.com/vim/vim/commit/73a024209cbfbd5b39a2e974084d807c6131e2ed
Use latest index.txt :argdedupe doc from Vim.
-rw-r--r-- | runtime/doc/editing.txt | 11 | ||||
-rw-r--r-- | runtime/doc/index.txt | 1 | ||||
-rw-r--r-- | src/nvim/arglist.c | 23 | ||||
-rw-r--r-- | src/nvim/ex_cmds.lua | 6 | ||||
-rw-r--r-- | src/nvim/testdir/test_arglist.vim | 29 |
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() |