patch 7.4.2117
Problem: Deleting an augroup that still has autocmds does not give a
warning. The next defined augroup takes its place.
Solution: Give a warning and prevent the index being used for another group
name.
diff --git a/src/fileio.c b/src/fileio.c
index 4542f6a..042bbec 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -7758,6 +7758,7 @@
*/
static garray_T augroups = {0, 0, sizeof(char_u *), 10, NULL};
#define AUGROUP_NAME(i) (((char_u **)augroups.ga_data)[i])
+static char_u *deleted_augroup = NULL;
/*
* The ID of the current group. Group 0 is the default one.
@@ -7812,7 +7813,7 @@
if (ap->group != AUGROUP_DEFAULT)
{
if (AUGROUP_NAME(ap->group) == NULL)
- msg_puts_attr((char_u *)_("--Deleted--"), hl_attr(HLF_E));
+ msg_puts_attr(deleted_augroup, hl_attr(HLF_E));
else
msg_puts_attr(AUGROUP_NAME(ap->group), hl_attr(HLF_T));
msg_puts((char_u *)" ");
@@ -8009,8 +8010,31 @@
EMSG2(_("E367: No such group: \"%s\""), name);
else
{
+ event_T event;
+ AutoPat *ap;
+ int in_use = FALSE;
+
+ for (event = (event_T)0; (int)event < (int)NUM_EVENTS;
+ event = (event_T)((int)event + 1))
+ {
+ for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next)
+ if (ap->group == i)
+ {
+ give_warning((char_u *)_("W19: Deleting augroup that is still in use"), TRUE);
+ in_use = TRUE;
+ event = NUM_EVENTS;
+ break;
+ }
+ }
vim_free(AUGROUP_NAME(i));
- AUGROUP_NAME(i) = NULL;
+ if (in_use)
+ {
+ if (deleted_augroup == NULL)
+ deleted_augroup = (char_u *)_("--Deleted--");
+ AUGROUP_NAME(i) = deleted_augroup;
+ }
+ else
+ AUGROUP_NAME(i) = NULL;
}
}
@@ -8024,7 +8048,8 @@
int i;
for (i = 0; i < augroups.ga_len; ++i)
- if (AUGROUP_NAME(i) != NULL && STRCMP(AUGROUP_NAME(i), name) == 0)
+ if (AUGROUP_NAME(i) != NULL && AUGROUP_NAME(i) != deleted_augroup
+ && STRCMP(AUGROUP_NAME(i), name) == 0)
return i;
return AUGROUP_ERROR;
}
@@ -8081,10 +8106,20 @@
void
free_all_autocmds(void)
{
+ int i;
+ char_u *s;
+
for (current_augroup = -1; current_augroup < augroups.ga_len;
++current_augroup)
do_autocmd((char_u *)"", TRUE);
- ga_clear_strings(&augroups);
+
+ for (i = 0; i < augroups.ga_len; ++i)
+ {
+ s = ((char_u **)(augroups.ga_data))[i];
+ if (s != deleted_augroup)
+ vim_free(s);
+ }
+ ga_clear(&augroups);
}
#endif
@@ -9830,7 +9865,8 @@
return (char_u *)"END";
if (idx >= augroups.ga_len) /* end of list */
return NULL;
- if (AUGROUP_NAME(idx) == NULL) /* skip deleted entries */
+ if (AUGROUP_NAME(idx) == NULL || AUGROUP_NAME(idx) == deleted_augroup)
+ /* skip deleted entries */
return (char_u *)"";
return AUGROUP_NAME(idx); /* return a name */
}
@@ -9894,7 +9930,8 @@
{
if (idx < augroups.ga_len) /* First list group names, if wanted */
{
- if (!include_groups || AUGROUP_NAME(idx) == NULL)
+ if (!include_groups || AUGROUP_NAME(idx) == NULL
+ || AUGROUP_NAME(idx) == deleted_augroup)
return (char_u *)""; /* skip deleted entries */
return AUGROUP_NAME(idx); /* return a name */
}
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index b9d5cfe..d856d32 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -151,3 +151,20 @@
au! vimBarTest|echo 'hello'
call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
endfunc
+
+func Test_augroup_warning()
+ augroup TheWarning
+ au VimEnter * echo 'entering'
+ augroup END
+ call assert_true(match(execute('au VimEnter'), "TheWarning.*VimEnter") >= 0)
+ redir => res
+ augroup! TheWarning
+ redir END
+ call assert_true(match(res, "W19:") >= 0)
+ call assert_true(match(execute('au VimEnter'), "-Deleted-.*VimEnter") >= 0)
+
+ " check "Another" does not take the pace of the deleted entry
+ augroup Another
+ augroup END
+ call assert_true(match(execute('au VimEnter'), "-Deleted-.*VimEnter") >= 0)
+endfunc
diff --git a/src/version.c b/src/version.c
index f797f41..962bae7 100644
--- a/src/version.c
+++ b/src/version.c
@@ -759,6 +759,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2117,
+/**/
2116,
/**/
2115,