updated for version 7.0047
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 5319449..5cecf30 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -3180,13 +3180,7 @@
p++;
xp->xp_pattern = p;
- if ((argt & XFILE)
-#ifdef FEAT_QUICKFIX
- || cmdidx == CMD_vimgrep
- || cmdidx == CMD_vimgrepadd
- || grep_internal(cmdidx)
-#endif
- )
+ if (argt & XFILE)
{
int in_quote = FALSE;
char_u *bow = NULL; /* Beginning of word */
@@ -3919,6 +3913,32 @@
}
}
+#ifdef FEAT_QUICKFIX
+static char_u *skip_grep_pat __ARGS((exarg_T *eap));
+
+/*
+ * For a ":vimgrep" or ":vimgrepadd" command return a pointer past the
+ * pattern. Otherwise return eap->arg.
+ */
+ static char_u *
+skip_grep_pat(eap)
+ exarg_T *eap;
+{
+ char_u *p = eap->arg;
+
+ if (*p != NUL && (eap->cmdidx == CMD_vimgrep
+ || eap->cmdidx == CMD_vimgrepadd || grep_internal(eap->cmdidx)))
+ {
+ p = skip_vimgrep_pat(p, NULL);
+ if (p == NULL)
+ p = eap->arg;
+ else if (*p != NUL && !vim_iswhite(*p))
+ ++p; /* step past ending separator of /pat/ */
+ }
+ return p;
+}
+#endif
+
/*
* Expand file name in Ex command argument.
* Return FAIL for failure, OK otherwise.
@@ -3935,13 +3955,20 @@
char_u *p;
int n;
+#ifdef FEAT_QUICKFIX
+ /* Skip a regexp pattern for ":vimgrep[add] pat file..." */
+ p = skip_grep_pat(eap);
+#else
+ p = eap->arg;
+#endif
+
/*
* Decide to expand wildcards *before* replacing '%', '#', etc. If
* the file name contains a wildcard it should not cause expanding.
* (it will be expanded anyway if there is a wildcard before replacing).
*/
- has_wildcards = mch_has_wildcard(eap->arg);
- for (p = eap->arg; *p; )
+ has_wildcards = mch_has_wildcard(p);
+ while (*p != NUL)
{
#ifdef FEAT_EVAL
/* Skip over `=expr`, wildcards in it are not expanded. */
@@ -4225,22 +4252,10 @@
{
char_u *p;
- p = eap->arg;
#ifdef FEAT_QUICKFIX
- if (*p != NUL && (eap->cmdidx == CMD_vimgrep
- || eap->cmdidx == CMD_vimgrepadd
- || grep_internal(eap->cmdidx)))
- {
- /* Skip over the pattern. */
- if (vim_isIDc(*p))
- p = skiptowhite(p);
- else
- {
- p = skip_regexp(p + 1, *p, TRUE, NULL);
- if (*p == *eap->arg)
- ++p;
- }
- }
+ p = skip_grep_pat(eap);
+#else
+ p = eap->arg;
#endif
for ( ; *p; mb_ptr_adv(p))
diff --git a/src/fileio.c b/src/fileio.c
index c888f35..ee1c90b 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -6585,7 +6585,7 @@
char_u *pat; /* pattern as typed (NULL when pattern
has been removed) */
int patlen; /* strlen() of pat */
- char_u *reg_pat; /* pattern converted to regexp */
+ regprog_T *reg_prog; /* compiled regprog for pattern */
char allow_dirs; /* Pattern may match whole path */
char last; /* last pattern for apply_autocmds() */
AutoCmd *cmds; /* list of commands to do */
@@ -6865,7 +6865,7 @@
if (ap->pat == NULL)
{
*prev_ap = ap->next;
- vim_free(ap->reg_pat);
+ vim_free(ap->reg_prog);
vim_free(ap);
}
else
@@ -7167,8 +7167,6 @@
if (old_ei != NULL)
{
set_string_option_direct((char_u *)"ei", -1, old_ei, OPT_FREE);
- apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn,
- curbuf->b_fname, TRUE, curbuf);
vim_free(old_ei);
}
}
@@ -7542,15 +7540,20 @@
if (is_buflocal)
{
ap->buflocal_nr = buflocal_nr;
- ap->reg_pat = NULL;
+ ap->reg_prog = NULL;
}
else
{
+ char_u *reg_pat;
+
ap->buflocal_nr = 0;
- ap->reg_pat = file_pat_to_reg_pat(pat, endpat,
+ reg_pat = file_pat_to_reg_pat(pat, endpat,
&ap->allow_dirs, TRUE);
- if (ap->reg_pat == NULL)
+ if (reg_pat != NULL)
+ ap->reg_prog = vim_regcomp(reg_pat, RE_MAGIC);
+ if (reg_pat == NULL || ap->reg_prog == NULL)
{
+ vim_free(reg_pat);
vim_free(ap->pat);
vim_free(ap);
return FAIL;
@@ -8250,8 +8253,8 @@
{
/* execution-condition */
if (ap->buflocal_nr == 0
- ? (match_file_pat(ap->reg_pat, apc->fname, apc->sfname,
- apc->tail, ap->allow_dirs))
+ ? (match_file_pat(NULL, ap->reg_prog, apc->fname,
+ apc->sfname, apc->tail, ap->allow_dirs))
: ap->buflocal_nr == apc->arg_bufnr)
{
name = event_nr2name(apc->event);
@@ -8381,8 +8384,8 @@
for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next)
if (ap->pat != NULL && ap->cmds != NULL
&& (ap->buflocal_nr == 0
- ? match_file_pat(ap->reg_pat, fname, sfname, tail,
- ap->allow_dirs)
+ ? match_file_pat(NULL, ap->reg_prog,
+ fname, sfname, tail, ap->allow_dirs)
: buf != NULL && ap->buflocal_nr == buf->b_fnum
))
{
@@ -8549,13 +8552,16 @@
#if defined(FEAT_AUTOCMD) || defined(FEAT_WILDIGN) || defined(PROTO)
/*
- * Try matching a filename with a pattern.
+ * Try matching a filename with a "pattern" ("prog" is NULL), or use the
+ * precompiled regprog "prog" ("pattern" is NULL). That avoids calling
+ * vim_regcomp() often.
* Used for autocommands and 'wildignore'.
* Returns TRUE if there is a match, FALSE otherwise.
*/
int
-match_file_pat(pattern, fname, sfname, tail, allow_dirs)
+match_file_pat(pattern, prog, fname, sfname, tail, allow_dirs)
char_u *pattern; /* pattern to match with */
+ regprog_T *prog; /* pre-compiled regprog or NULL */
char_u *fname; /* full path of file name */
char_u *sfname; /* short file name or NULL */
char_u *tail; /* tail of path */
@@ -8610,7 +8616,12 @@
}
else
#endif
- regmatch.regprog = vim_regcomp(pattern, RE_MAGIC);
+ {
+ if (prog != NULL)
+ regmatch.regprog = prog;
+ else
+ regmatch.regprog = vim_regcomp(pattern, RE_MAGIC);
+ }
/*
* Try for a match with the pattern with:
@@ -8633,7 +8644,8 @@
|| (!allow_dirs && vim_regexec(®match, tail, (colnr_T)0)))))
result = TRUE;
- vim_free(regmatch.regprog);
+ if (prog == NULL)
+ vim_free(regmatch.regprog);
return result;
}
#endif
@@ -8667,7 +8679,8 @@
regpat = file_pat_to_reg_pat(buf, NULL, &allow_dirs, FALSE);
if (regpat == NULL)
break;
- match = match_file_pat(regpat, ffname, sfname, tail, (int)allow_dirs);
+ match = match_file_pat(regpat, NULL, ffname, sfname,
+ tail, (int)allow_dirs);
vim_free(regpat);
if (match)
return TRUE;
diff --git a/src/globals.h b/src/globals.h
index 555c19e..1df8b87 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1402,6 +1402,10 @@
#if defined(FEAT_EVAL) || defined(FEAT_SYN_HL)
EXTERN char_u e_intern2[] INIT(=N_("E685: Internal error: %s"));
#endif
+#if defined(HAVE_SETJMP_H) || defined(HAVE_TRY_EXCEPT)
+EXTERN char_u e_complex[] INIT(=N_("E361: Crash intercepted; regexp too complex?"));
+#endif
+EXTERN char_u e_outofstack[] INIT(=N_("E363: pattern caused out-of-stack error"));
#ifdef MACOS_X_UNIX
diff --git a/src/gui_w32.c b/src/gui_w32.c
index 7e63549..a29de9d 100644
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -991,13 +991,10 @@
ATOM atom;
#endif
- /* Display any pending error messages */
- display_errors();
-
/* Return here if the window was already opened (happens when
* gui_mch_dialog() is called early). */
if (s_hwnd != NULL)
- return OK;
+ goto theend;
/*
* Load the tearoff bitmap
@@ -1224,6 +1221,10 @@
s_findrep_struct.wReplaceWithLen = MSWIN_FR_BUFSIZE;
#endif
+theend:
+ /* Display any pending error messages */
+ display_errors();
+
return OK;
}
@@ -2540,6 +2541,8 @@
int fontHeight;
int textWidth, minButtonWidth, messageWidth;
int maxDialogWidth;
+ int maxDialogHeight;
+ int scroll_flag = 0;
int vertical;
int dlgPaddingX;
int dlgPaddingY;
@@ -2554,9 +2557,14 @@
return dfltbutton; /* return default option */
#endif
+#if 0
/* If there is no window yet, open it. */
if (s_hwnd == NULL && gui_mch_init() == FAIL)
return dfltbutton;
+#else
+ if (s_hwnd == NULL)
+ get_dialog_font_metrics();
+#endif
if ((type < 0) || (type > VIM_LAST_TYPE))
type = 0;
@@ -2639,10 +2647,14 @@
if (maxDialogWidth < DLG_MIN_MAX_WIDTH)
maxDialogWidth = DLG_MIN_MAX_WIDTH;
+ maxDialogHeight = rect.bottom - rect.top - GetSystemMetrics(SM_CXFRAME) * 2;
+ if (maxDialogHeight < DLG_MIN_MAX_HEIGHT)
+ maxDialogHeight = DLG_MIN_MAX_HEIGHT;
+
/* Set dlgwidth to width of message */
pstart = message;
messageWidth = 0;
- msgheight = 0;
+ msgheight = fontHeight;
do
{
pend = vim_strchr(pstart, DLG_BUTTON_SEP);
@@ -2650,14 +2662,33 @@
pend = pstart + STRLEN(pstart); /* Last line of message. */
msgheight += fontHeight;
textWidth = GetTextWidth(hdc, pstart, (int)(pend - pstart));
- if (textWidth > messageWidth)
+ if (textWidth >= maxDialogWidth)
+ {
+ /* Line will wrap. This doesn't work correctly, because the wrap
+ * happens at a word boundary! */
+ messageWidth = maxDialogWidth;
+ while (textWidth >= maxDialogWidth)
+ {
+ msgheight += fontHeight;
+ textWidth -= maxDialogWidth;
+ }
+ }
+ else if (textWidth > messageWidth)
messageWidth = textWidth;
pstart = pend + 1;
} while (*pend != NUL);
- dlgwidth = messageWidth;
+
+ messageWidth += 10; /* roundoff space */
+
+ /* Restrict the size to a maximum. Causes a scrollbar to show up. */
+ if (msgheight > maxDialogHeight)
+ {
+ msgheight = maxDialogHeight;
+ scroll_flag = WS_VSCROLL;
+ }
/* Add width of icon to dlgwidth, and some space */
- dlgwidth += DLG_ICON_WIDTH + 3 * dlgPaddingX;
+ dlgwidth = messageWidth + DLG_ICON_WIDTH + 3 * dlgPaddingX;
if (msgheight < DLG_ICON_HEIGHT)
msgheight = DLG_ICON_HEIGHT;
@@ -2839,6 +2870,7 @@
DLG_NONBUTTON_CONTROL + 0, (WORD)0x0082,
dlg_icons[type]);
+#if 0
/* Dialog message */
p = add_dialog_element(p, SS_LEFT,
PixelToDialogX(2 * dlgPaddingX + DLG_ICON_WIDTH),
@@ -2846,6 +2878,15 @@
(WORD)(PixelToDialogX(messageWidth) + 1),
PixelToDialogY(msgheight),
DLG_NONBUTTON_CONTROL + 1, (WORD)0x0082, message);
+#else
+ /* Dialog message */
+ p = add_dialog_element(p, ES_LEFT|scroll_flag|ES_MULTILINE|ES_READONLY,
+ PixelToDialogX(2 * dlgPaddingX + DLG_ICON_WIDTH),
+ PixelToDialogY(dlgPaddingY),
+ (WORD)(PixelToDialogX(messageWidth) + 1),
+ PixelToDialogY(msgheight),
+ DLG_NONBUTTON_CONTROL + 1, (WORD)0x0081, message);
+#endif
/* Edit box */
if (textfield != NULL)
diff --git a/src/gui_w48.c b/src/gui_w48.c
index 00b5e66..2e09655 100644
--- a/src/gui_w48.c
+++ b/src/gui_w48.c
@@ -61,6 +61,7 @@
#define DLG_FONT_NAME "MS Sans Serif"
#define DLG_FONT_POINT_SIZE 8
#define DLG_MIN_MAX_WIDTH 400
+#define DLG_MIN_MAX_HEIGHT 400
#define DLG_NONBUTTON_CONTROL 5000 /* First ID of non-button controls */
diff --git a/src/os_mswin.c b/src/os_mswin.c
index f2a6c90..f5c4abf 100644
--- a/src/os_mswin.c
+++ b/src/os_mswin.c
@@ -595,11 +595,16 @@
#endif
STRCPY(s, _("...(truncated)"));
}
+
+ (void)gui_mch_dialog(VIM_ERROR, (char_u *)_("Error"),
+ p, (char_u *)_("&Ok"), 1, NULL);
+#if 0
#ifdef WIN3264
MessageBox(NULL, p, "Vim", MB_TASKMODAL|MB_SETFOREGROUND);
#else
MessageBox(NULL, p, "Vim", MB_TASKMODAL);
#endif
+#endif
break;
}
ga_clear(&error_ga);
diff --git a/src/proto/fileio.pro b/src/proto/fileio.pro
index d7c8095..68594ba 100644
--- a/src/proto/fileio.pro
+++ b/src/proto/fileio.pro
@@ -38,7 +38,7 @@
char_u *set_context_in_autocmd __ARGS((expand_T *xp, char_u *arg, int doautocmd));
char_u *get_event_name __ARGS((expand_T *xp, int idx));
int au_exists __ARGS((char_u *name, char_u *name_end, char_u *pattern));
-int match_file_pat __ARGS((char_u *pattern, char_u *fname, char_u *sfname, char_u *tail, int allow_dirs));
+int match_file_pat __ARGS((char_u *pattern, regprog_T *prog, char_u *fname, char_u *sfname, char_u *tail, int allow_dirs));
int match_file_list __ARGS((char_u *list, char_u *sfname, char_u *ffname));
char_u *file_pat_to_reg_pat __ARGS((char_u *pat, char_u *pat_end, char *allow_dirs, int no_bslash));
/* vim: set ft=c : */
diff --git a/src/quickfix.c b/src/quickfix.c
index 2a2ee14..a411003 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -2256,12 +2256,12 @@
{
regmmatch_T regmatch;
char_u *save_cpo;
- int fcount;
+ int fcount;
char_u **fnames;
- char_u *s;
- char_u *p;
+ char_u *s;
+ char_u *p;
int i;
- int fi;
+ int fi;
struct qf_line *prevp = NULL;
long lnum;
garray_T ga;
@@ -2282,20 +2282,11 @@
/* Get the search pattern: either white-separated or enclosed in // */
regmatch.regprog = NULL;
- if (vim_isIDc(*eap->arg))
+ p = skip_vimgrep_pat(eap->arg, &s);
+ if (p == NULL)
{
- s = eap->arg;
- p = skiptowhite(s);
- }
- else
- {
- s = eap->arg + 1;
- p = skip_regexp(s, *eap->arg, TRUE, NULL);
- if (*p != *eap->arg)
- {
- EMSG(_("E682: Invalid search pattern or delimiter"));
- goto theend;
- }
+ EMSG(_("E682: Invalid search pattern or delimiter"));
+ goto theend;
}
if (*p != NUL)
*p++ = NUL;
@@ -2391,6 +2382,25 @@
else
{
found_match = FALSE;
+#ifdef HAVE_SETJMP_H
+ /*
+ * Matching with a regexp may cause a very deep recursive call of
+ * regmatch(). Vim will crash when running out of stack space.
+ * Catch this here if the system supports it.
+ * It's a bit slow, thus do it outside of the loop.
+ */
+ mch_startjmp();
+ if (SETJMP(lc_jump_env) != 0)
+ {
+ mch_didjmp();
+# ifdef SIGHASARG
+ if (lc_signal != SIGINT)
+# endif
+ EMSG(_(e_complex));
+ got_int = TRUE;
+ goto jumpend;
+ }
+#endif
for (lnum = 1; lnum <= buf->b_ml.ml_line_count; ++lnum)
{
if (vim_regexec_multi(®match, curwin, buf, lnum,
@@ -2419,6 +2429,10 @@
if (got_int)
break;
}
+#ifdef HAVE_SETJMP_H
+jumpend:
+ mch_endjmp();
+#endif
if (using_dummy)
{
@@ -2453,10 +2467,12 @@
if (buf != NULL)
{
/* The buffer is still loaded, the Filetype autocommands
- * need to be done now, in that buffer. */
+ * need to be done now, in that buffer. And then the
+ * modelines (again). */
aucmd_prepbuf(&aco, buf);
apply_autocmds(EVENT_FILETYPE, buf->b_p_ft,
buf->b_fname, TRUE, buf);
+ do_modelines(FALSE);
aucmd_restbuf(&aco);
}
#endif
@@ -2491,6 +2507,33 @@
}
/*
+ * Skip over the pattern argument of ":vimgrep /pat/".
+ * Put the start of the pattern in "*s", unless "s" is NULL.
+ * Return a pointer to the char just past the pattern.
+ */
+ char_u *
+skip_vimgrep_pat(p, s)
+ char_u *p;
+ char_u **s;
+{
+ int c;
+
+ if (vim_isIDc(*p))
+ {
+ if (s != NULL)
+ *s = p;
+ return skiptowhite(p);
+ }
+ if (s != NULL)
+ *s = p + 1;
+ c = *p;
+ p = skip_regexp(p + 1, c, TRUE, NULL);
+ if (*p != c)
+ return NULL;
+ return p;
+}
+
+/*
* Load file "fname" into a dummy buffer and return the buffer pointer.
* Returns NULL if it fails.
* Must call unload_dummy_buffer() or wipe_dummy_buffer() later!
diff --git a/src/regexp.c b/src/regexp.c
index 4aa5b6a..a9915a3 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -726,7 +726,7 @@
/*
* Skip past regular expression.
- * Stop at end of 'p' or where 'dirc' is found ('/', '?', etc).
+ * Stop at end of "startp" or where "dirc" is found ('/', '?', etc).
* Take care of characters with a backslash in front of it.
* Skip strings inside [ and ].
* When "newp" is not NULL and "dirc" is '?', make an allocated copy of the
@@ -3010,33 +3010,12 @@
#ifdef HAVE_SETJMP_H
char_u *line;
colnr_T col;
+ int did_mch_startjmp = FALSE;
#endif
reg_tofree = NULL;
-#ifdef HAVE_TRY_EXCEPT
- __try
- {
-#endif
-
#ifdef HAVE_SETJMP_H
- /*
- * Matching with a regexp may cause a very deep recursive call of
- * regmatch(). Vim will crash when running out of stack space. Catch
- * this here if the system supports it.
- */
- mch_startjmp();
- if (SETJMP(lc_jump_env) != 0)
- {
- mch_didjmp();
-# ifdef SIGHASARG
- if (lc_signal != SIGINT)
-# endif
- EMSG(_("E361: Crash intercepted; regexp too complex?"));
- retval = 0L;
- goto theend;
- }
-
/* Trick to avoid "might be clobbered by `longjmp'" warning from gcc. */
line = line_arg;
col = col_arg;
@@ -3102,6 +3081,36 @@
goto theend;
}
+#ifdef HAVE_TRY_EXCEPT
+ __try
+ {
+#endif
+
+#ifdef HAVE_SETJMP_H
+ /*
+ * Matching with a regexp may cause a very deep recursive call of
+ * regmatch(). Vim will crash when running out of stack space. Catch
+ * this here if the system supports it.
+ * It's a bit slow, do it after the check for "regmust".
+ * Don't do it if the caller already set it up.
+ */
+ if (!lc_active)
+ {
+ did_mch_startjmp = TRUE;
+ mch_startjmp();
+ if (SETJMP(lc_jump_env) != 0)
+ {
+ mch_didjmp();
+# ifdef SIGHASARG
+ if (lc_signal != SIGINT)
+# endif
+ EMSG(_(e_complex));
+ retval = 0L;
+ goto inner_end;
+ }
+ }
+#endif
+
regline = line;
reglnum = 0;
out_of_stack = FALSE;
@@ -3168,8 +3177,12 @@
}
if (out_of_stack)
- EMSG(_("E363: pattern caused out-of-stack error"));
+ EMSG(_(e_outofstack));
+#ifdef HAVE_SETJMP_H
+inner_end:
+ ;
+#endif
#ifdef HAVE_TRY_EXCEPT
}
__except(EXCEPTION_EXECUTE_HANDLER)
@@ -3177,20 +3190,21 @@
if (GetExceptionCode() == EXCEPTION_STACK_OVERFLOW)
{
RESETSTKOFLW();
- EMSG(_("E363: pattern caused out-of-stack error"));
+ EMSG(_(e_outofstack));
}
else
- EMSG(_("E361: Crash intercepted; regexp too complex?"));
+ EMSG(_(e_complex));
retval = 0L;
}
#endif
+#ifdef HAVE_SETJMP_H
+ if (did_mch_startjmp)
+ mch_endjmp();
+#endif
theend:
/* Didn't find a match. */
vim_free(reg_tofree);
-#ifdef HAVE_SETJMP_H
- mch_endjmp();
-#endif
return retval;
}
diff --git a/src/structs.h b/src/structs.h
index 9d7bc92..ff4d2d6 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1015,9 +1015,12 @@
struct listvar_S
{
int lv_refcount; /* reference count */
+ int lv_len; /* number of items */
listitem_T *lv_first; /* first item, NULL if none */
listitem_T *lv_last; /* last item, NULL if none */
listwatch_T *lv_watch; /* first watcher, NULL if none */
+ int lv_idx; /* cached index of an item */
+ listitem_T *lv_idx_item; /* when not NULL item at index "lv_idx" */
char lv_lock; /* zero, VAR_LOCKED, VAR_FIXED */
};
diff --git a/src/version.h b/src/version.h
index 88aed5d..5b2e7d3 100644
--- a/src/version.h
+++ b/src/version.h
@@ -36,5 +36,5 @@
#define VIM_VERSION_NODOT "vim70aa"
#define VIM_VERSION_SHORT "7.0aa"
#define VIM_VERSION_MEDIUM "7.0aa ALPHA"
-#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2005 Jan 31)"
-#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2005 Jan 31, compiled "
+#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2005 Feb 2)"
+#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2005 Feb 2, compiled "