blob: 8a6896bae845d5b5a4f01d4576b21b0ee65b1da4 [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
Bram Moolenaare2c453d2019-08-21 14:37:09 +02001681 && !ins_compl_active())
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001682 {
1683 state = get_real_state();
1684 if (state == NORMAL_BUSY || (state & INSERT) != 0)
1685 return TRUE;
1686 }
1687 return FALSE;
1688}
1689
1690/*
1691 * Return TRUE when there is a CursorMoved autocommand defined.
1692 */
1693 int
1694has_cursormoved(void)
1695{
1696 return (first_autopat[(int)EVENT_CURSORMOVED] != NULL);
1697}
1698
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001699/*
1700 * Return TRUE when there is a CursorMovedI autocommand defined.
1701 */
1702 int
1703has_cursormovedI(void)
1704{
1705 return (first_autopat[(int)EVENT_CURSORMOVEDI] != NULL);
1706}
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001707
1708/*
1709 * Return TRUE when there is a TextChanged autocommand defined.
1710 */
1711 int
1712has_textchanged(void)
1713{
1714 return (first_autopat[(int)EVENT_TEXTCHANGED] != NULL);
1715}
1716
1717/*
1718 * Return TRUE when there is a TextChangedI autocommand defined.
1719 */
1720 int
1721has_textchangedI(void)
1722{
1723 return (first_autopat[(int)EVENT_TEXTCHANGEDI] != NULL);
1724}
1725
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001726/*
1727 * Return TRUE when there is a TextChangedP autocommand defined.
1728 */
1729 int
1730has_textchangedP(void)
1731{
1732 return (first_autopat[(int)EVENT_TEXTCHANGEDP] != NULL);
1733}
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001734
1735/*
1736 * Return TRUE when there is an InsertCharPre autocommand defined.
1737 */
1738 int
1739has_insertcharpre(void)
1740{
1741 return (first_autopat[(int)EVENT_INSERTCHARPRE] != NULL);
1742}
1743
1744/*
1745 * Return TRUE when there is an CmdUndefined autocommand defined.
1746 */
1747 int
1748has_cmdundefined(void)
1749{
1750 return (first_autopat[(int)EVENT_CMDUNDEFINED] != NULL);
1751}
1752
1753/*
1754 * Return TRUE when there is an FuncUndefined autocommand defined.
1755 */
1756 int
1757has_funcundefined(void)
1758{
1759 return (first_autopat[(int)EVENT_FUNCUNDEFINED] != NULL);
1760}
1761
1762#if defined(FEAT_EVAL) || defined(PROTO)
1763/*
1764 * Return TRUE when there is a TextYankPost autocommand defined.
1765 */
1766 int
1767has_textyankpost(void)
1768{
1769 return (first_autopat[(int)EVENT_TEXTYANKPOST] != NULL);
1770}
1771#endif
1772
Bram Moolenaard7f246c2019-04-08 18:15:41 +02001773#if defined(FEAT_EVAL) || defined(PROTO)
1774/*
1775 * Return TRUE when there is a CompleteChanged autocommand defined.
1776 */
1777 int
1778has_completechanged(void)
1779{
1780 return (first_autopat[(int)EVENT_COMPLETECHANGED] != NULL);
1781}
1782#endif
1783
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001784/*
1785 * Execute autocommands for "event" and file name "fname".
1786 * Return TRUE if some commands were executed.
1787 */
1788 static int
1789apply_autocmds_group(
1790 event_T event,
1791 char_u *fname, // NULL or empty means use actual file name
1792 char_u *fname_io, // fname to use for <afile> on cmdline, NULL means
1793 // use fname
1794 int force, // when TRUE, ignore autocmd_busy
1795 int group, // group ID, or AUGROUP_ALL
1796 buf_T *buf, // buffer for <abuf>
1797 exarg_T *eap UNUSED) // command arguments
1798{
1799 char_u *sfname = NULL; // short file name
1800 char_u *tail;
1801 int save_changed;
1802 buf_T *old_curbuf;
1803 int retval = FALSE;
1804 char_u *save_sourcing_name;
1805 linenr_T save_sourcing_lnum;
1806 char_u *save_autocmd_fname;
1807 int save_autocmd_fname_full;
1808 int save_autocmd_bufnr;
1809 char_u *save_autocmd_match;
1810 int save_autocmd_busy;
1811 int save_autocmd_nested;
1812 static int nesting = 0;
1813 AutoPatCmd patcmd;
1814 AutoPat *ap;
1815#ifdef FEAT_EVAL
1816 sctx_T save_current_sctx;
1817 funccal_entry_T funccal_entry;
1818 char_u *save_cmdarg;
1819 long save_cmdbang;
1820#endif
1821 static int filechangeshell_busy = FALSE;
1822#ifdef FEAT_PROFILE
1823 proftime_T wait_time;
1824#endif
1825 int did_save_redobuff = FALSE;
1826 save_redo_T save_redo;
1827 int save_KeyTyped = KeyTyped;
1828
1829 /*
1830 * Quickly return if there are no autocommands for this event or
1831 * autocommands are blocked.
1832 */
1833 if (event == NUM_EVENTS || first_autopat[(int)event] == NULL
1834 || autocmd_blocked > 0)
1835 goto BYPASS_AU;
1836
1837 /*
1838 * When autocommands are busy, new autocommands are only executed when
1839 * explicitly enabled with the "nested" flag.
1840 */
1841 if (autocmd_busy && !(force || autocmd_nested))
1842 goto BYPASS_AU;
1843
1844#ifdef FEAT_EVAL
1845 /*
1846 * Quickly return when immediately aborting on error, or when an interrupt
1847 * occurred or an exception was thrown but not caught.
1848 */
1849 if (aborting())
1850 goto BYPASS_AU;
1851#endif
1852
1853 /*
1854 * FileChangedShell never nests, because it can create an endless loop.
1855 */
1856 if (filechangeshell_busy && (event == EVENT_FILECHANGEDSHELL
1857 || event == EVENT_FILECHANGEDSHELLPOST))
1858 goto BYPASS_AU;
1859
1860 /*
1861 * Ignore events in 'eventignore'.
1862 */
1863 if (event_ignored(event))
1864 goto BYPASS_AU;
1865
1866 /*
1867 * Allow nesting of autocommands, but restrict the depth, because it's
1868 * possible to create an endless loop.
1869 */
1870 if (nesting == 10)
1871 {
1872 emsg(_("E218: autocommand nesting too deep"));
1873 goto BYPASS_AU;
1874 }
1875
1876 /*
1877 * Check if these autocommands are disabled. Used when doing ":all" or
1878 * ":ball".
1879 */
1880 if ( (autocmd_no_enter
1881 && (event == EVENT_WINENTER || event == EVENT_BUFENTER))
1882 || (autocmd_no_leave
1883 && (event == EVENT_WINLEAVE || event == EVENT_BUFLEAVE)))
1884 goto BYPASS_AU;
1885
1886 /*
1887 * Save the autocmd_* variables and info about the current buffer.
1888 */
1889 save_autocmd_fname = autocmd_fname;
1890 save_autocmd_fname_full = autocmd_fname_full;
1891 save_autocmd_bufnr = autocmd_bufnr;
1892 save_autocmd_match = autocmd_match;
1893 save_autocmd_busy = autocmd_busy;
1894 save_autocmd_nested = autocmd_nested;
1895 save_changed = curbuf->b_changed;
1896 old_curbuf = curbuf;
1897
1898 /*
1899 * Set the file name to be used for <afile>.
1900 * Make a copy to avoid that changing a buffer name or directory makes it
1901 * invalid.
1902 */
1903 if (fname_io == NULL)
1904 {
1905 if (event == EVENT_COLORSCHEME || event == EVENT_COLORSCHEMEPRE
1906 || event == EVENT_OPTIONSET)
1907 autocmd_fname = NULL;
1908 else if (fname != NULL && !ends_excmd(*fname))
1909 autocmd_fname = fname;
1910 else if (buf != NULL)
1911 autocmd_fname = buf->b_ffname;
1912 else
1913 autocmd_fname = NULL;
1914 }
1915 else
1916 autocmd_fname = fname_io;
1917 if (autocmd_fname != NULL)
1918 autocmd_fname = vim_strsave(autocmd_fname);
1919 autocmd_fname_full = FALSE; // call FullName_save() later
1920
1921 /*
1922 * Set the buffer number to be used for <abuf>.
1923 */
1924 if (buf == NULL)
1925 autocmd_bufnr = 0;
1926 else
1927 autocmd_bufnr = buf->b_fnum;
1928
1929 /*
1930 * When the file name is NULL or empty, use the file name of buffer "buf".
1931 * Always use the full path of the file name to match with, in case
1932 * "allow_dirs" is set.
1933 */
1934 if (fname == NULL || *fname == NUL)
1935 {
1936 if (buf == NULL)
1937 fname = NULL;
1938 else
1939 {
1940#ifdef FEAT_SYN_HL
1941 if (event == EVENT_SYNTAX)
1942 fname = buf->b_p_syn;
1943 else
1944#endif
1945 if (event == EVENT_FILETYPE)
1946 fname = buf->b_p_ft;
1947 else
1948 {
1949 if (buf->b_sfname != NULL)
1950 sfname = vim_strsave(buf->b_sfname);
1951 fname = buf->b_ffname;
1952 }
1953 }
1954 if (fname == NULL)
1955 fname = (char_u *)"";
1956 fname = vim_strsave(fname); // make a copy, so we can change it
1957 }
1958 else
1959 {
1960 sfname = vim_strsave(fname);
1961 // Don't try expanding FileType, Syntax, FuncUndefined, WindowID,
1962 // ColorScheme, QuickFixCmd* or DirChanged
1963 if (event == EVENT_FILETYPE
1964 || event == EVENT_SYNTAX
1965 || event == EVENT_CMDLINECHANGED
1966 || event == EVENT_CMDLINEENTER
1967 || event == EVENT_CMDLINELEAVE
1968 || event == EVENT_CMDWINENTER
1969 || event == EVENT_CMDWINLEAVE
1970 || event == EVENT_CMDUNDEFINED
1971 || event == EVENT_FUNCUNDEFINED
1972 || event == EVENT_REMOTEREPLY
1973 || event == EVENT_SPELLFILEMISSING
1974 || event == EVENT_QUICKFIXCMDPRE
1975 || event == EVENT_COLORSCHEME
1976 || event == EVENT_COLORSCHEMEPRE
1977 || event == EVENT_OPTIONSET
1978 || event == EVENT_QUICKFIXCMDPOST
1979 || event == EVENT_DIRCHANGED)
1980 {
1981 fname = vim_strsave(fname);
1982 autocmd_fname_full = TRUE; // don't expand it later
1983 }
1984 else
1985 fname = FullName_save(fname, FALSE);
1986 }
1987 if (fname == NULL) // out of memory
1988 {
1989 vim_free(sfname);
1990 retval = FALSE;
1991 goto BYPASS_AU;
1992 }
1993
1994#ifdef BACKSLASH_IN_FILENAME
1995 /*
1996 * Replace all backslashes with forward slashes. This makes the
1997 * autocommand patterns portable between Unix and MS-DOS.
1998 */
1999 if (sfname != NULL)
2000 forward_slash(sfname);
2001 forward_slash(fname);
2002#endif
2003
2004#ifdef VMS
2005 // remove version for correct match
2006 if (sfname != NULL)
2007 vms_remove_version(sfname);
2008 vms_remove_version(fname);
2009#endif
2010
2011 /*
2012 * Set the name to be used for <amatch>.
2013 */
2014 autocmd_match = fname;
2015
2016
2017 // Don't redraw while doing autocommands.
2018 ++RedrawingDisabled;
2019 save_sourcing_name = sourcing_name;
2020 sourcing_name = NULL; // don't free this one
2021 save_sourcing_lnum = sourcing_lnum;
2022 sourcing_lnum = 0; // no line number here
2023
2024#ifdef FEAT_EVAL
2025 save_current_sctx = current_sctx;
2026
2027# ifdef FEAT_PROFILE
2028 if (do_profiling == PROF_YES)
2029 prof_child_enter(&wait_time); // doesn't count for the caller itself
2030# endif
2031
2032 // Don't use local function variables, if called from a function.
2033 save_funccal(&funccal_entry);
2034#endif
2035
2036 /*
2037 * When starting to execute autocommands, save the search patterns.
2038 */
2039 if (!autocmd_busy)
2040 {
2041 save_search_patterns();
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002042 if (!ins_compl_active())
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002043 {
2044 saveRedobuff(&save_redo);
2045 did_save_redobuff = TRUE;
2046 }
2047 did_filetype = keep_filetype;
2048 }
2049
2050 /*
2051 * Note that we are applying autocmds. Some commands need to know.
2052 */
2053 autocmd_busy = TRUE;
2054 filechangeshell_busy = (event == EVENT_FILECHANGEDSHELL);
2055 ++nesting; // see matching decrement below
2056
2057 // Remember that FileType was triggered. Used for did_filetype().
2058 if (event == EVENT_FILETYPE)
2059 did_filetype = TRUE;
2060
2061 tail = gettail(fname);
2062
2063 // Find first autocommand that matches
2064 patcmd.curpat = first_autopat[(int)event];
2065 patcmd.nextcmd = NULL;
2066 patcmd.group = group;
2067 patcmd.fname = fname;
2068 patcmd.sfname = sfname;
2069 patcmd.tail = tail;
2070 patcmd.event = event;
2071 patcmd.arg_bufnr = autocmd_bufnr;
2072 patcmd.next = NULL;
2073 auto_next_pat(&patcmd, FALSE);
2074
2075 // found one, start executing the autocommands
2076 if (patcmd.curpat != NULL)
2077 {
2078 // add to active_apc_list
2079 patcmd.next = active_apc_list;
2080 active_apc_list = &patcmd;
2081
2082#ifdef FEAT_EVAL
2083 // set v:cmdarg (only when there is a matching pattern)
2084 save_cmdbang = (long)get_vim_var_nr(VV_CMDBANG);
2085 if (eap != NULL)
2086 {
2087 save_cmdarg = set_cmdarg(eap, NULL);
2088 set_vim_var_nr(VV_CMDBANG, (long)eap->forceit);
2089 }
2090 else
2091 save_cmdarg = NULL; // avoid gcc warning
2092#endif
2093 retval = TRUE;
2094 // mark the last pattern, to avoid an endless loop when more patterns
2095 // are added when executing autocommands
2096 for (ap = patcmd.curpat; ap->next != NULL; ap = ap->next)
2097 ap->last = FALSE;
2098 ap->last = TRUE;
Bram Moolenaara68e5952019-04-25 22:22:01 +02002099
2100 // make sure cursor and topline are valid
2101 check_lnums(TRUE);
2102
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002103 do_cmdline(NULL, getnextac, (void *)&patcmd,
2104 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
Bram Moolenaara68e5952019-04-25 22:22:01 +02002105
2106 // restore cursor and topline, unless they were changed
2107 reset_lnums();
2108
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002109#ifdef FEAT_EVAL
2110 if (eap != NULL)
2111 {
2112 (void)set_cmdarg(NULL, save_cmdarg);
2113 set_vim_var_nr(VV_CMDBANG, save_cmdbang);
2114 }
2115#endif
2116 // delete from active_apc_list
2117 if (active_apc_list == &patcmd) // just in case
2118 active_apc_list = patcmd.next;
2119 }
2120
2121 --RedrawingDisabled;
2122 autocmd_busy = save_autocmd_busy;
2123 filechangeshell_busy = FALSE;
2124 autocmd_nested = save_autocmd_nested;
2125 vim_free(sourcing_name);
2126 sourcing_name = save_sourcing_name;
2127 sourcing_lnum = save_sourcing_lnum;
2128 vim_free(autocmd_fname);
2129 autocmd_fname = save_autocmd_fname;
2130 autocmd_fname_full = save_autocmd_fname_full;
2131 autocmd_bufnr = save_autocmd_bufnr;
2132 autocmd_match = save_autocmd_match;
2133#ifdef FEAT_EVAL
2134 current_sctx = save_current_sctx;
2135 restore_funccal();
2136# ifdef FEAT_PROFILE
2137 if (do_profiling == PROF_YES)
2138 prof_child_exit(&wait_time);
2139# endif
2140#endif
2141 KeyTyped = save_KeyTyped;
2142 vim_free(fname);
2143 vim_free(sfname);
2144 --nesting; // see matching increment above
2145
2146 /*
2147 * When stopping to execute autocommands, restore the search patterns and
2148 * the redo buffer. Free any buffers in the au_pending_free_buf list and
2149 * free any windows in the au_pending_free_win list.
2150 */
2151 if (!autocmd_busy)
2152 {
2153 restore_search_patterns();
2154 if (did_save_redobuff)
2155 restoreRedobuff(&save_redo);
2156 did_filetype = FALSE;
2157 while (au_pending_free_buf != NULL)
2158 {
2159 buf_T *b = au_pending_free_buf->b_next;
2160 vim_free(au_pending_free_buf);
2161 au_pending_free_buf = b;
2162 }
2163 while (au_pending_free_win != NULL)
2164 {
2165 win_T *w = au_pending_free_win->w_next;
2166 vim_free(au_pending_free_win);
2167 au_pending_free_win = w;
2168 }
2169 }
2170
2171 /*
2172 * Some events don't set or reset the Changed flag.
2173 * Check if still in the same buffer!
2174 */
2175 if (curbuf == old_curbuf
2176 && (event == EVENT_BUFREADPOST
2177 || event == EVENT_BUFWRITEPOST
2178 || event == EVENT_FILEAPPENDPOST
2179 || event == EVENT_VIMLEAVE
2180 || event == EVENT_VIMLEAVEPRE))
2181 {
2182#ifdef FEAT_TITLE
2183 if (curbuf->b_changed != save_changed)
2184 need_maketitle = TRUE;
2185#endif
2186 curbuf->b_changed = save_changed;
2187 }
2188
2189 au_cleanup(); // may really delete removed patterns/commands now
2190
2191BYPASS_AU:
2192 // When wiping out a buffer make sure all its buffer-local autocommands
2193 // are deleted.
2194 if (event == EVENT_BUFWIPEOUT && buf != NULL)
2195 aubuflocal_remove(buf);
2196
2197 if (retval == OK && event == EVENT_FILETYPE)
2198 au_did_filetype = TRUE;
2199
2200 return retval;
2201}
2202
2203# ifdef FEAT_EVAL
2204static char_u *old_termresponse = NULL;
2205# endif
2206
2207/*
2208 * Block triggering autocommands until unblock_autocmd() is called.
2209 * Can be used recursively, so long as it's symmetric.
2210 */
2211 void
2212block_autocmds(void)
2213{
2214# ifdef FEAT_EVAL
2215 // Remember the value of v:termresponse.
2216 if (autocmd_blocked == 0)
2217 old_termresponse = get_vim_var_str(VV_TERMRESPONSE);
2218# endif
2219 ++autocmd_blocked;
2220}
2221
2222 void
2223unblock_autocmds(void)
2224{
2225 --autocmd_blocked;
2226
2227# ifdef FEAT_EVAL
2228 // When v:termresponse was set while autocommands were blocked, trigger
2229 // the autocommands now. Esp. useful when executing a shell command
2230 // during startup (vimdiff).
2231 if (autocmd_blocked == 0
2232 && get_vim_var_str(VV_TERMRESPONSE) != old_termresponse)
2233 apply_autocmds(EVENT_TERMRESPONSE, NULL, NULL, FALSE, curbuf);
2234# endif
2235}
2236
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002237 int
2238is_autocmd_blocked(void)
2239{
2240 return autocmd_blocked != 0;
2241}
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002242
2243/*
2244 * Find next autocommand pattern that matches.
2245 */
2246 static void
2247auto_next_pat(
2248 AutoPatCmd *apc,
2249 int stop_at_last) // stop when 'last' flag is set
2250{
2251 AutoPat *ap;
2252 AutoCmd *cp;
2253 char_u *name;
2254 char *s;
2255
2256 VIM_CLEAR(sourcing_name);
2257
2258 for (ap = apc->curpat; ap != NULL && !got_int; ap = ap->next)
2259 {
2260 apc->curpat = NULL;
2261
2262 // Only use a pattern when it has not been removed, has commands and
2263 // the group matches. For buffer-local autocommands only check the
2264 // buffer number.
2265 if (ap->pat != NULL && ap->cmds != NULL
2266 && (apc->group == AUGROUP_ALL || apc->group == ap->group))
2267 {
2268 // execution-condition
2269 if (ap->buflocal_nr == 0
2270 ? (match_file_pat(NULL, &ap->reg_prog, apc->fname,
2271 apc->sfname, apc->tail, ap->allow_dirs))
2272 : ap->buflocal_nr == apc->arg_bufnr)
2273 {
2274 name = event_nr2name(apc->event);
2275 s = _("%s Autocommands for \"%s\"");
Bram Moolenaar964b3742019-05-24 18:54:09 +02002276 sourcing_name = alloc(STRLEN(s)
2277 + STRLEN(name) + ap->patlen + 1);
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002278 if (sourcing_name != NULL)
2279 {
2280 sprintf((char *)sourcing_name, s,
2281 (char *)name, (char *)ap->pat);
2282 if (p_verbose >= 8)
2283 {
2284 verbose_enter();
2285 smsg(_("Executing %s"), sourcing_name);
2286 verbose_leave();
2287 }
2288 }
2289
2290 apc->curpat = ap;
2291 apc->nextcmd = ap->cmds;
2292 // mark last command
2293 for (cp = ap->cmds; cp->next != NULL; cp = cp->next)
2294 cp->last = FALSE;
2295 cp->last = TRUE;
2296 }
2297 line_breakcheck();
2298 if (apc->curpat != NULL) // found a match
2299 break;
2300 }
2301 if (stop_at_last && ap->last)
2302 break;
2303 }
2304}
2305
2306/*
2307 * Get next autocommand command.
2308 * Called by do_cmdline() to get the next line for ":if".
2309 * Returns allocated string, or NULL for end of autocommands.
2310 */
2311 char_u *
Bram Moolenaare96a2492019-06-25 04:12:16 +02002312getnextac(int c UNUSED, void *cookie, int indent UNUSED, int do_concat UNUSED)
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002313{
2314 AutoPatCmd *acp = (AutoPatCmd *)cookie;
2315 char_u *retval;
2316 AutoCmd *ac;
2317
2318 // Can be called again after returning the last line.
2319 if (acp->curpat == NULL)
2320 return NULL;
2321
2322 // repeat until we find an autocommand to execute
2323 for (;;)
2324 {
2325 // skip removed commands
2326 while (acp->nextcmd != NULL && acp->nextcmd->cmd == NULL)
2327 if (acp->nextcmd->last)
2328 acp->nextcmd = NULL;
2329 else
2330 acp->nextcmd = acp->nextcmd->next;
2331
2332 if (acp->nextcmd != NULL)
2333 break;
2334
2335 // at end of commands, find next pattern that matches
2336 if (acp->curpat->last)
2337 acp->curpat = NULL;
2338 else
2339 acp->curpat = acp->curpat->next;
2340 if (acp->curpat != NULL)
2341 auto_next_pat(acp, TRUE);
2342 if (acp->curpat == NULL)
2343 return NULL;
2344 }
2345
2346 ac = acp->nextcmd;
2347
2348 if (p_verbose >= 9)
2349 {
2350 verbose_enter_scroll();
2351 smsg(_("autocommand %s"), ac->cmd);
2352 msg_puts("\n"); // don't overwrite this either
2353 verbose_leave_scroll();
2354 }
2355 retval = vim_strsave(ac->cmd);
Bram Moolenaareb93f3f2019-04-04 15:04:56 +02002356 // Remove one-shot ("once") autocmd in anticipation of its execution.
2357 if (ac->once)
2358 au_del_cmd(ac);
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002359 autocmd_nested = ac->nested;
2360#ifdef FEAT_EVAL
2361 current_sctx = ac->script_ctx;
2362#endif
2363 if (ac->last)
2364 acp->nextcmd = NULL;
2365 else
2366 acp->nextcmd = ac->next;
2367 return retval;
2368}
2369
2370/*
2371 * Return TRUE if there is a matching autocommand for "fname".
2372 * To account for buffer-local autocommands, function needs to know
2373 * in which buffer the file will be opened.
2374 */
2375 int
2376has_autocmd(event_T event, char_u *sfname, buf_T *buf)
2377{
2378 AutoPat *ap;
2379 char_u *fname;
2380 char_u *tail = gettail(sfname);
2381 int retval = FALSE;
2382
2383 fname = FullName_save(sfname, FALSE);
2384 if (fname == NULL)
2385 return FALSE;
2386
2387#ifdef BACKSLASH_IN_FILENAME
2388 /*
2389 * Replace all backslashes with forward slashes. This makes the
2390 * autocommand patterns portable between Unix and MS-DOS.
2391 */
2392 sfname = vim_strsave(sfname);
2393 if (sfname != NULL)
2394 forward_slash(sfname);
2395 forward_slash(fname);
2396#endif
2397
2398 for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next)
2399 if (ap->pat != NULL && ap->cmds != NULL
2400 && (ap->buflocal_nr == 0
2401 ? match_file_pat(NULL, &ap->reg_prog,
2402 fname, sfname, tail, ap->allow_dirs)
2403 : buf != NULL && ap->buflocal_nr == buf->b_fnum
2404 ))
2405 {
2406 retval = TRUE;
2407 break;
2408 }
2409
2410 vim_free(fname);
2411#ifdef BACKSLASH_IN_FILENAME
2412 vim_free(sfname);
2413#endif
2414
2415 return retval;
2416}
2417
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002418/*
2419 * Function given to ExpandGeneric() to obtain the list of autocommand group
2420 * names.
2421 */
2422 char_u *
2423get_augroup_name(expand_T *xp UNUSED, int idx)
2424{
2425 if (idx == augroups.ga_len) // add "END" add the end
2426 return (char_u *)"END";
2427 if (idx >= augroups.ga_len) // end of list
2428 return NULL;
2429 if (AUGROUP_NAME(idx) == NULL || AUGROUP_NAME(idx) == get_deleted_augroup())
2430 // skip deleted entries
2431 return (char_u *)"";
2432 return AUGROUP_NAME(idx); // return a name
2433}
2434
2435static int include_groups = FALSE;
2436
2437 char_u *
2438set_context_in_autocmd(
2439 expand_T *xp,
2440 char_u *arg,
2441 int doautocmd) // TRUE for :doauto*, FALSE for :autocmd
2442{
2443 char_u *p;
2444 int group;
2445
2446 // check for a group name, skip it if present
2447 include_groups = FALSE;
2448 p = arg;
2449 group = au_get_grouparg(&arg);
2450 if (group == AUGROUP_ERROR)
2451 return NULL;
2452 // If there only is a group name that's what we expand.
2453 if (*arg == NUL && group != AUGROUP_ALL && !VIM_ISWHITE(arg[-1]))
2454 {
2455 arg = p;
2456 group = AUGROUP_ALL;
2457 }
2458
2459 // skip over event name
2460 for (p = arg; *p != NUL && !VIM_ISWHITE(*p); ++p)
2461 if (*p == ',')
2462 arg = p + 1;
2463 if (*p == NUL)
2464 {
2465 if (group == AUGROUP_ALL)
2466 include_groups = TRUE;
2467 xp->xp_context = EXPAND_EVENTS; // expand event name
2468 xp->xp_pattern = arg;
2469 return NULL;
2470 }
2471
2472 // skip over pattern
2473 arg = skipwhite(p);
2474 while (*arg && (!VIM_ISWHITE(*arg) || arg[-1] == '\\'))
2475 arg++;
2476 if (*arg)
2477 return arg; // expand (next) command
2478
2479 if (doautocmd)
2480 xp->xp_context = EXPAND_FILES; // expand file names
2481 else
2482 xp->xp_context = EXPAND_NOTHING; // pattern is not expanded
2483 return NULL;
2484}
2485
2486/*
2487 * Function given to ExpandGeneric() to obtain the list of event names.
2488 */
2489 char_u *
2490get_event_name(expand_T *xp UNUSED, int idx)
2491{
2492 if (idx < augroups.ga_len) // First list group names, if wanted
2493 {
2494 if (!include_groups || AUGROUP_NAME(idx) == NULL
2495 || AUGROUP_NAME(idx) == get_deleted_augroup())
2496 return (char_u *)""; // skip deleted entries
2497 return AUGROUP_NAME(idx); // return a name
2498 }
2499 return (char_u *)event_names[idx - augroups.ga_len].name;
2500}
2501
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002502
2503#if defined(FEAT_EVAL) || defined(PROTO)
2504/*
2505 * Return TRUE if autocmd is supported.
2506 */
2507 int
2508autocmd_supported(char_u *name)
2509{
2510 char_u *p;
2511
2512 return (event_name2nr(name, &p) != NUM_EVENTS);
2513}
2514
2515/*
2516 * Return TRUE if an autocommand is defined for a group, event and
2517 * pattern: The group can be omitted to accept any group. "event" and "pattern"
2518 * can be NULL to accept any event and pattern. "pattern" can be NULL to accept
2519 * any pattern. Buffer-local patterns <buffer> or <buffer=N> are accepted.
2520 * Used for:
2521 * exists("#Group") or
2522 * exists("#Group#Event") or
2523 * exists("#Group#Event#pat") or
2524 * exists("#Event") or
2525 * exists("#Event#pat")
2526 */
2527 int
2528au_exists(char_u *arg)
2529{
2530 char_u *arg_save;
2531 char_u *pattern = NULL;
2532 char_u *event_name;
2533 char_u *p;
2534 event_T event;
2535 AutoPat *ap;
2536 buf_T *buflocal_buf = NULL;
2537 int group;
2538 int retval = FALSE;
2539
2540 // Make a copy so that we can change the '#' chars to a NUL.
2541 arg_save = vim_strsave(arg);
2542 if (arg_save == NULL)
2543 return FALSE;
2544 p = vim_strchr(arg_save, '#');
2545 if (p != NULL)
2546 *p++ = NUL;
2547
2548 // First, look for an autocmd group name
2549 group = au_find_group(arg_save);
2550 if (group == AUGROUP_ERROR)
2551 {
2552 // Didn't match a group name, assume the first argument is an event.
2553 group = AUGROUP_ALL;
2554 event_name = arg_save;
2555 }
2556 else
2557 {
2558 if (p == NULL)
2559 {
2560 // "Group": group name is present and it's recognized
2561 retval = TRUE;
2562 goto theend;
2563 }
2564
2565 // Must be "Group#Event" or "Group#Event#pat".
2566 event_name = p;
2567 p = vim_strchr(event_name, '#');
2568 if (p != NULL)
2569 *p++ = NUL; // "Group#Event#pat"
2570 }
2571
2572 pattern = p; // "pattern" is NULL when there is no pattern
2573
2574 // find the index (enum) for the event name
2575 event = event_name2nr(event_name, &p);
2576
2577 // return FALSE if the event name is not recognized
2578 if (event == NUM_EVENTS)
2579 goto theend;
2580
2581 // Find the first autocommand for this event.
2582 // If there isn't any, return FALSE;
2583 // If there is one and no pattern given, return TRUE;
2584 ap = first_autopat[(int)event];
2585 if (ap == NULL)
2586 goto theend;
2587
2588 // if pattern is "<buffer>", special handling is needed which uses curbuf
2589 // for pattern "<buffer=N>, fnamecmp() will work fine
2590 if (pattern != NULL && STRICMP(pattern, "<buffer>") == 0)
2591 buflocal_buf = curbuf;
2592
2593 // Check if there is an autocommand with the given pattern.
2594 for ( ; ap != NULL; ap = ap->next)
2595 // only use a pattern when it has not been removed and has commands.
2596 // For buffer-local autocommands, fnamecmp() works fine.
2597 if (ap->pat != NULL && ap->cmds != NULL
2598 && (group == AUGROUP_ALL || ap->group == group)
2599 && (pattern == NULL
2600 || (buflocal_buf == NULL
2601 ? fnamecmp(ap->pat, pattern) == 0
2602 : ap->buflocal_nr == buflocal_buf->b_fnum)))
2603 {
2604 retval = TRUE;
2605 break;
2606 }
2607
2608theend:
2609 vim_free(arg_save);
2610 return retval;
2611}
2612#endif