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