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