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