From: zeertzjq Date: Mon, 20 Jul 2026 15:19:20 +0000 (+0000) Subject: patch 9.2.0812: :argdelete with pattern leads to wrong argidx() X-Git-Tag: v9.2.0812^0 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=3b40a14a46c2e4f2a29dbf0b2fe48260ce2166ab;p=thirdparty%2Fvim.git patch 9.2.0812: :argdelete with pattern leads to wrong argidx() Problem: :argdelete with pattern leads to wrong argidx(). Solution: Correct argidx() in both branches of ex_argdelete(). Also use ARGCOUNT macro in two more places (zeertzjq). related: patch 7.4.1119 related: neovim/neovim#40564 closes: #20697 Signed-off-by: zeertzjq Signed-off-by: Christian Brabandt --- diff --git a/src/arglist.c b/src/arglist.c index 84de912f01..80e91475a9 100644 --- a/src/arglist.c +++ b/src/arglist.c @@ -429,7 +429,7 @@ arglist_del_files(garray_T *alist_ga) vim_free(ARGLIST[match].ae_fname); mch_memmove(ARGLIST + match, ARGLIST + match + 1, (ARGCOUNT - match - 1) * sizeof(aentry_T)); - --ALIST(curwin)->al_ga.ga_len; + --ARGCOUNT; if (curwin->w_arg_idx > match) --curwin->w_arg_idx; --match; @@ -900,33 +900,37 @@ ex_argdelete(exarg_T *eap) eap->line2 = ARGCOUNT; n = eap->line2 - eap->line1 + 1; if (*eap->arg != NUL) + { // Can't have both a range and an argument. emsg(_(e_invalid_argument)); - else if (n <= 0) + return; + } + if (n <= 0) { // Don't give an error for ":%argdel" if the list is empty. if (eap->line1 != 1 || eap->line2 != 0) emsg(_(e_invalid_range)); + return; } - else - { - for (i = eap->line1; i <= eap->line2; ++i) - vim_free(ARGLIST[i - 1].ae_fname); - mch_memmove(ARGLIST + eap->line1 - 1, ARGLIST + eap->line2, - (size_t)((ARGCOUNT - eap->line2) * sizeof(aentry_T))); - ALIST(curwin)->al_ga.ga_len -= n; - if (curwin->w_arg_idx >= eap->line2) - curwin->w_arg_idx -= n; - else if (curwin->w_arg_idx > eap->line1) - curwin->w_arg_idx = eap->line1; - if (ARGCOUNT == 0) - curwin->w_arg_idx = 0; - else if (curwin->w_arg_idx >= ARGCOUNT) - curwin->w_arg_idx = ARGCOUNT - 1; - } + + for (i = eap->line1; i <= eap->line2; ++i) + vim_free(ARGLIST[i - 1].ae_fname); + mch_memmove(ARGLIST + eap->line1 - 1, ARGLIST + eap->line2, + (size_t)((ARGCOUNT - eap->line2) * sizeof(aentry_T))); + ARGCOUNT -= n; + if (curwin->w_arg_idx >= eap->line2) + curwin->w_arg_idx -= n; + else if (curwin->w_arg_idx > eap->line1) + curwin->w_arg_idx = eap->line1; } else do_arglist(eap->arg, AL_DEL, 0, FALSE); + + if (ARGCOUNT == 0) + curwin->w_arg_idx = 0; + else if (curwin->w_arg_idx >= ARGCOUNT) + curwin->w_arg_idx = ARGCOUNT - 1; + maketitle(); } diff --git a/src/testdir/test_arglist.vim b/src/testdir/test_arglist.vim index f62d2cfabf..9df54a19dd 100644 --- a/src/testdir/test_arglist.vim +++ b/src/testdir/test_arglist.vim @@ -457,15 +457,40 @@ func Test_argdelete() args aa a aaa b bb argdelete a* call assert_equal(['b', 'bb'], argv()) + call assert_equal(0, argidx()) call assert_equal('aa', expand('%:t')) last + call assert_equal(1, argidx()) + call assert_equal('bb', expand('%:t')) argdelete % call assert_equal(['b'], argv()) - call assert_fails('argdelete', 'E610:') + call assert_equal(0, argidx()) + call assert_equal('bb', expand('%:t')) + call assert_fails('1,100argdelete', 'E16:') call assert_fails('argdel /\)/', 'E55:') call assert_fails('1argdel 1', 'E474:') + call Reset_arglist() + args aa a aaa b bb + 4argument + call assert_equal(3, argidx()) + call assert_equal('b', expand('%:t')) + argdelete aa* + call assert_equal(['a', 'b', 'bb'], argv()) + call assert_equal(1, argidx()) + call assert_equal('b', expand('%:t')) + 2argdelete + call assert_equal(['a', 'bb'], argv()) + call assert_equal(1, argidx()) + call assert_equal('b', expand('%:t')) + %argdelete + call assert_equal([], argv()) + call assert_equal(0, argidx()) + call assert_equal('b', expand('%:t')) + " :%argdelete when the arglist is already empty should not error + %argdelete + call Reset_arglist() args a b c d next diff --git a/src/version.c b/src/version.c index e523f6dad4..333bbc87d8 100644 --- a/src/version.c +++ b/src/version.c @@ -759,6 +759,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 812, /**/ 811, /**/