Hi,
This is a result of a previous discussion[1] which concluded that a more general
Error autocmd event would be a better addition than the proposed TagNotFound
event.

Questions and comments regarding the patch in no particular order:

- Is the addition to the main_loop function at a suitable location?

- The error code (emsg_code) is the actual code including the 'E' prefix.
  Another solution is to use the numerical representation of the error code.

- The get_error_pat function is used to translate error codes into something
  more descriptive. As of writing this only one such mapping is present. We
  could either ensure that all possible error codes has a mapping or add them on
  demand. The function is doing a linear search of error_pats. If the error code
  is represented as an int this could be replaced with a constant lookup if the
  array index is equal to the error code:

    static const char *error_pat[] = {
      [426] = "tagnotfound",
    }

  If mappings of all possible error codes is present the array won't end up
  being that sparse.

  The existing solution (representing error codes as string) could also be
  improved by replacing the linear search with a binary search.

- If no mapping of the error code to pattern is found the actual error code is
  used as the amatch argument when triggering the Error event.

[1] https://groups.google.com/d/msg/vim_dev/XzhNNjbtfow/u6BWsne4CwAJ

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/fileio.c b/src/fileio.c
index ecec757..9a1e294 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -7666,6 +7666,7 @@ static struct event_name
     {"CursorMoved",	EVENT_CURSORMOVED},
     {"CursorMovedI",	EVENT_CURSORMOVEDI},
     {"EncodingChanged",	EVENT_ENCODINGCHANGED},
+    {"Error",		EVENT_ERROR},
     {"FileEncoding",	EVENT_ENCODINGCHANGED},
     {"FileAppendPost",	EVENT_FILEAPPENDPOST},
     {"FileAppendPre",	EVENT_FILEAPPENDPRE},
@@ -7725,6 +7726,21 @@ static struct event_name
     {NULL,		(event_T)0}
 };
 
