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