Commit: patch 9.2.0812: :argdelete with pattern leads to wrong argidx()

2 views
Skip to first unread message

Christian Brabandt

unread,
Jul 20, 2026, 11:30:15 AM (yesterday) Jul 20
to vim...@googlegroups.com
patch 9.2.0812: :argdelete with pattern leads to wrong argidx()

Commit: https://github.com/vim/vim/commit/3b40a14a46c2e4f2a29dbf0b2fe48260ce2166ab
Author: zeertzjq <zeer...@outlook.com>
Date: Mon Jul 20 15:19:20 2026 +0000

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 <zeer...@outlook.com>
Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/arglist.c b/src/arglist.c
index 84de912f0..80e91475a 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 f62d2cfab..9df54a19d 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 e523f6dad..333bbc87d 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,
/**/
Reply all
Reply to author
Forward
0 new messages