+
+/*
+ * Mapping of error code to pattern used for <amatch> when triggering the Error
+ * event.
+ */
+static struct error_pat
+{
+    const char	*code;
+    const char	*pat;
+} error_pats[] =
+{
+    {"E426",	"tagnotfound"},
+    {NULL,	NULL}
+};
+
 static AutoPat *first_autopat[NUM_EVENTS] =
 {
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -9351,7 +9367,7 @@ apply_autocmds_group(
     {
 	sfname = vim_strsave(fname);
 	/* Don't try expanding FileType, Syntax, FuncUndefined, WindowID,
-	 * ColorScheme or QuickFixCmd* */
+	 * ColorScheme, Error or QuickFixCmd* */
 	if (event == EVENT_FILETYPE
 		|| event == EVENT_SYNTAX
 		|| event == EVENT_FUNCUNDEFINED
@@ -9359,6 +9375,7 @@ apply_autocmds_group(
 		|| event == EVENT_SPELLFILEMISSING
 		|| event == EVENT_QUICKFIXCMDPRE
 		|| event == EVENT_COLORSCHEME
+		|| event == EVENT_ERROR
 		|| event == EVENT_OPTIONSET
 		|| event == EVENT_QUICKFIXCMDPOST)
 	    fname = vim_strsave(fname);
@@ -9750,20 +9767,26 @@ has_autocmd(event_T event, char_u *sfname, buf_T *buf)
     char_u	*tail = gettail(sfname);
     int		retval = FALSE;
 
-    fname = FullName_save(sfname, FALSE);
-    if (fname == NULL)
-	return FALSE;
-
+    /* don't try expanding Error */
+    if (event == EVENT_ERROR) {
+	fname = vim_strsave(sfname);
+	if (fname == NULL)
+	    return FALSE;
+    } else {
+	fname = FullName_save(sfname, FALSE);
+	if (fname == NULL)
+	    return FALSE;
 #ifdef BACKSLASH_IN_FILENAME
-    /*
-     * Replace all backslashes with forward slashes.  This makes the
-     * autocommand patterns portable between Unix and MS-DOS.
-     */
-    sfname = vim_strsave(sfname);
-    if (sfname != NULL)
-	forward_slash(sfname);
-    forward_slash(fname);
+	/*
+	 * Replace all backslashes with forward slashes.  This makes the
+	 * autocommand patterns portable between Unix and MS-DOS.
+	 */
+	sfname = vim_strsave(sfname);
+	if (sfname != NULL)
+	    forward_slash(sfname);
+	forward_slash(fname);
 #endif
+    }
 
     for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next)
 	if (ap->pat != NULL && ap->cmds != NULL
@@ -10358,3 +10381,22 @@ write_eintr(int fd, void *buf, size_t bufsize)
     return ret;
 }
 #endif
+
+
+/*
+ * Get the corresponding pattern for the given error message code. The returned
+ * value is used for <amatch> when triggering the Error autocmd event.
+ */
+    char_u *
+get_error_pat(char_u *code)
+{
+    size_t	len;
+    int		i;
+
+    len = STRLEN(code);
+    for (i = 0; error_pats[i].code; i++)
+	if (STRNCMP(error_pats[i].code, code, len) == 0)
+	    return (char_u *)error_pats[i].pat;
+
+    return NULL;
+}
diff --git a/src/globals.h b/src/globals.h
index 4c1b41f..4342b71 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -184,6 +184,10 @@ EXTERN int	did_emsg;		    /* set by emsg() when the message
 EXTERN int	did_emsg_syntax;	    /* did_emsg set because of a
 					       syntax error */
 EXTERN int	called_emsg;		    /* always set by emsg() */
+#ifdef FEAT_AUTOCMD
+EXTERN char_u	*emsg_code INIT(= NULL);    /* last error message code set by
+					       emsg() */
+#endif
 EXTERN int	ex_exitval INIT(= 0);	    /* exit value for ex mode */
 EXTERN int	emsg_on_display INIT(= FALSE);	/* there is an error message */
 EXTERN int	rc_did_emsg INIT(= FALSE);  /* vim_regcomp() called emsg() */
diff --git a/src/main.c b/src/main.c
index e412641..aad656a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1278,6 +1278,20 @@ main_loop(
 		fileinfo(FALSE, TRUE, FALSE);
 		need_fileinfo = FALSE;
 	    }
+#ifdef FEAT_AUTOCMD
+	    if (did_emsg && emsg_code) {
+		char_u *pat = get_error_pat(emsg_code);
+		if (pat && has_autocmd(EVENT_ERROR, pat, curbuf))
+		    apply_autocmds(EVENT_ERROR, pat, curbuf->b_fname, FALSE,
+				   curbuf);
+		else if (has_autocmd(EVENT_ERROR, emsg_code, curbuf))
+		    apply_autocmds(EVENT_ERROR, emsg_code, curbuf->b_fname,
+				   FALSE, curbuf);
+
+		vim_free(emsg_code);
+		emsg_code = NULL;
+	    }
+#endif
 
 	    emsg_on_display = FALSE;	/* can delete error message now */
 	    did_emsg = FALSE;
diff --git a/src/message.c b/src/message.c
index b352590..65f95e0 100644
--- a/src/message.c
+++ b/src/message.c
@@ -559,6 +559,14 @@ emsg(char_u *s)
 	    return TRUE;
 	}
 
+#ifdef FEAT_AUTOCMD
+	{
+	    char_u *end = vim_strchr(s, ':');
+	    if (end)
+		emsg_code = vim_strnsave(s, end - s);
+	}
+#endif
+
 	/* set "v:errmsg", also when using ":silent! cmd" */
 	set_vim_var_string(VV_ERRMSG, s, -1);
 #endif
diff --git a/src/proto/fileio.pro b/src/proto/fileio.pro
index 9cd6414..dd8453e 100644
--- a/src/proto/fileio.pro
+++ b/src/proto/fileio.pro
@@ -64,4 +64,5 @@ int match_file_list(char_u *list, char_u *sfname, char_u *ffname);
 char_u *file_pat_to_reg_pat(char_u *pat, char_u *pat_end, char *allow_dirs, int no_bslash);
 long read_eintr(int fd, void *buf, size_t bufsize);
 long write_eintr(int fd, void *buf, size_t bufsize);
+char_u *get_error_pat(char_u *code);
 /* vim: set ft=c : */
diff --git a/src/vim.h b/src/vim.h
index 02f3036..b9c0c22 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1295,6 +1295,7 @@ enum auto_event
     EVENT_WINENTER,		/* after entering a window */
     EVENT_WINLEAVE,		/* before leaving a window */
     EVENT_ENCODINGCHANGED,	/* after changing the 'encoding' option */
+    EVENT_ERROR,		/* an error occured */
     EVENT_INSERTCHARPRE,	/* before inserting a char */
     EVENT_CURSORHOLD,		/* cursor in same position for a while */
     EVENT_CURSORHOLDI,		/* idem, in Insert mode */

Raspunde prin e-mail lui