Mercurial > vim
comparison src/fileio.c @ 40:f1d2a58883b9 v7.0024
updated for version 7.0024
author | vimboss |
---|---|
date | Fri, 24 Dec 2004 14:35:23 +0000 |
parents | 410fa1a31baf |
children | f529edb9bab3 |
comparison
equal
deleted
inserted
replaced
39:410fa1a31baf | 40:f1d2a58883b9 |
---|---|
6588 char_u *reg_pat; /* pattern converted to regexp */ | 6588 char_u *reg_pat; /* pattern converted to regexp */ |
6589 char allow_dirs; /* Pattern may match whole path */ | 6589 char allow_dirs; /* Pattern may match whole path */ |
6590 char last; /* last pattern for apply_autocmds() */ | 6590 char last; /* last pattern for apply_autocmds() */ |
6591 AutoCmd *cmds; /* list of commands to do */ | 6591 AutoCmd *cmds; /* list of commands to do */ |
6592 struct AutoPat *next; /* next AutoPat in AutoPat list */ | 6592 struct AutoPat *next; /* next AutoPat in AutoPat list */ |
6593 int buflocal_nr; /* !=0 for buffer-local AutoPat */ | |
6593 } AutoPat; | 6594 } AutoPat; |
6594 | 6595 |
6595 static struct event_name | 6596 static struct event_name |
6596 { | 6597 { |
6597 char *name; /* event name */ | 6598 char *name; /* event name */ |
6684 int group; /* group being used */ | 6685 int group; /* group being used */ |
6685 char_u *fname; /* fname to match with */ | 6686 char_u *fname; /* fname to match with */ |
6686 char_u *sfname; /* sfname to match with */ | 6687 char_u *sfname; /* sfname to match with */ |
6687 char_u *tail; /* tail of fname */ | 6688 char_u *tail; /* tail of fname */ |
6688 EVENT_T event; /* current event */ | 6689 EVENT_T event; /* current event */ |
6690 int arg_bufnr; /* initially equal to <abuf>, set to zero when | |
6691 buf is deleted */ | |
6692 struct AutoPatCmd *next; /* chain of active apc-s for auto-invalidation*/ | |
6689 } AutoPatCmd; | 6693 } AutoPatCmd; |
6694 | |
6695 AutoPatCmd *active_apc_list = NULL; /* stack of active autocommands */ | |
6690 | 6696 |
6691 /* | 6697 /* |
6692 * augroups stores a list of autocmd group names. | 6698 * augroups stores a list of autocmd group names. |
6693 */ | 6699 */ |
6694 garray_T augroups = {0, 0, sizeof(char_u *), 10, NULL}; | 6700 garray_T augroups = {0, 0, sizeof(char_u *), 10, NULL}; |
6719 static int do_autocmd_event __ARGS((EVENT_T event, char_u *pat, int nested, char_u *cmd, int forceit, int group)); | 6725 static int do_autocmd_event __ARGS((EVENT_T event, char_u *pat, int nested, char_u *cmd, int forceit, int group)); |
6720 static char_u *getnextac __ARGS((int c, void *cookie, int indent)); | 6726 static char_u *getnextac __ARGS((int c, void *cookie, int indent)); |
6721 static int apply_autocmds_group __ARGS((EVENT_T event, char_u *fname, char_u *fname_io, int force, int group, buf_T *buf, exarg_T *eap)); | 6727 static int apply_autocmds_group __ARGS((EVENT_T event, char_u *fname, char_u *fname_io, int force, int group, buf_T *buf, exarg_T *eap)); |
6722 static void auto_next_pat __ARGS((AutoPatCmd *apc, int stop_at_last)); | 6728 static void auto_next_pat __ARGS((AutoPatCmd *apc, int stop_at_last)); |
6723 | 6729 |
6730 | |
6724 static EVENT_T last_event; | 6731 static EVENT_T last_event; |
6725 static int last_group; | 6732 static int last_group; |
6726 | 6733 |
6727 /* | 6734 /* |
6728 * Show the autocommands for one AutoPat. | 6735 * Show the autocommands for one AutoPat. |
6793 au_remove_pat(ap) | 6800 au_remove_pat(ap) |
6794 AutoPat *ap; | 6801 AutoPat *ap; |
6795 { | 6802 { |
6796 vim_free(ap->pat); | 6803 vim_free(ap->pat); |
6797 ap->pat = NULL; | 6804 ap->pat = NULL; |
6805 ap->buflocal_nr = -1; | |
6798 au_need_clean = TRUE; | 6806 au_need_clean = TRUE; |
6799 } | 6807 } |
6800 | 6808 |
6801 /* | 6809 /* |
6802 * Mark all commands for a pattern for deletion. | 6810 * Mark all commands for a pattern for deletion. |
6864 prev_ap = &(ap->next); | 6872 prev_ap = &(ap->next); |
6865 } | 6873 } |
6866 } | 6874 } |
6867 | 6875 |
6868 au_need_clean = FALSE; | 6876 au_need_clean = FALSE; |
6877 } | |
6878 | |
6879 /* | |
6880 * Called when buffer is freed, to remove/invalidate related buffer-local | |
6881 * autocmds. | |
6882 */ | |
6883 void | |
6884 aubuflocal_remove(buf) | |
6885 buf_T *buf; | |
6886 { | |
6887 AutoPat *ap; | |
6888 EVENT_T event; | |
6889 AutoPatCmd *apc; | |
6890 | |
6891 /* invalidate currently executing autocommands */ | |
6892 for (apc = active_apc_list; apc; apc = apc->next) | |
6893 if (buf->b_fnum == apc->arg_bufnr) | |
6894 apc->arg_bufnr = 0; | |
6895 | |
6896 /* invalidate buflocals looping through events */ | |
6897 for (event = (EVENT_T)0; (int)event < (int)NUM_EVENTS; | |
6898 event = (EVENT_T)((int)event + 1)) | |
6899 /* loop over all autocommand patterns */ | |
6900 for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) | |
6901 if (ap->buflocal_nr == buf->b_fnum) | |
6902 { | |
6903 au_remove_pat(ap); | |
6904 if (p_verbose >= 6) | |
6905 smsg((char_u *) | |
6906 _("auto-removing autocommand: %s <buffer=%d>"), | |
6907 event_nr2name(event), buf->b_fnum); | |
6908 } | |
6909 au_cleanup(); | |
6869 } | 6910 } |
6870 | 6911 |
6871 /* | 6912 /* |
6872 * Add an autocmd group name. | 6913 * Add an autocmd group name. |
6873 * Return it's ID. Returns AUGROUP_ERROR (< 0) for error. | 6914 * Return it's ID. Returns AUGROUP_ERROR (< 0) for error. |
7290 int brace_level; | 7331 int brace_level; |
7291 char_u *endpat; | 7332 char_u *endpat; |
7292 int findgroup; | 7333 int findgroup; |
7293 int allgroups; | 7334 int allgroups; |
7294 int patlen; | 7335 int patlen; |
7336 int is_buflocal; | |
7337 int buflocal_nr; | |
7338 char_u buflocal_pat[25]; /* for "<buffer=X>" */ | |
7295 | 7339 |
7296 if (group == AUGROUP_ALL) | 7340 if (group == AUGROUP_ALL) |
7297 findgroup = current_augroup; | 7341 findgroup = current_augroup; |
7298 else | 7342 else |
7299 findgroup = group; | 7343 findgroup = group; |
7337 if (pat == endpat) /* ignore single comma */ | 7381 if (pat == endpat) /* ignore single comma */ |
7338 continue; | 7382 continue; |
7339 patlen = (int)(endpat - pat); | 7383 patlen = (int)(endpat - pat); |
7340 | 7384 |
7341 /* | 7385 /* |
7386 * detect special <buflocal[=X]> buffer-local patterns | |
7387 */ | |
7388 is_buflocal = FALSE; | |
7389 buflocal_nr = 0; | |
7390 | |
7391 if (patlen >= 7 && STRNCMP(pat, "<buffer", 7) == 0 | |
7392 && pat[patlen - 1] == '>') | |
7393 { | |
7394 /* Error will be printed only for addition. printing and removing | |
7395 * will proceed silently. */ | |
7396 is_buflocal = TRUE; | |
7397 if (patlen == 8) | |
7398 buflocal_nr = curbuf->b_fnum; | |
7399 else if (patlen > 9 && pat[7] == '=') | |
7400 { | |
7401 /* <buffer=abuf> */ | |
7402 if (patlen == 13 && STRNICMP(pat, "<buffer=abuf>", 13)) | |
7403 buflocal_nr = autocmd_bufnr; | |
7404 /* <buffer=123> */ | |
7405 else if (skipdigits(pat + 8) == pat + patlen - 1) | |
7406 buflocal_nr = atoi((char *)pat + 8); | |
7407 } | |
7408 } | |
7409 | |
7410 if (is_buflocal) | |
7411 { | |
7412 /* normalize pat into standard "<buffer>#N" form */ | |
7413 sprintf((char *)buflocal_pat, "<buffer=%d>", buflocal_nr); | |
7414 pat = buflocal_pat; /* can modify pat and patlen */ | |
7415 patlen = STRLEN(buflocal_pat); /* but not endpat */ | |
7416 } | |
7417 | |
7418 /* | |
7342 * Find AutoPat entries with this pattern. | 7419 * Find AutoPat entries with this pattern. |
7343 */ | 7420 */ |
7344 prev_ap = &first_autopat[(int)event]; | 7421 prev_ap = &first_autopat[(int)event]; |
7345 while ((ap = *prev_ap) != NULL) | 7422 while ((ap = *prev_ap) != NULL) |
7346 { | 7423 { |
7349 /* Accept a pattern when: | 7426 /* Accept a pattern when: |
7350 * - a group was specified and it's that group, or a group was | 7427 * - a group was specified and it's that group, or a group was |
7351 * not specified and it's the current group, or a group was | 7428 * not specified and it's the current group, or a group was |
7352 * not specified and we are listing | 7429 * not specified and we are listing |
7353 * - the length of the pattern matches | 7430 * - the length of the pattern matches |
7354 * - the pattern matches | 7431 * - the pattern matches. |
7432 * For <buffer[=X]>, this condition works because we normalize | |
7433 * all buffer-local patterns. | |
7355 */ | 7434 */ |
7356 if ((allgroups || ap->group == findgroup) | 7435 if ((allgroups || ap->group == findgroup) |
7357 && ap->patlen == patlen | 7436 && ap->patlen == patlen |
7358 && STRNCMP(pat, ap->pat, patlen) == 0) | 7437 && STRNCMP(pat, ap->pat, patlen) == 0) |
7359 { | 7438 { |
7372 } | 7451 } |
7373 au_remove_pat(ap); | 7452 au_remove_pat(ap); |
7374 } | 7453 } |
7375 | 7454 |
7376 /* | 7455 /* |
7377 * Show autocmd's for this autopat | 7456 * Show autocmd's for this autopat, or buflocals <buffer=X> |
7378 */ | 7457 */ |
7379 else if (*cmd == NUL) | 7458 else if (*cmd == NUL) |
7380 show_autocmd(ap, event); | 7459 show_autocmd(ap, event); |
7381 | 7460 |
7382 /* | 7461 /* |
7399 * end of the list (or not is not in the list at all), add the | 7478 * end of the list (or not is not in the list at all), add the |
7400 * pattern at the end of the list. | 7479 * pattern at the end of the list. |
7401 */ | 7480 */ |
7402 if (ap == NULL) | 7481 if (ap == NULL) |
7403 { | 7482 { |
7483 /* refuse to add buffer-local ap if buffer number is invalid */ | |
7484 if (is_buflocal && (buflocal_nr == 0 | |
7485 || buflist_findnr(buflocal_nr) == NULL)) | |
7486 { | |
7487 EMSGN(_("E680: <buffer=%d>: invalid buffer number "), | |
7488 buflocal_nr); | |
7489 return FAIL; | |
7490 } | |
7491 | |
7404 ap = (AutoPat *)alloc((unsigned)sizeof(AutoPat)); | 7492 ap = (AutoPat *)alloc((unsigned)sizeof(AutoPat)); |
7405 if (ap == NULL) | 7493 if (ap == NULL) |
7406 return FAIL; | 7494 return FAIL; |
7407 ap->pat = vim_strnsave(pat, patlen); | 7495 ap->pat = vim_strnsave(pat, patlen); |
7408 ap->patlen = patlen; | 7496 ap->patlen = patlen; |
7409 if (ap->pat == NULL) | 7497 if (ap->pat == NULL) |
7410 { | 7498 { |
7411 vim_free(ap); | 7499 vim_free(ap); |
7412 return FAIL; | 7500 return FAIL; |
7413 } | 7501 } |
7414 ap->reg_pat = file_pat_to_reg_pat(pat, endpat, | 7502 |
7415 &ap->allow_dirs, TRUE); | 7503 if (is_buflocal) |
7416 if (ap->reg_pat == NULL) | |
7417 { | 7504 { |
7418 vim_free(ap->pat); | 7505 ap->buflocal_nr = buflocal_nr; |
7419 vim_free(ap); | 7506 ap->reg_pat = NULL; |
7420 return FAIL; | 7507 } |
7508 else | |
7509 { | |
7510 ap->buflocal_nr = 0; | |
7511 ap->reg_pat = file_pat_to_reg_pat(pat, endpat, | |
7512 &ap->allow_dirs, TRUE); | |
7513 if (ap->reg_pat == NULL) | |
7514 { | |
7515 vim_free(ap->pat); | |
7516 vim_free(ap); | |
7517 return FAIL; | |
7518 } | |
7421 } | 7519 } |
7422 ap->cmds = NULL; | 7520 ap->cmds = NULL; |
7423 *prev_ap = ap; | 7521 *prev_ap = ap; |
7424 ap->next = NULL; | 7522 ap->next = NULL; |
7425 if (group == AUGROUP_ALL) | 7523 if (group == AUGROUP_ALL) |
7784 /* | 7882 /* |
7785 * Quickly return if there are no autocommands for this event or | 7883 * Quickly return if there are no autocommands for this event or |
7786 * autocommands are blocked. | 7884 * autocommands are blocked. |
7787 */ | 7885 */ |
7788 if (first_autopat[(int)event] == NULL || autocmd_block > 0) | 7886 if (first_autopat[(int)event] == NULL || autocmd_block > 0) |
7789 return retval; | 7887 goto BYPASS_AU; |
7790 | 7888 |
7791 /* | 7889 /* |
7792 * When autocommands are busy, new autocommands are only executed when | 7890 * When autocommands are busy, new autocommands are only executed when |
7793 * explicitly enabled with the "nested" flag. | 7891 * explicitly enabled with the "nested" flag. |
7794 */ | 7892 */ |
7795 if (autocmd_busy && !(force || autocmd_nested)) | 7893 if (autocmd_busy && !(force || autocmd_nested)) |
7796 return retval; | 7894 goto BYPASS_AU; |
7797 | 7895 |
7798 #ifdef FEAT_EVAL | 7896 #ifdef FEAT_EVAL |
7799 /* | 7897 /* |
7800 * Quickly return when immdediately aborting on error, or when an interrupt | 7898 * Quickly return when immdediately aborting on error, or when an interrupt |
7801 * occurred or an exception was thrown but not caught. | 7899 * occurred or an exception was thrown but not caught. |
7802 */ | 7900 */ |
7803 if (aborting()) | 7901 if (aborting()) |
7804 return retval; | 7902 goto BYPASS_AU; |
7805 #endif | 7903 #endif |
7806 | 7904 |
7807 /* | 7905 /* |
7808 * FileChangedShell never nests, because it can create an endless loop. | 7906 * FileChangedShell never nests, because it can create an endless loop. |
7809 */ | 7907 */ |
7810 if (filechangeshell_busy && event == EVENT_FILECHANGEDSHELL) | 7908 if (filechangeshell_busy && event == EVENT_FILECHANGEDSHELL) |
7811 return retval; | 7909 goto BYPASS_AU; |
7812 | 7910 |
7813 /* | 7911 /* |
7814 * Ignore events in 'eventignore'. | 7912 * Ignore events in 'eventignore'. |
7815 */ | 7913 */ |
7816 if (event_ignored(event)) | 7914 if (event_ignored(event)) |
7817 return retval; | 7915 goto BYPASS_AU; |
7818 | 7916 |
7819 /* | 7917 /* |
7820 * Allow nesting of autocommands, but restrict the depth, because it's | 7918 * Allow nesting of autocommands, but restrict the depth, because it's |
7821 * possible to create an endless loop. | 7919 * possible to create an endless loop. |
7822 */ | 7920 */ |
7823 if (nesting == 10) | 7921 if (nesting == 10) |
7824 { | 7922 { |
7825 EMSG(_("E218: autocommand nesting too deep")); | 7923 EMSG(_("E218: autocommand nesting too deep")); |
7826 return retval; | 7924 goto BYPASS_AU; |
7827 } | 7925 } |
7828 | 7926 |
7829 /* | 7927 /* |
7830 * Check if these autocommands are disabled. Used when doing ":all" or | 7928 * Check if these autocommands are disabled. Used when doing ":all" or |
7831 * ":ball". | 7929 * ":ball". |
7832 */ | 7930 */ |
7833 if ( (autocmd_no_enter | 7931 if ( (autocmd_no_enter |
7834 && (event == EVENT_WINENTER || event == EVENT_BUFENTER)) | 7932 && (event == EVENT_WINENTER || event == EVENT_BUFENTER)) |
7835 || (autocmd_no_leave | 7933 || (autocmd_no_leave |
7836 && (event == EVENT_WINLEAVE || event == EVENT_BUFLEAVE))) | 7934 && (event == EVENT_WINLEAVE || event == EVENT_BUFLEAVE))) |
7837 return retval; | 7935 goto BYPASS_AU; |
7838 | 7936 |
7839 /* | 7937 /* |
7840 * Save the autocmd_* variables and info about the current buffer. | 7938 * Save the autocmd_* variables and info about the current buffer. |
7841 */ | 7939 */ |
7842 save_autocmd_fname = autocmd_fname; | 7940 save_autocmd_fname = autocmd_fname; |
7902 else | 8000 else |
7903 { | 8001 { |
7904 sfname = vim_strsave(fname); | 8002 sfname = vim_strsave(fname); |
7905 /* Don't try expanding FileType, Syntax or WindowID. */ | 8003 /* Don't try expanding FileType, Syntax or WindowID. */ |
7906 if (event == EVENT_FILETYPE || event == EVENT_SYNTAX | 8004 if (event == EVENT_FILETYPE || event == EVENT_SYNTAX |
7907 || event == EVENT_REMOTEREPLY) | 8005 || event == EVENT_REMOTEREPLY) |
7908 fname = vim_strsave(fname); | 8006 fname = vim_strsave(fname); |
7909 else | 8007 else |
7910 fname = FullName_save(fname, FALSE); | 8008 fname = FullName_save(fname, FALSE); |
7911 } | 8009 } |
7912 if (fname == NULL) /* out of memory */ | 8010 if (fname == NULL) /* out of memory */ |
7913 { | 8011 { |
7914 vim_free(sfname); | 8012 vim_free(sfname); |
7915 return FALSE; | 8013 retval = FALSE; |
8014 goto BYPASS_AU; | |
7916 } | 8015 } |
7917 | 8016 |
7918 #ifdef BACKSLASH_IN_FILENAME | 8017 #ifdef BACKSLASH_IN_FILENAME |
7919 /* | 8018 /* |
7920 * Replace all backslashes with forward slashes. This makes the | 8019 * Replace all backslashes with forward slashes. This makes the |
7981 patcmd.group = group; | 8080 patcmd.group = group; |
7982 patcmd.fname = fname; | 8081 patcmd.fname = fname; |
7983 patcmd.sfname = sfname; | 8082 patcmd.sfname = sfname; |
7984 patcmd.tail = tail; | 8083 patcmd.tail = tail; |
7985 patcmd.event = event; | 8084 patcmd.event = event; |
8085 patcmd.arg_bufnr = autocmd_bufnr; | |
8086 patcmd.next = NULL; | |
7986 auto_next_pat(&patcmd, FALSE); | 8087 auto_next_pat(&patcmd, FALSE); |
7987 | 8088 |
7988 /* found one, start executing the autocommands */ | 8089 /* found one, start executing the autocommands */ |
7989 if (patcmd.curpat != NULL) | 8090 if (patcmd.curpat != NULL) |
7990 { | 8091 { |
8092 /* add to active_apc_list */ | |
8093 patcmd.next = active_apc_list; | |
8094 active_apc_list = &patcmd; | |
8095 | |
7991 #ifdef FEAT_EVAL | 8096 #ifdef FEAT_EVAL |
7992 /* set v:cmdarg (only when there is a matching pattern) */ | 8097 /* set v:cmdarg (only when there is a matching pattern) */ |
7993 save_cmdbang = get_vim_var_nr(VV_CMDBANG); | 8098 save_cmdbang = get_vim_var_nr(VV_CMDBANG); |
7994 if (eap != NULL) | 8099 if (eap != NULL) |
7995 { | 8100 { |
8013 { | 8118 { |
8014 (void)set_cmdarg(NULL, save_cmdarg); | 8119 (void)set_cmdarg(NULL, save_cmdarg); |
8015 set_vim_var_nr(VV_CMDBANG, save_cmdbang); | 8120 set_vim_var_nr(VV_CMDBANG, save_cmdbang); |
8016 } | 8121 } |
8017 #endif | 8122 #endif |
8123 /* delete from active_apc_list */ | |
8124 if (active_apc_list == &patcmd) /* just in case */ | |
8125 active_apc_list = patcmd.next; | |
8018 } | 8126 } |
8019 | 8127 |
8020 --RedrawingDisabled; | 8128 --RedrawingDisabled; |
8021 autocmd_busy = save_autocmd_busy; | 8129 autocmd_busy = save_autocmd_busy; |
8022 filechangeshell_busy = FALSE; | 8130 filechangeshell_busy = FALSE; |
8063 #endif | 8171 #endif |
8064 curbuf->b_changed = save_changed; | 8172 curbuf->b_changed = save_changed; |
8065 } | 8173 } |
8066 | 8174 |
8067 au_cleanup(); /* may really delete removed patterns/commands now */ | 8175 au_cleanup(); /* may really delete removed patterns/commands now */ |
8176 | |
8177 BYPASS_AU: | |
8178 /* When wiping out a buffer make sure all its buffer-local autocommands | |
8179 * are deleted. */ | |
8180 if (event == EVENT_BUFWIPEOUT && buf != NULL) | |
8181 aubuflocal_remove(buf); | |
8182 | |
8068 return retval; | 8183 return retval; |
8069 } | 8184 } |
8070 | 8185 |
8071 /* | 8186 /* |
8072 * Find next autocommand pattern that matches. | 8187 * Find next autocommand pattern that matches. |
8087 for (ap = apc->curpat; ap != NULL && !got_int; ap = ap->next) | 8202 for (ap = apc->curpat; ap != NULL && !got_int; ap = ap->next) |
8088 { | 8203 { |
8089 apc->curpat = NULL; | 8204 apc->curpat = NULL; |
8090 | 8205 |
8091 /* only use a pattern when it has not been removed, has commands and | 8206 /* only use a pattern when it has not been removed, has commands and |
8092 * the group matches */ | 8207 * the group matches. For buffer-local autocommands only check the |
8208 * buffer number. */ | |
8093 if (ap->pat != NULL && ap->cmds != NULL | 8209 if (ap->pat != NULL && ap->cmds != NULL |
8094 && (apc->group == AUGROUP_ALL || apc->group == ap->group)) | 8210 && (apc->group == AUGROUP_ALL || apc->group == ap->group)) |
8095 { | 8211 { |
8096 if (match_file_pat(ap->reg_pat, apc->fname, apc->sfname, apc->tail, | 8212 /* execution-condition */ |
8097 ap->allow_dirs)) | 8213 if (ap->buflocal_nr == 0 |
8214 ? (match_file_pat(ap->reg_pat, apc->fname, apc->sfname, | |
8215 apc->tail, ap->allow_dirs)) | |
8216 : ap->buflocal_nr == apc->arg_bufnr) | |
8098 { | 8217 { |
8099 name = event_nr2name(apc->event); | 8218 name = event_nr2name(apc->event); |
8100 s = _("%s Auto commands for \"%s\""); | 8219 s = _("%s Auto commands for \"%s\""); |
8101 sourcing_name = alloc((unsigned)(STRLEN(s) | 8220 sourcing_name = alloc((unsigned)(STRLEN(s) |
8102 + STRLEN(name) + ap->patlen + 1)); | 8221 + STRLEN(name) + ap->patlen + 1)); |
8189 return retval; | 8308 return retval; |
8190 } | 8309 } |
8191 | 8310 |
8192 /* | 8311 /* |
8193 * Return TRUE if there is a matching autocommand for "fname". | 8312 * Return TRUE if there is a matching autocommand for "fname". |
8313 * To account for buffer-local autocommands, function needs to know | |
8314 * in which buffer the file will be opened. | |
8194 */ | 8315 */ |
8195 int | 8316 int |
8196 has_autocmd(event, sfname) | 8317 has_autocmd(event, sfname, buf) |
8197 EVENT_T event; | 8318 EVENT_T event; |
8198 char_u *sfname; | 8319 char_u *sfname; |
8320 buf_T *buf; | |
8199 { | 8321 { |
8200 AutoPat *ap; | 8322 AutoPat *ap; |
8201 char_u *fname; | 8323 char_u *fname; |
8202 char_u *tail = gettail(sfname); | 8324 char_u *tail = gettail(sfname); |
8203 int retval = FALSE; | 8325 int retval = FALSE; |
8217 forward_slash(fname); | 8339 forward_slash(fname); |
8218 #endif | 8340 #endif |
8219 | 8341 |
8220 for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) | 8342 for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) |
8221 if (ap->pat != NULL && ap->cmds != NULL | 8343 if (ap->pat != NULL && ap->cmds != NULL |
8222 && match_file_pat(ap->reg_pat, fname, sfname, tail, | 8344 && (ap->buflocal_nr == 0 |
8223 ap->allow_dirs)) | 8345 ? match_file_pat(ap->reg_pat, fname, sfname, tail, |
8346 ap->allow_dirs) | |
8347 : buf != NULL && ap->buflocal_nr == buf->b_fnum | |
8348 )) | |
8224 { | 8349 { |
8225 retval = TRUE; | 8350 retval = TRUE; |
8226 break; | 8351 break; |
8227 } | 8352 } |
8228 | 8353 |
8325 | 8450 |
8326 #endif /* FEAT_CMDL_COMPL */ | 8451 #endif /* FEAT_CMDL_COMPL */ |
8327 | 8452 |
8328 /* | 8453 /* |
8329 * Return TRUE if an autocommand is defined for "event" and "pattern". | 8454 * Return TRUE if an autocommand is defined for "event" and "pattern". |
8330 * "pattern" can be NULL to accept any pattern. | 8455 * "pattern" can be NULL to accept any pattern. Buffer-local patterns |
8456 * <buffer> or <buffer=N> are accepted. | |
8457 * Used for exists("#Event#pat") | |
8331 */ | 8458 */ |
8332 int | 8459 int |
8333 au_exists(name, name_end, pattern) | 8460 au_exists(name, name_end, pattern) |
8334 char_u *name; | 8461 char_u *name; |
8335 char_u *name_end; | 8462 char_u *name_end; |
8337 { | 8464 { |
8338 char_u *event_name; | 8465 char_u *event_name; |
8339 char_u *p; | 8466 char_u *p; |
8340 EVENT_T event; | 8467 EVENT_T event; |
8341 AutoPat *ap; | 8468 AutoPat *ap; |
8469 buf_T *buflocal_buf = NULL; | |
8342 | 8470 |
8343 /* find the index (enum) for the event name */ | 8471 /* find the index (enum) for the event name */ |
8344 event_name = vim_strnsave(name, (int)(name_end - name)); | 8472 event_name = vim_strnsave(name, (int)(name_end - name)); |
8345 if (event_name == NULL) | 8473 if (event_name == NULL) |
8346 return FALSE; | 8474 return FALSE; |
8358 if (ap == NULL) | 8486 if (ap == NULL) |
8359 return FALSE; | 8487 return FALSE; |
8360 if (pattern == NULL) | 8488 if (pattern == NULL) |
8361 return TRUE; | 8489 return TRUE; |
8362 | 8490 |
8491 /* if pattern is "<buffer>", special handling is needed which uses curbuf */ | |
8492 /* for pattern "<buffer=N>, fnamecmp() will work fine */ | |
8493 if (STRICMP(pattern, "<buffer>") == 0) | |
8494 buflocal_buf = curbuf; | |
8495 | |
8363 /* Check if there is an autocommand with the given pattern. */ | 8496 /* Check if there is an autocommand with the given pattern. */ |
8364 for ( ; ap != NULL; ap = ap->next) | 8497 for ( ; ap != NULL; ap = ap->next) |
8365 /* only use a pattern when it has not been removed and has commands */ | 8498 /* only use a pattern when it has not been removed and has commands. */ |
8499 /* For buffer-local autocommands, fnamecmp() works fine. */ | |
8366 if (ap->pat != NULL && ap->cmds != NULL | 8500 if (ap->pat != NULL && ap->cmds != NULL |
8367 && fnamecmp(ap->pat, pattern) == 0) | 8501 && (buflocal_buf == NULL |
8502 ? fnamecmp(ap->pat, pattern) == 0 | |
8503 : ap->buflocal_nr == buflocal_buf->b_fnum)) | |
8368 return TRUE; | 8504 return TRUE; |
8369 | 8505 |
8370 return FALSE; | 8506 return FALSE; |
8371 } | 8507 } |
8508 | |
8372 #endif /* FEAT_AUTOCMD */ | 8509 #endif /* FEAT_AUTOCMD */ |
8373 | 8510 |
8374 #if defined(FEAT_AUTOCMD) || defined(FEAT_WILDIGN) || defined(PROTO) | 8511 #if defined(FEAT_AUTOCMD) || defined(FEAT_WILDIGN) || defined(PROTO) |
8375 /* | 8512 /* |
8376 * Try matching a filename with a pattern. | 8513 * Try matching a filename with a pattern. |