blob: 8e0754b6904b2bdbd93975ac33cc97aa1a082be0 [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},
Bram Moolenaar3f169ce2020-01-26 22:43:31 +0100117 {"CompleteDonePre", EVENT_COMPLETEDONEPRE},
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100118 {"CursorHold", EVENT_CURSORHOLD},
119 {"CursorHoldI", EVENT_CURSORHOLDI},
120 {"CursorMoved", EVENT_CURSORMOVED},
121 {"CursorMovedI", EVENT_CURSORMOVEDI},
122 {"DiffUpdated", EVENT_DIFFUPDATED},
123 {"DirChanged", EVENT_DIRCHANGED},
124 {"EncodingChanged", EVENT_ENCODINGCHANGED},
125 {"ExitPre", EVENT_EXITPRE},
126 {"FileEncoding", EVENT_ENCODINGCHANGED},
127 {"FileAppendPost", EVENT_FILEAPPENDPOST},
128 {"FileAppendPre", EVENT_FILEAPPENDPRE},
129 {"FileAppendCmd", EVENT_FILEAPPENDCMD},
130 {"FileChangedShell",EVENT_FILECHANGEDSHELL},
131 {"FileChangedShellPost",EVENT_FILECHANGEDSHELLPOST},
132 {"FileChangedRO", EVENT_FILECHANGEDRO},
133 {"FileReadPost", EVENT_FILEREADPOST},
134 {"FileReadPre", EVENT_FILEREADPRE},
135 {"FileReadCmd", EVENT_FILEREADCMD},
136 {"FileType", EVENT_FILETYPE},
137 {"FileWritePost", EVENT_FILEWRITEPOST},
138 {"FileWritePre", EVENT_FILEWRITEPRE},
139 {"FileWriteCmd", EVENT_FILEWRITECMD},
140 {"FilterReadPost", EVENT_FILTERREADPOST},
141 {"FilterReadPre", EVENT_FILTERREADPRE},
142 {"FilterWritePost", EVENT_FILTERWRITEPOST},
143 {"FilterWritePre", EVENT_FILTERWRITEPRE},
144 {"FocusGained", EVENT_FOCUSGAINED},
145 {"FocusLost", EVENT_FOCUSLOST},
146 {"FuncUndefined", EVENT_FUNCUNDEFINED},
147 {"GUIEnter", EVENT_GUIENTER},
148 {"GUIFailed", EVENT_GUIFAILED},
149 {"InsertChange", EVENT_INSERTCHANGE},
150 {"InsertEnter", EVENT_INSERTENTER},
151 {"InsertLeave", EVENT_INSERTLEAVE},
152 {"InsertCharPre", EVENT_INSERTCHARPRE},
153 {"MenuPopup", EVENT_MENUPOPUP},
154 {"OptionSet", EVENT_OPTIONSET},
155 {"QuickFixCmdPost", EVENT_QUICKFIXCMDPOST},
156 {"QuickFixCmdPre", EVENT_QUICKFIXCMDPRE},
157 {"QuitPre", EVENT_QUITPRE},
158 {"RemoteReply", EVENT_REMOTEREPLY},
Bram Moolenaar8aeec402019-09-15 23:02:04 +0200159 {"SafeState", EVENT_SAFESTATE},
Bram Moolenaar69198cb2019-09-16 21:58:13 +0200160 {"SafeStateAgain", EVENT_SAFESTATEAGAIN},
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100161 {"SessionLoadPost", EVENT_SESSIONLOADPOST},
162 {"ShellCmdPost", EVENT_SHELLCMDPOST},
163 {"ShellFilterPost", EVENT_SHELLFILTERPOST},
Bram Moolenaarbe5ee862020-06-10 20:56:58 +0200164 {"SigUSR1", EVENT_SIGUSR1},
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100165 {"SourceCmd", EVENT_SOURCECMD},
166 {"SourcePre", EVENT_SOURCEPRE},
167 {"SourcePost", EVENT_SOURCEPOST},
168 {"SpellFileMissing",EVENT_SPELLFILEMISSING},
169 {"StdinReadPost", EVENT_STDINREADPOST},
170 {"StdinReadPre", EVENT_STDINREADPRE},
171 {"SwapExists", EVENT_SWAPEXISTS},
172 {"Syntax", EVENT_SYNTAX},
173 {"TabNew", EVENT_TABNEW},
174 {"TabClosed", EVENT_TABCLOSED},
175 {"TabEnter", EVENT_TABENTER},
176 {"TabLeave", EVENT_TABLEAVE},
177 {"TermChanged", EVENT_TERMCHANGED},
178 {"TerminalOpen", EVENT_TERMINALOPEN},
Bram Moolenaar28ed4df2019-10-26 16:21:40 +0200179 {"TerminalWinOpen", EVENT_TERMINALWINOPEN},
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100180 {"TermResponse", EVENT_TERMRESPONSE},
181 {"TextChanged", EVENT_TEXTCHANGED},
182 {"TextChangedI", EVENT_TEXTCHANGEDI},
183 {"TextChangedP", EVENT_TEXTCHANGEDP},
184 {"User", EVENT_USER},
185 {"VimEnter", EVENT_VIMENTER},
186 {"VimLeave", EVENT_VIMLEAVE},
187 {"VimLeavePre", EVENT_VIMLEAVEPRE},
188 {"WinNew", EVENT_WINNEW},
189 {"WinEnter", EVENT_WINENTER},
190 {"WinLeave", EVENT_WINLEAVE},
191 {"VimResized", EVENT_VIMRESIZED},
192 {"TextYankPost", EVENT_TEXTYANKPOST},
193 {NULL, (event_T)0}
194};
195
196static AutoPat *first_autopat[NUM_EVENTS] =
197{
198 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
199 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
200 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
201 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
202 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
203 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
204};
205
206static AutoPat *last_autopat[NUM_EVENTS] =
207{
208 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
209 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
210 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
211 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
212 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
213 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
214};
215
216#define AUGROUP_DEFAULT -1 // default autocmd group
217#define AUGROUP_ERROR -2 // erroneous autocmd group
218#define AUGROUP_ALL -3 // all autocmd groups
219
220/*
221 * struct used to keep status while executing autocommands for an event.
222 */
Bram Moolenaar1a47ae32019-12-29 23:04:25 +0100223struct AutoPatCmd_S
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100224{
225 AutoPat *curpat; // next AutoPat to examine
226 AutoCmd *nextcmd; // next AutoCmd to execute
227 int group; // group being used
228 char_u *fname; // fname to match with
229 char_u *sfname; // sfname to match with
230 char_u *tail; // tail of fname
231 event_T event; // current event
232 int arg_bufnr; // Initially equal to <abuf>, set to zero when
233 // buf is deleted.
Bram Moolenaar1a47ae32019-12-29 23:04:25 +0100234 AutoPatCmd *next; // chain of active apc-s for auto-invalidation
235};
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100236
Bram Moolenaarc667da52019-11-30 20:52:27 +0100237static AutoPatCmd *active_apc_list = NULL; // stack of active autocommands
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100238
Bram Moolenaaraeea7212020-04-02 18:50:46 +0200239// Macro to loop over all the patterns for an autocmd event
240#define FOR_ALL_AUTOCMD_PATTERNS(event, ap) \
241 for ((ap) = first_autopat[(int)(event)]; (ap) != NULL; (ap) = (ap)->next)
242
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100243/*
244 * augroups stores a list of autocmd group names.
245 */
246static garray_T augroups = {0, 0, sizeof(char_u *), 10, NULL};
247#define AUGROUP_NAME(i) (((char_u **)augroups.ga_data)[i])
Bram Moolenaarc667da52019-11-30 20:52:27 +0100248// use get_deleted_augroup() to get this
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100249static char_u *deleted_augroup = NULL;
250
251/*
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100252 * The ID of the current group. Group 0 is the default one.
253 */
254static int current_augroup = AUGROUP_DEFAULT;
255
Bram Moolenaarc667da52019-11-30 20:52:27 +0100256static int au_need_clean = FALSE; // need to delete marked patterns
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100257
258static char_u *event_nr2name(event_T event);
259static int au_get_grouparg(char_u **argp);
Bram Moolenaareb93f3f2019-04-04 15:04:56 +0200260static 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 +0100261static int apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io, int force, int group, buf_T *buf, exarg_T *eap);
262static void auto_next_pat(AutoPatCmd *apc, int stop_at_last);
263static int au_find_group(char_u *name);
264
265static event_T last_event;
266static int last_group;
Bram Moolenaarc667da52019-11-30 20:52:27 +0100267static int autocmd_blocked = 0; // block all autocmds
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100268
269 static char_u *
270get_deleted_augroup(void)
271{
272 if (deleted_augroup == NULL)
273 deleted_augroup = (char_u *)_("--Deleted--");
274 return deleted_augroup;
275}
276
277/*
278 * Show the autocommands for one AutoPat.
279 */
280 static void
281show_autocmd(AutoPat *ap, event_T event)
282{
283 AutoCmd *ac;
284
285 // Check for "got_int" (here and at various places below), which is set
286 // when "q" has been hit for the "--more--" prompt
287 if (got_int)
288 return;
289 if (ap->pat == NULL) // pattern has been removed
290 return;
291
292 msg_putchar('\n');
293 if (got_int)
294 return;
295 if (event != last_event || ap->group != last_group)
296 {
297 if (ap->group != AUGROUP_DEFAULT)
298 {
299 if (AUGROUP_NAME(ap->group) == NULL)
300 msg_puts_attr((char *)get_deleted_augroup(), HL_ATTR(HLF_E));
301 else
302 msg_puts_attr((char *)AUGROUP_NAME(ap->group), HL_ATTR(HLF_T));
303 msg_puts(" ");
304 }
305 msg_puts_attr((char *)event_nr2name(event), HL_ATTR(HLF_T));
306 last_event = event;
307 last_group = ap->group;
308 msg_putchar('\n');
309 if (got_int)
310 return;
311 }
312 msg_col = 4;
313 msg_outtrans(ap->pat);
314
315 for (ac = ap->cmds; ac != NULL; ac = ac->next)
316 {
317 if (ac->cmd != NULL) // skip removed commands
318 {
319 if (msg_col >= 14)
320 msg_putchar('\n');
321 msg_col = 14;
322 if (got_int)
323 return;
324 msg_outtrans(ac->cmd);
325#ifdef FEAT_EVAL
326 if (p_verbose > 0)
327 last_set_msg(ac->script_ctx);
328#endif
329 if (got_int)
330 return;
331 if (ac->next != NULL)
332 {
333 msg_putchar('\n');
334 if (got_int)
335 return;
336 }
337 }
338 }
339}
340
341/*
342 * Mark an autocommand pattern for deletion.
343 */
344 static void
345au_remove_pat(AutoPat *ap)
346{
347 VIM_CLEAR(ap->pat);
348 ap->buflocal_nr = -1;
349 au_need_clean = TRUE;
350}
351
352/*
353 * Mark all commands for a pattern for deletion.
354 */
355 static void
356au_remove_cmds(AutoPat *ap)
357{
358 AutoCmd *ac;
359
360 for (ac = ap->cmds; ac != NULL; ac = ac->next)
361 VIM_CLEAR(ac->cmd);
362 au_need_clean = TRUE;
363}
364
Bram Moolenaareb93f3f2019-04-04 15:04:56 +0200365// Delete one command from an autocmd pattern.
366static void au_del_cmd(AutoCmd *ac)
367{
368 VIM_CLEAR(ac->cmd);
369 au_need_clean = TRUE;
370}
371
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100372/*
373 * Cleanup autocommands and patterns that have been deleted.
374 * This is only done when not executing autocommands.
375 */
376 static void
377au_cleanup(void)
378{
379 AutoPat *ap, **prev_ap;
380 AutoCmd *ac, **prev_ac;
381 event_T event;
382
383 if (autocmd_busy || !au_need_clean)
384 return;
385
386 // loop over all events
387 for (event = (event_T)0; (int)event < (int)NUM_EVENTS;
388 event = (event_T)((int)event + 1))
389 {
390 // loop over all autocommand patterns
391 prev_ap = &(first_autopat[(int)event]);
392 for (ap = *prev_ap; ap != NULL; ap = *prev_ap)
393 {
Bram Moolenaareb93f3f2019-04-04 15:04:56 +0200394 int has_cmd = FALSE;
395
Bram Moolenaar8f4aeb52019-04-04 15:40:56 +0200396 // loop over all commands for this pattern
397 prev_ac = &(ap->cmds);
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100398 for (ac = *prev_ac; ac != NULL; ac = *prev_ac)
399 {
400 // remove the command if the pattern is to be deleted or when
401 // the command has been marked for deletion
402 if (ap->pat == NULL || ac->cmd == NULL)
403 {
404 *prev_ac = ac->next;
405 vim_free(ac->cmd);
406 vim_free(ac);
407 }
Bram Moolenaar8f4aeb52019-04-04 15:40:56 +0200408 else
409 {
Bram Moolenaareb93f3f2019-04-04 15:04:56 +0200410 has_cmd = TRUE;
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100411 prev_ac = &(ac->next);
Bram Moolenaareb93f3f2019-04-04 15:04:56 +0200412 }
413 }
414
Bram Moolenaar8f4aeb52019-04-04 15:40:56 +0200415 if (ap->pat != NULL && !has_cmd)
Bram Moolenaareb93f3f2019-04-04 15:04:56 +0200416 // Pattern was not marked for deletion, but all of its
417 // commands were. So mark the pattern for deletion.
418 au_remove_pat(ap);
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100419
420 // remove the pattern if it has been marked for deletion
421 if (ap->pat == NULL)
422 {
423 if (ap->next == NULL)
424 {
425 if (prev_ap == &(first_autopat[(int)event]))
426 last_autopat[(int)event] = NULL;
427 else
428 // this depends on the "next" field being the first in
429 // the struct
430 last_autopat[(int)event] = (AutoPat *)prev_ap;
431 }
432 *prev_ap = ap->next;
433 vim_regfree(ap->reg_prog);
434 vim_free(ap);
435 }
436 else
437 prev_ap = &(ap->next);
438 }
439 }
440
441 au_need_clean = FALSE;
442}
443
444/*
445 * Called when buffer is freed, to remove/invalidate related buffer-local
446 * autocmds.
447 */
448 void
449aubuflocal_remove(buf_T *buf)
450{
451 AutoPat *ap;
452 event_T event;
453 AutoPatCmd *apc;
454
455 // invalidate currently executing autocommands
456 for (apc = active_apc_list; apc; apc = apc->next)
457 if (buf->b_fnum == apc->arg_bufnr)
458 apc->arg_bufnr = 0;
459
460 // invalidate buflocals looping through events
461 for (event = (event_T)0; (int)event < (int)NUM_EVENTS;
462 event = (event_T)((int)event + 1))
463 // loop over all autocommand patterns
Bram Moolenaaraeea7212020-04-02 18:50:46 +0200464 FOR_ALL_AUTOCMD_PATTERNS(event, ap)
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100465 if (ap->buflocal_nr == buf->b_fnum)
466 {
467 au_remove_pat(ap);
468 if (p_verbose >= 6)
469 {
470 verbose_enter();
471 smsg(_("auto-removing autocommand: %s <buffer=%d>"),
472 event_nr2name(event), buf->b_fnum);
473 verbose_leave();
474 }
475 }
476 au_cleanup();
477}
478
479/*
480 * Add an autocmd group name.
481 * Return its ID. Returns AUGROUP_ERROR (< 0) for error.
482 */
483 static int
484au_new_group(char_u *name)
485{
486 int i;
487
488 i = au_find_group(name);
489 if (i == AUGROUP_ERROR) // the group doesn't exist yet, add it
490 {
491 // First try using a free entry.
492 for (i = 0; i < augroups.ga_len; ++i)
493 if (AUGROUP_NAME(i) == NULL)
494 break;
495 if (i == augroups.ga_len && ga_grow(&augroups, 1) == FAIL)
496 return AUGROUP_ERROR;
497
498 AUGROUP_NAME(i) = vim_strsave(name);
499 if (AUGROUP_NAME(i) == NULL)
500 return AUGROUP_ERROR;
501 if (i == augroups.ga_len)
502 ++augroups.ga_len;
503 }
504
505 return i;
506}
507
508 static void
509au_del_group(char_u *name)
510{
511 int i;
512
513 i = au_find_group(name);
514 if (i == AUGROUP_ERROR) // the group doesn't exist
515 semsg(_("E367: No such group: \"%s\""), name);
516 else if (i == current_augroup)
517 emsg(_("E936: Cannot delete the current group"));
518 else
519 {
520 event_T event;
521 AutoPat *ap;
522 int in_use = FALSE;
523
524 for (event = (event_T)0; (int)event < (int)NUM_EVENTS;
525 event = (event_T)((int)event + 1))
526 {
Bram Moolenaaraeea7212020-04-02 18:50:46 +0200527 FOR_ALL_AUTOCMD_PATTERNS(event, ap)
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100528 if (ap->group == i && ap->pat != NULL)
529 {
530 give_warning((char_u *)_("W19: Deleting augroup that is still in use"), TRUE);
531 in_use = TRUE;
532 event = NUM_EVENTS;
533 break;
534 }
535 }
536 vim_free(AUGROUP_NAME(i));
537 if (in_use)
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100538 AUGROUP_NAME(i) = get_deleted_augroup();
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100539 else
540 AUGROUP_NAME(i) = NULL;
541 }
542}
543
544/*
545 * Find the ID of an autocmd group name.
546 * Return its ID. Returns AUGROUP_ERROR (< 0) for error.
547 */
548 static int
549au_find_group(char_u *name)
550{
551 int i;
552
553 for (i = 0; i < augroups.ga_len; ++i)
554 if (AUGROUP_NAME(i) != NULL && AUGROUP_NAME(i) != get_deleted_augroup()
555 && STRCMP(AUGROUP_NAME(i), name) == 0)
556 return i;
557 return AUGROUP_ERROR;
558}
559
560/*
561 * Return TRUE if augroup "name" exists.
562 */
563 int
564au_has_group(char_u *name)
565{
566 return au_find_group(name) != AUGROUP_ERROR;
567}
568
569/*
570 * ":augroup {name}".
571 */
572 void
573do_augroup(char_u *arg, int del_group)
574{
575 int i;
576
577 if (del_group)
578 {
579 if (*arg == NUL)
580 emsg(_(e_argreq));
581 else
582 au_del_group(arg);
583 }
584 else if (STRICMP(arg, "end") == 0) // ":aug end": back to group 0
585 current_augroup = AUGROUP_DEFAULT;
586 else if (*arg) // ":aug xxx": switch to group xxx
587 {
588 i = au_new_group(arg);
589 if (i != AUGROUP_ERROR)
590 current_augroup = i;
591 }
592 else // ":aug": list the group names
593 {
594 msg_start();
595 for (i = 0; i < augroups.ga_len; ++i)
596 {
597 if (AUGROUP_NAME(i) != NULL)
598 {
599 msg_puts((char *)AUGROUP_NAME(i));
600 msg_puts(" ");
601 }
602 }
603 msg_clr_eos();
604 msg_end();
605 }
606}
607
608#if defined(EXITFREE) || defined(PROTO)
609 void
610free_all_autocmds(void)
611{
612 int i;
613 char_u *s;
614
615 for (current_augroup = -1; current_augroup < augroups.ga_len;
616 ++current_augroup)
617 do_autocmd((char_u *)"", TRUE);
618
619 for (i = 0; i < augroups.ga_len; ++i)
620 {
621 s = ((char_u **)(augroups.ga_data))[i];
622 if (s != get_deleted_augroup())
623 vim_free(s);
624 }
625 ga_clear(&augroups);
626}
627#endif
628
629/*
630 * Return the event number for event name "start".
631 * Return NUM_EVENTS if the event name was not found.
632 * Return a pointer to the next event name in "end".
633 */
634 static event_T
635event_name2nr(char_u *start, char_u **end)
636{
637 char_u *p;
638 int i;
639 int len;
640
641 // the event name ends with end of line, '|', a blank or a comma
642 for (p = start; *p && !VIM_ISWHITE(*p) && *p != ',' && *p != '|'; ++p)
643 ;
644 for (i = 0; event_names[i].name != NULL; ++i)
645 {
646 len = (int)STRLEN(event_names[i].name);
647 if (len == p - start && STRNICMP(event_names[i].name, start, len) == 0)
648 break;
649 }
650 if (*p == ',')
651 ++p;
652 *end = p;
653 if (event_names[i].name == NULL)
654 return NUM_EVENTS;
655 return event_names[i].event;
656}
657
658/*
659 * Return the name for event "event".
660 */
661 static char_u *
662event_nr2name(event_T event)
663{
664 int i;
665
666 for (i = 0; event_names[i].name != NULL; ++i)
667 if (event_names[i].event == event)
668 return (char_u *)event_names[i].name;
669 return (char_u *)"Unknown";
670}
671
672/*
673 * Scan over the events. "*" stands for all events.
674 */
675 static char_u *
676find_end_event(
677 char_u *arg,
678 int have_group) // TRUE when group name was found
679{
680 char_u *pat;
681 char_u *p;
682
683 if (*arg == '*')
684 {
685 if (arg[1] && !VIM_ISWHITE(arg[1]))
686 {
687 semsg(_("E215: Illegal character after *: %s"), arg);
688 return NULL;
689 }
690 pat = arg + 1;
691 }
692 else
693 {
694 for (pat = arg; *pat && *pat != '|' && !VIM_ISWHITE(*pat); pat = p)
695 {
696 if ((int)event_name2nr(pat, &p) >= (int)NUM_EVENTS)
697 {
698 if (have_group)
699 semsg(_("E216: No such event: %s"), pat);
700 else
701 semsg(_("E216: No such group or event: %s"), pat);
702 return NULL;
703 }
704 }
705 }
706 return pat;
707}
708
709/*
710 * Return TRUE if "event" is included in 'eventignore'.
711 */
712 static int
713event_ignored(event_T event)
714{
715 char_u *p = p_ei;
716
717 while (*p != NUL)
718 {
719 if (STRNICMP(p, "all", 3) == 0 && (p[3] == NUL || p[3] == ','))
720 return TRUE;
721 if (event_name2nr(p, &p) == event)
722 return TRUE;
723 }
724
725 return FALSE;
726}
727
728/*
729 * Return OK when the contents of p_ei is valid, FAIL otherwise.
730 */
731 int
732check_ei(void)
733{
734 char_u *p = p_ei;
735
736 while (*p)
737 {
738 if (STRNICMP(p, "all", 3) == 0 && (p[3] == NUL || p[3] == ','))
739 {
740 p += 3;
741 if (*p == ',')
742 ++p;
743 }
744 else if (event_name2nr(p, &p) == NUM_EVENTS)
745 return FAIL;
746 }
747
748 return OK;
749}
750
751# if defined(FEAT_SYN_HL) || defined(PROTO)
752
753/*
754 * Add "what" to 'eventignore' to skip loading syntax highlighting for every
755 * buffer loaded into the window. "what" must start with a comma.
756 * Returns the old value of 'eventignore' in allocated memory.
757 */
758 char_u *
759au_event_disable(char *what)
760{
761 char_u *new_ei;
762 char_u *save_ei;
763
764 save_ei = vim_strsave(p_ei);
765 if (save_ei != NULL)
766 {
Bram Moolenaardf44a272020-06-07 20:49:05 +0200767 new_ei = vim_strnsave(p_ei, STRLEN(p_ei) + STRLEN(what));
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100768 if (new_ei != NULL)
769 {
770 if (*what == ',' && *p_ei == NUL)
771 STRCPY(new_ei, what + 1);
772 else
773 STRCAT(new_ei, what);
774 set_string_option_direct((char_u *)"ei", -1, new_ei,
775 OPT_FREE, SID_NONE);
776 vim_free(new_ei);
777 }
778 }
779 return save_ei;
780}
781
782 void
783au_event_restore(char_u *old_ei)
784{
785 if (old_ei != NULL)
786 {
787 set_string_option_direct((char_u *)"ei", -1, old_ei,
788 OPT_FREE, SID_NONE);
789 vim_free(old_ei);
790 }
791}
Bram Moolenaarc667da52019-11-30 20:52:27 +0100792# endif // FEAT_SYN_HL
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100793
794/*
795 * do_autocmd() -- implements the :autocmd command. Can be used in the
796 * following ways:
797 *
798 * :autocmd <event> <pat> <cmd> Add <cmd> to the list of commands that
799 * will be automatically executed for <event>
800 * when editing a file matching <pat>, in
801 * the current group.
802 * :autocmd <event> <pat> Show the autocommands associated with
803 * <event> and <pat>.
804 * :autocmd <event> Show the autocommands associated with
805 * <event>.
806 * :autocmd Show all autocommands.
807 * :autocmd! <event> <pat> <cmd> Remove all autocommands associated with
808 * <event> and <pat>, and add the command
809 * <cmd>, for the current group.
810 * :autocmd! <event> <pat> Remove all autocommands associated with
811 * <event> and <pat> for the current group.
812 * :autocmd! <event> Remove all autocommands associated with
813 * <event> for the current group.
814 * :autocmd! Remove ALL autocommands for the current
815 * group.
816 *
817 * Multiple events and patterns may be given separated by commas. Here are
818 * some examples:
819 * :autocmd bufread,bufenter *.c,*.h set tw=0 smartindent noic
820 * :autocmd bufleave * set tw=79 nosmartindent ic infercase
821 *
822 * :autocmd * *.c show all autocommands for *.c files.
823 *
824 * Mostly a {group} argument can optionally appear before <event>.
825 */
826 void
827do_autocmd(char_u *arg_in, int forceit)
828{
829 char_u *arg = arg_in;
830 char_u *pat;
831 char_u *envpat = NULL;
832 char_u *cmd;
833 event_T event;
834 int need_free = FALSE;
835 int nested = FALSE;
Bram Moolenaareb93f3f2019-04-04 15:04:56 +0200836 int once = FALSE;
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100837 int group;
Bram Moolenaareb93f3f2019-04-04 15:04:56 +0200838 int i;
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100839
840 if (*arg == '|')
841 {
842 arg = (char_u *)"";
843 group = AUGROUP_ALL; // no argument, use all groups
844 }
845 else
846 {
847 /*
848 * Check for a legal group name. If not, use AUGROUP_ALL.
849 */
850 group = au_get_grouparg(&arg);
851 if (arg == NULL) // out of memory
852 return;
853 }
854
855 /*
856 * Scan over the events.
857 * If we find an illegal name, return here, don't do anything.
858 */
859 pat = find_end_event(arg, group != AUGROUP_ALL);
860 if (pat == NULL)
861 return;
862
863 pat = skipwhite(pat);
864 if (*pat == '|')
865 {
866 pat = (char_u *)"";
867 cmd = (char_u *)"";
868 }
869 else
870 {
871 /*
872 * Scan over the pattern. Put a NUL at the end.
873 */
874 cmd = pat;
875 while (*cmd && (!VIM_ISWHITE(*cmd) || cmd[-1] == '\\'))
876 cmd++;
877 if (*cmd)
878 *cmd++ = NUL;
879
880 // Expand environment variables in the pattern. Set 'shellslash', we
881 // want forward slashes here.
882 if (vim_strchr(pat, '$') != NULL || vim_strchr(pat, '~') != NULL)
883 {
884#ifdef BACKSLASH_IN_FILENAME
885 int p_ssl_save = p_ssl;
886
887 p_ssl = TRUE;
888#endif
889 envpat = expand_env_save(pat);
890#ifdef BACKSLASH_IN_FILENAME
891 p_ssl = p_ssl_save;
892#endif
893 if (envpat != NULL)
894 pat = envpat;
895 }
896
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100897 cmd = skipwhite(cmd);
Bram Moolenaareb93f3f2019-04-04 15:04:56 +0200898 for (i = 0; i < 2; i++)
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100899 {
Bram Moolenaareb93f3f2019-04-04 15:04:56 +0200900 if (*cmd != NUL)
901 {
902 // Check for "++once" flag.
903 if (STRNCMP(cmd, "++once", 6) == 0 && VIM_ISWHITE(cmd[6]))
904 {
905 if (once)
906 semsg(_(e_duparg2), "++once");
907 once = TRUE;
908 cmd = skipwhite(cmd + 6);
909 }
910
911 // Check for "++nested" flag.
912 if ((STRNCMP(cmd, "++nested", 8) == 0 && VIM_ISWHITE(cmd[8])))
913 {
914 if (nested)
915 semsg(_(e_duparg2), "++nested");
916 nested = TRUE;
917 cmd = skipwhite(cmd + 8);
918 }
919
920 // Check for the old "nested" flag.
921 if (STRNCMP(cmd, "nested", 6) == 0 && VIM_ISWHITE(cmd[6]))
922 {
923 if (nested)
924 semsg(_(e_duparg2), "nested");
925 nested = TRUE;
926 cmd = skipwhite(cmd + 6);
927 }
928 }
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100929 }
930
931 /*
932 * Find the start of the commands.
933 * Expand <sfile> in it.
934 */
935 if (*cmd != NUL)
936 {
937 cmd = expand_sfile(cmd);
938 if (cmd == NULL) // some error
939 return;
940 need_free = TRUE;
941 }
942 }
943
944 /*
945 * Print header when showing autocommands.
946 */
947 if (!forceit && *cmd == NUL)
948 // Highlight title
949 msg_puts_title(_("\n--- Autocommands ---"));
950
951 /*
952 * Loop over the events.
953 */
954 last_event = (event_T)-1; // for listing the event name
955 last_group = AUGROUP_ERROR; // for listing the group name
956 if (*arg == '*' || *arg == NUL || *arg == '|')
957 {
958 for (event = (event_T)0; (int)event < (int)NUM_EVENTS;
959 event = (event_T)((int)event + 1))
960 if (do_autocmd_event(event, pat,
Bram Moolenaareb93f3f2019-04-04 15:04:56 +0200961 once, nested, cmd, forceit, group) == FAIL)
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100962 break;
963 }
964 else
965 {
966 while (*arg && *arg != '|' && !VIM_ISWHITE(*arg))
967 if (do_autocmd_event(event_name2nr(arg, &arg), pat,
Bram Moolenaareb93f3f2019-04-04 15:04:56 +0200968 once, nested, cmd, forceit, group) == FAIL)
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100969 break;
970 }
971
972 if (need_free)
973 vim_free(cmd);
974 vim_free(envpat);
975}
976
977/*
978 * Find the group ID in a ":autocmd" or ":doautocmd" argument.
979 * The "argp" argument is advanced to the following argument.
980 *
981 * Returns the group ID, AUGROUP_ERROR for error (out of memory).
982 */
983 static int
984au_get_grouparg(char_u **argp)
985{
986 char_u *group_name;
987 char_u *p;
988 char_u *arg = *argp;
989 int group = AUGROUP_ALL;
990
991 for (p = arg; *p && !VIM_ISWHITE(*p) && *p != '|'; ++p)
992 ;
993 if (p > arg)
994 {
Bram Moolenaardf44a272020-06-07 20:49:05 +0200995 group_name = vim_strnsave(arg, p - arg);
Bram Moolenaar3e460fd2019-01-26 16:21:07 +0100996 if (group_name == NULL) // out of memory
997 return AUGROUP_ERROR;
998 group = au_find_group(group_name);
999 if (group == AUGROUP_ERROR)
1000 group = AUGROUP_ALL; // no match, use all groups
1001 else
1002 *argp = skipwhite(p); // match, skip over group name
1003 vim_free(group_name);
1004 }
1005 return group;
1006}
1007
1008/*
1009 * do_autocmd() for one event.
1010 * If *pat == NUL do for all patterns.
1011 * If *cmd == NUL show entries.
1012 * If forceit == TRUE delete entries.
1013 * If group is not AUGROUP_ALL, only use this group.
1014 */
1015 static int
1016do_autocmd_event(
1017 event_T event,
1018 char_u *pat,
Bram Moolenaareb93f3f2019-04-04 15:04:56 +02001019 int once,
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001020 int nested,
1021 char_u *cmd,
1022 int forceit,
1023 int group)
1024{
1025 AutoPat *ap;
1026 AutoPat **prev_ap;
1027 AutoCmd *ac;
1028 AutoCmd **prev_ac;
1029 int brace_level;
1030 char_u *endpat;
1031 int findgroup;
1032 int allgroups;
1033 int patlen;
1034 int is_buflocal;
1035 int buflocal_nr;
Bram Moolenaarc667da52019-11-30 20:52:27 +01001036 char_u buflocal_pat[25]; // for "<buffer=X>"
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001037
1038 if (group == AUGROUP_ALL)
1039 findgroup = current_augroup;
1040 else
1041 findgroup = group;
1042 allgroups = (group == AUGROUP_ALL && !forceit && *cmd == NUL);
1043
1044 /*
1045 * Show or delete all patterns for an event.
1046 */
1047 if (*pat == NUL)
1048 {
Bram Moolenaaraeea7212020-04-02 18:50:46 +02001049 FOR_ALL_AUTOCMD_PATTERNS(event, ap)
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001050 {
1051 if (forceit) // delete the AutoPat, if it's in the current group
1052 {
1053 if (ap->group == findgroup)
1054 au_remove_pat(ap);
1055 }
1056 else if (group == AUGROUP_ALL || ap->group == group)
1057 show_autocmd(ap, event);
1058 }
1059 }
1060
1061 /*
1062 * Loop through all the specified patterns.
1063 */
1064 for ( ; *pat; pat = (*endpat == ',' ? endpat + 1 : endpat))
1065 {
1066 /*
1067 * Find end of the pattern.
1068 * Watch out for a comma in braces, like "*.\{obj,o\}".
1069 */
1070 brace_level = 0;
1071 for (endpat = pat; *endpat && (*endpat != ',' || brace_level
1072 || (endpat > pat && endpat[-1] == '\\')); ++endpat)
1073 {
1074 if (*endpat == '{')
1075 brace_level++;
1076 else if (*endpat == '}')
1077 brace_level--;
1078 }
1079 if (pat == endpat) // ignore single comma
1080 continue;
1081 patlen = (int)(endpat - pat);
1082
1083 /*
1084 * detect special <buflocal[=X]> buffer-local patterns
1085 */
1086 is_buflocal = FALSE;
1087 buflocal_nr = 0;
1088
1089 if (patlen >= 8 && STRNCMP(pat, "<buffer", 7) == 0
1090 && pat[patlen - 1] == '>')
1091 {
1092 // "<buffer...>": Error will be printed only for addition.
1093 // printing and removing will proceed silently.
1094 is_buflocal = TRUE;
1095 if (patlen == 8)
1096 // "<buffer>"
1097 buflocal_nr = curbuf->b_fnum;
1098 else if (patlen > 9 && pat[7] == '=')
1099 {
1100 if (patlen == 13 && STRNICMP(pat, "<buffer=abuf>", 13) == 0)
1101 // "<buffer=abuf>"
1102 buflocal_nr = autocmd_bufnr;
1103 else if (skipdigits(pat + 8) == pat + patlen - 1)
1104 // "<buffer=123>"
1105 buflocal_nr = atoi((char *)pat + 8);
1106 }
1107 }
1108
1109 if (is_buflocal)
1110 {
1111 // normalize pat into standard "<buffer>#N" form
1112 sprintf((char *)buflocal_pat, "<buffer=%d>", buflocal_nr);
1113 pat = buflocal_pat; // can modify pat and patlen
1114 patlen = (int)STRLEN(buflocal_pat); // but not endpat
1115 }
1116
1117 /*
1118 * Find AutoPat entries with this pattern. When adding a command it
1119 * always goes at or after the last one, so start at the end.
1120 */
1121 if (!forceit && *cmd != NUL && last_autopat[(int)event] != NULL)
1122 prev_ap = &last_autopat[(int)event];
1123 else
1124 prev_ap = &first_autopat[(int)event];
1125 while ((ap = *prev_ap) != NULL)
1126 {
1127 if (ap->pat != NULL)
1128 {
Bram Moolenaarc667da52019-11-30 20:52:27 +01001129 /*
1130 * Accept a pattern when:
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001131 * - 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 {
Bram Moolenaarc667da52019-11-30 20:52:27 +01001187 // refuse to add buffer-local ap if buffer number is invalid
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001188 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;
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01001251 ac->script_ctx.sc_lnum += SOURCING_LNUM;
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001252#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;
Bram Moolenaar32aa1022019-11-02 22:54:41 +01001594 // In case the autocommand moves the cursor to a position that
1595 // does not exist in curbuf.
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001596 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 */
Bram Moolenaar5843f5f2019-08-20 20:13:45 +02001672 static int
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001673has_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
Bram Moolenaare2c453d2019-08-21 14:37:09 +02001691 && !ins_compl_active())
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001692 {
1693 state = get_real_state();
1694 if (state == NORMAL_BUSY || (state & INSERT) != 0)
1695 return TRUE;
1696 }
1697 return FALSE;
1698}
1699
1700/*
1701 * Return TRUE when there is a CursorMoved autocommand defined.
1702 */
1703 int
1704has_cursormoved(void)
1705{
1706 return (first_autopat[(int)EVENT_CURSORMOVED] != NULL);
1707}
1708
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001709/*
1710 * Return TRUE when there is a CursorMovedI autocommand defined.
1711 */
1712 int
1713has_cursormovedI(void)
1714{
1715 return (first_autopat[(int)EVENT_CURSORMOVEDI] != NULL);
1716}
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001717
1718/*
1719 * Return TRUE when there is a TextChanged autocommand defined.
1720 */
1721 int
1722has_textchanged(void)
1723{
1724 return (first_autopat[(int)EVENT_TEXTCHANGED] != NULL);
1725}
1726
1727/*
1728 * Return TRUE when there is a TextChangedI autocommand defined.
1729 */
1730 int
1731has_textchangedI(void)
1732{
1733 return (first_autopat[(int)EVENT_TEXTCHANGEDI] != NULL);
1734}
1735
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001736/*
1737 * Return TRUE when there is a TextChangedP autocommand defined.
1738 */
1739 int
1740has_textchangedP(void)
1741{
1742 return (first_autopat[(int)EVENT_TEXTCHANGEDP] != NULL);
1743}
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001744
1745/*
1746 * Return TRUE when there is an InsertCharPre autocommand defined.
1747 */
1748 int
1749has_insertcharpre(void)
1750{
1751 return (first_autopat[(int)EVENT_INSERTCHARPRE] != NULL);
1752}
1753
1754/*
1755 * Return TRUE when there is an CmdUndefined autocommand defined.
1756 */
1757 int
1758has_cmdundefined(void)
1759{
1760 return (first_autopat[(int)EVENT_CMDUNDEFINED] != NULL);
1761}
1762
1763/*
1764 * Return TRUE when there is an FuncUndefined autocommand defined.
1765 */
1766 int
1767has_funcundefined(void)
1768{
1769 return (first_autopat[(int)EVENT_FUNCUNDEFINED] != NULL);
1770}
1771
1772#if defined(FEAT_EVAL) || defined(PROTO)
1773/*
1774 * Return TRUE when there is a TextYankPost autocommand defined.
1775 */
1776 int
1777has_textyankpost(void)
1778{
1779 return (first_autopat[(int)EVENT_TEXTYANKPOST] != NULL);
1780}
1781#endif
1782
Bram Moolenaard7f246c2019-04-08 18:15:41 +02001783#if defined(FEAT_EVAL) || defined(PROTO)
1784/*
1785 * Return TRUE when there is a CompleteChanged autocommand defined.
1786 */
1787 int
1788has_completechanged(void)
1789{
1790 return (first_autopat[(int)EVENT_COMPLETECHANGED] != NULL);
1791}
1792#endif
1793
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001794/*
1795 * Execute autocommands for "event" and file name "fname".
1796 * Return TRUE if some commands were executed.
1797 */
1798 static int
1799apply_autocmds_group(
1800 event_T event,
1801 char_u *fname, // NULL or empty means use actual file name
1802 char_u *fname_io, // fname to use for <afile> on cmdline, NULL means
1803 // use fname
1804 int force, // when TRUE, ignore autocmd_busy
1805 int group, // group ID, or AUGROUP_ALL
1806 buf_T *buf, // buffer for <abuf>
1807 exarg_T *eap UNUSED) // command arguments
1808{
1809 char_u *sfname = NULL; // short file name
1810 char_u *tail;
1811 int save_changed;
1812 buf_T *old_curbuf;
1813 int retval = FALSE;
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001814 char_u *save_autocmd_fname;
1815 int save_autocmd_fname_full;
1816 int save_autocmd_bufnr;
1817 char_u *save_autocmd_match;
1818 int save_autocmd_busy;
1819 int save_autocmd_nested;
1820 static int nesting = 0;
1821 AutoPatCmd patcmd;
1822 AutoPat *ap;
1823#ifdef FEAT_EVAL
1824 sctx_T save_current_sctx;
1825 funccal_entry_T funccal_entry;
1826 char_u *save_cmdarg;
1827 long save_cmdbang;
1828#endif
1829 static int filechangeshell_busy = FALSE;
1830#ifdef FEAT_PROFILE
1831 proftime_T wait_time;
1832#endif
1833 int did_save_redobuff = FALSE;
1834 save_redo_T save_redo;
1835 int save_KeyTyped = KeyTyped;
Bram Moolenaare31ee862020-01-07 20:59:34 +01001836 ESTACK_CHECK_DECLARATION
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01001837
1838 /*
1839 * Quickly return if there are no autocommands for this event or
1840 * autocommands are blocked.
1841 */
1842 if (event == NUM_EVENTS || first_autopat[(int)event] == NULL
1843 || autocmd_blocked > 0)
1844 goto BYPASS_AU;
1845
1846 /*
1847 * When autocommands are busy, new autocommands are only executed when
1848 * explicitly enabled with the "nested" flag.
1849 */
1850 if (autocmd_busy && !(force || autocmd_nested))
1851 goto BYPASS_AU;
1852
1853#ifdef FEAT_EVAL
1854 /*
1855 * Quickly return when immediately aborting on error, or when an interrupt
1856 * occurred or an exception was thrown but not caught.
1857 */
1858 if (aborting())
1859 goto BYPASS_AU;
1860#endif
1861
1862 /*
1863 * FileChangedShell never nests, because it can create an endless loop.
1864 */
1865 if (filechangeshell_busy && (event == EVENT_FILECHANGEDSHELL
1866 || event == EVENT_FILECHANGEDSHELLPOST))
1867 goto BYPASS_AU;
1868
1869 /*
1870 * Ignore events in 'eventignore'.
1871 */
1872 if (event_ignored(event))
1873 goto BYPASS_AU;
1874
1875 /*
1876 * Allow nesting of autocommands, but restrict the depth, because it's
1877 * possible to create an endless loop.
1878 */
1879 if (nesting == 10)
1880 {
1881 emsg(_("E218: autocommand nesting too deep"));
1882 goto BYPASS_AU;
1883 }
1884
1885 /*
1886 * Check if these autocommands are disabled. Used when doing ":all" or
1887 * ":ball".
1888 */
1889 if ( (autocmd_no_enter
1890 && (event == EVENT_WINENTER || event == EVENT_BUFENTER))
1891 || (autocmd_no_leave
1892 && (event == EVENT_WINLEAVE || event == EVENT_BUFLEAVE)))
1893 goto BYPASS_AU;
1894
1895 /*
1896 * Save the autocmd_* variables and info about the current buffer.
1897 */
1898 save_autocmd_fname = autocmd_fname;
1899 save_autocmd_fname_full = autocmd_fname_full;
1900 save_autocmd_bufnr = autocmd_bufnr;
1901 save_autocmd_match = autocmd_match;
1902 save_autocmd_busy = autocmd_busy;
1903 save_autocmd_nested = autocmd_nested;
1904 save_changed = curbuf->b_changed;
1905 old_curbuf = curbuf;
1906
1907 /*
1908 * Set the file name to be used for <afile>.
1909 * Make a copy to avoid that changing a buffer name or directory makes it
1910 * invalid.
1911 */
1912 if (fname_io == NULL)
1913 {
1914 if (event == EVENT_COLORSCHEME || event == EVENT_COLORSCHEMEPRE
1915 || event == EVENT_OPTIONSET)
1916 autocmd_fname = NULL;
1917 else if (fname != NULL && !ends_excmd(*fname))
1918 autocmd_fname = fname;
1919 else if (buf != NULL)
1920 autocmd_fname = buf->b_ffname;
1921 else
1922 autocmd_fname = NULL;
1923 }
1924 else
1925 autocmd_fname = fname_io;
1926 if (autocmd_fname != NULL)
1927 autocmd_fname = vim_strsave(autocmd_fname);
1928 autocmd_fname_full = FALSE; // call FullName_save() later
1929
1930 /*
1931 * Set the buffer number to be used for <abuf>.
1932 */
1933 if (buf == NULL)
1934 autocmd_bufnr = 0;
1935 else
1936 autocmd_bufnr = buf->b_fnum;
1937
1938 /*
1939 * When the file name is NULL or empty, use the file name of buffer "buf".
1940 * Always use the full path of the file name to match with, in case
1941 * "allow_dirs" is set.
1942 */
1943 if (fname == NULL || *fname == NUL)
1944 {
1945 if (buf == NULL)
1946 fname = NULL;
1947 else
1948 {
1949#ifdef FEAT_SYN_HL
1950 if (event == EVENT_SYNTAX)
1951 fname = buf->b_p_syn;
1952 else
1953#endif
1954 if (event == EVENT_FILETYPE)
1955 fname = buf->b_p_ft;
1956 else
1957 {
1958 if (buf->b_sfname != NULL)
1959 sfname = vim_strsave(buf->b_sfname);
1960 fname = buf->b_ffname;
1961 }
1962 }
1963 if (fname == NULL)
1964 fname = (char_u *)"";
1965 fname = vim_strsave(fname); // make a copy, so we can change it
1966 }
1967 else
1968 {
1969 sfname = vim_strsave(fname);
1970 // Don't try expanding FileType, Syntax, FuncUndefined, WindowID,
1971 // ColorScheme, QuickFixCmd* or DirChanged
1972 if (event == EVENT_FILETYPE
1973 || event == EVENT_SYNTAX
1974 || event == EVENT_CMDLINECHANGED
1975 || event == EVENT_CMDLINEENTER
1976 || event == EVENT_CMDLINELEAVE
1977 || event == EVENT_CMDWINENTER
1978 || event == EVENT_CMDWINLEAVE
1979 || event == EVENT_CMDUNDEFINED
1980 || event == EVENT_FUNCUNDEFINED
1981 || event == EVENT_REMOTEREPLY
1982 || event == EVENT_SPELLFILEMISSING
1983 || event == EVENT_QUICKFIXCMDPRE
1984 || event == EVENT_COLORSCHEME
1985 || event == EVENT_COLORSCHEMEPRE
1986 || event == EVENT_OPTIONSET
1987 || event == EVENT_QUICKFIXCMDPOST
1988 || event == EVENT_DIRCHANGED)
1989 {
1990 fname = vim_strsave(fname);
1991 autocmd_fname_full = TRUE; // don't expand it later
1992 }
1993 else
1994 fname = FullName_save(fname, FALSE);
1995 }
1996 if (fname == NULL) // out of memory
1997 {
1998 vim_free(sfname);
1999 retval = FALSE;
2000 goto BYPASS_AU;
2001 }
2002
2003#ifdef BACKSLASH_IN_FILENAME
2004 /*
2005 * Replace all backslashes with forward slashes. This makes the
2006 * autocommand patterns portable between Unix and MS-DOS.
2007 */
2008 if (sfname != NULL)
2009 forward_slash(sfname);
2010 forward_slash(fname);
2011#endif
2012
2013#ifdef VMS
2014 // remove version for correct match
2015 if (sfname != NULL)
2016 vms_remove_version(sfname);
2017 vms_remove_version(fname);
2018#endif
2019
2020 /*
2021 * Set the name to be used for <amatch>.
2022 */
2023 autocmd_match = fname;
2024
2025
2026 // Don't redraw while doing autocommands.
2027 ++RedrawingDisabled;
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01002028
2029 // name and lnum are filled in later
2030 estack_push(ETYPE_AUCMD, NULL, 0);
Bram Moolenaare31ee862020-01-07 20:59:34 +01002031 ESTACK_CHECK_SETUP
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002032
2033#ifdef FEAT_EVAL
2034 save_current_sctx = current_sctx;
2035
2036# ifdef FEAT_PROFILE
2037 if (do_profiling == PROF_YES)
2038 prof_child_enter(&wait_time); // doesn't count for the caller itself
2039# endif
2040
2041 // Don't use local function variables, if called from a function.
2042 save_funccal(&funccal_entry);
2043#endif
2044
2045 /*
2046 * When starting to execute autocommands, save the search patterns.
2047 */
2048 if (!autocmd_busy)
2049 {
2050 save_search_patterns();
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002051 if (!ins_compl_active())
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002052 {
2053 saveRedobuff(&save_redo);
2054 did_save_redobuff = TRUE;
2055 }
2056 did_filetype = keep_filetype;
2057 }
2058
2059 /*
2060 * Note that we are applying autocmds. Some commands need to know.
2061 */
2062 autocmd_busy = TRUE;
2063 filechangeshell_busy = (event == EVENT_FILECHANGEDSHELL);
2064 ++nesting; // see matching decrement below
2065
2066 // Remember that FileType was triggered. Used for did_filetype().
2067 if (event == EVENT_FILETYPE)
2068 did_filetype = TRUE;
2069
2070 tail = gettail(fname);
2071
2072 // Find first autocommand that matches
2073 patcmd.curpat = first_autopat[(int)event];
2074 patcmd.nextcmd = NULL;
2075 patcmd.group = group;
2076 patcmd.fname = fname;
2077 patcmd.sfname = sfname;
2078 patcmd.tail = tail;
2079 patcmd.event = event;
2080 patcmd.arg_bufnr = autocmd_bufnr;
2081 patcmd.next = NULL;
2082 auto_next_pat(&patcmd, FALSE);
2083
2084 // found one, start executing the autocommands
2085 if (patcmd.curpat != NULL)
2086 {
2087 // add to active_apc_list
2088 patcmd.next = active_apc_list;
2089 active_apc_list = &patcmd;
2090
2091#ifdef FEAT_EVAL
2092 // set v:cmdarg (only when there is a matching pattern)
2093 save_cmdbang = (long)get_vim_var_nr(VV_CMDBANG);
2094 if (eap != NULL)
2095 {
2096 save_cmdarg = set_cmdarg(eap, NULL);
2097 set_vim_var_nr(VV_CMDBANG, (long)eap->forceit);
2098 }
2099 else
2100 save_cmdarg = NULL; // avoid gcc warning
2101#endif
2102 retval = TRUE;
2103 // mark the last pattern, to avoid an endless loop when more patterns
2104 // are added when executing autocommands
2105 for (ap = patcmd.curpat; ap->next != NULL; ap = ap->next)
2106 ap->last = FALSE;
2107 ap->last = TRUE;
Bram Moolenaara68e5952019-04-25 22:22:01 +02002108
2109 // make sure cursor and topline are valid
2110 check_lnums(TRUE);
2111
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002112 do_cmdline(NULL, getnextac, (void *)&patcmd,
2113 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
Bram Moolenaara68e5952019-04-25 22:22:01 +02002114
2115 // restore cursor and topline, unless they were changed
2116 reset_lnums();
2117
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002118#ifdef FEAT_EVAL
2119 if (eap != NULL)
2120 {
2121 (void)set_cmdarg(NULL, save_cmdarg);
2122 set_vim_var_nr(VV_CMDBANG, save_cmdbang);
2123 }
2124#endif
2125 // delete from active_apc_list
2126 if (active_apc_list == &patcmd) // just in case
2127 active_apc_list = patcmd.next;
2128 }
2129
2130 --RedrawingDisabled;
2131 autocmd_busy = save_autocmd_busy;
2132 filechangeshell_busy = FALSE;
2133 autocmd_nested = save_autocmd_nested;
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01002134 vim_free(SOURCING_NAME);
Bram Moolenaare31ee862020-01-07 20:59:34 +01002135 ESTACK_CHECK_NOW
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01002136 estack_pop();
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002137 vim_free(autocmd_fname);
2138 autocmd_fname = save_autocmd_fname;
2139 autocmd_fname_full = save_autocmd_fname_full;
2140 autocmd_bufnr = save_autocmd_bufnr;
2141 autocmd_match = save_autocmd_match;
2142#ifdef FEAT_EVAL
2143 current_sctx = save_current_sctx;
2144 restore_funccal();
2145# ifdef FEAT_PROFILE
2146 if (do_profiling == PROF_YES)
2147 prof_child_exit(&wait_time);
2148# endif
2149#endif
2150 KeyTyped = save_KeyTyped;
2151 vim_free(fname);
2152 vim_free(sfname);
2153 --nesting; // see matching increment above
2154
2155 /*
2156 * When stopping to execute autocommands, restore the search patterns and
2157 * the redo buffer. Free any buffers in the au_pending_free_buf list and
2158 * free any windows in the au_pending_free_win list.
2159 */
2160 if (!autocmd_busy)
2161 {
2162 restore_search_patterns();
2163 if (did_save_redobuff)
2164 restoreRedobuff(&save_redo);
2165 did_filetype = FALSE;
2166 while (au_pending_free_buf != NULL)
2167 {
2168 buf_T *b = au_pending_free_buf->b_next;
2169 vim_free(au_pending_free_buf);
2170 au_pending_free_buf = b;
2171 }
2172 while (au_pending_free_win != NULL)
2173 {
2174 win_T *w = au_pending_free_win->w_next;
2175 vim_free(au_pending_free_win);
2176 au_pending_free_win = w;
2177 }
2178 }
2179
2180 /*
2181 * Some events don't set or reset the Changed flag.
2182 * Check if still in the same buffer!
2183 */
2184 if (curbuf == old_curbuf
2185 && (event == EVENT_BUFREADPOST
2186 || event == EVENT_BUFWRITEPOST
2187 || event == EVENT_FILEAPPENDPOST
2188 || event == EVENT_VIMLEAVE
2189 || event == EVENT_VIMLEAVEPRE))
2190 {
2191#ifdef FEAT_TITLE
2192 if (curbuf->b_changed != save_changed)
2193 need_maketitle = TRUE;
2194#endif
2195 curbuf->b_changed = save_changed;
2196 }
2197
2198 au_cleanup(); // may really delete removed patterns/commands now
2199
2200BYPASS_AU:
2201 // When wiping out a buffer make sure all its buffer-local autocommands
2202 // are deleted.
2203 if (event == EVENT_BUFWIPEOUT && buf != NULL)
2204 aubuflocal_remove(buf);
2205
2206 if (retval == OK && event == EVENT_FILETYPE)
2207 au_did_filetype = TRUE;
2208
2209 return retval;
2210}
2211
2212# ifdef FEAT_EVAL
2213static char_u *old_termresponse = NULL;
2214# endif
2215
2216/*
2217 * Block triggering autocommands until unblock_autocmd() is called.
2218 * Can be used recursively, so long as it's symmetric.
2219 */
2220 void
2221block_autocmds(void)
2222{
2223# ifdef FEAT_EVAL
2224 // Remember the value of v:termresponse.
2225 if (autocmd_blocked == 0)
2226 old_termresponse = get_vim_var_str(VV_TERMRESPONSE);
2227# endif
2228 ++autocmd_blocked;
2229}
2230
2231 void
2232unblock_autocmds(void)
2233{
2234 --autocmd_blocked;
2235
2236# ifdef FEAT_EVAL
2237 // When v:termresponse was set while autocommands were blocked, trigger
2238 // the autocommands now. Esp. useful when executing a shell command
2239 // during startup (vimdiff).
2240 if (autocmd_blocked == 0
2241 && get_vim_var_str(VV_TERMRESPONSE) != old_termresponse)
2242 apply_autocmds(EVENT_TERMRESPONSE, NULL, NULL, FALSE, curbuf);
2243# endif
2244}
2245
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002246 int
2247is_autocmd_blocked(void)
2248{
2249 return autocmd_blocked != 0;
2250}
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002251
2252/*
2253 * Find next autocommand pattern that matches.
2254 */
2255 static void
2256auto_next_pat(
2257 AutoPatCmd *apc,
2258 int stop_at_last) // stop when 'last' flag is set
2259{
2260 AutoPat *ap;
2261 AutoCmd *cp;
2262 char_u *name;
2263 char *s;
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01002264 char_u **sourcing_namep = &SOURCING_NAME;
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002265
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01002266 VIM_CLEAR(*sourcing_namep);
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002267
2268 for (ap = apc->curpat; ap != NULL && !got_int; ap = ap->next)
2269 {
2270 apc->curpat = NULL;
2271
2272 // Only use a pattern when it has not been removed, has commands and
2273 // the group matches. For buffer-local autocommands only check the
2274 // buffer number.
2275 if (ap->pat != NULL && ap->cmds != NULL
2276 && (apc->group == AUGROUP_ALL || apc->group == ap->group))
2277 {
2278 // execution-condition
2279 if (ap->buflocal_nr == 0
2280 ? (match_file_pat(NULL, &ap->reg_prog, apc->fname,
2281 apc->sfname, apc->tail, ap->allow_dirs))
2282 : ap->buflocal_nr == apc->arg_bufnr)
2283 {
2284 name = event_nr2name(apc->event);
2285 s = _("%s Autocommands for \"%s\"");
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01002286 *sourcing_namep = alloc(STRLEN(s)
Bram Moolenaar964b3742019-05-24 18:54:09 +02002287 + STRLEN(name) + ap->patlen + 1);
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01002288 if (*sourcing_namep != NULL)
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002289 {
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01002290 sprintf((char *)*sourcing_namep, s,
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002291 (char *)name, (char *)ap->pat);
2292 if (p_verbose >= 8)
2293 {
2294 verbose_enter();
Bram Moolenaar1a47ae32019-12-29 23:04:25 +01002295 smsg(_("Executing %s"), *sourcing_namep);
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002296 verbose_leave();
2297 }
2298 }
2299
2300 apc->curpat = ap;
2301 apc->nextcmd = ap->cmds;
2302 // mark last command
2303 for (cp = ap->cmds; cp->next != NULL; cp = cp->next)
2304 cp->last = FALSE;
2305 cp->last = TRUE;
2306 }
2307 line_breakcheck();
2308 if (apc->curpat != NULL) // found a match
2309 break;
2310 }
2311 if (stop_at_last && ap->last)
2312 break;
2313 }
2314}
2315
2316/*
2317 * Get next autocommand command.
2318 * Called by do_cmdline() to get the next line for ":if".
2319 * Returns allocated string, or NULL for end of autocommands.
2320 */
2321 char_u *
Bram Moolenaare96a2492019-06-25 04:12:16 +02002322getnextac(int c UNUSED, void *cookie, int indent UNUSED, int do_concat UNUSED)
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002323{
2324 AutoPatCmd *acp = (AutoPatCmd *)cookie;
2325 char_u *retval;
2326 AutoCmd *ac;
2327
2328 // Can be called again after returning the last line.
2329 if (acp->curpat == NULL)
2330 return NULL;
2331
2332 // repeat until we find an autocommand to execute
2333 for (;;)
2334 {
2335 // skip removed commands
2336 while (acp->nextcmd != NULL && acp->nextcmd->cmd == NULL)
2337 if (acp->nextcmd->last)
2338 acp->nextcmd = NULL;
2339 else
2340 acp->nextcmd = acp->nextcmd->next;
2341
2342 if (acp->nextcmd != NULL)
2343 break;
2344
2345 // at end of commands, find next pattern that matches
2346 if (acp->curpat->last)
2347 acp->curpat = NULL;
2348 else
2349 acp->curpat = acp->curpat->next;
2350 if (acp->curpat != NULL)
2351 auto_next_pat(acp, TRUE);
2352 if (acp->curpat == NULL)
2353 return NULL;
2354 }
2355
2356 ac = acp->nextcmd;
2357
2358 if (p_verbose >= 9)
2359 {
2360 verbose_enter_scroll();
2361 smsg(_("autocommand %s"), ac->cmd);
2362 msg_puts("\n"); // don't overwrite this either
2363 verbose_leave_scroll();
2364 }
2365 retval = vim_strsave(ac->cmd);
Bram Moolenaareb93f3f2019-04-04 15:04:56 +02002366 // Remove one-shot ("once") autocmd in anticipation of its execution.
2367 if (ac->once)
2368 au_del_cmd(ac);
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002369 autocmd_nested = ac->nested;
2370#ifdef FEAT_EVAL
2371 current_sctx = ac->script_ctx;
2372#endif
2373 if (ac->last)
2374 acp->nextcmd = NULL;
2375 else
2376 acp->nextcmd = ac->next;
2377 return retval;
2378}
2379
2380/*
2381 * Return TRUE if there is a matching autocommand for "fname".
2382 * To account for buffer-local autocommands, function needs to know
2383 * in which buffer the file will be opened.
2384 */
2385 int
2386has_autocmd(event_T event, char_u *sfname, buf_T *buf)
2387{
2388 AutoPat *ap;
2389 char_u *fname;
2390 char_u *tail = gettail(sfname);
2391 int retval = FALSE;
2392
2393 fname = FullName_save(sfname, FALSE);
2394 if (fname == NULL)
2395 return FALSE;
2396
2397#ifdef BACKSLASH_IN_FILENAME
2398 /*
2399 * Replace all backslashes with forward slashes. This makes the
2400 * autocommand patterns portable between Unix and MS-DOS.
2401 */
2402 sfname = vim_strsave(sfname);
2403 if (sfname != NULL)
2404 forward_slash(sfname);
2405 forward_slash(fname);
2406#endif
2407
Bram Moolenaaraeea7212020-04-02 18:50:46 +02002408 FOR_ALL_AUTOCMD_PATTERNS(event, ap)
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002409 if (ap->pat != NULL && ap->cmds != NULL
2410 && (ap->buflocal_nr == 0
2411 ? match_file_pat(NULL, &ap->reg_prog,
2412 fname, sfname, tail, ap->allow_dirs)
2413 : buf != NULL && ap->buflocal_nr == buf->b_fnum
2414 ))
2415 {
2416 retval = TRUE;
2417 break;
2418 }
2419
2420 vim_free(fname);
2421#ifdef BACKSLASH_IN_FILENAME
2422 vim_free(sfname);
2423#endif
2424
2425 return retval;
2426}
2427
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002428/*
2429 * Function given to ExpandGeneric() to obtain the list of autocommand group
2430 * names.
2431 */
2432 char_u *
2433get_augroup_name(expand_T *xp UNUSED, int idx)
2434{
2435 if (idx == augroups.ga_len) // add "END" add the end
2436 return (char_u *)"END";
2437 if (idx >= augroups.ga_len) // end of list
2438 return NULL;
2439 if (AUGROUP_NAME(idx) == NULL || AUGROUP_NAME(idx) == get_deleted_augroup())
2440 // skip deleted entries
2441 return (char_u *)"";
2442 return AUGROUP_NAME(idx); // return a name
2443}
2444
2445static int include_groups = FALSE;
2446
2447 char_u *
2448set_context_in_autocmd(
2449 expand_T *xp,
2450 char_u *arg,
2451 int doautocmd) // TRUE for :doauto*, FALSE for :autocmd
2452{
2453 char_u *p;
2454 int group;
2455
2456 // check for a group name, skip it if present
2457 include_groups = FALSE;
2458 p = arg;
2459 group = au_get_grouparg(&arg);
2460 if (group == AUGROUP_ERROR)
2461 return NULL;
2462 // If there only is a group name that's what we expand.
2463 if (*arg == NUL && group != AUGROUP_ALL && !VIM_ISWHITE(arg[-1]))
2464 {
2465 arg = p;
2466 group = AUGROUP_ALL;
2467 }
2468
2469 // skip over event name
2470 for (p = arg; *p != NUL && !VIM_ISWHITE(*p); ++p)
2471 if (*p == ',')
2472 arg = p + 1;
2473 if (*p == NUL)
2474 {
2475 if (group == AUGROUP_ALL)
2476 include_groups = TRUE;
2477 xp->xp_context = EXPAND_EVENTS; // expand event name
2478 xp->xp_pattern = arg;
2479 return NULL;
2480 }
2481
2482 // skip over pattern
2483 arg = skipwhite(p);
2484 while (*arg && (!VIM_ISWHITE(*arg) || arg[-1] == '\\'))
2485 arg++;
2486 if (*arg)
2487 return arg; // expand (next) command
2488
2489 if (doautocmd)
2490 xp->xp_context = EXPAND_FILES; // expand file names
2491 else
2492 xp->xp_context = EXPAND_NOTHING; // pattern is not expanded
2493 return NULL;
2494}
2495
2496/*
2497 * Function given to ExpandGeneric() to obtain the list of event names.
2498 */
2499 char_u *
2500get_event_name(expand_T *xp UNUSED, int idx)
2501{
2502 if (idx < augroups.ga_len) // First list group names, if wanted
2503 {
2504 if (!include_groups || AUGROUP_NAME(idx) == NULL
2505 || AUGROUP_NAME(idx) == get_deleted_augroup())
2506 return (char_u *)""; // skip deleted entries
2507 return AUGROUP_NAME(idx); // return a name
2508 }
2509 return (char_u *)event_names[idx - augroups.ga_len].name;
2510}
2511
Bram Moolenaar3e460fd2019-01-26 16:21:07 +01002512
2513#if defined(FEAT_EVAL) || defined(PROTO)
2514/*
2515 * Return TRUE if autocmd is supported.
2516 */
2517 int
2518autocmd_supported(char_u *name)
2519{
2520 char_u *p;
2521
2522 return (event_name2nr(name, &p) != NUM_EVENTS);
2523}
2524
2525/*
2526 * Return TRUE if an autocommand is defined for a group, event and
2527 * pattern: The group can be omitted to accept any group. "event" and "pattern"
2528 * can be NULL to accept any event and pattern. "pattern" can be NULL to accept
2529 * any pattern. Buffer-local patterns <buffer> or <buffer=N> are accepted.
2530 * Used for:
2531 * exists("#Group") or
2532 * exists("#Group#Event") or
2533 * exists("#Group#Event#pat") or
2534 * exists("#Event") or
2535 * exists("#Event#pat")
2536 */
2537 int
2538au_exists(char_u *arg)
2539{
2540 char_u *arg_save;
2541 char_u *pattern = NULL;
2542 char_u *event_name;
2543 char_u *p;
2544 event_T event;
2545 AutoPat *ap;
2546 buf_T *buflocal_buf = NULL;
2547 int group;
2548 int retval = FALSE;
2549
2550 // Make a copy so that we can change the '#' chars to a NUL.
2551 arg_save = vim_strsave(arg);
2552 if (arg_save == NULL)
2553 return FALSE;
2554 p = vim_strchr(arg_save, '#');
2555 if (p != NULL)
2556 *p++ = NUL;
2557
2558 // First, look for an autocmd group name
2559 group = au_find_group(arg_save);
2560 if (group == AUGROUP_ERROR)
2561 {
2562 // Didn't match a group name, assume the first argument is an event.
2563 group = AUGROUP_ALL;
2564 event_name = arg_save;
2565 }
2566 else
2567 {
2568 if (p == NULL)
2569 {
2570 // "Group": group name is present and it's recognized
2571 retval = TRUE;
2572 goto theend;
2573 }
2574
2575 // Must be "Group#Event" or "Group#Event#pat".
2576 event_name = p;
2577 p = vim_strchr(event_name, '#');
2578 if (p != NULL)
2579 *p++ = NUL; // "Group#Event#pat"
2580 }
2581
2582 pattern = p; // "pattern" is NULL when there is no pattern
2583
2584 // find the index (enum) for the event name
2585 event = event_name2nr(event_name, &p);
2586
2587 // return FALSE if the event name is not recognized
2588 if (event == NUM_EVENTS)
2589 goto theend;
2590
2591 // Find the first autocommand for this event.
2592 // If there isn't any, return FALSE;
2593 // If there is one and no pattern given, return TRUE;
2594 ap = first_autopat[(int)event];
2595 if (ap == NULL)
2596 goto theend;
2597
2598 // if pattern is "<buffer>", special handling is needed which uses curbuf
2599 // for pattern "<buffer=N>, fnamecmp() will work fine
2600 if (pattern != NULL && STRICMP(pattern, "<buffer>") == 0)
2601 buflocal_buf = curbuf;
2602
2603 // Check if there is an autocommand with the given pattern.
2604 for ( ; ap != NULL; ap = ap->next)
2605 // only use a pattern when it has not been removed and has commands.
2606 // For buffer-local autocommands, fnamecmp() works fine.
2607 if (ap->pat != NULL && ap->cmds != NULL
2608 && (group == AUGROUP_ALL || ap->group == group)
2609 && (pattern == NULL
2610 || (buflocal_buf == NULL
2611 ? fnamecmp(ap->pat, pattern) == 0
2612 : ap->buflocal_nr == buflocal_buf->b_fnum)))
2613 {
2614 retval = TRUE;
2615 break;
2616 }
2617
2618theend:
2619 vim_free(arg_save);
2620 return retval;
2621}
2622#endif