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