1 /* vi:set ts=8 sts=4 sw=4 noet:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *
5  * Do ":help uganda"  in Vim to read copying and usage conditions.
6  * Do ":help credits" in Vim to see a list of people who contributed.
7  * See README.txt for an overview of the Vim source code.
8  */
9 
10 /*
11  * autocmd.c: Autocommand related functions
12  */
13 
14 #include "vim.h"
15 
16 /*
17  * The autocommands are stored in a list for each event.
18  * Autocommands for the same pattern, that are consecutive, are joined
19  * together, to avoid having to match the pattern too often.
20  * The result is an array of Autopat lists, which point to AutoCmd lists:
21  *
22  * last_autopat[0]  -----------------------------+
23  *						 V
24  * first_autopat[0] --> Autopat.next  -->  Autopat.next -->  NULL
25  *			Autopat.cmds	   Autopat.cmds
26  *			    |			 |
27  *			    V			 V
28  *			AutoCmd.next	   AutoCmd.next
29  *			    |			 |
30  *			    V			 V
31  *			AutoCmd.next		NULL
32  *			    |
33  *			    V
34  *			   NULL
35  *
36  * last_autopat[1]  --------+
37  *			    V
38  * first_autopat[1] --> Autopat.next  -->  NULL
39  *			Autopat.cmds
40  *			    |
41  *			    V
42  *			AutoCmd.next
43  *			    |
44  *			    V
45  *			   NULL
46  *   etc.
47  *
48  *   The order of AutoCmds is important, this is the order in which they were
49  *   defined and will have to be executed.
50  */
51 typedef struct AutoCmd
52 {
53     char_u	    *cmd;		// The command to be executed (NULL
54 					// when command has been removed).
55     char	    once;		// "One shot": removed after execution
56     char	    nested;		// If autocommands nest here.
57     char	    last;		// last command in list
58     sctx_T	    script_ctx;		// script context where defined
59     struct AutoCmd  *next;		// next AutoCmd in list
60 } AutoCmd;
61 
62 typedef struct AutoPat
63 {
64     struct AutoPat  *next;		// Next AutoPat in AutoPat list; MUST
65 					// be the first entry.
66     char_u	    *pat;		// pattern as typed (NULL when pattern
67 					// has been removed)
68     regprog_T	    *reg_prog;		// compiled regprog for pattern
69     AutoCmd	    *cmds;		// list of commands to do
70     int		    group;		// group ID
71     int		    patlen;		// strlen() of pat
72     int		    buflocal_nr;	// !=0 for buffer-local AutoPat
73     char	    allow_dirs;		// Pattern may match whole path
74     char	    last;		// last pattern for apply_autocmds()
75 } AutoPat;
76 
77 static struct event_name
78 {
79     char	*name;	// event name
80     event_T	event;	// event number
81 } event_names[] =
82 {
83     {"BufAdd",		EVENT_BUFADD},
84     {"BufCreate",	EVENT_BUFADD},
85     {"BufDelete",	EVENT_BUFDELETE},
86     {"BufEnter",	EVENT_BUFENTER},
87     {"BufFilePost",	EVENT_BUFFILEPOST},
88     {"BufFilePre",	EVENT_BUFFILEPRE},
89     {"BufHidden",	EVENT_BUFHIDDEN},
90     {"BufLeave",	EVENT_BUFLEAVE},
91     {"BufNew",		EVENT_BUFNEW},
92     {"BufNewFile",	EVENT_BUFNEWFILE},
93     {"BufRead",		EVENT_BUFREADPOST},
94     {"BufReadCmd",	EVENT_BUFREADCMD},
95     {"BufReadPost",	EVENT_BUFREADPOST},
96     {"BufReadPre",	EVENT_BUFREADPRE},
97     {"BufUnload",	EVENT_BUFUNLOAD},
98     {"BufWinEnter",	EVENT_BUFWINENTER},
99     {"BufWinLeave",	EVENT_BUFWINLEAVE},
100     {"BufWipeout",	EVENT_BUFWIPEOUT},
101     {"BufWrite",	EVENT_BUFWRITEPRE},
102     {"BufWritePost",	EVENT_BUFWRITEPOST},
103     {"BufWritePre",	EVENT_BUFWRITEPRE},
104     {"BufWriteCmd",	EVENT_BUFWRITECMD},
105     {"CmdlineChanged",	EVENT_CMDLINECHANGED},
106     {"CmdlineEnter",	EVENT_CMDLINEENTER},
107     {"CmdlineLeave",	EVENT_CMDLINELEAVE},
108     {"CmdwinEnter",	EVENT_CMDWINENTER},
109     {"CmdwinLeave",	EVENT_CMDWINLEAVE},
110     {"CmdUndefined",	EVENT_CMDUNDEFINED},
111     {"ColorScheme",	EVENT_COLORSCHEME},
112     {"ColorSchemePre",	EVENT_COLORSCHEMEPRE},
113     {"CompleteChanged",	EVENT_COMPLETECHANGED},
114     {"CompleteDone",	EVENT_COMPLETEDONE},
115     {"CompleteDonePre",	EVENT_COMPLETEDONEPRE},
116     {"CursorHold",	EVENT_CURSORHOLD},
117     {"CursorHoldI",	EVENT_CURSORHOLDI},
118     {"CursorMoved",	EVENT_CURSORMOVED},
119     {"CursorMovedI",	EVENT_CURSORMOVEDI},
120     {"DiffUpdated",	EVENT_DIFFUPDATED},
121     {"DirChanged",	EVENT_DIRCHANGED},
122     {"EncodingChanged",	EVENT_ENCODINGCHANGED},
123     {"ExitPre",		EVENT_EXITPRE},
124     {"FileEncoding",	EVENT_ENCODINGCHANGED},
125     {"FileAppendPost",	EVENT_FILEAPPENDPOST},
126     {"FileAppendPre",	EVENT_FILEAPPENDPRE},
127     {"FileAppendCmd",	EVENT_FILEAPPENDCMD},
128     {"FileChangedShell",EVENT_FILECHANGEDSHELL},
129     {"FileChangedShellPost",EVENT_FILECHANGEDSHELLPOST},
130     {"FileChangedRO",	EVENT_FILECHANGEDRO},
131     {"FileReadPost",	EVENT_FILEREADPOST},
132     {"FileReadPre",	EVENT_FILEREADPRE},
133     {"FileReadCmd",	EVENT_FILEREADCMD},
134     {"FileType",	EVENT_FILETYPE},
135     {"FileWritePost",	EVENT_FILEWRITEPOST},
136     {"FileWritePre",	EVENT_FILEWRITEPRE},
137     {"FileWriteCmd",	EVENT_FILEWRITECMD},
138     {"FilterReadPost",	EVENT_FILTERREADPOST},
139     {"FilterReadPre",	EVENT_FILTERREADPRE},
140     {"FilterWritePost",	EVENT_FILTERWRITEPOST},
141     {"FilterWritePre",	EVENT_FILTERWRITEPRE},
142     {"FocusGained",	EVENT_FOCUSGAINED},
143     {"FocusLost",	EVENT_FOCUSLOST},
144     {"FuncUndefined",	EVENT_FUNCUNDEFINED},
145     {"GUIEnter",	EVENT_GUIENTER},
146     {"GUIFailed",	EVENT_GUIFAILED},
147     {"InsertChange",	EVENT_INSERTCHANGE},
148     {"InsertEnter",	EVENT_INSERTENTER},
149     {"InsertLeave",	EVENT_INSERTLEAVE},
150     {"InsertLeavePre",	EVENT_INSERTLEAVEPRE},
151     {"InsertCharPre",	EVENT_INSERTCHARPRE},
152     {"MenuPopup",	EVENT_MENUPOPUP},
153     {"ModeChanged",	EVENT_MODECHANGED},
154     {"OptionSet",	EVENT_OPTIONSET},
155     {"QuickFixCmdPost",	EVENT_QUICKFIXCMDPOST},
156     {"QuickFixCmdPre",	EVENT_QUICKFIXCMDPRE},
157     {"QuitPre",		EVENT_QUITPRE},
158     {"RemoteReply",	EVENT_REMOTEREPLY},
159     {"SafeState",	EVENT_SAFESTATE},
160     {"SafeStateAgain",	EVENT_SAFESTATEAGAIN},
161     {"SessionLoadPost",	EVENT_SESSIONLOADPOST},
162     {"ShellCmdPost",	EVENT_SHELLCMDPOST},
163     {"ShellFilterPost",	EVENT_SHELLFILTERPOST},
164     {"SigUSR1",		EVENT_SIGUSR1},
165     {"SourceCmd",	EVENT_SOURCECMD},
166     {"SourcePre",	EVENT_SOURCEPRE},
167     {"SourcePost",	EVENT_SOURCEPOST},
168     {"SpellFileMissing",EVENT_SPELLFILEMISSING},
169     {"StdinReadPost",	EVENT_STDINREADPOST},
170     {"StdinReadPre",	EVENT_STDINREADPRE},
171     {"SwapExists",	EVENT_SWAPEXISTS},
172     {"Syntax",		EVENT_SYNTAX},
173     {"TabNew",		EVENT_TABNEW},
174     {"TabClosed",	EVENT_TABCLOSED},
175     {"TabEnter",	EVENT_TABENTER},
176     {"TabLeave",	EVENT_TABLEAVE},
177     {"TermChanged",	EVENT_TERMCHANGED},
178     {"TerminalOpen",	EVENT_TERMINALOPEN},
179     {"TerminalWinOpen", EVENT_TERMINALWINOPEN},
180     {"TermResponse",	EVENT_TERMRESPONSE},
181     {"TextChanged",	EVENT_TEXTCHANGED},
182     {"TextChangedI",	EVENT_TEXTCHANGEDI},
183     {"TextChangedP",	EVENT_TEXTCHANGEDP},
184     {"User",		EVENT_USER},
185     {"VimEnter",	EVENT_VIMENTER},
186     {"VimLeave",	EVENT_VIMLEAVE},
187     {"VimLeavePre",	EVENT_VIMLEAVEPRE},
188     {"WinNew",		EVENT_WINNEW},
189     {"WinClosed",	EVENT_WINCLOSED},
190     {"WinEnter",	EVENT_WINENTER},
191     {"WinLeave",	EVENT_WINLEAVE},
192     {"VimResized",	EVENT_VIMRESIZED},
193     {"TextYankPost",	EVENT_TEXTYANKPOST},
194     {"VimSuspend",	EVENT_VIMSUSPEND},
195     {"VimResume",	EVENT_VIMRESUME},
196     {NULL,		(event_T)0}
197 };
198 
199 static AutoPat *first_autopat[NUM_EVENTS] =
200 {
201     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
202     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
203     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
204     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
205     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
206     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
207 };
208 
209 static AutoPat *last_autopat[NUM_EVENTS] =
210 {
211     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
212     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
213     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
214     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
215     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
216     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
217 };
218 
219 #define AUGROUP_DEFAULT    -1	    // default autocmd group
220 #define AUGROUP_ERROR	   -2	    // erroneous autocmd group
221 #define AUGROUP_ALL	   -3	    // all autocmd groups
222 
223 /*
224  * struct used to keep status while executing autocommands for an event.
225  */
226 struct AutoPatCmd_S
227 {
228     AutoPat	*curpat;	// next AutoPat to examine
229     AutoCmd	*nextcmd;	// next AutoCmd to execute
230     int		group;		// group being used
231     char_u	*fname;		// fname to match with
232     char_u	*sfname;	// sfname to match with
233     char_u	*tail;		// tail of fname
234     event_T	event;		// current event
235     int		arg_bufnr;	// Initially equal to <abuf>, set to zero when
236 				// buf is deleted.
237     AutoPatCmd   *next;		// chain of active apc-s for auto-invalidation
238 };
239 
240 static AutoPatCmd *active_apc_list = NULL; // stack of active autocommands
241 
242 // Macro to loop over all the patterns for an autocmd event
243 #define FOR_ALL_AUTOCMD_PATTERNS(event, ap) \
244     for ((ap) = first_autopat[(int)(event)]; (ap) != NULL; (ap) = (ap)->next)
245 
246 /*
247  * augroups stores a list of autocmd group names.
248  */
249 static garray_T augroups = {0, 0, sizeof(char_u *), 10, NULL};
250 #define AUGROUP_NAME(i) (((char_u **)augroups.ga_data)[i])
251 // use get_deleted_augroup() to get this
252 static char_u *deleted_augroup = NULL;
253 
254 /*
255  * The ID of the current group.  Group 0 is the default one.
256  */
257 static int current_augroup = AUGROUP_DEFAULT;
258 
259 static int au_need_clean = FALSE;   // need to delete marked patterns
260 
261 static char_u *event_nr2name(event_T event);
262 static int au_get_grouparg(char_u **argp);
263 static int do_autocmd_event(event_T event, char_u *pat, int once, int nested, char_u *cmd, int forceit, int group, int flags);
264 static int apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io, int force, int group, buf_T *buf, exarg_T *eap);
265 static void auto_next_pat(AutoPatCmd *apc, int stop_at_last);
266 static int au_find_group(char_u *name);
267 
268 static event_T	last_event;
269 static int	last_group;
270 static int	autocmd_blocked = 0;	// block all autocmds
271 
272     static char_u *
get_deleted_augroup(void)273 get_deleted_augroup(void)
274 {
275     if (deleted_augroup == NULL)
276 	deleted_augroup = (char_u *)_("--Deleted--");
277     return deleted_augroup;
278 }
279 
280 /*
281  * Show the autocommands for one AutoPat.
282  */
283     static void
show_autocmd(AutoPat * ap,event_T event)284 show_autocmd(AutoPat *ap, event_T event)
285 {
286     AutoCmd *ac;
287 
288     // Check for "got_int" (here and at various places below), which is set
289     // when "q" has been hit for the "--more--" prompt
290     if (got_int)
291 	return;
292     if (ap->pat == NULL)		// pattern has been removed
293 	return;
294 
295     msg_putchar('\n');
296     if (got_int)
297 	return;
298     if (event != last_event || ap->group != last_group)
299     {
300 	if (ap->group != AUGROUP_DEFAULT)
301 	{
302 	    if (AUGROUP_NAME(ap->group) == NULL)
303 		msg_puts_attr((char *)get_deleted_augroup(), HL_ATTR(HLF_E));
304 	    else
305 		msg_puts_attr((char *)AUGROUP_NAME(ap->group), HL_ATTR(HLF_T));
306 	    msg_puts("  ");
307 	}
308 	msg_puts_attr((char *)event_nr2name(event), HL_ATTR(HLF_T));
309 	last_event = event;
310 	last_group = ap->group;
311 	msg_putchar('\n');
312 	if (got_int)
313 	    return;
314     }
315     msg_col = 4;
316     msg_outtrans(ap->pat);
317 
318     for (ac = ap->cmds; ac != NULL; ac = ac->next)
319     {
320 	if (ac->cmd != NULL)		// skip removed commands
321 	{
322 	    if (msg_col >= 14)
323 		msg_putchar('\n');
324 	    msg_col = 14;
325 	    if (got_int)
326 		return;
327 	    msg_outtrans(ac->cmd);
328 #ifdef FEAT_EVAL
329 	    if (p_verbose > 0)
330 		last_set_msg(ac->script_ctx);
331 #endif
332 	    if (got_int)
333 		return;
334 	    if (ac->next != NULL)
335 	    {
336 		msg_putchar('\n');
337 		if (got_int)
338 		    return;
339 	    }
340 	}
341     }
342 }
343 
344 /*
345  * Mark an autocommand pattern for deletion.
346  */
347     static void
au_remove_pat(AutoPat * ap)348 au_remove_pat(AutoPat *ap)
349 {
350     VIM_CLEAR(ap->pat);
351     ap->buflocal_nr = -1;
352     au_need_clean = TRUE;
353 }
354 
355 /*
356  * Mark all commands for a pattern for deletion.
357  */
358     static void
au_remove_cmds(AutoPat * ap)359 au_remove_cmds(AutoPat *ap)
360 {
361     AutoCmd *ac;
362 
363     for (ac = ap->cmds; ac != NULL; ac = ac->next)
364 	VIM_CLEAR(ac->cmd);
365     au_need_clean = TRUE;
366 }
367 
368 // Delete one command from an autocmd pattern.
au_del_cmd(AutoCmd * ac)369 static void au_del_cmd(AutoCmd *ac)
370 {
371     VIM_CLEAR(ac->cmd);
372     au_need_clean = TRUE;
373 }
374 
375 /*
376  * Cleanup autocommands and patterns that have been deleted.
377  * This is only done when not executing autocommands.
378  */
379     static void
au_cleanup(void)380 au_cleanup(void)
381 {
382     AutoPat	*ap, **prev_ap;
383     AutoCmd	*ac, **prev_ac;
384     event_T	event;
385 
386     if (autocmd_busy || !au_need_clean)
387 	return;
388 
389     // loop over all events
390     for (event = (event_T)0; (int)event < NUM_EVENTS;
391 					    event = (event_T)((int)event + 1))
392     {
393 	// loop over all autocommand patterns
394 	prev_ap = &(first_autopat[(int)event]);
395 	for (ap = *prev_ap; ap != NULL; ap = *prev_ap)
396 	{
397 	    int has_cmd = FALSE;
398 
399 	    // loop over all commands for this pattern
400 	    prev_ac = &(ap->cmds);
401 	    for (ac = *prev_ac; ac != NULL; ac = *prev_ac)
402 	    {
403 		// remove the command if the pattern is to be deleted or when
404 		// the command has been marked for deletion
405 		if (ap->pat == NULL || ac->cmd == NULL)
406 		{
407 		    *prev_ac = ac->next;
408 		    vim_free(ac->cmd);
409 		    vim_free(ac);
410 		}
411 		else
412 		{
413 		    has_cmd = TRUE;
414 		    prev_ac = &(ac->next);
415 		}
416 	    }
417 
418 	    if (ap->pat != NULL && !has_cmd)
419 		// Pattern was not marked for deletion, but all of its
420 		// commands were.  So mark the pattern for deletion.
421 		au_remove_pat(ap);
422 
423 	    // remove the pattern if it has been marked for deletion
424 	    if (ap->pat == NULL)
425 	    {
426 		if (ap->next == NULL)
427 		{
428 		    if (prev_ap == &(first_autopat[(int)event]))
429 			last_autopat[(int)event] = NULL;
430 		    else
431 			// this depends on the "next" field being the first in
432 			// the struct
433 			last_autopat[(int)event] = (AutoPat *)prev_ap;
434 		}
435 		*prev_ap = ap->next;
436 		vim_regfree(ap->reg_prog);
437 		vim_free(ap);
438 	    }
439 	    else
440 		prev_ap = &(ap->next);
441 	}
442     }
443 
444     au_need_clean = FALSE;
445 }
446 
447 /*
448  * Called when buffer is freed, to remove/invalidate related buffer-local
449  * autocmds.
450  */
451     void
aubuflocal_remove(buf_T * buf)452 aubuflocal_remove(buf_T *buf)
453 {
454     AutoPat	*ap;
455     event_T	event;
456     AutoPatCmd	*apc;
457 
458     // invalidate currently executing autocommands
459     for (apc = active_apc_list; apc; apc = apc->next)
460 	if (buf->b_fnum == apc->arg_bufnr)
461 	    apc->arg_bufnr = 0;
462 
463     // invalidate buflocals looping through events
464     for (event = (event_T)0; (int)event < NUM_EVENTS;
465 					    event = (event_T)((int)event + 1))
466 	// loop over all autocommand patterns
467 	FOR_ALL_AUTOCMD_PATTERNS(event, ap)
468 	    if (ap->buflocal_nr == buf->b_fnum)
469 	    {
470 		au_remove_pat(ap);
471 		if (p_verbose >= 6)
472 		{
473 		    verbose_enter();
474 		    smsg(_("auto-removing autocommand: %s <buffer=%d>"),
475 					   event_nr2name(event), buf->b_fnum);
476 		    verbose_leave();
477 		}
478 	    }
479     au_cleanup();
480 }
481 
482 /*
483  * Add an autocmd group name.
484  * Return its ID.  Returns AUGROUP_ERROR (< 0) for error.
485  */
486     static int
au_new_group(char_u * name)487 au_new_group(char_u *name)
488 {
489     int		i;
490 
491     i = au_find_group(name);
492     if (i == AUGROUP_ERROR)	// the group doesn't exist yet, add it
493     {
494 	// First try using a free entry.
495 	for (i = 0; i < augroups.ga_len; ++i)
496 	    if (AUGROUP_NAME(i) == NULL)
497 		break;
498 	if (i == augroups.ga_len && ga_grow(&augroups, 1) == FAIL)
499 	    return AUGROUP_ERROR;
500 
501 	AUGROUP_NAME(i) = vim_strsave(name);
502 	if (AUGROUP_NAME(i) == NULL)
503 	    return AUGROUP_ERROR;
504 	if (i == augroups.ga_len)
505 	    ++augroups.ga_len;
506     }
507 
508     return i;
509 }
510 
511     static void
au_del_group(char_u * name)512 au_del_group(char_u *name)
513 {
514     int	    i;
515 
516     i = au_find_group(name);
517     if (i == AUGROUP_ERROR)	// the group doesn't exist
518 	semsg(_("E367: No such group: \"%s\""), name);
519     else if (i == current_augroup)
520 	emsg(_("E936: Cannot delete the current group"));
521     else
522     {
523 	event_T	event;
524 	AutoPat	*ap;
525 	int	in_use = FALSE;
526 
527 	for (event = (event_T)0; (int)event < NUM_EVENTS;
528 					    event = (event_T)((int)event + 1))
529 	{
530 	    FOR_ALL_AUTOCMD_PATTERNS(event, ap)
531 		if (ap->group == i && ap->pat != NULL)
532 		{
533 		    give_warning((char_u *)_("W19: Deleting augroup that is still in use"), TRUE);
534 		    in_use = TRUE;
535 		    event = NUM_EVENTS;
536 		    break;
537 		}
538 	}
539 	vim_free(AUGROUP_NAME(i));
540 	if (in_use)
541 	    AUGROUP_NAME(i) = get_deleted_augroup();
542 	else
543 	    AUGROUP_NAME(i) = NULL;
544     }
545 }
546 
547 /*
548  * Find the ID of an autocmd group name.
549  * Return its ID.  Returns AUGROUP_ERROR (< 0) for error.
550  */
551     static int
au_find_group(char_u * name)552 au_find_group(char_u *name)
553 {
554     int	    i;
555 
556     for (i = 0; i < augroups.ga_len; ++i)
557 	if (AUGROUP_NAME(i) != NULL && AUGROUP_NAME(i) != get_deleted_augroup()
558 		&& STRCMP(AUGROUP_NAME(i), name) == 0)
559 	    return i;
560     return AUGROUP_ERROR;
561 }
562 
563 /*
564  * Return TRUE if augroup "name" exists.
565  */
566     int
au_has_group(char_u * name)567 au_has_group(char_u *name)
568 {
569     return au_find_group(name) != AUGROUP_ERROR;
570 }
571 
572 /*
573  * ":augroup {name}".
574  */
575     void
do_augroup(char_u * arg,int del_group)576 do_augroup(char_u *arg, int del_group)
577 {
578     int	    i;
579 
580     if (del_group)
581     {
582 	if (*arg == NUL)
583 	    emsg(_(e_argreq));
584 	else
585 	    au_del_group(arg);
586     }
587     else if (STRICMP(arg, "end") == 0)   // ":aug end": back to group 0
588 	current_augroup = AUGROUP_DEFAULT;
589     else if (*arg)		    // ":aug xxx": switch to group xxx
590     {
591 	i = au_new_group(arg);
592 	if (i != AUGROUP_ERROR)
593 	    current_augroup = i;
594     }
595     else			    // ":aug": list the group names
596     {
597 	msg_start();
598 	for (i = 0; i < augroups.ga_len; ++i)
599 	{
600 	    if (AUGROUP_NAME(i) != NULL)
601 	    {
602 		msg_puts((char *)AUGROUP_NAME(i));
603 		msg_puts("  ");
604 	    }
605 	}
606 	msg_clr_eos();
607 	msg_end();
608     }
609 }
610 
611 #if defined(EXITFREE) || defined(PROTO)
612     void
free_all_autocmds(void)613 free_all_autocmds(void)
614 {
615     int		i;
616     char_u	*s;
617 
618     for (current_augroup = -1; current_augroup < augroups.ga_len;
619 							    ++current_augroup)
620 	do_autocmd(NULL, (char_u *)"", TRUE);
621 
622     for (i = 0; i < augroups.ga_len; ++i)
623     {
624 	s = ((char_u **)(augroups.ga_data))[i];
625 	if (s != get_deleted_augroup())
626 	    vim_free(s);
627     }
628     ga_clear(&augroups);
629 }
630 #endif
631 
632 /*
633  * Return the event number for event name "start".
634  * Return NUM_EVENTS if the event name was not found.
635  * Return a pointer to the next event name in "end".
636  */
637     static event_T
event_name2nr(char_u * start,char_u ** end)638 event_name2nr(char_u *start, char_u **end)
639 {
640     char_u	*p;
641     int		i;
642     int		len;
643 
644     // the event name ends with end of line, '|', a blank or a comma
645     for (p = start; *p && !VIM_ISWHITE(*p) && *p != ',' && *p != '|'; ++p)
646 	;
647     for (i = 0; event_names[i].name != NULL; ++i)
648     {
649 	len = (int)STRLEN(event_names[i].name);
650 	if (len == p - start && STRNICMP(event_names[i].name, start, len) == 0)
651 	    break;
652     }
653     if (*p == ',')
654 	++p;
655     *end = p;
656     if (event_names[i].name == NULL)
657 	return NUM_EVENTS;
658     return event_names[i].event;
659 }
660 
661 /*
662  * Return the name for event "event".
663  */
664     static char_u *
event_nr2name(event_T event)665 event_nr2name(event_T event)
666 {
667     int	    i;
668 
669     for (i = 0; event_names[i].name != NULL; ++i)
670 	if (event_names[i].event == event)
671 	    return (char_u *)event_names[i].name;
672     return (char_u *)"Unknown";
673 }
674 
675 /*
676  * Scan over the events.  "*" stands for all events.
677  */
678     static char_u *
find_end_event(char_u * arg,int have_group)679 find_end_event(
680     char_u  *arg,
681     int	    have_group)	    // TRUE when group name was found
682 {
683     char_u  *pat;
684     char_u  *p;
685 
686     if (*arg == '*')
687     {
688 	if (arg[1] && !VIM_ISWHITE(arg[1]))
689 	{
690 	    semsg(_("E215: Illegal character after *: %s"), arg);
691 	    return NULL;
692 	}
693 	pat = arg + 1;
694     }
695     else
696     {
697 	for (pat = arg; *pat && *pat != '|' && !VIM_ISWHITE(*pat); pat = p)
698 	{
699 	    if ((int)event_name2nr(pat, &p) >= NUM_EVENTS)
700 	    {
701 		if (have_group)
702 		    semsg(_("E216: No such event: %s"), pat);
703 		else
704 		    semsg(_("E216: No such group or event: %s"), pat);
705 		return NULL;
706 	    }
707 	}
708     }
709     return pat;
710 }
711 
712 /*
713  * Return TRUE if "event" is included in 'eventignore'.
714  */
715     static int
event_ignored(event_T event)716 event_ignored(event_T event)
717 {
718     char_u	*p = p_ei;
719 
720     while (*p != NUL)
721     {
722 	if (STRNICMP(p, "all", 3) == 0 && (p[3] == NUL || p[3] == ','))
723 	    return TRUE;
724 	if (event_name2nr(p, &p) == event)
725 	    return TRUE;
726     }
727 
728     return FALSE;
729 }
730 
731 /*
732  * Return OK when the contents of p_ei is valid, FAIL otherwise.
733  */
734     int
check_ei(void)735 check_ei(void)
736 {
737     char_u	*p = p_ei;
738 
739     while (*p)
740     {
741 	if (STRNICMP(p, "all", 3) == 0 && (p[3] == NUL || p[3] == ','))
742 	{
743 	    p += 3;
744 	    if (*p == ',')
745 		++p;
746 	}
747 	else if (event_name2nr(p, &p) == NUM_EVENTS)
748 	    return FAIL;
749     }
750 
751     return OK;
752 }
753 
754 # if defined(FEAT_SYN_HL) || defined(PROTO)
755 
756 /*
757  * Add "what" to 'eventignore' to skip loading syntax highlighting for every
758  * buffer loaded into the window.  "what" must start with a comma.
759  * Returns the old value of 'eventignore' in allocated memory.
760  */
761     char_u *
au_event_disable(char * what)762 au_event_disable(char *what)
763 {
764     char_u	*new_ei;
765     char_u	*save_ei;
766 
767     save_ei = vim_strsave(p_ei);
768     if (save_ei != NULL)
769     {
770 	new_ei = vim_strnsave(p_ei, STRLEN(p_ei) + STRLEN(what));
771 	if (new_ei != NULL)
772 	{
773 	    if (*what == ',' && *p_ei == NUL)
774 		STRCPY(new_ei, what + 1);
775 	    else
776 		STRCAT(new_ei, what);
777 	    set_string_option_direct((char_u *)"ei", -1, new_ei,
778 							  OPT_FREE, SID_NONE);
779 	    vim_free(new_ei);
780 	}
781     }
782     return save_ei;
783 }
784 
785     void
au_event_restore(char_u * old_ei)786 au_event_restore(char_u *old_ei)
787 {
788     if (old_ei != NULL)
789     {
790 	set_string_option_direct((char_u *)"ei", -1, old_ei,
791 							  OPT_FREE, SID_NONE);
792 	vim_free(old_ei);
793     }
794 }
795 # endif  // FEAT_SYN_HL
796 
797 /*
798  * do_autocmd() -- implements the :autocmd command.  Can be used in the
799  *  following ways:
800  *
801  * :autocmd <event> <pat> <cmd>	    Add <cmd> to the list of commands that
802  *				    will be automatically executed for <event>
803  *				    when editing a file matching <pat>, in
804  *				    the current group.
805  * :autocmd <event> <pat>	    Show the autocommands associated with
806  *				    <event> and <pat>.
807  * :autocmd <event>		    Show the autocommands associated with
808  *				    <event>.
809  * :autocmd			    Show all autocommands.
810  * :autocmd! <event> <pat> <cmd>    Remove all autocommands associated with
811  *				    <event> and <pat>, and add the command
812  *				    <cmd>, for the current group.
813  * :autocmd! <event> <pat>	    Remove all autocommands associated with
814  *				    <event> and <pat> for the current group.
815  * :autocmd! <event>		    Remove all autocommands associated with
816  *				    <event> for the current group.
817  * :autocmd!			    Remove ALL autocommands for the current
818  *				    group.
819  *
820  *  Multiple events and patterns may be given separated by commas.  Here are
821  *  some examples:
822  * :autocmd bufread,bufenter *.c,*.h	set tw=0 smartindent noic
823  * :autocmd bufleave	     *		set tw=79 nosmartindent ic infercase
824  *
825  * :autocmd * *.c		show all autocommands for *.c files.
826  *
827  * Mostly a {group} argument can optionally appear before <event>.
828  * "eap" can be NULL.
829  */
830     void
do_autocmd(exarg_T * eap,char_u * arg_in,int forceit)831 do_autocmd(exarg_T *eap, char_u *arg_in, int forceit)
832 {
833     char_u	*arg = arg_in;
834     char_u	*pat;
835     char_u	*envpat = NULL;
836     char_u	*cmd;
837     int		cmd_need_free = FALSE;
838     event_T	event;
839     char_u	*tofree = NULL;
840     int		nested = FALSE;
841     int		once = FALSE;
842     int		group;
843     int		i;
844     int		flags = 0;
845 
846     if (*arg == '|')
847     {
848 	eap->nextcmd = arg + 1;
849 	arg = (char_u *)"";
850 	group = AUGROUP_ALL;	// no argument, use all groups
851     }
852     else
853     {
854 	/*
855 	 * Check for a legal group name.  If not, use AUGROUP_ALL.
856 	 */
857 	group = au_get_grouparg(&arg);
858 	if (arg == NULL)	    // out of memory
859 	    return;
860     }
861 
862     /*
863      * Scan over the events.
864      * If we find an illegal name, return here, don't do anything.
865      */
866     pat = find_end_event(arg, group != AUGROUP_ALL);
867     if (pat == NULL)
868 	return;
869 
870     pat = skipwhite(pat);
871     if (*pat == '|')
872     {
873 	eap->nextcmd = pat + 1;
874 	pat = (char_u *)"";
875 	cmd = (char_u *)"";
876     }
877     else
878     {
879 	/*
880 	 * Scan over the pattern.  Put a NUL at the end.
881 	 */
882 	cmd = pat;
883 	while (*cmd && (!VIM_ISWHITE(*cmd) || cmd[-1] == '\\'))
884 	    cmd++;
885 	if (*cmd)
886 	    *cmd++ = NUL;
887 
888 	// Expand environment variables in the pattern.  Set 'shellslash', we
889 	// want forward slashes here.
890 	if (vim_strchr(pat, '$') != NULL || vim_strchr(pat, '~') != NULL)
891 	{
892 #ifdef BACKSLASH_IN_FILENAME
893 	    int	p_ssl_save = p_ssl;
894 
895 	    p_ssl = TRUE;
896 #endif
897 	    envpat = expand_env_save(pat);
898 #ifdef BACKSLASH_IN_FILENAME
899 	    p_ssl = p_ssl_save;
900 #endif
901 	    if (envpat != NULL)
902 		pat = envpat;
903 	}
904 
905 	cmd = skipwhite(cmd);
906 	for (i = 0; i < 2; i++)
907 	{
908 	    if (*cmd != NUL)
909 	    {
910 		// Check for "++once" flag.
911 		if (STRNCMP(cmd, "++once", 6) == 0 && VIM_ISWHITE(cmd[6]))
912 		{
913 		    if (once)
914 			semsg(_(e_duparg2), "++once");
915 		    once = TRUE;
916 		    cmd = skipwhite(cmd + 6);
917 		}
918 
919 		// Check for "++nested" flag.
920 		if ((STRNCMP(cmd, "++nested", 8) == 0 && VIM_ISWHITE(cmd[8])))
921 		{
922 		    if (nested)
923 			semsg(_(e_duparg2), "++nested");
924 		    nested = TRUE;
925 		    cmd = skipwhite(cmd + 8);
926 		}
927 
928 		// Check for the old "nested" flag.
929 		if (STRNCMP(cmd, "nested", 6) == 0 && VIM_ISWHITE(cmd[6]))
930 		{
931 		    if (nested)
932 			semsg(_(e_duparg2), "nested");
933 		    nested = TRUE;
934 		    cmd = skipwhite(cmd + 6);
935 		}
936 	    }
937 	}
938 
939 	/*
940 	 * Find the start of the commands.
941 	 * Expand <sfile> in it.
942 	 */
943 	if (*cmd != NUL)
944 	{
945 	    if (eap != NULL)
946 		// Read a {} block if it follows.
947 		cmd = may_get_cmd_block(eap, cmd, &tofree, &flags);
948 
949 	    cmd = expand_sfile(cmd);
950 	    if (cmd == NULL)	    // some error
951 		return;
952 	    cmd_need_free = TRUE;
953 	}
954     }
955 
956     /*
957      * Print header when showing autocommands.
958      */
959     if (!forceit && *cmd == NUL)
960 	// Highlight title
961 	msg_puts_title(_("\n--- Autocommands ---"));
962 
963     /*
964      * Loop over the events.
965      */
966     last_event = (event_T)-1;		// for listing the event name
967     last_group = AUGROUP_ERROR;		// for listing the group name
968     if (*arg == '*' || *arg == NUL || *arg == '|')
969     {
970 	if (!forceit && *cmd != NUL)
971 	    emsg(_(e_cannot_define_autocommands_for_all_events));
972 	else
973 	    for (event = (event_T)0; (int)event < NUM_EVENTS;
974 					     event = (event_T)((int)event + 1))
975 		if (do_autocmd_event(event, pat,
976 			     once, nested, cmd, forceit, group, flags) == FAIL)
977 		    break;
978     }
979     else
980     {
981 	while (*arg && *arg != '|' && !VIM_ISWHITE(*arg))
982 	    if (do_autocmd_event(event_name2nr(arg, &arg), pat,
983 			  once, nested,	cmd, forceit, group, flags) == FAIL)
984 		break;
985     }
986 
987     if (cmd_need_free)
988 	vim_free(cmd);
989     vim_free(tofree);
990     vim_free(envpat);
991 }
992 
993 /*
994  * Find the group ID in a ":autocmd" or ":doautocmd" argument.
995  * The "argp" argument is advanced to the following argument.
996  *
997  * Returns the group ID, AUGROUP_ERROR for error (out of memory).
998  */
999     static int
au_get_grouparg(char_u ** argp)1000 au_get_grouparg(char_u **argp)
1001 {
1002     char_u	*group_name;
1003     char_u	*p;
1004     char_u	*arg = *argp;
1005     int		group = AUGROUP_ALL;
1006 
1007     for (p = arg; *p && !VIM_ISWHITE(*p) && *p != '|'; ++p)
1008 	;
1009     if (p > arg)
1010     {
1011 	group_name = vim_strnsave(arg, p - arg);
1012 	if (group_name == NULL)		// out of memory
1013 	    return AUGROUP_ERROR;
1014 	group = au_find_group(group_name);
1015 	if (group == AUGROUP_ERROR)
1016 	    group = AUGROUP_ALL;	// no match, use all groups
1017 	else
1018 	    *argp = skipwhite(p);	// match, skip over group name
1019 	vim_free(group_name);
1020     }
1021     return group;
1022 }
1023 
1024 /*
1025  * do_autocmd() for one event.
1026  * If *pat == NUL do for all patterns.
1027  * If *cmd == NUL show entries.
1028  * If forceit == TRUE delete entries.
1029  * If group is not AUGROUP_ALL, only use this group.
1030  */
1031     static int
do_autocmd_event(event_T event,char_u * pat,int once,int nested,char_u * cmd,int forceit,int group,int flags)1032 do_autocmd_event(
1033     event_T	event,
1034     char_u	*pat,
1035     int		once,
1036     int		nested,
1037     char_u	*cmd,
1038     int		forceit,
1039     int		group,
1040     int		flags)
1041 {
1042     AutoPat	*ap;
1043     AutoPat	**prev_ap;
1044     AutoCmd	*ac;
1045     AutoCmd	**prev_ac;
1046     int		brace_level;
1047     char_u	*endpat;
1048     int		findgroup;
1049     int		allgroups;
1050     int		patlen;
1051     int		is_buflocal;
1052     int		buflocal_nr;
1053     char_u	buflocal_pat[25];	// for "<buffer=X>"
1054 
1055     if (group == AUGROUP_ALL)
1056 	findgroup = current_augroup;
1057     else
1058 	findgroup = group;
1059     allgroups = (group == AUGROUP_ALL && !forceit && *cmd == NUL);
1060 
1061     /*
1062      * Show or delete all patterns for an event.
1063      */
1064     if (*pat == NUL)
1065     {
1066 	FOR_ALL_AUTOCMD_PATTERNS(event, ap)
1067 	{
1068 	    if (forceit)  // delete the AutoPat, if it's in the current group
1069 	    {
1070 		if (ap->group == findgroup)
1071 		    au_remove_pat(ap);
1072 	    }
1073 	    else if (group == AUGROUP_ALL || ap->group == group)
1074 		show_autocmd(ap, event);
1075 	}
1076     }
1077 
1078     /*
1079      * Loop through all the specified patterns.
1080      */
1081     for ( ; *pat; pat = (*endpat == ',' ? endpat + 1 : endpat))
1082     {
1083 	/*
1084 	 * Find end of the pattern.
1085 	 * Watch out for a comma in braces, like "*.\{obj,o\}".
1086 	 */
1087 	brace_level = 0;
1088 	for (endpat = pat; *endpat && (*endpat != ',' || brace_level
1089 			   || (endpat > pat && endpat[-1] == '\\')); ++endpat)
1090 	{
1091 	    if (*endpat == '{')
1092 		brace_level++;
1093 	    else if (*endpat == '}')
1094 		brace_level--;
1095 	}
1096 	if (pat == endpat)		// ignore single comma
1097 	    continue;
1098 	patlen = (int)(endpat - pat);
1099 
1100 	/*
1101 	 * detect special <buflocal[=X]> buffer-local patterns
1102 	 */
1103 	is_buflocal = FALSE;
1104 	buflocal_nr = 0;
1105 
1106 	if (patlen >= 8 && STRNCMP(pat, "<buffer", 7) == 0
1107 						    && pat[patlen - 1] == '>')
1108 	{
1109 	    // "<buffer...>": Error will be printed only for addition.
1110 	    // printing and removing will proceed silently.
1111 	    is_buflocal = TRUE;
1112 	    if (patlen == 8)
1113 		// "<buffer>"
1114 		buflocal_nr = curbuf->b_fnum;
1115 	    else if (patlen > 9 && pat[7] == '=')
1116 	    {
1117 		if (patlen == 13 && STRNICMP(pat, "<buffer=abuf>", 13) == 0)
1118 		    // "<buffer=abuf>"
1119 		    buflocal_nr = autocmd_bufnr;
1120 		else if (skipdigits(pat + 8) == pat + patlen - 1)
1121 		    // "<buffer=123>"
1122 		    buflocal_nr = atoi((char *)pat + 8);
1123 	    }
1124 	}
1125 
1126 	if (is_buflocal)
1127 	{
1128 	    // normalize pat into standard "<buffer>#N" form
1129 	    sprintf((char *)buflocal_pat, "<buffer=%d>", buflocal_nr);
1130 	    pat = buflocal_pat;			// can modify pat and patlen
1131 	    patlen = (int)STRLEN(buflocal_pat);	//   but not endpat
1132 	}
1133 
1134 	/*
1135 	 * Find AutoPat entries with this pattern.  When adding a command it
1136 	 * always goes at or after the last one, so start at the end.
1137 	 */
1138 	if (!forceit && *cmd != NUL && last_autopat[(int)event] != NULL)
1139 	    prev_ap = &last_autopat[(int)event];
1140 	else
1141 	    prev_ap = &first_autopat[(int)event];
1142 	while ((ap = *prev_ap) != NULL)
1143 	{
1144 	    if (ap->pat != NULL)
1145 	    {
1146 		/*
1147 		 * Accept a pattern when:
1148 		 * - a group was specified and it's that group, or a group was
1149 		 *   not specified and it's the current group, or a group was
1150 		 *   not specified and we are listing
1151 		 * - the length of the pattern matches
1152 		 * - the pattern matches.
1153 		 * For <buffer[=X]>, this condition works because we normalize
1154 		 * all buffer-local patterns.
1155 		 */
1156 		if ((allgroups || ap->group == findgroup)
1157 			&& ap->patlen == patlen
1158 			&& STRNCMP(pat, ap->pat, patlen) == 0)
1159 		{
1160 		    /*
1161 		     * Remove existing autocommands.
1162 		     * If adding any new autocmd's for this AutoPat, don't
1163 		     * delete the pattern from the autopat list, append to
1164 		     * this list.
1165 		     */
1166 		    if (forceit)
1167 		    {
1168 			if (*cmd != NUL && ap->next == NULL)
1169 			{
1170 			    au_remove_cmds(ap);
1171 			    break;
1172 			}
1173 			au_remove_pat(ap);
1174 		    }
1175 
1176 		    /*
1177 		     * Show autocmd's for this autopat, or buflocals <buffer=X>
1178 		     */
1179 		    else if (*cmd == NUL)
1180 			show_autocmd(ap, event);
1181 
1182 		    /*
1183 		     * Add autocmd to this autopat, if it's the last one.
1184 		     */
1185 		    else if (ap->next == NULL)
1186 			break;
1187 		}
1188 	    }
1189 	    prev_ap = &ap->next;
1190 	}
1191 
1192 	/*
1193 	 * Add a new command.
1194 	 */
1195 	if (*cmd != NUL)
1196 	{
1197 	    /*
1198 	     * If the pattern we want to add a command to does appear at the
1199 	     * end of the list (or not is not in the list at all), add the
1200 	     * pattern at the end of the list.
1201 	     */
1202 	    if (ap == NULL)
1203 	    {
1204 		// refuse to add buffer-local ap if buffer number is invalid
1205 		if (is_buflocal && (buflocal_nr == 0
1206 				      || buflist_findnr(buflocal_nr) == NULL))
1207 		{
1208 		    semsg(_("E680: <buffer=%d>: invalid buffer number "),
1209 								 buflocal_nr);
1210 		    return FAIL;
1211 		}
1212 
1213 		ap = ALLOC_ONE(AutoPat);
1214 		if (ap == NULL)
1215 		    return FAIL;
1216 		ap->pat = vim_strnsave(pat, patlen);
1217 		ap->patlen = patlen;
1218 		if (ap->pat == NULL)
1219 		{
1220 		    vim_free(ap);
1221 		    return FAIL;
1222 		}
1223 
1224 #ifdef FEAT_EVAL
1225 		// need to initialize last_mode for the first ModeChanged
1226 		// autocmd
1227 		if (event == EVENT_MODECHANGED && !has_modechanged())
1228 		{
1229 		    typval_T rettv;
1230 		    typval_T tv[2];
1231 
1232 		    tv[0].v_type = VAR_NUMBER;
1233 		    tv[0].vval.v_number = 1;
1234 		    tv[1].v_type = VAR_UNKNOWN;
1235 		    f_mode(tv, &rettv);
1236 		    STRCPY(last_mode, rettv.vval.v_string);
1237 		    vim_free(rettv.vval.v_string);
1238 		}
1239 #endif
1240 
1241 		if (is_buflocal)
1242 		{
1243 		    ap->buflocal_nr = buflocal_nr;
1244 		    ap->reg_prog = NULL;
1245 		}
1246 		else
1247 		{
1248 		    char_u	*reg_pat;
1249 
1250 		    ap->buflocal_nr = 0;
1251 		    reg_pat = file_pat_to_reg_pat(pat, endpat,
1252 							 &ap->allow_dirs, TRUE);
1253 		    if (reg_pat != NULL)
1254 			ap->reg_prog = vim_regcomp(reg_pat, RE_MAGIC);
1255 		    vim_free(reg_pat);
1256 		    if (reg_pat == NULL || ap->reg_prog == NULL)
1257 		    {
1258 			vim_free(ap->pat);
1259 			vim_free(ap);
1260 			return FAIL;
1261 		    }
1262 		}
1263 		ap->cmds = NULL;
1264 		*prev_ap = ap;
1265 		last_autopat[(int)event] = ap;
1266 		ap->next = NULL;
1267 		if (group == AUGROUP_ALL)
1268 		    ap->group = current_augroup;
1269 		else
1270 		    ap->group = group;
1271 	    }
1272 
1273 	    /*
1274 	     * Add the autocmd at the end of the AutoCmd list.
1275 	     */
1276 	    prev_ac = &(ap->cmds);
1277 	    while ((ac = *prev_ac) != NULL)
1278 		prev_ac = &ac->next;
1279 	    ac = ALLOC_ONE(AutoCmd);
1280 	    if (ac == NULL)
1281 		return FAIL;
1282 	    ac->cmd = vim_strsave(cmd);
1283 	    ac->script_ctx = current_sctx;
1284 	    if (flags & UC_VIM9)
1285 		ac->script_ctx.sc_version = SCRIPT_VERSION_VIM9;
1286 #ifdef FEAT_EVAL
1287 	    ac->script_ctx.sc_lnum += SOURCING_LNUM;
1288 #endif
1289 	    if (ac->cmd == NULL)
1290 	    {
1291 		vim_free(ac);
1292 		return FAIL;
1293 	    }
1294 	    ac->next = NULL;
1295 	    *prev_ac = ac;
1296 	    ac->once = once;
1297 	    ac->nested = nested;
1298 	}
1299     }
1300 
1301     au_cleanup();	// may really delete removed patterns/commands now
1302     return OK;
1303 }
1304 
1305 /*
1306  * Implementation of ":doautocmd [group] event [fname]".
1307  * Return OK for success, FAIL for failure;
1308  */
1309     int
do_doautocmd(char_u * arg_start,int do_msg,int * did_something)1310 do_doautocmd(
1311     char_u	*arg_start,
1312     int		do_msg,	    // give message for no matching autocmds?
1313     int		*did_something)
1314 {
1315     char_u	*arg = arg_start;
1316     char_u	*fname;
1317     int		nothing_done = TRUE;
1318     int		group;
1319 
1320     if (did_something != NULL)
1321 	*did_something = FALSE;
1322 
1323     /*
1324      * Check for a legal group name.  If not, use AUGROUP_ALL.
1325      */
1326     group = au_get_grouparg(&arg);
1327     if (arg == NULL)	    // out of memory
1328 	return FAIL;
1329 
1330     if (*arg == '*')
1331     {
1332 	emsg(_("E217: Can't execute autocommands for ALL events"));
1333 	return FAIL;
1334     }
1335 
1336     /*
1337      * Scan over the events.
1338      * If we find an illegal name, return here, don't do anything.
1339      */
1340     fname = find_end_event(arg, group != AUGROUP_ALL);
1341     if (fname == NULL)
1342 	return FAIL;
1343 
1344     fname = skipwhite(fname);
1345 
1346     /*
1347      * Loop over the events.
1348      */
1349     while (*arg && !ends_excmd(*arg) && !VIM_ISWHITE(*arg))
1350 	if (apply_autocmds_group(event_name2nr(arg, &arg),
1351 				      fname, NULL, TRUE, group, curbuf, NULL))
1352 	    nothing_done = FALSE;
1353 
1354     if (nothing_done && do_msg
1355 #ifdef FEAT_EVAL
1356 		&& !aborting()
1357 #endif
1358 	       )
1359 	smsg(_("No matching autocommands: %s"), arg_start);
1360     if (did_something != NULL)
1361 	*did_something = !nothing_done;
1362 
1363 #ifdef FEAT_EVAL
1364     return aborting() ? FAIL : OK;
1365 #else
1366     return OK;
1367 #endif
1368 }
1369 
1370 /*
1371  * ":doautoall": execute autocommands for each loaded buffer.
1372  */
1373     void
ex_doautoall(exarg_T * eap)1374 ex_doautoall(exarg_T *eap)
1375 {
1376     int		retval = OK;
1377     aco_save_T	aco;
1378     buf_T	*buf;
1379     bufref_T	bufref;
1380     char_u	*arg = eap->arg;
1381     int		call_do_modelines = check_nomodeline(&arg);
1382     int		did_aucmd;
1383 
1384     /*
1385      * This is a bit tricky: For some commands curwin->w_buffer needs to be
1386      * equal to curbuf, but for some buffers there may not be a window.
1387      * So we change the buffer for the current window for a moment.  This
1388      * gives problems when the autocommands make changes to the list of
1389      * buffers or windows...
1390      */
1391     FOR_ALL_BUFFERS(buf)
1392     {
1393 	// Only do loaded buffers and skip the current buffer, it's done last.
1394 	if (buf->b_ml.ml_mfp != NULL && buf != curbuf)
1395 	{
1396 	    // find a window for this buffer and save some values
1397 	    aucmd_prepbuf(&aco, buf);
1398 	    set_bufref(&bufref, buf);
1399 
1400 	    // execute the autocommands for this buffer
1401 	    retval = do_doautocmd(arg, FALSE, &did_aucmd);
1402 
1403 	    if (call_do_modelines && did_aucmd)
1404 		// Execute the modeline settings, but don't set window-local
1405 		// options if we are using the current window for another
1406 		// buffer.
1407 		do_modelines(curwin == aucmd_win ? OPT_NOWIN : 0);
1408 
1409 	    // restore the current window
1410 	    aucmd_restbuf(&aco);
1411 
1412 	    // stop if there is some error or buffer was deleted
1413 	    if (retval == FAIL || !bufref_valid(&bufref))
1414 	    {
1415 		retval = FAIL;
1416 		break;
1417 	    }
1418 	}
1419     }
1420 
1421     // Execute autocommands for the current buffer last.
1422     if (retval == OK)
1423     {
1424 	do_doautocmd(arg, FALSE, &did_aucmd);
1425 	if (call_do_modelines && did_aucmd)
1426 	    do_modelines(0);
1427     }
1428 
1429     check_cursor();	    // just in case lines got deleted
1430 }
1431 
1432 /*
1433  * Check *argp for <nomodeline>.  When it is present return FALSE, otherwise
1434  * return TRUE and advance *argp to after it.
1435  * Thus return TRUE when do_modelines() should be called.
1436  */
1437     int
check_nomodeline(char_u ** argp)1438 check_nomodeline(char_u **argp)
1439 {
1440     if (STRNCMP(*argp, "<nomodeline>", 12) == 0)
1441     {
1442 	*argp = skipwhite(*argp + 12);
1443 	return FALSE;
1444     }
1445     return TRUE;
1446 }
1447 
1448 /*
1449  * Prepare for executing autocommands for (hidden) buffer "buf".
1450  * Search for a visible window containing the current buffer.  If there isn't
1451  * one then use "aucmd_win".
1452  * Set "curbuf" and "curwin" to match "buf".
1453  */
1454     void
aucmd_prepbuf(aco_save_T * aco,buf_T * buf)1455 aucmd_prepbuf(
1456     aco_save_T	*aco,		// structure to save values in
1457     buf_T	*buf)		// new curbuf
1458 {
1459     win_T	*win;
1460     int		save_ea;
1461 #ifdef FEAT_AUTOCHDIR
1462     int		save_acd;
1463 #endif
1464 
1465     // Find a window that is for the new buffer
1466     if (buf == curbuf)		// be quick when buf is curbuf
1467 	win = curwin;
1468     else
1469 	FOR_ALL_WINDOWS(win)
1470 	    if (win->w_buffer == buf)
1471 		break;
1472 
1473     // Allocate "aucmd_win" when needed.  If this fails (out of memory) fall
1474     // back to using the current window.
1475     if (win == NULL && aucmd_win == NULL)
1476     {
1477 	aucmd_win = win_alloc_popup_win();
1478 	if (aucmd_win == NULL)
1479 	    win = curwin;
1480     }
1481     if (win == NULL && aucmd_win_used)
1482 	// Strange recursive autocommand, fall back to using the current
1483 	// window.  Expect a few side effects...
1484 	win = curwin;
1485 
1486     aco->save_curwin_id = curwin->w_id;
1487     aco->save_curbuf = curbuf;
1488     aco->save_prevwin_id = prevwin == NULL ? 0 : prevwin->w_id;
1489     if (win != NULL)
1490     {
1491 	// There is a window for "buf" in the current tab page, make it the
1492 	// curwin.  This is preferred, it has the least side effects (esp. if
1493 	// "buf" is curbuf).
1494 	aco->use_aucmd_win = FALSE;
1495 	curwin = win;
1496     }
1497     else
1498     {
1499 	// There is no window for "buf", use "aucmd_win".  To minimize the side
1500 	// effects, insert it in the current tab page.
1501 	// Anything related to a window (e.g., setting folds) may have
1502 	// unexpected results.
1503 	aco->use_aucmd_win = TRUE;
1504 	aucmd_win_used = TRUE;
1505 
1506 	win_init_popup_win(aucmd_win, buf);
1507 
1508 	aco->globaldir = globaldir;
1509 	globaldir = NULL;
1510 
1511 	// Split the current window, put the aucmd_win in the upper half.
1512 	// We don't want the BufEnter or WinEnter autocommands.
1513 	block_autocmds();
1514 	make_snapshot(SNAP_AUCMD_IDX);
1515 	save_ea = p_ea;
1516 	p_ea = FALSE;
1517 
1518 #ifdef FEAT_AUTOCHDIR
1519 	// Prevent chdir() call in win_enter_ext(), through do_autochdir().
1520 	save_acd = p_acd;
1521 	p_acd = FALSE;
1522 #endif
1523 
1524 	(void)win_split_ins(0, WSP_TOP, aucmd_win, 0);
1525 	(void)win_comp_pos();   // recompute window positions
1526 	p_ea = save_ea;
1527 #ifdef FEAT_AUTOCHDIR
1528 	p_acd = save_acd;
1529 #endif
1530 	unblock_autocmds();
1531 	curwin = aucmd_win;
1532     }
1533     curbuf = buf;
1534     aco->new_curwin_id = curwin->w_id;
1535     set_bufref(&aco->new_curbuf, curbuf);
1536 }
1537 
1538 /*
1539  * Cleanup after executing autocommands for a (hidden) buffer.
1540  * Restore the window as it was (if possible).
1541  */
1542     void
aucmd_restbuf(aco_save_T * aco)1543 aucmd_restbuf(
1544     aco_save_T	*aco)		// structure holding saved values
1545 {
1546     int	    dummy;
1547     win_T   *save_curwin;
1548 
1549     if (aco->use_aucmd_win)
1550     {
1551 	--curbuf->b_nwindows;
1552 	// Find "aucmd_win", it can't be closed, but it may be in another tab
1553 	// page. Do not trigger autocommands here.
1554 	block_autocmds();
1555 	if (curwin != aucmd_win)
1556 	{
1557 	    tabpage_T	*tp;
1558 	    win_T	*wp;
1559 
1560 	    FOR_ALL_TAB_WINDOWS(tp, wp)
1561 	    {
1562 		if (wp == aucmd_win)
1563 		{
1564 		    if (tp != curtab)
1565 			goto_tabpage_tp(tp, TRUE, TRUE);
1566 		    win_goto(aucmd_win);
1567 		    goto win_found;
1568 		}
1569 	    }
1570 	}
1571 win_found:
1572 
1573 	// Remove the window and frame from the tree of frames.
1574 	(void)winframe_remove(curwin, &dummy, NULL);
1575 	win_remove(curwin, NULL);
1576 	aucmd_win_used = FALSE;
1577 	last_status(FALSE);	    // may need to remove last status line
1578 
1579 	if (!valid_tabpage_win(curtab))
1580 	    // no valid window in current tabpage
1581 	    close_tabpage(curtab);
1582 
1583 	restore_snapshot(SNAP_AUCMD_IDX, FALSE);
1584 	(void)win_comp_pos();   // recompute window positions
1585 	unblock_autocmds();
1586 
1587 	save_curwin = win_find_by_id(aco->save_curwin_id);
1588 	if (save_curwin != NULL)
1589 	    curwin = save_curwin;
1590 	else
1591 	    // Hmm, original window disappeared.  Just use the first one.
1592 	    curwin = firstwin;
1593 	curbuf = curwin->w_buffer;
1594 #ifdef FEAT_JOB_CHANNEL
1595 	// May need to restore insert mode for a prompt buffer.
1596 	entering_window(curwin);
1597 #endif
1598 	prevwin = win_find_by_id(aco->save_prevwin_id);
1599 #ifdef FEAT_EVAL
1600 	vars_clear(&aucmd_win->w_vars->dv_hashtab);  // free all w: variables
1601 	hash_init(&aucmd_win->w_vars->dv_hashtab);   // re-use the hashtab
1602 #endif
1603 	vim_free(globaldir);
1604 	globaldir = aco->globaldir;
1605 
1606 	// the buffer contents may have changed
1607 	check_cursor();
1608 	if (curwin->w_topline > curbuf->b_ml.ml_line_count)
1609 	{
1610 	    curwin->w_topline = curbuf->b_ml.ml_line_count;
1611 #ifdef FEAT_DIFF
1612 	    curwin->w_topfill = 0;
1613 #endif
1614 	}
1615 #if defined(FEAT_GUI)
1616 	// Hide the scrollbars from the aucmd_win and update.
1617 	gui_mch_enable_scrollbar(&aucmd_win->w_scrollbars[SBAR_LEFT], FALSE);
1618 	gui_mch_enable_scrollbar(&aucmd_win->w_scrollbars[SBAR_RIGHT], FALSE);
1619 	gui_may_update_scrollbars();
1620 #endif
1621     }
1622     else
1623     {
1624 	// Restore curwin.  Use the window ID, a window may have been closed
1625 	// and the memory re-used for another one.
1626 	save_curwin = win_find_by_id(aco->save_curwin_id);
1627 	if (save_curwin != NULL)
1628 	{
1629 	    // Restore the buffer which was previously edited by curwin, if
1630 	    // it was changed, we are still the same window and the buffer is
1631 	    // valid.
1632 	    if (curwin->w_id == aco->new_curwin_id
1633 		    && curbuf != aco->new_curbuf.br_buf
1634 		    && bufref_valid(&aco->new_curbuf)
1635 		    && aco->new_curbuf.br_buf->b_ml.ml_mfp != NULL)
1636 	    {
1637 # if defined(FEAT_SYN_HL) || defined(FEAT_SPELL)
1638 		if (curwin->w_s == &curbuf->b_s)
1639 		    curwin->w_s = &aco->new_curbuf.br_buf->b_s;
1640 # endif
1641 		--curbuf->b_nwindows;
1642 		curbuf = aco->new_curbuf.br_buf;
1643 		curwin->w_buffer = curbuf;
1644 		++curbuf->b_nwindows;
1645 	    }
1646 
1647 	    curwin = save_curwin;
1648 	    curbuf = curwin->w_buffer;
1649 	    prevwin = win_find_by_id(aco->save_prevwin_id);
1650 	    // In case the autocommand moves the cursor to a position that
1651 	    // does not exist in curbuf.
1652 	    check_cursor();
1653 	}
1654     }
1655 }
1656 
1657 static int	autocmd_nested = FALSE;
1658 
1659 /*
1660  * Execute autocommands for "event" and file name "fname".
1661  * Return TRUE if some commands were executed.
1662  */
1663     int
apply_autocmds(event_T event,char_u * fname,char_u * fname_io,int force,buf_T * buf)1664 apply_autocmds(
1665     event_T	event,
1666     char_u	*fname,	    // NULL or empty means use actual file name
1667     char_u	*fname_io,  // fname to use for <afile> on cmdline
1668     int		force,	    // when TRUE, ignore autocmd_busy
1669     buf_T	*buf)	    // buffer for <abuf>
1670 {
1671     return apply_autocmds_group(event, fname, fname_io, force,
1672 						      AUGROUP_ALL, buf, NULL);
1673 }
1674 
1675 /*
1676  * Like apply_autocmds(), but with extra "eap" argument.  This takes care of
1677  * setting v:filearg.
1678  */
1679     int
apply_autocmds_exarg(event_T event,char_u * fname,char_u * fname_io,int force,buf_T * buf,exarg_T * eap)1680 apply_autocmds_exarg(
1681     event_T	event,
1682     char_u	*fname,
1683     char_u	*fname_io,
1684     int		force,
1685     buf_T	*buf,
1686     exarg_T	*eap)
1687 {
1688     return apply_autocmds_group(event, fname, fname_io, force,
1689 						       AUGROUP_ALL, buf, eap);
1690 }
1691 
1692 /*
1693  * Like apply_autocmds(), but handles the caller's retval.  If the script
1694  * processing is being aborted or if retval is FAIL when inside a try
1695  * conditional, no autocommands are executed.  If otherwise the autocommands
1696  * cause the script to be aborted, retval is set to FAIL.
1697  */
1698     int
apply_autocmds_retval(event_T event,char_u * fname,char_u * fname_io,int force,buf_T * buf,int * retval)1699 apply_autocmds_retval(
1700     event_T	event,
1701     char_u	*fname,	    // NULL or empty means use actual file name
1702     char_u	*fname_io,  // fname to use for <afile> on cmdline
1703     int		force,	    // when TRUE, ignore autocmd_busy
1704     buf_T	*buf,	    // buffer for <abuf>
1705     int		*retval)    // pointer to caller's retval
1706 {
1707     int		did_cmd;
1708 
1709 #ifdef FEAT_EVAL
1710     if (should_abort(*retval))
1711 	return FALSE;
1712 #endif
1713 
1714     did_cmd = apply_autocmds_group(event, fname, fname_io, force,
1715 						      AUGROUP_ALL, buf, NULL);
1716     if (did_cmd
1717 #ifdef FEAT_EVAL
1718 	    && aborting()
1719 #endif
1720 	    )
1721 	*retval = FAIL;
1722     return did_cmd;
1723 }
1724 
1725 /*
1726  * Return TRUE when there is a CursorHold autocommand defined.
1727  */
1728     static int
has_cursorhold(void)1729 has_cursorhold(void)
1730 {
1731     return (first_autopat[(int)(get_real_state() == NORMAL_BUSY
1732 			    ? EVENT_CURSORHOLD : EVENT_CURSORHOLDI)] != NULL);
1733 }
1734 
1735 /*
1736  * Return TRUE if the CursorHold event can be triggered.
1737  */
1738     int
trigger_cursorhold(void)1739 trigger_cursorhold(void)
1740 {
1741     int		state;
1742 
1743     if (!did_cursorhold
1744 	    && has_cursorhold()
1745 	    && reg_recording == 0
1746 	    && typebuf.tb_len == 0
1747 	    && !ins_compl_active())
1748     {
1749 	state = get_real_state();
1750 	if (state == NORMAL_BUSY || (state & INSERT) != 0)
1751 	    return TRUE;
1752     }
1753     return FALSE;
1754 }
1755 
1756 /*
1757  * Return TRUE when there is a CursorMoved autocommand defined.
1758  */
1759     int
has_cursormoved(void)1760 has_cursormoved(void)
1761 {
1762     return (first_autopat[(int)EVENT_CURSORMOVED] != NULL);
1763 }
1764 
1765 /*
1766  * Return TRUE when there is a CursorMovedI autocommand defined.
1767  */
1768     int
has_cursormovedI(void)1769 has_cursormovedI(void)
1770 {
1771     return (first_autopat[(int)EVENT_CURSORMOVEDI] != NULL);
1772 }
1773 
1774 /*
1775  * Return TRUE when there is a TextChanged autocommand defined.
1776  */
1777     int
has_textchanged(void)1778 has_textchanged(void)
1779 {
1780     return (first_autopat[(int)EVENT_TEXTCHANGED] != NULL);
1781 }
1782 
1783 /*
1784  * Return TRUE when there is a TextChangedI autocommand defined.
1785  */
1786     int
has_textchangedI(void)1787 has_textchangedI(void)
1788 {
1789     return (first_autopat[(int)EVENT_TEXTCHANGEDI] != NULL);
1790 }
1791 
1792 /*
1793  * Return TRUE when there is a TextChangedP autocommand defined.
1794  */
1795     int
has_textchangedP(void)1796 has_textchangedP(void)
1797 {
1798     return (first_autopat[(int)EVENT_TEXTCHANGEDP] != NULL);
1799 }
1800 
1801 /*
1802  * Return TRUE when there is an InsertCharPre autocommand defined.
1803  */
1804     int
has_insertcharpre(void)1805 has_insertcharpre(void)
1806 {
1807     return (first_autopat[(int)EVENT_INSERTCHARPRE] != NULL);
1808 }
1809 
1810 /*
1811  * Return TRUE when there is an CmdUndefined autocommand defined.
1812  */
1813     int
has_cmdundefined(void)1814 has_cmdundefined(void)
1815 {
1816     return (first_autopat[(int)EVENT_CMDUNDEFINED] != NULL);
1817 }
1818 
1819 #if defined(FEAT_EVAL) || defined(PROTO)
1820 /*
1821  * Return TRUE when there is a TextYankPost autocommand defined.
1822  */
1823     int
has_textyankpost(void)1824 has_textyankpost(void)
1825 {
1826     return (first_autopat[(int)EVENT_TEXTYANKPOST] != NULL);
1827 }
1828 #endif
1829 
1830 #if defined(FEAT_EVAL) || defined(PROTO)
1831 /*
1832  * Return TRUE when there is a CompleteChanged autocommand defined.
1833  */
1834     int
has_completechanged(void)1835 has_completechanged(void)
1836 {
1837     return (first_autopat[(int)EVENT_COMPLETECHANGED] != NULL);
1838 }
1839 #endif
1840 
1841 #if defined(FEAT_EVAL) || defined(PROTO)
1842 /*
1843  * Return TRUE when there is a ModeChanged autocommand defined.
1844  */
1845     int
has_modechanged(void)1846 has_modechanged(void)
1847 {
1848     return (first_autopat[(int)EVENT_MODECHANGED] != NULL);
1849 }
1850 #endif
1851 
1852 /*
1853  * Execute autocommands for "event" and file name "fname".
1854  * Return TRUE if some commands were executed.
1855  */
1856     static int
apply_autocmds_group(event_T event,char_u * fname,char_u * fname_io,int force,int group,buf_T * buf,exarg_T * eap UNUSED)1857 apply_autocmds_group(
1858     event_T	event,
1859     char_u	*fname,	     // NULL or empty means use actual file name
1860     char_u	*fname_io,   // fname to use for <afile> on cmdline, NULL means
1861 			     // use fname
1862     int		force,	     // when TRUE, ignore autocmd_busy
1863     int		group,	     // group ID, or AUGROUP_ALL
1864     buf_T	*buf,	     // buffer for <abuf>
1865     exarg_T	*eap UNUSED) // command arguments
1866 {
1867     char_u	*sfname = NULL;	// short file name
1868     char_u	*tail;
1869     int		save_changed;
1870     buf_T	*old_curbuf;
1871     int		retval = FALSE;
1872     char_u	*save_autocmd_fname;
1873     int		save_autocmd_fname_full;
1874     int		save_autocmd_bufnr;
1875     char_u	*save_autocmd_match;
1876     int		save_autocmd_busy;
1877     int		save_autocmd_nested;
1878     static int	nesting = 0;
1879     AutoPatCmd	patcmd;
1880     AutoPat	*ap;
1881     sctx_T	save_current_sctx;
1882 #ifdef FEAT_EVAL
1883     funccal_entry_T funccal_entry;
1884     char_u	*save_cmdarg;
1885     long	save_cmdbang;
1886 #endif
1887     static int	filechangeshell_busy = FALSE;
1888 #ifdef FEAT_PROFILE
1889     proftime_T	wait_time;
1890 #endif
1891     int		did_save_redobuff = FALSE;
1892     save_redo_T	save_redo;
1893     int		save_KeyTyped = KeyTyped;
1894     ESTACK_CHECK_DECLARATION
1895 
1896     /*
1897      * Quickly return if there are no autocommands for this event or
1898      * autocommands are blocked.
1899      */
1900     if (event == NUM_EVENTS || first_autopat[(int)event] == NULL
1901 	    || autocmd_blocked > 0)
1902 	goto BYPASS_AU;
1903 
1904     /*
1905      * When autocommands are busy, new autocommands are only executed when
1906      * explicitly enabled with the "nested" flag.
1907      */
1908     if (autocmd_busy && !(force || autocmd_nested))
1909 	goto BYPASS_AU;
1910 
1911 #ifdef FEAT_EVAL
1912     /*
1913      * Quickly return when immediately aborting on error, or when an interrupt
1914      * occurred or an exception was thrown but not caught.
1915      */
1916     if (aborting())
1917 	goto BYPASS_AU;
1918 #endif
1919 
1920     /*
1921      * FileChangedShell never nests, because it can create an endless loop.
1922      */
1923     if (filechangeshell_busy && (event == EVENT_FILECHANGEDSHELL
1924 				      || event == EVENT_FILECHANGEDSHELLPOST))
1925 	goto BYPASS_AU;
1926 
1927     /*
1928      * Ignore events in 'eventignore'.
1929      */
1930     if (event_ignored(event))
1931 	goto BYPASS_AU;
1932 
1933     /*
1934      * Allow nesting of autocommands, but restrict the depth, because it's
1935      * possible to create an endless loop.
1936      */
1937     if (nesting == 10)
1938     {
1939 	emsg(_("E218: autocommand nesting too deep"));
1940 	goto BYPASS_AU;
1941     }
1942 
1943     /*
1944      * Check if these autocommands are disabled.  Used when doing ":all" or
1945      * ":ball".
1946      */
1947     if (       (autocmd_no_enter
1948 		&& (event == EVENT_WINENTER || event == EVENT_BUFENTER))
1949 	    || (autocmd_no_leave
1950 		&& (event == EVENT_WINLEAVE || event == EVENT_BUFLEAVE)))
1951 	goto BYPASS_AU;
1952 
1953     /*
1954      * Save the autocmd_* variables and info about the current buffer.
1955      */
1956     save_autocmd_fname = autocmd_fname;
1957     save_autocmd_fname_full = autocmd_fname_full;
1958     save_autocmd_bufnr = autocmd_bufnr;
1959     save_autocmd_match = autocmd_match;
1960     save_autocmd_busy = autocmd_busy;
1961     save_autocmd_nested = autocmd_nested;
1962     save_changed = curbuf->b_changed;
1963     old_curbuf = curbuf;
1964 
1965     /*
1966      * Set the file name to be used for <afile>.
1967      * Make a copy to avoid that changing a buffer name or directory makes it
1968      * invalid.
1969      */
1970     if (fname_io == NULL)
1971     {
1972 	if (event == EVENT_COLORSCHEME || event == EVENT_COLORSCHEMEPRE
1973 						   || event == EVENT_OPTIONSET
1974 						   || event == EVENT_MODECHANGED)
1975 	    autocmd_fname = NULL;
1976 	else if (fname != NULL && !ends_excmd(*fname))
1977 	    autocmd_fname = fname;
1978 	else if (buf != NULL)
1979 	    autocmd_fname = buf->b_ffname;
1980 	else
1981 	    autocmd_fname = NULL;
1982     }
1983     else
1984 	autocmd_fname = fname_io;
1985     if (autocmd_fname != NULL)
1986 	autocmd_fname = vim_strsave(autocmd_fname);
1987     autocmd_fname_full = FALSE; // call FullName_save() later
1988 
1989     /*
1990      * Set the buffer number to be used for <abuf>.
1991      */
1992     if (buf == NULL)
1993 	autocmd_bufnr = 0;
1994     else
1995 	autocmd_bufnr = buf->b_fnum;
1996 
1997     /*
1998      * When the file name is NULL or empty, use the file name of buffer "buf".
1999      * Always use the full path of the file name to match with, in case
2000      * "allow_dirs" is set.
2001      */
2002     if (fname == NULL || *fname == NUL)
2003     {
2004 	if (buf == NULL)
2005 	    fname = NULL;
2006 	else
2007 	{
2008 #ifdef FEAT_SYN_HL
2009 	    if (event == EVENT_SYNTAX)
2010 		fname = buf->b_p_syn;
2011 	    else
2012 #endif
2013 		if (event == EVENT_FILETYPE)
2014 		    fname = buf->b_p_ft;
2015 		else
2016 		{
2017 		    if (buf->b_sfname != NULL)
2018 			sfname = vim_strsave(buf->b_sfname);
2019 		    fname = buf->b_ffname;
2020 		}
2021 	}
2022 	if (fname == NULL)
2023 	    fname = (char_u *)"";
2024 	fname = vim_strsave(fname);	// make a copy, so we can change it
2025     }
2026     else
2027     {
2028 	sfname = vim_strsave(fname);
2029 	// Don't try expanding FileType, Syntax, FuncUndefined, WindowID,
2030 	// ColorScheme, QuickFixCmd* or DirChanged
2031 	if (event == EVENT_FILETYPE
2032 		|| event == EVENT_SYNTAX
2033 		|| event == EVENT_CMDLINECHANGED
2034 		|| event == EVENT_CMDLINEENTER
2035 		|| event == EVENT_CMDLINELEAVE
2036 		|| event == EVENT_CMDWINENTER
2037 		|| event == EVENT_CMDWINLEAVE
2038 		|| event == EVENT_CMDUNDEFINED
2039 		|| event == EVENT_FUNCUNDEFINED
2040 		|| event == EVENT_REMOTEREPLY
2041 		|| event == EVENT_SPELLFILEMISSING
2042 		|| event == EVENT_QUICKFIXCMDPRE
2043 		|| event == EVENT_COLORSCHEME
2044 		|| event == EVENT_COLORSCHEMEPRE
2045 		|| event == EVENT_OPTIONSET
2046 		|| event == EVENT_QUICKFIXCMDPOST
2047 		|| event == EVENT_DIRCHANGED
2048 		|| event == EVENT_MODECHANGED
2049 		|| event == EVENT_WINCLOSED)
2050 	{
2051 	    fname = vim_strsave(fname);
2052 	    autocmd_fname_full = TRUE; // don't expand it later
2053 	}
2054 	else
2055 	    fname = FullName_save(fname, FALSE);
2056     }
2057     if (fname == NULL)	    // out of memory
2058     {
2059 	vim_free(sfname);
2060 	retval = FALSE;
2061 	goto BYPASS_AU;
2062     }
2063 
2064 #ifdef BACKSLASH_IN_FILENAME
2065     /*
2066      * Replace all backslashes with forward slashes.  This makes the
2067      * autocommand patterns portable between Unix and MS-DOS.
2068      */
2069     if (sfname != NULL)
2070 	forward_slash(sfname);
2071     forward_slash(fname);
2072 #endif
2073 
2074 #ifdef VMS
2075     // remove version for correct match
2076     if (sfname != NULL)
2077 	vms_remove_version(sfname);
2078     vms_remove_version(fname);
2079 #endif
2080 
2081     /*
2082      * Set the name to be used for <amatch>.
2083      */
2084     autocmd_match = fname;
2085 
2086 
2087     // Don't redraw while doing autocommands.
2088     ++RedrawingDisabled;
2089 
2090     // name and lnum are filled in later
2091     estack_push(ETYPE_AUCMD, NULL, 0);
2092     ESTACK_CHECK_SETUP
2093 
2094     save_current_sctx = current_sctx;
2095 
2096 #ifdef FEAT_EVAL
2097 # ifdef FEAT_PROFILE
2098     if (do_profiling == PROF_YES)
2099 	prof_child_enter(&wait_time); // doesn't count for the caller itself
2100 # endif
2101 
2102     // Don't use local function variables, if called from a function.
2103     save_funccal(&funccal_entry);
2104 #endif
2105 
2106     /*
2107      * When starting to execute autocommands, save the search patterns.
2108      */
2109     if (!autocmd_busy)
2110     {
2111 	save_search_patterns();
2112 	if (!ins_compl_active())
2113 	{
2114 	    saveRedobuff(&save_redo);
2115 	    did_save_redobuff = TRUE;
2116 	}
2117 	did_filetype = keep_filetype;
2118     }
2119 
2120     /*
2121      * Note that we are applying autocmds.  Some commands need to know.
2122      */
2123     autocmd_busy = TRUE;
2124     filechangeshell_busy = (event == EVENT_FILECHANGEDSHELL);
2125     ++nesting;		// see matching decrement below
2126 
2127     // Remember that FileType was triggered.  Used for did_filetype().
2128     if (event == EVENT_FILETYPE)
2129 	did_filetype = TRUE;
2130 
2131     tail = gettail(fname);
2132 
2133     // Find first autocommand that matches
2134     patcmd.curpat = first_autopat[(int)event];
2135     patcmd.nextcmd = NULL;
2136     patcmd.group = group;
2137     patcmd.fname = fname;
2138     patcmd.sfname = sfname;
2139     patcmd.tail = tail;
2140     patcmd.event = event;
2141     patcmd.arg_bufnr = autocmd_bufnr;
2142     patcmd.next = NULL;
2143     auto_next_pat(&patcmd, FALSE);
2144 
2145     // found one, start executing the autocommands
2146     if (patcmd.curpat != NULL)
2147     {
2148 	// add to active_apc_list
2149 	patcmd.next = active_apc_list;
2150 	active_apc_list = &patcmd;
2151 
2152 #ifdef FEAT_EVAL
2153 	// set v:cmdarg (only when there is a matching pattern)
2154 	save_cmdbang = (long)get_vim_var_nr(VV_CMDBANG);
2155 	if (eap != NULL)
2156 	{
2157 	    save_cmdarg = set_cmdarg(eap, NULL);
2158 	    set_vim_var_nr(VV_CMDBANG, (long)eap->forceit);
2159 	}
2160 	else
2161 	    save_cmdarg = NULL;	// avoid gcc warning
2162 #endif
2163 	retval = TRUE;
2164 	// mark the last pattern, to avoid an endless loop when more patterns
2165 	// are added when executing autocommands
2166 	for (ap = patcmd.curpat; ap->next != NULL; ap = ap->next)
2167 	    ap->last = FALSE;
2168 	ap->last = TRUE;
2169 
2170 	if (nesting == 1)
2171 	    // make sure cursor and topline are valid
2172 	    check_lnums(TRUE);
2173 
2174 	do_cmdline(NULL, getnextac, (void *)&patcmd,
2175 				     DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
2176 
2177 	if (nesting == 1)
2178 	    // restore cursor and topline, unless they were changed
2179 	    reset_lnums();
2180 
2181 #ifdef FEAT_EVAL
2182 	if (eap != NULL)
2183 	{
2184 	    (void)set_cmdarg(NULL, save_cmdarg);
2185 	    set_vim_var_nr(VV_CMDBANG, save_cmdbang);
2186 	}
2187 #endif
2188 	// delete from active_apc_list
2189 	if (active_apc_list == &patcmd)	    // just in case
2190 	    active_apc_list = patcmd.next;
2191     }
2192 
2193     --RedrawingDisabled;
2194     autocmd_busy = save_autocmd_busy;
2195     filechangeshell_busy = FALSE;
2196     autocmd_nested = save_autocmd_nested;
2197     vim_free(SOURCING_NAME);
2198     ESTACK_CHECK_NOW
2199     estack_pop();
2200     vim_free(autocmd_fname);
2201     autocmd_fname = save_autocmd_fname;
2202     autocmd_fname_full = save_autocmd_fname_full;
2203     autocmd_bufnr = save_autocmd_bufnr;
2204     autocmd_match = save_autocmd_match;
2205     current_sctx = save_current_sctx;
2206 #ifdef FEAT_EVAL
2207     restore_funccal();
2208 # ifdef FEAT_PROFILE
2209     if (do_profiling == PROF_YES)
2210 	prof_child_exit(&wait_time);
2211 # endif
2212 #endif
2213     KeyTyped = save_KeyTyped;
2214     vim_free(fname);
2215     vim_free(sfname);
2216     --nesting;		// see matching increment above
2217 
2218     /*
2219      * When stopping to execute autocommands, restore the search patterns and
2220      * the redo buffer.  Free any buffers in the au_pending_free_buf list and
2221      * free any windows in the au_pending_free_win list.
2222      */
2223     if (!autocmd_busy)
2224     {
2225 	restore_search_patterns();
2226 	if (did_save_redobuff)
2227 	    restoreRedobuff(&save_redo);
2228 	did_filetype = FALSE;
2229 	while (au_pending_free_buf != NULL)
2230 	{
2231 	    buf_T *b = au_pending_free_buf->b_next;
2232 
2233 	    vim_free(au_pending_free_buf);
2234 	    au_pending_free_buf = b;
2235 	}
2236 	while (au_pending_free_win != NULL)
2237 	{
2238 	    win_T *w = au_pending_free_win->w_next;
2239 
2240 	    vim_free(au_pending_free_win);
2241 	    au_pending_free_win = w;
2242 	}
2243     }
2244 
2245     /*
2246      * Some events don't set or reset the Changed flag.
2247      * Check if still in the same buffer!
2248      */
2249     if (curbuf == old_curbuf
2250 	    && (event == EVENT_BUFREADPOST
2251 		|| event == EVENT_BUFWRITEPOST
2252 		|| event == EVENT_FILEAPPENDPOST
2253 		|| event == EVENT_VIMLEAVE
2254 		|| event == EVENT_VIMLEAVEPRE))
2255     {
2256 	if (curbuf->b_changed != save_changed)
2257 	    need_maketitle = TRUE;
2258 	curbuf->b_changed = save_changed;
2259     }
2260 
2261     au_cleanup();	// may really delete removed patterns/commands now
2262 
2263 BYPASS_AU:
2264     // When wiping out a buffer make sure all its buffer-local autocommands
2265     // are deleted.
2266     if (event == EVENT_BUFWIPEOUT && buf != NULL)
2267 	aubuflocal_remove(buf);
2268 
2269     if (retval == OK && event == EVENT_FILETYPE)
2270 	au_did_filetype = TRUE;
2271 
2272     return retval;
2273 }
2274 
2275 # ifdef FEAT_EVAL
2276 static char_u	*old_termresponse = NULL;
2277 # endif
2278 
2279 /*
2280  * Block triggering autocommands until unblock_autocmd() is called.
2281  * Can be used recursively, so long as it's symmetric.
2282  */
2283     void
block_autocmds(void)2284 block_autocmds(void)
2285 {
2286 # ifdef FEAT_EVAL
2287     // Remember the value of v:termresponse.
2288     if (autocmd_blocked == 0)
2289 	old_termresponse = get_vim_var_str(VV_TERMRESPONSE);
2290 # endif
2291     ++autocmd_blocked;
2292 }
2293 
2294     void
unblock_autocmds(void)2295 unblock_autocmds(void)
2296 {
2297     --autocmd_blocked;
2298 
2299 # ifdef FEAT_EVAL
2300     // When v:termresponse was set while autocommands were blocked, trigger
2301     // the autocommands now.  Esp. useful when executing a shell command
2302     // during startup (vimdiff).
2303     if (autocmd_blocked == 0
2304 		      && get_vim_var_str(VV_TERMRESPONSE) != old_termresponse)
2305 	apply_autocmds(EVENT_TERMRESPONSE, NULL, NULL, FALSE, curbuf);
2306 # endif
2307 }
2308 
2309     int
is_autocmd_blocked(void)2310 is_autocmd_blocked(void)
2311 {
2312     return autocmd_blocked != 0;
2313 }
2314 
2315 /*
2316  * Find next autocommand pattern that matches.
2317  */
2318     static void
auto_next_pat(AutoPatCmd * apc,int stop_at_last)2319 auto_next_pat(
2320     AutoPatCmd	*apc,
2321     int		stop_at_last)	    // stop when 'last' flag is set
2322 {
2323     AutoPat	*ap;
2324     AutoCmd	*cp;
2325     char_u	*name;
2326     char	*s;
2327     char_u	**sourcing_namep = &SOURCING_NAME;
2328 
2329     VIM_CLEAR(*sourcing_namep);
2330 
2331     for (ap = apc->curpat; ap != NULL && !got_int; ap = ap->next)
2332     {
2333 	apc->curpat = NULL;
2334 
2335 	// Only use a pattern when it has not been removed, has commands and
2336 	// the group matches. For buffer-local autocommands only check the
2337 	// buffer number.
2338 	if (ap->pat != NULL && ap->cmds != NULL
2339 		&& (apc->group == AUGROUP_ALL || apc->group == ap->group))
2340 	{
2341 	    // execution-condition
2342 	    if (ap->buflocal_nr == 0
2343 		    ? (match_file_pat(NULL, &ap->reg_prog, apc->fname,
2344 				      apc->sfname, apc->tail, ap->allow_dirs))
2345 		    : ap->buflocal_nr == apc->arg_bufnr)
2346 	    {
2347 		name = event_nr2name(apc->event);
2348 		s = _("%s Autocommands for \"%s\"");
2349 		*sourcing_namep = alloc(STRLEN(s)
2350 					      + STRLEN(name) + ap->patlen + 1);
2351 		if (*sourcing_namep != NULL)
2352 		{
2353 		    sprintf((char *)*sourcing_namep, s,
2354 					       (char *)name, (char *)ap->pat);
2355 		    if (p_verbose >= 8)
2356 		    {
2357 			verbose_enter();
2358 			smsg(_("Executing %s"), *sourcing_namep);
2359 			verbose_leave();
2360 		    }
2361 		}
2362 
2363 		apc->curpat = ap;
2364 		apc->nextcmd = ap->cmds;
2365 		// mark last command
2366 		for (cp = ap->cmds; cp->next != NULL; cp = cp->next)
2367 		    cp->last = FALSE;
2368 		cp->last = TRUE;
2369 	    }
2370 	    line_breakcheck();
2371 	    if (apc->curpat != NULL)	    // found a match
2372 		break;
2373 	}
2374 	if (stop_at_last && ap->last)
2375 	    break;
2376     }
2377 }
2378 
2379 /*
2380  * Get next autocommand command.
2381  * Called by do_cmdline() to get the next line for ":if".
2382  * Returns allocated string, or NULL for end of autocommands.
2383  */
2384     char_u *
getnextac(int c UNUSED,void * cookie,int indent UNUSED,getline_opt_T options UNUSED)2385 getnextac(
2386 	int c UNUSED,
2387 	void *cookie,
2388 	int indent UNUSED,
2389 	getline_opt_T options UNUSED)
2390 {
2391     AutoPatCmd	    *acp = (AutoPatCmd *)cookie;
2392     char_u	    *retval;
2393     AutoCmd	    *ac;
2394 
2395     // Can be called again after returning the last line.
2396     if (acp->curpat == NULL)
2397 	return NULL;
2398 
2399     // repeat until we find an autocommand to execute
2400     for (;;)
2401     {
2402 	// skip removed commands
2403 	while (acp->nextcmd != NULL && acp->nextcmd->cmd == NULL)
2404 	    if (acp->nextcmd->last)
2405 		acp->nextcmd = NULL;
2406 	    else
2407 		acp->nextcmd = acp->nextcmd->next;
2408 
2409 	if (acp->nextcmd != NULL)
2410 	    break;
2411 
2412 	// at end of commands, find next pattern that matches
2413 	if (acp->curpat->last)
2414 	    acp->curpat = NULL;
2415 	else
2416 	    acp->curpat = acp->curpat->next;
2417 	if (acp->curpat != NULL)
2418 	    auto_next_pat(acp, TRUE);
2419 	if (acp->curpat == NULL)
2420 	    return NULL;
2421     }
2422 
2423     ac = acp->nextcmd;
2424 
2425     if (p_verbose >= 9)
2426     {
2427 	verbose_enter_scroll();
2428 	smsg(_("autocommand %s"), ac->cmd);
2429 	msg_puts("\n");   // don't overwrite this either
2430 	verbose_leave_scroll();
2431     }
2432     retval = vim_strsave(ac->cmd);
2433     // Remove one-shot ("once") autocmd in anticipation of its execution.
2434     if (ac->once)
2435 	au_del_cmd(ac);
2436     autocmd_nested = ac->nested;
2437     current_sctx = ac->script_ctx;
2438     if (ac->last)
2439 	acp->nextcmd = NULL;
2440     else
2441 	acp->nextcmd = ac->next;
2442     return retval;
2443 }
2444 
2445 /*
2446  * Return TRUE if there is a matching autocommand for "fname".
2447  * To account for buffer-local autocommands, function needs to know
2448  * in which buffer the file will be opened.
2449  */
2450     int
has_autocmd(event_T event,char_u * sfname,buf_T * buf)2451 has_autocmd(event_T event, char_u *sfname, buf_T *buf)
2452 {
2453     AutoPat	*ap;
2454     char_u	*fname;
2455     char_u	*tail = gettail(sfname);
2456     int		retval = FALSE;
2457 
2458     fname = FullName_save(sfname, FALSE);
2459     if (fname == NULL)
2460 	return FALSE;
2461 
2462 #ifdef BACKSLASH_IN_FILENAME
2463     /*
2464      * Replace all backslashes with forward slashes.  This makes the
2465      * autocommand patterns portable between Unix and MS-DOS.
2466      */
2467     sfname = vim_strsave(sfname);
2468     if (sfname != NULL)
2469 	forward_slash(sfname);
2470     forward_slash(fname);
2471 #endif
2472 
2473     FOR_ALL_AUTOCMD_PATTERNS(event, ap)
2474 	if (ap->pat != NULL && ap->cmds != NULL
2475 	      && (ap->buflocal_nr == 0
2476 		? match_file_pat(NULL, &ap->reg_prog,
2477 					  fname, sfname, tail, ap->allow_dirs)
2478 		: buf != NULL && ap->buflocal_nr == buf->b_fnum
2479 	   ))
2480 	{
2481 	    retval = TRUE;
2482 	    break;
2483 	}
2484 
2485     vim_free(fname);
2486 #ifdef BACKSLASH_IN_FILENAME
2487     vim_free(sfname);
2488 #endif
2489 
2490     return retval;
2491 }
2492 
2493 /*
2494  * Function given to ExpandGeneric() to obtain the list of autocommand group
2495  * names.
2496  */
2497     char_u *
get_augroup_name(expand_T * xp UNUSED,int idx)2498 get_augroup_name(expand_T *xp UNUSED, int idx)
2499 {
2500     if (idx == augroups.ga_len)		// add "END" add the end
2501 	return (char_u *)"END";
2502     if (idx >= augroups.ga_len)		// end of list
2503 	return NULL;
2504     if (AUGROUP_NAME(idx) == NULL || AUGROUP_NAME(idx) == get_deleted_augroup())
2505 	// skip deleted entries
2506 	return (char_u *)"";
2507     return AUGROUP_NAME(idx);		// return a name
2508 }
2509 
2510 static int include_groups = FALSE;
2511 
2512     char_u  *
set_context_in_autocmd(expand_T * xp,char_u * arg,int doautocmd)2513 set_context_in_autocmd(
2514     expand_T	*xp,
2515     char_u	*arg,
2516     int		doautocmd)	// TRUE for :doauto*, FALSE for :autocmd
2517 {
2518     char_u	*p;
2519     int		group;
2520 
2521     // check for a group name, skip it if present
2522     include_groups = FALSE;
2523     p = arg;
2524     group = au_get_grouparg(&arg);
2525     if (group == AUGROUP_ERROR)
2526 	return NULL;
2527     // If there only is a group name that's what we expand.
2528     if (*arg == NUL && group != AUGROUP_ALL && !VIM_ISWHITE(arg[-1]))
2529     {
2530 	arg = p;
2531 	group = AUGROUP_ALL;
2532     }
2533 
2534     // skip over event name
2535     for (p = arg; *p != NUL && !VIM_ISWHITE(*p); ++p)
2536 	if (*p == ',')
2537 	    arg = p + 1;
2538     if (*p == NUL)
2539     {
2540 	if (group == AUGROUP_ALL)
2541 	    include_groups = TRUE;
2542 	xp->xp_context = EXPAND_EVENTS;	    // expand event name
2543 	xp->xp_pattern = arg;
2544 	return NULL;
2545     }
2546 
2547     // skip over pattern
2548     arg = skipwhite(p);
2549     while (*arg && (!VIM_ISWHITE(*arg) || arg[-1] == '\\'))
2550 	arg++;
2551     if (*arg)
2552 	return arg;			    // expand (next) command
2553 
2554     if (doautocmd)
2555 	xp->xp_context = EXPAND_FILES;	    // expand file names
2556     else
2557 	xp->xp_context = EXPAND_NOTHING;    // pattern is not expanded
2558     return NULL;
2559 }
2560 
2561 /*
2562  * Function given to ExpandGeneric() to obtain the list of event names.
2563  */
2564     char_u *
get_event_name(expand_T * xp UNUSED,int idx)2565 get_event_name(expand_T *xp UNUSED, int idx)
2566 {
2567     if (idx < augroups.ga_len)		// First list group names, if wanted
2568     {
2569 	if (!include_groups || AUGROUP_NAME(idx) == NULL
2570 				 || AUGROUP_NAME(idx) == get_deleted_augroup())
2571 	    return (char_u *)"";	// skip deleted entries
2572 	return AUGROUP_NAME(idx);	// return a name
2573     }
2574     return (char_u *)event_names[idx - augroups.ga_len].name;
2575 }
2576 
2577 
2578 #if defined(FEAT_EVAL) || defined(PROTO)
2579 /*
2580  * Return TRUE if autocmd is supported.
2581  */
2582     int
autocmd_supported(char_u * name)2583 autocmd_supported(char_u *name)
2584 {
2585     char_u *p;
2586 
2587     return (event_name2nr(name, &p) != NUM_EVENTS);
2588 }
2589 
2590 /*
2591  * Return TRUE if an autocommand is defined for a group, event and
2592  * pattern:  The group can be omitted to accept any group. "event" and "pattern"
2593  * can be NULL to accept any event and pattern. "pattern" can be NULL to accept
2594  * any pattern. Buffer-local patterns <buffer> or <buffer=N> are accepted.
2595  * Used for:
2596  *	exists("#Group") or
2597  *	exists("#Group#Event") or
2598  *	exists("#Group#Event#pat") or
2599  *	exists("#Event") or
2600  *	exists("#Event#pat")
2601  */
2602     int
au_exists(char_u * arg)2603 au_exists(char_u *arg)
2604 {
2605     char_u	*arg_save;
2606     char_u	*pattern = NULL;
2607     char_u	*event_name;
2608     char_u	*p;
2609     event_T	event;
2610     AutoPat	*ap;
2611     buf_T	*buflocal_buf = NULL;
2612     int		group;
2613     int		retval = FALSE;
2614 
2615     // Make a copy so that we can change the '#' chars to a NUL.
2616     arg_save = vim_strsave(arg);
2617     if (arg_save == NULL)
2618 	return FALSE;
2619     p = vim_strchr(arg_save, '#');
2620     if (p != NULL)
2621 	*p++ = NUL;
2622 
2623     // First, look for an autocmd group name
2624     group = au_find_group(arg_save);
2625     if (group == AUGROUP_ERROR)
2626     {
2627 	// Didn't match a group name, assume the first argument is an event.
2628 	group = AUGROUP_ALL;
2629 	event_name = arg_save;
2630     }
2631     else
2632     {
2633 	if (p == NULL)
2634 	{
2635 	    // "Group": group name is present and it's recognized
2636 	    retval = TRUE;
2637 	    goto theend;
2638 	}
2639 
2640 	// Must be "Group#Event" or "Group#Event#pat".
2641 	event_name = p;
2642 	p = vim_strchr(event_name, '#');
2643 	if (p != NULL)
2644 	    *p++ = NUL;	    // "Group#Event#pat"
2645     }
2646 
2647     pattern = p;	    // "pattern" is NULL when there is no pattern
2648 
2649     // find the index (enum) for the event name
2650     event = event_name2nr(event_name, &p);
2651 
2652     // return FALSE if the event name is not recognized
2653     if (event == NUM_EVENTS)
2654 	goto theend;
2655 
2656     // Find the first autocommand for this event.
2657     // If there isn't any, return FALSE;
2658     // If there is one and no pattern given, return TRUE;
2659     ap = first_autopat[(int)event];
2660     if (ap == NULL)
2661 	goto theend;
2662 
2663     // if pattern is "<buffer>", special handling is needed which uses curbuf
2664     // for pattern "<buffer=N>, fnamecmp() will work fine
2665     if (pattern != NULL && STRICMP(pattern, "<buffer>") == 0)
2666 	buflocal_buf = curbuf;
2667 
2668     // Check if there is an autocommand with the given pattern.
2669     for ( ; ap != NULL; ap = ap->next)
2670 	// only use a pattern when it has not been removed and has commands.
2671 	// For buffer-local autocommands, fnamecmp() works fine.
2672 	if (ap->pat != NULL && ap->cmds != NULL
2673 	    && (group == AUGROUP_ALL || ap->group == group)
2674 	    && (pattern == NULL
2675 		|| (buflocal_buf == NULL
2676 		    ? fnamecmp(ap->pat, pattern) == 0
2677 		    : ap->buflocal_nr == buflocal_buf->b_fnum)))
2678 	{
2679 	    retval = TRUE;
2680 	    break;
2681 	}
2682 
2683 theend:
2684     vim_free(arg_save);
2685     return retval;
2686 }
2687 #endif
2688