summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/eval.txt33
-rw-r--r--runtime/doc/netbeans.txt3
-rw-r--r--runtime/doc/tags2
-rw-r--r--runtime/ftplugin/vhdl.vim41
-rw-r--r--src/ex_docmd.c63
-rw-r--r--src/fileio.c45
-rw-r--r--src/globals.h4
-rw-r--r--src/gui_w32.c57
-rw-r--r--src/gui_w48.c1
-rw-r--r--src/os_mswin.c5
-rw-r--r--src/proto/fileio.pro2
-rw-r--r--src/quickfix.c79
-rw-r--r--src/regexp.c72
-rw-r--r--src/structs.h3
-rw-r--r--src/version.h4
15 files changed, 301 insertions, 113 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index dc58f1cd7..034276b13 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1,4 +1,4 @@
-*eval.txt* For Vim version 7.0aa. Last change: 2005 Jan 31
+*eval.txt* For Vim version 7.0aa. Last change: 2005 Feb 02
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -80,8 +80,8 @@ Note that in the command >
"foo" is converted to 0, which means FALSE. To test for a non-empty string,
use strlen(): >
:if strlen("foo")
-< *E728* *E729* *E730* *E731*
-List and Funcref types are not automatically converted.
+< *E745* *E728* *E703* *E729* *E730* *E731*
+List, Dictionary and Funcref types are not automatically converted.
*E706*
You will get an error if you try to change the type of a variable. You need
@@ -93,7 +93,7 @@ equivalent though. Consider this sequence of commands: >
1.2 Function references ~
- *Funcref* *E695* *E703* *E718*
+ *Funcref* *E695* *E718*
A Funcref variable is obtained with the |function()| function. It can be used
in an expression in the place of a function name, before the parenthesis
around the arguments, to invoke the function it refers to. Example: >
@@ -1560,11 +1560,11 @@ add({list}, {expr}) *add()*
append({lnum}, {expr}) *append()*
- When {expr} is a List: Append each item of the list as a text
+ When {expr} is a List: Append each item of the List as a text
line below line {lnum} in the current buffer.
- Otherwise append the text line {expr} below line {lnum} in the
- current buffer.
- {lnum} can be zero, to insert a line before the first one.
+ Otherwise append {expr} as one text line below line {lnum} in
+ the current buffer.
+ {lnum} can be zero to insert a line before the first one.
Returns 1 for failure ({lnum} out of range or out of memory),
0 for success. Example: >
:let failed = append(line('$'), "# THE END")
@@ -2683,7 +2683,8 @@ indent({lnum}) The result is a Number, which is indent of line {lnum} in the
index({list}, {expr} [, {start} [, {ic}]]) *index()*
Return the lowest index in List {list} where the item has a
value equal to {expr}.
- If {start} is given then skip items with a lower index.
+ If {start} is given then start looking at the item with index
+ {start} (may be negative for an item relative to the end).
When {ic} is given and it is non-zero, ignore case. Otherwise
case must match.
-1 is returned when {expr} is not found in {list}.
@@ -3762,15 +3763,17 @@ tr({src}, {fromstr}, {tostr}) *tr()*
*type()*
type({expr}) The result is a Number, depending on the type of {expr}:
- Number: 0
- String: 1
- Funcref: 2
- List: 3
- To avoid the magic numbers it can be used this way: >
+ Number: 0
+ String: 1
+ Funcref: 2
+ List: 3
+ Dictionary: 4
+ To avoid the magic numbers it should be used this way: >
:if type(myvar) == type(0)
:if type(myvar) == type("")
:if type(myvar) == type(function("tr"))
:if type(myvar) == type([])
+ :if type(myvar) == type({})
values({dict}) *values()*
Return a List with all the values of {dict}. The List is in
@@ -4358,7 +4361,7 @@ This would call the function "my_func_whizz(parameter)".
When the selected range of items is partly past the
end of the list, items will be added.
- *:let+=* *:let-=* *:let.=*
+ *:let+=* *:let-=* *:let.=* *E734*
:let {var} += {expr1} Like ":let {var} = {var} + {expr1}".
:let {var} -= {expr1} Like ":let {var} = {var} - {expr1}".
:let {var} .= {expr1} Like ":let {var} = {var} . {expr1}".
diff --git a/runtime/doc/netbeans.txt b/runtime/doc/netbeans.txt
index 11c24a687..5007122d0 100644
--- a/runtime/doc/netbeans.txt
+++ b/runtime/doc/netbeans.txt
@@ -560,6 +560,9 @@ stopCaretListen
stopDocumentListen
Mark the buffer to stop reporting changes to the IDE.
Opposite of startDocumentListen.
+ NOTE: if "netbeansBuffer" was used to mark this buffer as a
+ NetBeans buffer, then the buffer is deleted in Vim. This is
+ for compatibility with Sun Studio 10.
unguard off len
Opposite of "guard", remove guarding for a text area.
diff --git a/runtime/doc/tags b/runtime/doc/tags
index 227d1f307..c8e765fcc 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -3639,6 +3639,7 @@ E730 eval.txt /*E730*
E731 eval.txt /*E731*
E732 eval.txt /*E732*
E733 eval.txt /*E733*
+E734 eval.txt /*E734*
E735 eval.txt /*E735*
E736 eval.txt /*E736*
E737 eval.txt /*E737*
@@ -3650,6 +3651,7 @@ E741 eval.txt /*E741*
E742 eval.txt /*E742*
E743 eval.txt /*E743*
E744 netbeans.txt /*E744*
+E745 eval.txt /*E745*
E75 vi_diff.txt /*E75*
E76 pattern.txt /*E76*
E77 message.txt /*E77*
diff --git a/runtime/ftplugin/vhdl.vim b/runtime/ftplugin/vhdl.vim
new file mode 100644
index 000000000..3e4ca4b60
--- /dev/null
+++ b/runtime/ftplugin/vhdl.vim
@@ -0,0 +1,41 @@
+" Vim filetype plugin file
+" Language: VHDL
+" Maintainer: R.Shankar (shankar at txc.stpn.soft.net)
+" Last Change: Tue Oct 8
+
+
+" Only do this when not done yet for this buffer
+if exists("b:did_ftplugin")
+ finish
+endif
+
+" Don't load another plugin for this buffer
+let b:did_ftplugin = 1
+
+" Set 'formatoptions' to break comment lines but not other lines,
+" and insert the comment leader when hitting <CR> or using "o".
+"setlocal fo-=t fo+=croqlm1
+
+" Set 'comments' to format dashed lists in comments.
+"setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
+
+" Format comments to be up to 78 characters long
+setlocal tw=75
+
+set cpo-=C
+
+" Win32 can filter files in the browse dialog
+"if has("gui_win32") && !exists("b:browsefilter")
+" let b:browsefilter = "Verilog Source Files (*.v)\t*.v\n" .
+" \ "All Files (*.*)\t*.*\n"
+"endif
+
+" Let the matchit plugin know what items can be matched.
+if ! exists("b:match_words") && exists("loaded_matchit")
+ let b:match_ignorecase=1
+ let s:notend = '\%(\<end\s\+\)\@<!'
+ let b:match_words=
+ \ s:notend . '\<if\>:\<elsif\>:\<else\>:\<end\>\s\+\<if\>,' .
+ \ s:notend . '\<case\>:\<when\>:\<end\>\s\+\<case\>,' .
+ \ s:notend . '\<process\>:\<end\>\s\+\<process\>'
+endif
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 53194496f..5cecf30c6 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -3180,13 +3180,7 @@ set_one_cmd_context(xp, buff)
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 @@ correct_range(eap)
}
}
+#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 @@ expand_filename(eap, cmdlinep, errormsgp)
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 @@ separate_nextcmd(eap)
{
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 c888f3533..ee1c90b88 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -6585,7 +6585,7 @@ typedef struct AutoPat
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 @@ au_cleanup()
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 @@ au_event_restore(old_ei)
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 @@ do_autocmd_event(event, pat, nested, cmd, forceit, group)
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 @@ auto_next_pat(apc, stop_at_last)
{
/* 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 @@ has_autocmd(event, sfname, buf)
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 @@ au_exists(name, name_end, pattern)
#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 @@ match_file_pat(pattern, fname, sfname, tail, allow_dirs)
}
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 @@ match_file_pat(pattern, fname, sfname, tail, allow_dirs)
|| (!allow_dirs && vim_regexec(&regmatch, tail, (colnr_T)0)))))
result = TRUE;
- vim_free(regmatch.regprog);
+ if (prog == NULL)
+ vim_free(regmatch.regprog);
return result;
}
#endif
@@ -8667,7 +8679,8 @@ match_file_list(list, sfname, ffname)
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 555c19e4e..1df8b87fe 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1402,6 +1402,10 @@ EXTERN char_u e_nbreadonly[] INIT(=N_("E744: NetBeans does not allow changes in
#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 7e6354932..a29de9d26 100644
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -991,13 +991,10 @@ gui_mch_init(void)
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 @@ gui_mch_init(void)
s_findrep_struct.wReplaceWithLen = MSWIN_FR_BUFSIZE;
#endif
+theend:
+ /* Display any pending error messages */
+ display_errors();
+
return OK;
}
@@ -2540,6 +2541,8 @@ gui_mch_dialog(
int fontHeight;
int textWidth, minButtonWidth, messageWidth;
int maxDialogWidth;
+ int maxDialogHeight;
+ int scroll_flag = 0;
int vertical;
int dlgPaddingX;
int dlgPaddingY;
@@ -2554,9 +2557,14 @@ gui_mch_dialog(
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 @@ gui_mch_dialog(
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 @@ gui_mch_dialog(
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 @@ gui_mch_dialog(
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 @@ gui_mch_dialog(
(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 00b5e6665..2e0965583 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 f2a6c905b..f5c4abf4a 100644
--- a/src/os_mswin.c
+++ b/src/os_mswin.c
@@ -595,11 +595,16 @@ display_errors()
#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 d7c80956c..68594ba8f 100644
--- a/src/proto/fileio.pro
+++ b/src/proto/fileio.pro
@@ -38,7 +38,7 @@ char_u *get_augroup_name __ARGS((expand_T *xp, int idx));
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 2a2ee14c4..a4110035f 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -2256,12 +2256,12 @@ ex_vimgrep(eap)
{
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 @@ ex_vimgrep(eap)
/* 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 @@ ex_vimgrep(eap)
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(&regmatch, curwin, buf, lnum,
@@ -2419,6 +2429,10 @@ ex_vimgrep(eap)
if (got_int)
break;
}
+#ifdef HAVE_SETJMP_H
+jumpend:
+ mch_endjmp();
+#endif
if (using_dummy)
{
@@ -2453,10 +2467,12 @@ ex_vimgrep(eap)
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 @@ theend:
}
/*
+ * 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 4aa5b6aba..a9915a3b1 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -726,7 +726,7 @@ re_lookbehind(prog)
/*
* 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 @@ vim_regexec_both(line, col)
#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 @@ vim_regexec_both(line, col)
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 @@ vim_regexec_both(line, col)
}
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 @@ vim_regexec_both(line, col)
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 9d7bc9205..ff4d2d64e 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1015,9 +1015,12 @@ struct listwatch_S
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 88aed5dda..5b2e7d363 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 "