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