summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buffer.c23
-rw-r--r--src/charset.c2
-rw-r--r--src/digraph.c4
-rw-r--r--src/edit.c1
-rw-r--r--src/eval.c15
-rw-r--r--src/ex_cmds.c3
-rw-r--r--src/ex_cmds.h6
-rw-r--r--src/ex_cmds2.c60
-rw-r--r--src/ex_docmd.c66
-rw-r--r--src/ex_getln.c7
-rw-r--r--src/fileio.c3
-rw-r--r--src/fold.c10
-rw-r--r--src/gui_gtk.c3
-rw-r--r--src/if_xcmdsrv.c4
-rw-r--r--src/main.c2
-rw-r--r--src/mbyte.c4
-rw-r--r--src/menu.c1
-rw-r--r--src/message.c1
-rw-r--r--src/misc1.c39
-rw-r--r--src/misc2.c25
-rw-r--r--src/option.c9
-rw-r--r--src/os_mswin.c3
-rw-r--r--src/os_win32.c21
-rw-r--r--src/proto/buffer.pro1
-rw-r--r--src/proto/ex_cmds2.pro1
-rw-r--r--src/proto/ex_docmd.pro4
-rw-r--r--src/proto/quickfix.pro3
-rw-r--r--src/quickfix.c242
-rw-r--r--src/regexp.c5
-rw-r--r--src/structs.h3
-rw-r--r--src/syntax.c14
-rw-r--r--src/tag.c4
-rw-r--r--src/term.c3
33 files changed, 416 insertions, 176 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 4003b9c98..1ed7a0055 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1699,6 +1699,7 @@ free_buf_options(buf, free_p_ff)
clear_string_option(&buf->b_p_kp);
clear_string_option(&buf->b_p_mps);
clear_string_option(&buf->b_p_fo);
+ clear_string_option(&buf->b_p_flp);
clear_string_option(&buf->b_p_isk);
#ifdef FEAT_KEYMAP
clear_string_option(&buf->b_p_keymap);
@@ -2541,6 +2542,28 @@ setfname(buf, ffname, sfname, message)
}
/*
+ * Crude way of changing the name of a buffer. Use with care!
+ * The name should be relative to the current directory.
+ */
+ void
+buf_set_name(fnum, name)
+ int fnum;
+ char_u *name;
+{
+ buf_T *buf;
+
+ buf = buflist_findnr(fnum);
+ if (buf != NULL)
+ {
+ vim_free(buf->b_sfname);
+ vim_free(buf->b_ffname);
+ buf->b_sfname = vim_strsave(name);
+ buf->b_ffname = FullName_save(buf->b_sfname, FALSE);
+ buf->b_fname = buf->b_sfname;
+ }
+}
+
+/*
* Take care of what needs to be done when the name of buffer "buf" has
* changed.
*/
diff --git a/src/charset.c b/src/charset.c
index 4560a96d1..0a46306fc 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -415,7 +415,6 @@ str_foldcase(str, len)
mch_memmove(ga.ga_data, str, (size_t)len);
GA_CHAR(len) = NUL;
ga.ga_len = len;
- ga.ga_room -= len;
/* Make each character lower case. */
i = 0;
@@ -451,7 +450,6 @@ str_foldcase(str, len)
mch_memmove(GA_PTR(i) + nl, GA_PTR(i) + ol,
STRLEN(GA_PTR(i) + ol) + 1);
ga.ga_len += nl - ol;
- ga.ga_room -= nl - ol;
}
}
(void)utf_char2bytes(lc, GA_PTR(i));
diff --git a/src/digraph.c b/src/digraph.c
index 4c15d498c..31d7f3788 100644
--- a/src/digraph.c
+++ b/src/digraph.c
@@ -2230,7 +2230,6 @@ putdigraph(str)
dp->char2 = char2;
dp->result = n;
++user_digraphs.ga_len;
- --user_digraphs.ga_room;
}
}
}
@@ -2450,10 +2449,7 @@ ex_loadkeymap(eap)
vim_free(kp->to);
}
else
- {
++curbuf->b_kmap_ga.ga_len;
- --curbuf->b_kmap_ga.ga_room;
- }
}
vim_free(line);
}
diff --git a/src/edit.c b/src/edit.c
index a2ceb50f7..15812c7ff 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -2707,7 +2707,6 @@ expand_by_function(lnum, col, base, matches)
break;
((char_u **)ga.ga_data)[ga.ga_len] = vim_strnsave(p, len);
++ga.ga_len;
- --ga.ga_room;
}
if (*pnext != NUL)
++pnext;
diff --git a/src/eval.c b/src/eval.c
index e06fd167d..dcd86e519 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -5972,7 +5972,6 @@ f_inputrestore(argvars, retvar)
if (ga_userinput.ga_len > 0)
{
--ga_userinput.ga_len;
- ++ga_userinput.ga_room;
restore_typeahead((tasave_T *)(ga_userinput.ga_data)
+ ga_userinput.ga_len);
retvar->var_val.var_number = 0; /* OK */
@@ -5999,7 +5998,6 @@ f_inputsave(argvars, retvar)
save_typeahead((tasave_T *)(ga_userinput.ga_data)
+ ga_userinput.ga_len);
++ga_userinput.ga_len;
- --ga_userinput.ga_room;
retvar->var_val.var_number = 0; /* OK */
}
else
@@ -8092,7 +8090,6 @@ error:
ga_grow(&ga, cplen);
mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen);
ga.ga_len += cplen;
- ga.ga_room -= cplen;
instr += inlen;
}
@@ -9109,7 +9106,6 @@ new_script_vars(id)
{
var_init(&SCRIPT_VARS(ga_scripts.ga_len + 1));
++ga_scripts.ga_len;
- --ga_scripts.ga_room;
}
}
}
@@ -9269,10 +9265,7 @@ set_var(name, varp)
if ((v->var_name = vim_strsave(varname)) == NULL)
return;
if (i == gap->ga_len)
- {
++gap->ga_len;
- --gap->ga_room;
- }
}
copy_var(varp, v);
}
@@ -9441,12 +9434,8 @@ ex_execute(eap)
break;
}
if (ga.ga_len)
- {
((char_u *)(ga.ga_data))[ga.ga_len++] = ' ';
- --ga.ga_room;
- }
STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p);
- ga.ga_room -= len;
ga.ga_len += len;
}
@@ -9675,7 +9664,6 @@ ex_function(eap)
((char_u **)(newargs.ga_data))[newargs.ga_len] = arg;
*p = c;
newargs.ga_len++;
- newargs.ga_room--;
if (*p == ',')
++p;
else
@@ -9829,7 +9817,6 @@ ex_function(eap)
goto erret;
((char_u **)(newlines.ga_data))[newlines.ga_len] = theline;
newlines.ga_len++;
- newlines.ga_room--;
}
/* Don't define the function when skipping commands or when an error was
@@ -11398,7 +11385,6 @@ do_string_sub(str, pat, sub, flags)
(void)vim_regsub(&regmatch, sub, (char_u *)ga.ga_data
+ ga.ga_len + i, TRUE, TRUE, FALSE);
ga.ga_len += i + sublen - 1;
- ga.ga_room -= i + sublen - 1;
/* avoid getting stuck on a match with an empty string */
if (tail == regmatch.endp[0])
{
@@ -11406,7 +11392,6 @@ do_string_sub(str, pat, sub, flags)
break;
*((char_u *)ga.ga_data + ga.ga_len) = *tail++;
++ga.ga_len;
- --ga.ga_room;
}
else
{
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 7a176e066..adac95b83 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -5315,7 +5315,6 @@ ex_helptags(eap)
break;
((char_u *)ga.ga_data)[ga.ga_len++] = lang[0];
((char_u *)ga.ga_data)[ga.ga_len++] = lang[1];
- ga.ga_room -= 2;
}
}
}
@@ -5425,7 +5424,6 @@ helptags_one(dir, ext, tagfname)
sprintf((char *)s, "help-tags\t%s\t1\n", tagfname);
((char_u **)ga.ga_data)[ga.ga_len] = s;
++ga.ga_len;
- --ga.ga_room;
}
}
}
@@ -5516,7 +5514,6 @@ helptags_one(dir, ext, tagfname)
}
((char_u **)ga.ga_data)[ga.ga_len] = s;
++ga.ga_len;
- --ga.ga_room;
sprintf((char *)s, "%s\t%s", p1, fname);
/* find next '*' */
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index f59d0182e..b44dd1de2 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -190,6 +190,8 @@ EX(CMD_call, "call", ex_call,
RANGE|NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
EX(CMD_catch, "catch", ex_catch,
EXTRA|SBOXOK|CMDWIN),
+EX(CMD_cbuffer, "cbuffer", ex_cbuffer,
+ RANGE|NOTADR|WORD1|TRLBAR),
EX(CMD_cc, "cc", ex_cc,
RANGE|NOTADR|COUNT|TRLBAR|BANG),
EX(CMD_cclose, "cclose", ex_cclose,
@@ -838,6 +840,10 @@ EX(CMD_visual, "visual", ex_edit,
BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
EX(CMD_view, "view", ex_edit,
BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+EX(CMD_vimgrep, "vimgrep", ex_vimgrep,
+ EXTRA|TRLBAR|NEEDARG),
+EX(CMD_vimgrepadd, "vimgrepadd", ex_vimgrep,
+ EXTRA|TRLBAR|NEEDARG),
EX(CMD_viusage, "viusage", ex_viusage,
TRLBAR),
EX(CMD_vmap, "vmap", ex_map,
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index 715bf99eb..a1831332a 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -491,7 +491,6 @@ ex_breakadd(eap)
if (bp->dbg_lnum == 0) /* default line number is 1 */
bp->dbg_lnum = 1;
BREAKP(dbg_breakp.ga_len++).dbg_nr = ++last_breakp;
- --dbg_breakp.ga_room;
++debug_tick;
}
}
@@ -564,7 +563,6 @@ ex_breakdel(eap)
vim_free(BREAKP(todel).dbg_name);
vim_free(BREAKP(todel).dbg_prog);
--dbg_breakp.ga_len;
- ++dbg_breakp.ga_room;
if (todel < dbg_breakp.ga_len)
mch_memmove(&BREAKP(todel), &BREAKP(todel + 1),
(dbg_breakp.ga_len - todel) * sizeof(struct debuggy));
@@ -1063,6 +1061,31 @@ do_one_arg(str)
return str;
}
+/*
+ * Separate the arguments in "str" and return a list of pointers in the
+ * growarray "gap".
+ */
+ int
+get_arglist(gap, str)
+ garray_T *gap;
+ char_u *str;
+{
+ ga_init2(gap, (int)sizeof(char_u *), 20);
+ while (*str != NUL)
+ {
+ if (ga_grow(gap, 1) == FAIL)
+ {
+ ga_clear(gap);
+ return FAIL;
+ }
+ ((char_u **)gap->ga_data)[gap->ga_len++] = str;
+
+ /* Isolate one argument, change it in-place, put a NUL after it. */
+ str = do_one_arg(str);
+ }
+ return OK;
+}
+
#if defined(FEAT_GUI) || defined(FEAT_CLIENTSERVER) || defined(PROTO)
/*
* Redefine the argument list.
@@ -1101,20 +1124,8 @@ do_arglist(str, what, after)
/*
* Collect all file name arguments in "new_ga".
*/
- ga_init2(&new_ga, (int)sizeof(char_u *), 20);
- while (*str)
- {
- if (ga_grow(&new_ga, 1) == FAIL)
- {
- ga_clear(&new_ga);
- return FAIL;
- }
- ((char_u **)new_ga.ga_data)[new_ga.ga_len++] = str;
- --new_ga.ga_room;
-
- /* Isolate one argument, change it in-place, put a NUL after it. */
- str = do_one_arg(str);
- }
+ if (get_arglist(&new_ga, str) == FAIL)
+ return FAIL;
#ifdef FEAT_LISTCMDS
if (what == AL_DEL)
@@ -1154,7 +1165,6 @@ do_arglist(str, what, after)
mch_memmove(ARGLIST + match, ARGLIST + match + 1,
(ARGCOUNT - match - 1) * sizeof(aentry_T));
--ALIST(curwin)->al_ga.ga_len;
- ++ALIST(curwin)->al_ga.ga_room;
if (curwin->w_arg_idx > match)
--curwin->w_arg_idx;
--match;
@@ -1189,7 +1199,7 @@ do_arglist(str, what, after)
}
else /* what == AL_SET */
#endif
- alist_set(ALIST(curwin), exp_count, exp_files, FALSE);
+ alist_set(ALIST(curwin), exp_count, exp_files, FALSE, NULL, 0);
}
alist_check_arg_idx();
@@ -1342,7 +1352,6 @@ ex_args(eap)
AARGLIST(curwin->w_alist)[gap->ga_len].ae_fnum =
GARGLIST[i].ae_fnum;
++gap->ga_len;
- --gap->ga_room;
}
}
#endif
@@ -1579,7 +1588,6 @@ ex_argdelete(eap)
mch_memmove(ARGLIST + eap->line1 - 1, ARGLIST + eap->line2,
(size_t)((ARGCOUNT - eap->line2) * sizeof(aentry_T)));
ALIST(curwin)->al_ga.ga_len -= n;
- ALIST(curwin)->al_ga.ga_room += n;
if (curwin->w_arg_idx >= eap->line2)
curwin->w_arg_idx -= n;
else if (curwin->w_arg_idx > eap->line1)
@@ -1786,7 +1794,6 @@ alist_add_list(count, files, after)
ARGLIST[after + i].ae_fnum = buflist_add(files[i], BLN_LISTED);
}
ALIST(curwin)->al_ga.ga_len += count;
- ALIST(curwin)->al_ga.ga_room -= count;
if (curwin->w_arg_idx >= after)
++curwin->w_arg_idx;
return after;
@@ -2365,7 +2372,6 @@ do_source(fname, check_other, is_vimrc)
{
SCRIPT_NAME(script_names.ga_len + 1) = NULL;
++script_names.ga_len;
- --script_names.ga_room;
}
SCRIPT_NAME(current_SID) = fname_exp;
# ifdef UNIX
@@ -2674,12 +2680,14 @@ get_one_sourceline(sp)
#ifdef USE_CR
if (sp->fileformat == EOL_MAC)
{
- if (fgets_cr((char *)buf + ga.ga_len, ga.ga_room, sp->fp) == NULL)
+ if (fgets_cr((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
+ sp->fp) == NULL)
break;
}
else
#endif
- if (fgets((char *)buf + ga.ga_len, ga.ga_room, sp->fp) == NULL)
+ if (fgets((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
+ sp->fp) == NULL)
break;
len = (int)STRLEN(buf);
#ifdef USE_CRNL
@@ -2723,11 +2731,10 @@ get_one_sourceline(sp)
#endif
have_read = TRUE;
- ga.ga_room -= len - ga.ga_len;
ga.ga_len = len;
/* If the line was longer than the buffer, read more. */
- if (ga.ga_room == 1 && buf[len - 1] != '\n')
+ if (ga.ga_maxlen - ga.ga_len == 1 && buf[len - 1] != '\n')
continue;
if (len >= 1 && buf[len - 1] == '\n') /* remove trailing NL */
@@ -2749,7 +2756,6 @@ get_one_sourceline(sp)
buf[len - 2] = '\n';
--len;
--ga.ga_len;
- ++ga.ga_room;
}
else /* lines like ":map xx yy^M" will have failed */
{
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 82f90ddf7..3e5870bb9 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -112,12 +112,14 @@ static char_u *skip_cmd_arg __ARGS((char_u *p, int rembs));
static int getargopt __ARGS((exarg_T *eap));
#ifndef FEAT_QUICKFIX
# define ex_make ex_ni
+# define ex_cbuffer ex_ni
# define ex_cc ex_ni
# define ex_cnext ex_ni
# define ex_cfile ex_ni
# define qf_list ex_ni
# define qf_age ex_ni
# define ex_helpgrep ex_ni
+# define ex_vimgrep ex_ni
#endif
#if !defined(FEAT_QUICKFIX) || !defined(FEAT_WINDOWS)
# define ex_cclose ex_ni
@@ -1469,7 +1471,6 @@ store_while_line(gap, line)
((wcmd_T *)(gap->ga_data))[gap->ga_len].line = vim_strsave(line);
((wcmd_T *)(gap->ga_data))[gap->ga_len].lnum = sourcing_lnum;
++gap->ga_len;
- --gap->ga_room;
return OK;
}
@@ -1484,7 +1485,6 @@ free_cmdlines(gap)
{
vim_free(((wcmd_T *)(gap->ga_data))[gap->ga_len - 1].line);
--gap->ga_len;
- ++gap->ga_room;
}
}
#endif
@@ -2108,11 +2108,13 @@ do_one_cmd(cmdlinep, sourcing,
#ifdef FEAT_QUICKFIX
/*
- * For the :make and :grep commands we insert the 'makeprg'/'grepprg'
+ * For the ":make" and ":grep" commands we insert the 'makeprg'/'grepprg'
* option here, so things like % get expanded.
+ * Don't do it when ":vimgrep" is used for ":grep".
*/
- if (ea.cmdidx == CMD_make || ea.cmdidx == CMD_grep
- || ea.cmdidx == CMD_grepadd)
+ if ((ea.cmdidx == CMD_make
+ || ea.cmdidx == CMD_grep || ea.cmdidx == CMD_grepadd)
+ && !grep_internal(&ea))
{
char_u *new_cmdline;
char_u *program;
@@ -4200,7 +4202,20 @@ separate_nextcmd(eap)
{
char_u *p;
- for (p = eap->arg; *p; ++p)
+ p = eap->arg;
+#ifdef FEAT_QUICKFIX
+ if (eap->cmdidx == CMD_vimgrep
+ || eap->cmdidx == CMD_vimgrepadd
+ || grep_internal(eap))
+ {
+ /* Skip over the pattern. */
+ p = skip_regexp(p + 1, *p, TRUE, NULL);
+ if (*p == *eap->arg)
+ ++p;
+ }
+#endif
+
+ for ( ; *p; mb_ptr_adv(p))
{
if (*p == Ctrl_V)
{
@@ -4218,8 +4233,6 @@ separate_nextcmd(eap)
{
p += 2;
(void)skip_expr(&p);
- if (*p == '`')
- ++p;
}
#endif
@@ -4250,11 +4263,8 @@ separate_nextcmd(eap)
break;
}
}
-#ifdef FEAT_MBYTE
- else if (has_mbyte)
- p += (*mb_ptr2len_check)(p) - 1; /* skip bytes of multi-byte char */
-#endif
}
+
if (!(eap->argt & NOTRLCOM)) /* remove trailing spaces */
del_trailing_spaces(eap->arg);
}
@@ -4780,7 +4790,6 @@ uc_add_command(name, name_len, rep, argt, def, flags, compl, compl_arg, force)
mch_memmove(cmd + 1, cmd, (gap->ga_len - i) * sizeof(ucmd_T));
++gap->ga_len;
- --gap->ga_room;
cmd->uc_name = p;
}
@@ -5292,7 +5301,6 @@ ex_delcommand(eap)
# endif
--gap->ga_len;
- ++gap->ga_room;
if (i < gap->ga_len)
mch_memmove(cmd, cmd + 1, (gap->ga_len - i) * sizeof(ucmd_T));
@@ -6171,7 +6179,7 @@ handle_drop(filec, filev, split)
/*
* Set up the new argument list.
*/
- alist_set(ALIST(curwin), filec, filev, FALSE);
+ alist_set(ALIST(curwin), filec, filev, FALSE, NULL, 0);
/*
* Move to the first file.
@@ -6257,11 +6265,16 @@ alist_new()
#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE) || defined(PROTO)
/*
* Expand the file names in the global argument list.
+ * If "fnum_list" is not NULL, use "fnum_list[fnum_len]" as a list of buffer
+ * numbers to be re-used.
*/
void
-alist_expand()
+alist_expand(fnum_list, fnum_len)
+ int *fnum_list;
+ int fnum_len;
{
char_u **old_arg_files;
+ int old_arg_count;
char_u **new_arg_files;
int new_arg_file_count;
char_u *save_p_su = p_su;
@@ -6275,14 +6288,16 @@ alist_expand()
if (old_arg_files != NULL)
{
for (i = 0; i < GARGCOUNT; ++i)
- old_arg_files[i] = GARGLIST[i].ae_fname;
- if (expand_wildcards(GARGCOUNT, old_arg_files,
+ old_arg_files[i] = vim_strsave(GARGLIST[i].ae_fname);
+ old_arg_count = GARGCOUNT;
+ if (expand_wildcards(old_arg_count, old_arg_files,
&new_arg_file_count, &new_arg_files,
EW_FILE|EW_NOTFOUND|EW_ADDSLASH) == OK
&& new_arg_file_count > 0)
{
- alist_set(&global_alist, new_arg_file_count, new_arg_files, TRUE);
- vim_free(old_arg_files);
+ alist_set(&global_alist, new_arg_file_count, new_arg_files,
+ TRUE, fnum_list, fnum_len);
+ FreeWild(old_arg_count, old_arg_files);
}
}
p_su = save_p_su;
@@ -6294,11 +6309,13 @@ alist_expand()
* Takes over the allocated files[] and the allocated fnames in it.
*/
void
-alist_set(al, count, files, use_curbuf)
+alist_set(al, count, files, use_curbuf, fnum_list, fnum_len)
alist_T *al;
int count;
char_u **files;
int use_curbuf;
+ int *fnum_list;
+ int fnum_len;
{
int i;
@@ -6315,6 +6332,12 @@ alist_set(al, count, files, use_curbuf)
vim_free(files[i++]);
break;
}
+
+ /* May set buffer name of a buffer previously used for the
+ * argument list, so that it's re-used by alist_add. */
+ if (fnum_list != NULL && i < fnum_len)
+ buf_set_name(fnum_list[i], files[i]);
+
alist_add(al, files[i], use_curbuf ? 2 : 1);
ui_breakcheck();
}
@@ -6348,7 +6371,6 @@ alist_add(al, fname, set_fnum)
AARGLIST(al)[al->al_ga.ga_len].ae_fnum =
buflist_add(fname, BLN_LISTED | (set_fnum == 2 ? BLN_CURBUF : 0));
++al->al_ga.ga_len;
- --al->al_ga.ga_room;
}
#if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 8c153021a..103bf1b30 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -1964,7 +1964,6 @@ getexmodeline(c, dummy, indent)
char_u *q;
--line_ga.ga_len;
- ++line_ga.ga_room;
/* compute column that cursor should be in */
v = 0;
q = ((char_u *)line_ga.ga_data);
@@ -1992,7 +1991,6 @@ getexmodeline(c, dummy, indent)
{
msg_col = startcol;
msg_clr_eos();
- line_ga.ga_room += line_ga.ga_len;
line_ga.ga_len = 0;
continue;
}
@@ -2024,7 +2022,6 @@ getexmodeline(c, dummy, indent)
vcol += char2cells(c1);
}
++line_ga.ga_len;
- --line_ga.ga_room;
escaped = FALSE;
}
windgoto(msg_row, msg_col);
@@ -2036,7 +2033,6 @@ getexmodeline(c, dummy, indent)
#ifndef NO_COOKED_INPUT
{
line_ga.ga_len += len;
- line_ga.ga_room -= len;
}
#endif
p = (char_u *)(line_ga.ga_data) + line_ga.ga_len;
@@ -4122,7 +4118,6 @@ ExpandUserDefined(xp, regmatch, num_file, file)
((char_u **)ga.ga_data)[ga.ga_len] = vim_strnsave(s, (int)(e - s));
++ga.ga_len;
- --ga.ga_room;
*e = keep;
if (*e != NUL)
@@ -4179,7 +4174,6 @@ ExpandRTDir(pat, num_file, file, dirname)
((char_u **)ga.ga_data)[ga.ga_len] =
vim_strnsave(s, (int)(e - s - 4));
++ga.ga_len;
- --ga.ga_room;
}
if (*e != NUL)
++e;
@@ -4247,7 +4241,6 @@ globpath(path, file)
*cur++ = '\n';
}
ga.ga_len += len;
- ga.ga_room -= len;
}
FreeWild(num_p, p);
}
diff --git a/src/fileio.c b/src/fileio.c
index 98d9cffba..accd81cf0 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -6933,10 +6933,7 @@ au_new_group(name)
if (AUGROUP_NAME(i) == NULL)
return AUGROUP_ERROR;
if (i == augroups.ga_len)
- {
++augroups.ga_len;
- --augroups.ga_room;
- }
}
return i;
diff --git a/src/fold.c b/src/fold.c
index b1c7031f5..6c3334e2f 100644
--- a/src/fold.c
+++ b/src/fold.c
@@ -689,7 +689,6 @@ foldCreate(start, end)
/* Move contained folds to inside new fold. */
mch_memmove(fold_ga.ga_data, fp, sizeof(fold_T) * cont);
fold_ga.ga_len += cont;
- fold_ga.ga_room -= cont;
i += cont;
/* Adjust line numbers in contained folds to be relative to the
@@ -702,7 +701,6 @@ foldCreate(start, end)
mch_memmove(fp + 1, (fold_T *)gap->ga_data + i,
sizeof(fold_T) * (gap->ga_len - i));
gap->ga_len = gap->ga_len + 1 - cont;
- gap->ga_room = gap->ga_room - 1 + cont;
/* insert new fold */
fp->fd_nested = fold_ga;
@@ -1136,7 +1134,6 @@ cloneFoldGrowArray(from, to)
to_p->fd_small = from_p->fd_small;
cloneFoldGrowArray(&from_p->fd_nested, &to_p->fd_nested);
++to->ga_len;
- --to->ga_room;
++from_p;
++to_p;
}
@@ -1455,7 +1452,6 @@ deleteFoldEntry(gap, idx, recursive)
/* recursively delete the contained folds */
deleteFoldRecurse(&fp->fd_nested);
--gap->ga_len;
- ++gap->ga_room;
if (idx < gap->ga_len)
mch_memmove(fp, fp + 1, sizeof(fold_T) * (gap->ga_len - idx));
}
@@ -1485,7 +1481,6 @@ deleteFoldEntry(gap, idx, recursive)
mch_memmove(fp, nfp, (size_t)(sizeof(fold_T) * moved));
vim_free(nfp);
gap->ga_len += moved - 1;
- gap->ga_room -= moved - 1;
}
}
}
@@ -2762,7 +2757,6 @@ foldInsert(gap, i)
if (i < gap->ga_len)
mch_memmove(fp + 1, fp, sizeof(fold_T) * (gap->ga_len - i));
++gap->ga_len;
- --gap->ga_room;
ga_init2(&fp->fd_nested, (int)sizeof(fold_T), 10);
return OK;
}
@@ -2812,9 +2806,7 @@ foldSplit(gap, i, top, bot)
-= fp[1].fd_top - fp->fd_top;
}
gap2->ga_len = len;
- gap2->ga_room -= len;
gap1->ga_len -= len;
- gap1->ga_room += len;
}
fp->fd_len = top - fp->fd_top;
fold_changed = TRUE;
@@ -2931,10 +2923,8 @@ foldMerge(fp1, gap, fp2)
= ((fold_T *)gap2->ga_data)[idx];
((fold_T *)gap1->ga_data)[gap1->ga_len].fd_top += fp1->fd_len;
++gap1->ga_len;
- --gap1->ga_room;
}
gap2->ga_len = 0;
- /* fp2->fd_nested.ga_room isn't updated, we delete it below */
}
fp1->fd_len += fp2->fd_len;
diff --git a/src/gui_gtk.c b/src/gui_gtk.c
index 4e4c1d97f..e97dc4f4d 100644
--- a/src/gui_gtk.c
+++ b/src/gui_gtk.c
@@ -1348,6 +1348,8 @@ gui_mch_browse(int saving,
return vim_strsave(p);
}
+#if defined(HAVE_GTK2) || defined(PROTO)
+
/*
* Put up a directory selector
* Returns the selected name in allocated memory, or NULL for Cancel.
@@ -1416,6 +1418,7 @@ gui_mch_browsedir(
return gui_mch_browse(0, title, NULL, NULL, initdir, NULL);
# endif
}
+#endif
#endif /* FEAT_BROWSE */
diff --git a/src/if_xcmdsrv.c b/src/if_xcmdsrv.c
index b24101f3f..4a091bd27 100644
--- a/src/if_xcmdsrv.c
+++ b/src/if_xcmdsrv.c
@@ -735,7 +735,6 @@ ServerReplyFind(w, op)
ga_init2(&e.strings, 1, 100);
memcpy(p, &e, sizeof(e));
serverReply.ga_len++;
- serverReply.ga_room--;
}
}
else if (p != NULL && op == SROP_Delete)
@@ -743,7 +742,6 @@ ServerReplyFind(w, op)
ga_clear(&p->strings);
mch_memmove(p, p + 1, (serverReply.ga_len - i - 1) * sizeof(*p));
serverReply.ga_len--;
- serverReply.ga_room++;
}
return p;
@@ -844,7 +842,6 @@ serverReadReply(dpy, win, str, localLoop)
{
s = (char_u *) p->strings.ga_data;
mch_memmove(s, s + len, p->strings.ga_len - len);
- p->strings.ga_room += len;
p->strings.ga_len -= len;
}
else
@@ -1276,7 +1273,6 @@ serverEventProc(dpy, eventPtr)
sprintf(reply.ga_data, "%cr%c-s %s%c-r ", 0, 0, serial, 0);
#endif
reply.ga_len = 10 + STRLEN(serial);
- reply.ga_room -= reply.ga_len;
}
res = NULL;
if (serverName != NULL && STRICMP(name, serverName) == 0)
diff --git a/src/main.c b/src/main.c
index b35aaf9e0..d71ef605f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1137,7 +1137,7 @@ scripterror:
* filename characters but are excluded from 'isfname' to make
* "gf" work on a file name in parenthesis (e.g.: see vim.h). */
do_cmdline_cmd((char_u *)":set isf+=(,)");
- alist_expand();
+ alist_expand(NULL, 0);
do_cmdline_cmd((char_u *)":set isf&");
}
#endif
diff --git a/src/mbyte.c b/src/mbyte.c
index e739a5b04..8b997af0c 100644
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -692,11 +692,7 @@ codepage_invalid:
/* When changing 'encoding' while starting up, then convert the command
* line arguments from the active codepage to 'encoding'. */
if (starting != 0)
- {
- extern void fix_arg_enc(void);
-
fix_arg_enc();
- }
#endif
#ifdef FEAT_AUTOCMD
diff --git a/src/menu.c b/src/menu.c
index aeb3c61c2..17d437121 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -2306,7 +2306,6 @@ ex_menutranslate(eap)
tp[menutrans_ga.ga_len].from_noamp = from_noamp;
tp[menutrans_ga.ga_len].to = to;
++menutrans_ga.ga_len;
- --menutrans_ga.ga_room;
}
else
{
diff --git a/src/message.c b/src/message.c
index 6a2386478..58e4ffb80 100644
--- a/src/message.c
+++ b/src/message.c
@@ -2275,7 +2275,6 @@ mch_errmsg(str)
#endif
--len; /* don't count the NUL at the end */
error_ga.ga_len += len;
- error_ga.ga_room -= len;
}
}
diff --git a/src/misc1.c b/src/misc1.c
index 891fbb5cc..0bdcce8b1 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -382,30 +382,36 @@ copy_indent(size, src)
/*
* Return the indent of the current line after a number. Return -1 if no
* number was found. Used for 'n' in 'formatoptions': numbered list.
+ * Since a pattern is used it can actually handle more than numbers.
*/
int
get_number_indent(lnum)
linenr_T lnum;
{
- char_u *line;
- char_u *p;
colnr_T col;
pos_T pos;
+ regmmatch_T regmatch;
if (lnum > curbuf->b_ml.ml_line_count)
return -1;
- line = ml_get(lnum);
- p = skipwhite(line);
- if (!VIM_ISDIGIT(*p))
- return -1;
- p = skipdigits(p);
- if (vim_strchr((char_u *)":.)]}\t ", *p) == NULL)
- return -1;
- p = skipwhite(p + 1);
- if (*p == NUL)
+ pos.lnum = 0;
+ regmatch.regprog = vim_regcomp(curbuf->b_p_flp, RE_MAGIC);
+ if (regmatch.regprog != NULL)
+ {
+ regmatch.rmm_ic = FALSE;
+ if (vim_regexec_multi(&regmatch, curwin, curbuf, lnum, (colnr_T)0))
+ {
+ pos.lnum = regmatch.endpos[0].lnum + lnum;
+ pos.col = regmatch.endpos[0].col;
+#ifdef FEAT_VIRTUALEDIT
+ pos.coladd = 0;
+#endif
+ }
+ vim_free(regmatch.regprog);
+ }
+
+ if (pos.lnum == 0 || *ml_get_pos(&pos) == NUL)
return -1;
- pos.lnum = lnum;
- pos.col = (colnr_T)(p - line);
getvcol(curwin, &pos, &col, NULL, NULL);
return (int)col;
}
@@ -3804,9 +3810,9 @@ remove_tail_with_ext(p, pend, ext)
char_u *newend = pend - len;
if (newend >= p && fnamencmp(newend, ext, len - 1) == 0)
- while (newend != p && !after_pathsep(newend))
- mb_ptr_back(newend);
- if (newend == p || after_pathsep(newend))
+ while (newend > p && !after_pathsep(p, newend))
+ mb_ptr_back(p, newend);
+ if (newend == p || after_pathsep(p, newend))
return newend;
return pend;
}
@@ -8447,7 +8453,6 @@ addfile(gap, f, flags)
add_pathsep(p);
#endif
((char_u **)gap->ga_data)[gap->ga_len++] = p;
- --gap->ga_room;
}
#endif /* !NO_EXPANDPATH */
diff --git a/src/misc2.c b/src/misc2.c
index 7a8502603..30e1a1f01 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -1525,7 +1525,7 @@ ga_init(gap)
garray_T *gap;
{
gap->ga_data = NULL;
- gap->ga_room = 0;
+ gap->ga_maxlen = 0;
gap->ga_len = 0;
}
@@ -1552,7 +1552,7 @@ ga_grow(gap, n)
size_t len;
char_u *pp;
- if (gap->ga_room < n)
+ if (gap->ga_maxlen - gap->ga_len < n)
{
if (n < gap->ga_growsize)
n = gap->ga_growsize;
@@ -1560,7 +1560,7 @@ ga_grow(gap, n)
pp = alloc_clear((unsigned)len);
if (pp == NULL)
return FAIL;
- gap->ga_room = n;
+ gap->ga_maxlen = gap->ga_len + n;
if (gap->ga_data != NULL)
{
mch_memmove(pp, gap->ga_data,
@@ -1587,7 +1587,6 @@ ga_concat(gap, s)
{
mch_memmove((char *)gap->ga_data + gap->ga_len, s, (size_t)len);
gap->ga_len += len;
- gap->ga_room -= len;
}
}
@@ -1603,7 +1602,6 @@ ga_append(gap, c)
{
*((char *)gap->ga_data + gap->ga_len) = c;
++gap->ga_len;
- --gap->ga_room;
}
}
@@ -5224,7 +5222,7 @@ pathcmp(p, q, maxlen)
int maxlen;
{
int i;
- const char *s;
+ const char *s = NULL;
for (i = 0; maxlen < 0 || i < maxlen; ++i)
{
@@ -5264,18 +5262,19 @@ pathcmp(p, q, maxlen)
return ((char_u *)p)[i] - ((char_u *)q)[i]; /* no match */
}
}
+ if (s == NULL) /* "i" ran into "maxlen" */
+ return 0;
/* ignore a trailing slash, but not "//" or ":/" */
- if (i >= maxlen
- || (s[i + 1] == NUL
- && i > 0
- && !after_pathsep((char_u *)s, (char_u *)s + i)
+ if (s[i + 1] == NUL
+ && i > 0
+ && !after_pathsep((char_u *)s, (char_u *)s + i)
#ifdef BACKSLASH_IN_FILENAME
- && (s[i] == '/' || s[i] == '\\')
+ && (s[i] == '/' || s[i] == '\\')
#else
- && s[i] == '/'
+ && s[i] == '/'
#endif
- ))
+ )
return 0; /* match with trailing slash */
if (s == q)
return -1; /* no match */
diff --git a/src/option.c b/src/option.c
index 3cb91a4f7..2bfeec3a2 100644
--- a/src/option.c
+++ b/src/option.c
@@ -82,6 +82,7 @@ typedef enum
, PV_FF
, PV_FML
, PV_FMR
+ , PV_FLP
, PV_FO
, PV_FT
, PV_GP
@@ -183,6 +184,7 @@ static char_u *p_fenc;
#endif
static char_u *p_ff;
static char_u *p_fo;
+static char_u *p_flp;
#ifdef FEAT_AUTOCMD
static char_u *p_ft;
#endif
@@ -952,6 +954,9 @@ static struct vimoption
{"formatoptions","fo", P_STRING|P_ALLOCED|P_VIM|P_FLAGLIST,
(char_u *)&p_fo, PV_FO,
{(char_u *)DFLT_FO_VI, (char_u *)DFLT_FO_VIM}},
+ {"formatlistpat","flp", P_STRING|P_ALLOCED|P_VI_DEF,
+ (char_u *)&p_flp, PV_FLP,
+ {(char_u *)"^\\s*\\d\\+[\\]:.)}\\t ]\\s*", (char_u *)0L}},
{"formatprg", "fp", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
(char_u *)&p_fp, PV_NONE,
{(char_u *)"", (char_u *)0L}},
@@ -2636,7 +2641,6 @@ set_init_1()
STRCAT(ga.ga_data, p);
add_pathsep(ga.ga_data);
STRCAT(ga.ga_data, "*");
- ga.ga_room -= len;
ga.ga_len += len;
}
}
@@ -4487,6 +4491,7 @@ check_buf_options(buf)
check_string_option(&buf->b_p_kp);
check_string_option(&buf->b_p_mps);
check_string_option(&buf->b_p_fo);
+ check_string_option(&buf->b_p_flp);
check_string_option(&buf->b_p_isk);
#ifdef FEAT_COMMENTS
check_string_option(&buf->b_p_com);
@@ -8082,6 +8087,7 @@ get_varp(p)
case PV_FT: return (char_u *)&(curbuf->b_p_ft);
#endif
case PV_FO: return (char_u *)&(curbuf->b_p_fo);
+ case PV_FLP: return (char_u *)&(curbuf->b_p_flp);
case PV_IMI: return (char_u *)&(curbuf->b_p_iminsert);
case PV_IMS: return (char_u *)&(curbuf->b_p_imsearch);
case PV_INF: return (char_u *)&(curbuf->b_p_inf);
@@ -8404,6 +8410,7 @@ buf_copy_options(buf, flags)
buf->b_p_cms = vim_strsave(p_cms);
#endif
buf->b_p_fo = vim_strsave(p_fo);
+ buf->b_p_flp = vim_strsave(p_flp);
buf->b_p_nf = vim_strsave(p_nf);
buf->b_p_mps = vim_strsave(p_mps);
#ifdef FEAT_SMARTINDENT
diff --git a/src/os_mswin.c b/src/os_mswin.c
index cea1054f5..f2a6c905b 100644
--- a/src/os_mswin.c
+++ b/src/os_mswin.c
@@ -2908,7 +2908,6 @@ static garray_T reply_list = {0, 0, sizeof(reply_T), 5, 0};
#define REPLY_ITEM(i) ((reply_T *)(reply_list.ga_data) + (i))
#define REPLY_COUNT (reply_list.ga_len)
-#define REPLY_ROOM (reply_list.ga_room)
/* Flag which is used to wait for a reply */
static int reply_received = 0;
@@ -2932,7 +2931,6 @@ save_reply(HWND server, char_u *reply, int expr)
return FAIL;
++REPLY_COUNT;
- --REPLY_ROOM;
reply_received = 1;
return OK;
}
@@ -2976,7 +2974,6 @@ serverGetReply(HWND server, int *expr_res, int remove, int wait)
mch_memmove(rep, rep + 1,
(REPLY_COUNT - i - 1) * sizeof(reply_T));
--REPLY_COUNT;
- ++REPLY_ROOM;
}
/* Return the reply to the caller, who takes on responsibility
diff --git a/src/os_win32.c b/src/os_win32.c
index 40544b20c..a50f5d994 100644
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -4988,6 +4988,7 @@ fix_arg_enc(void)
int i;
int idx;
char_u *str;
+ int *fnum_list;
/* Safety checks:
* - if argument count differs between the wide and non-wide argument
@@ -5002,17 +5003,31 @@ fix_arg_enc(void)
|| used_alist_count != GARGCOUNT)
return;
+ /* Remember the buffer numbers for the arguments. */
+ fnum_list = (int *)alloc((int)sizeof(int) * GARGCOUNT);
+ if (fnum_list == NULL)
+ return; /* out of memory */
+ for (i = 0; i < GARGCOUNT; ++i)
+ fnum_list[i] = GARGLIST[i].ae_fnum;
+
/* Clear the argument list. Make room for the new arguments. */
alist_clear(&global_alist);
if (ga_grow(&global_alist.al_ga, used_file_count) == FAIL)
- return; /* out of memory */
+ return; /* out of memory */
for (i = 0; i < used_file_count; ++i)
{
idx = used_file_indexes[i];
str = ucs2_to_enc(ArglistW[idx], NULL);
if (str != NULL)
+ {
+ /* Re-use the old buffer by renaming it. When not using literal
+ * names it's done by alist_expand() below. */
+ if (used_file_literal)
+ buf_set_name(fnum_list[i], str);
+
alist_add(&global_alist, str, used_file_literal ? 2 : 0);
+ }
}
if (!used_file_literal)
@@ -5022,7 +5037,7 @@ fix_arg_enc(void)
* filename characters but are excluded from 'isfname' to make
* "gf" work on a file name in parenthesis (e.g.: see vim.h). */
do_cmdline_cmd((char_u *)":let SaVe_ISF = &isf|set isf+=(,)");
- alist_expand();
+ alist_expand(fnum_list, used_alist_count);
do_cmdline_cmd((char_u *)":let &isf = SaVe_ISF|unlet SaVe_ISF");
}
@@ -5034,5 +5049,7 @@ fix_arg_enc(void)
if (GARGCOUNT == 1 && used_file_full_path)
(void)vim_chdirfile(alist_name(&GARGLIST[0]));
}
+
+ set_alist_count();
}
#endif
diff --git a/src/proto/buffer.pro b/src/proto/buffer.pro
index 861fba271..4f00e9c00 100644
--- a/src/proto/buffer.pro
+++ b/src/proto/buffer.pro
@@ -25,6 +25,7 @@ linenr_T buflist_findlnum __ARGS((buf_T *buf));
void buflist_list __ARGS((exarg_T *eap));
int buflist_name_nr __ARGS((int fnum, char_u **fname, linenr_T *lnum));
int setfname __ARGS((buf_T *buf, char_u *ffname, char_u *sfname, int message));
+void buf_set_name __ARGS((int fnum, char_u *name));
void buf_name_changed __ARGS((buf_T *buf));
buf_T *setaltfname __ARGS((char_u *ffname, char_u *sfname, linenr_T lnum));
char_u *getaltfname __ARGS((int errmsg));
diff --git a/src/proto/ex_cmds2.pro b/src/proto/ex_cmds2.pro
index c66c702b2..304bbef8a 100644
--- a/src/proto/ex_cmds2.pro
+++ b/src/proto/ex_cmds2.pro
@@ -18,6 +18,7 @@ int can_abandon __ARGS((buf_T *buf, int forceit));
int check_changed_any __ARGS((int hidden));
int check_fname __ARGS((void));
int buf_write_all __ARGS((buf_T *buf, int forceit));
+int get_arglist __ARGS((garray_T *gap, char_u *str));
void set_arglist __ARGS((char_u *str));
void check_arg_idx __ARGS((win_T *win));
void ex_args __ARGS((exarg_T *eap));
diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro
index b6f3b7a7a..9fabda446 100644
--- a/src/proto/ex_docmd.pro
+++ b/src/proto/ex_docmd.pro
@@ -25,8 +25,8 @@ void alist_clear __ARGS((alist_T *al));
void alist_init __ARGS((alist_T *al));
void alist_unlink __ARGS((alist_T *al));
void alist_new __ARGS((void));
-void alist_expand __ARGS((void));
-void alist_set __ARGS((alist_T *al, int count, char_u **files, int use_curbuf));
+void alist_expand __ARGS((int *fnum_list, int fnum_len));
+void alist_set __ARGS((alist_T *al, int count, char_u **files, int use_curbuf, int *fnum_list, int fnum_len));
void alist_add __ARGS((alist_T *al, char_u *fname, int set_fnum));
void alist_slash_adjust __ARGS((void));
void ex_splitview __ARGS((exarg_T *eap));
diff --git a/src/proto/quickfix.pro b/src/proto/quickfix.pro
index c1d619dc0..adec72f0f 100644
--- a/src/proto/quickfix.pro
+++ b/src/proto/quickfix.pro
@@ -13,9 +13,12 @@ int bt_nofile __ARGS((buf_T *buf));
int bt_dontwrite __ARGS((buf_T *buf));
int bt_dontwrite_msg __ARGS((buf_T *buf));
int buf_hide __ARGS((buf_T *buf));
+int grep_internal __ARGS((exarg_T *eap));
void ex_make __ARGS((exarg_T *eap));
void ex_cc __ARGS((exarg_T *eap));
void ex_cnext __ARGS((exarg_T *eap));
void ex_cfile __ARGS((exarg_T *eap));
+void ex_vimgrep __ARGS((exarg_T *eap));
+void ex_cbuffer __ARGS((exarg_T *eap));
void ex_helpgrep __ARGS((exarg_T *eap));
/* vim: set ft=c : */
diff --git a/src/quickfix.c b/src/quickfix.c
index 0cb9c6956..dbde1550f 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -86,6 +86,7 @@ struct eformat
/* '-' do not include this line */
};
+static int qf_init_ext __ARGS((char_u *efile, buf_T *buf, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast));
static void qf_new_list __ARGS((void));
static int qf_add_entry __ARGS((struct qf_line **prevp, char_u *dir, char_u *fname, char_u *mesg, long lnum, int col, int virt_col, int nr, int type, int valid));
static void qf_msg __ARGS((void));
@@ -106,7 +107,8 @@ static void qf_fill_buffer __ARGS((void));
static char_u *get_mef_name __ARGS((void));
/*
- * Read the errorfile into memory, line by line, building the error list.
+ * Read the errorfile "efile" into memory, line by line, building the error
+ * list.
* Return -1 for error, number of errors for success.
*/
int
@@ -115,6 +117,29 @@ qf_init(efile, errorformat, newlist)
char_u *errorformat;
int newlist; /* TRUE: start a new error list */
{
+ if (efile == NULL)
+ return FAIL;
+ return qf_init_ext(efile, curbuf, errorformat, newlist,
+ (linenr_T)0, (linenr_T)0);
+}
+
+/*
+ * Read the errorfile "efile" into memory, line by line, building the error
+ * list.
+ * Alternative: when "efile" is null read errors from buffer "buf".
+ * Always use 'errorformat' from "buf" if there is a local value.
+ * Then lnumfirst and lnumlast specify the range of lines to use.
+ * Return -1 for error, number of errors for success.
+ */
+ static int
+qf_init_ext(efile, buf, errorformat, newlist, lnumfirst, lnumlast)
+ char_u *efile;
+ buf_T *buf;
+ char_u *errorformat;
+ int newlist; /* TRUE: start a new error list */
+ linenr_T lnumfirst; /* first line number to use */
+ linenr_T lnumlast; /* last line number to use */
+{
char_u *namebuf;
char_u *errmsg;
char_u *fmtstr = NULL;
@@ -122,9 +147,10 @@ qf_init(efile, errorformat, newlist)
char_u use_virt_col = FALSE;
int type = 0;
int valid;
+ linenr_T buflnum = lnumfirst;
long lnum = 0L;
int enr = 0;
- FILE *fd;
+ FILE *fd = NULL;
struct qf_line *qfprev = NULL; /* init to make SASC shut up */
char_u *efmp;
struct eformat *fmt_first = NULL;
@@ -163,15 +189,12 @@ qf_init(efile, errorformat, newlist)
{'v', "\\d\\+"}
};
- if (efile == NULL)
- return FAIL;
-
namebuf = alloc(CMDBUFFSIZE + 1);
errmsg = alloc(CMDBUFFSIZE + 1);
if (namebuf == NULL || errmsg == NULL)
goto qf_init_end;
- if ((fd = mch_fopen((char *)efile, "r")) == NULL)
+ if (efile != NULL && (fd = mch_fopen((char *)efile, "r")) == NULL)
{
EMSG2(_(e_openerrf), efile);
goto qf_init_end;
@@ -191,8 +214,8 @@ qf_init(efile, errorformat, newlist)
* regex prog. Only a few % characters are allowed.
*/
/* Use the local value of 'errorformat' if it's set. */
- if (errorformat == p_efm && *curbuf->b_p_efm != NUL)
- efm = curbuf->b_p_efm;
+ if (errorformat == p_efm && *buf->b_p_efm != NUL)
+ efm = buf->b_p_efm;
else
efm = errorformat;
/*
@@ -405,8 +428,18 @@ qf_init(efile, errorformat, newlist)
* Read the lines in the error file one by one.
* Try to recognize one of the error formats in each line.
*/
- while (fgets((char *)IObuff, CMDBUFFSIZE - 2, fd) != NULL && !got_int)
+ while (!got_int)
{
+ /* Get the next line. */
+ if (fd == NULL)
+ {
+ if (buflnum > lnumlast)
+ break;
+ STRNCPY(IObuff, ml_get_buf(buf, buflnum++, FALSE), CMDBUFFSIZE - 2);
+ }
+ else if (fgets((char *)IObuff, CMDBUFFSIZE - 2, fd) == NULL)
+ break;
+
IObuff[CMDBUFFSIZE - 2] = NUL; /* for very long lines */
if ((efmp = vim_strrchr(IObuff, '\n')) != NULL)
*efmp = NUL;
@@ -594,7 +627,7 @@ restofline:
goto error2;
line_breakcheck();
}
- if (!ferror(fd))
+ if (fd == NULL || !ferror(fd))
{
if (qf_lists[qf_curlist].qf_index == 0) /* no valid entry found */
{
@@ -618,7 +651,8 @@ error2:
if (qf_curlist > 0)
--qf_curlist;
qf_init_ok:
- fclose(fd);
+ if (fd != NULL)
+ fclose(fd);
for (fmt_ptr = fmt_first; fmt_ptr != NULL; fmt_ptr = fmt_first)
{
fmt_first = fmt_ptr->next;
@@ -2026,6 +2060,18 @@ buf_hide(buf)
}
/*
+ * Return TRUE when using ":vimgrep" for ":grep".
+ */
+ int
+grep_internal(eap)
+ exarg_T *eap;
+{
+ return ((eap->cmdidx == CMD_grep || eap->cmdidx == CMD_grepadd)
+ && STRCMP("internal",
+ *curbuf->b_p_gp == NUL ? p_gp : curbuf->b_p_gp) == 0);
+}
+
+/*
* Used for ":make", ":grep" and ":grepadd".
*/
void
@@ -2036,6 +2082,13 @@ ex_make(eap)
char_u *cmd;
unsigned len;
+ /* Redirect ":grep" to ":vimgrep" if 'grepprg' is "internal". */
+ if (grep_internal(eap))
+ {
+ ex_vimgrep(eap);
+ return;
+ }
+
autowrite_all();
name = get_mef_name();
if (name == NULL)
@@ -2075,7 +2128,7 @@ ex_make(eap)
#endif
if (qf_init(name, eap->cmdidx != CMD_make ? p_gefm : p_efm,
- eap->cmdidx != CMD_grepadd) > 0
+ eap->cmdidx != CMD_grepadd) > 0
&& !eap->forceit)
qf_jump(0, 0, FALSE); /* display first error */
@@ -2190,6 +2243,171 @@ ex_cfile(eap)
}
/*
+ * ":vimgrep {pattern} file(s)"
+ */
+ void
+ex_vimgrep(eap)
+ exarg_T *eap;
+{
+ regmatch_T regmatch;
+ char_u *save_cpo;
+ int fcount;
+ char_u **fnames;
+ char_u *p;
+ int i;
+ FILE *fd;
+ int fi;
+ struct qf_line *prevp = NULL;
+ long lnum;
+ garray_T ga;
+
+ /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
+ save_cpo = p_cpo;
+ p_cpo = empty_option;
+
+ /* Get the search pattern */
+ regmatch.regprog = NULL;
+ p = skip_regexp(eap->arg + 1, *eap->arg, TRUE, NULL);
+ if (*p != *eap->arg)
+ {
+ EMSG(_("E682: Invalid search pattern or delimiter"));
+ goto theend;
+ }
+ *p++ = NUL;
+ regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC);
+ if (regmatch.regprog == NULL)
+ goto theend;
+ regmatch.rm_ic = FALSE;
+
+ p = skipwhite(p);
+ if (*p == NUL)
+ {
+ EMSG(_("E683: File name missing or invalid pattern"));
+ goto theend;
+ }
+
+ if ((eap->cmdidx != CMD_grepadd && eap->cmdidx != CMD_vimgrepadd)
+ || qf_curlist == qf_listcount)
+ /* make place for a new list */
+ qf_new_list();
+ else if (qf_lists[qf_curlist].qf_count > 0)
+ /* Adding to existing list, find last entry. */
+ for (prevp = qf_lists[qf_curlist].qf_start;
+ prevp->qf_next != prevp; prevp = prevp->qf_next)
+ ;
+
+ /* parse the list of arguments */
+ if (get_arglist(&ga, p) == FAIL)
+ goto theend;
+ i = gen_expand_wildcards(ga.ga_len, (char_u **)ga.ga_data,
+ &fcount, &fnames, EW_FILE|EW_NOTFOUND);
+ ga_clear(&ga);
+ if (i == FAIL)
+ goto theend;
+ if (fcount == 0)
+ {
+ EMSG(_(e_nomatch));
+ goto theend;
+ }
+
+ for (fi = 0; fi < fcount && !got_int; ++fi)
+ {
+ fd = fopen((char *)fnames[fi], "r");
+ if (fd == NULL)
+ smsg((char_u *)_("Cannot open file \"%s\""), fnames[fi]);
+ else
+ {
+ lnum = 1;
+ while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int)
+ {
+ if (vim_regexec(&regmatch, IObuff, (colnr_T)0))
+ {
+ int l = STRLEN(IObuff);
+
+ /* remove trailing CR, LF, spaces, etc. */
+ while (l > 0 && IObuff[l - 1] <= ' ')
+ IObuff[--l] = NUL;
+
+ if (qf_add_entry(&prevp,
+ NULL, /* dir */
+ fnames[fi],
+ IObuff,
+ lnum,
+ (int)(regmatch.startp[0] - IObuff) + 1,/* col */
+ FALSE, /* virt_col */
+ 0, /* nr */
+ 0, /* type */
+ TRUE /* valid */
+ ) == FAIL)
+ {
+ got_int = TRUE;
+ break;
+ }
+ }
+ ++lnum;
+ line_breakcheck();
+ }
+ fclose(fd);
+ }
+ }
+
+ FreeWild(fcount, fnames);
+
+ qf_lists[qf_curlist].qf_nonevalid = FALSE;
+ qf_lists[qf_curlist].qf_ptr = qf_lists[qf_curlist].qf_start;
+ qf_lists[qf_curlist].qf_index = 1;
+
+#ifdef FEAT_WINDOWS
+ qf_update_buffer();
+#endif
+
+ /* Jump to first match. */
+ if (qf_lists[qf_curlist].qf_count > 0)
+ qf_jump(0, 0, FALSE);
+
+theend:
+ vim_free(regmatch.regprog);
+
+ /* Only resture 'cpo' when it wasn't set in the mean time. */
+ if (p_cpo == empty_option)
+ p_cpo = save_cpo;
+ else
+ free_string_option(save_cpo);
+}
+
+/*
+ * ":[range]cbuffer [bufnr]" command.
+ */
+ void
+ex_cbuffer(eap)
+ exarg_T *eap;
+{
+ buf_T *buf = NULL;
+
+ if (*eap->arg == NUL)
+ buf = curbuf;
+ else if (*skipwhite(skipdigits(eap->arg)) == NUL)
+ buf = buflist_findnr(atoi((char *)eap->arg));
+ if (buf == NULL)
+ EMSG(_(e_invarg));
+ else if (buf->b_ml.ml_mfp == NULL)
+ EMSG(_("E681: Buffer is not loaded"));
+ else
+ {
+ if (eap->addr_count == 0)
+ {
+ eap->line1 = 1;
+ eap->line2 = buf->b_ml.ml_line_count;
+ }
+ if (eap->line1 < 1 || eap->line1 > buf->b_ml.ml_line_count
+ || eap->line2 < 1 || eap->line2 > buf->b_ml.ml_line_count)
+ EMSG(_(e_invrange));
+ else
+ qf_init_ext(NULL, buf, p_efm, TRUE, eap->line1, eap->line2);
+ }
+}
+
+/*
* ":helpgrep {pattern}"
*/
void
diff --git a/src/regexp.c b/src/regexp.c
index 2e828541a..4aa5b6aba 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' of where 'dirc' is found ('/', '?', etc).
+ * Stop at end of 'p' 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
@@ -787,7 +787,8 @@ skip_regexp(startp, dirc, magic, newp)
}
/*
- * vim_regcomp - compile a regular expression into internal code
+ * vim_regcomp() - compile a regular expression into internal code
+ * Returns the program in allocated space. Returns NULL for an error.
*
* We can't allocate space until we know how big the compiled form will be,
* but we can't compile it (and thus know how big it is) until we've got a
diff --git a/src/structs.h b/src/structs.h
index 84b1a2471..3d713935b 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -55,7 +55,7 @@ typedef struct
typedef struct growarray
{
int ga_len; /* current number of items used */
- int ga_room; /* number of unused items at the end */
+ int ga_maxlen; /* maximum number of items possible */
int ga_itemsize; /* sizeof(item) */
int ga_growsize; /* number of items to grow each time */
void *ga_data; /* pointer to the first item */
@@ -1127,6 +1127,7 @@ struct file_buffer
char_u *b_p_ft; /* 'filetype' */
#endif
char_u *b_p_fo; /* 'formatoptions' */
+ char_u *b_p_flp; /* 'formatlistpat' */
int b_p_inf; /* 'infercase' */
char_u *b_p_isk; /* 'iskeyword' */
#ifdef FEAT_FIND_ID
diff --git a/src/syntax.c b/src/syntax.c
index 0c706c82d..91ef7cdf7 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -1394,10 +1394,7 @@ store_current_state(sp)
if (ga_grow(&sp->sst_union.sst_ga, current_state.ga_len) == FAIL)
sp->sst_stacksize = 0;
else
- {
sp->sst_union.sst_ga.ga_len = current_state.ga_len;
- sp->sst_union.sst_ga.ga_room -= current_state.ga_len;
- }
bp = SYN_STATE_P(&(sp->sst_union.sst_ga));
}
else
@@ -1454,7 +1451,6 @@ load_current_state(from)
update_si_attr(i);
}
current_state.ga_len = from->sst_stacksize;
- current_state.ga_room -= current_state.ga_len;
}
current_next_list = from->sst_next_list;
current_next_flags = from->sst_next_flags;
@@ -2089,7 +2085,6 @@ syn_current_attr(syncing, displaying)
{
((int *)(zero_width_next_ga.ga_data))
[zero_width_next_ga.ga_len++] = next_match_idx;
- --zero_width_next_ga.ga_room;
}
next_match_idx = -1;
}
@@ -2579,7 +2574,6 @@ push_current_state(idx)
vim_memset(&CUR_STATE(current_state.ga_len), 0, sizeof(stateitem_T));
CUR_STATE(current_state.ga_len).si_idx = idx;
++current_state.ga_len;
- --current_state.ga_room;
return OK;
}
@@ -2593,7 +2587,6 @@ pop_current_state()
{
unref_extmatch(CUR_STATE(current_state.ga_len - 1).si_extmatch);
--current_state.ga_len;
- ++current_state.ga_room;
}
/* after the end of a pattern, try matching a keyword or pattern */
next_match_idx = -1;
@@ -3151,7 +3144,6 @@ syn_remove_pattern(buf, idx)
mch_memmove(spp, spp + 1,
sizeof(synpat_T) * (buf->b_syn_patterns.ga_len - idx - 1));
--buf->b_syn_patterns.ga_len;
- --buf->b_syn_patterns.ga_room;
}
/*
@@ -4499,7 +4491,6 @@ syn_cmd_match(eap, syncing)
curbuf->b_syn_containedin = TRUE;
SYN_ITEMS(curbuf)[idx].sp_next_list = next_list;
++curbuf->b_syn_patterns.ga_len;
- --curbuf->b_syn_patterns.ga_room;
/* remember that we found a match for syncing on */
if (flags & (HL_SYNC_HERE|HL_SYNC_THERE))
@@ -4742,7 +4733,6 @@ syn_cmd_region(eap, syncing)
SYN_ITEMS(curbuf)[idx].sp_next_list = next_list;
}
++curbuf->b_syn_patterns.ga_len;
- --curbuf->b_syn_patterns.ga_room;
++idx;
#ifdef FEAT_FOLDING
if (flags & HL_FOLD)
@@ -5033,7 +5023,6 @@ syn_add_cluster(name)
SYN_CLSTR(curbuf)[len].scl_name_u = vim_strsave_up(name);
SYN_CLSTR(curbuf)[len].scl_list = NULL;
++curbuf->b_syn_clusters.ga_len;
- --curbuf->b_syn_clusters.ga_room;
return len + SYNID_CLUSTER;
}
@@ -7467,7 +7456,6 @@ get_attr_entry(table, aep)
gap->ae_u.cterm.bg_color = aep->ae_u.cterm.bg_color;
}
++table->ga_len;
- --table->ga_room;
return (table->ga_len - 1 + ATTR_OFF);
}
@@ -7972,7 +7960,6 @@ syn_add_group(name)
HL_TABLE()[highlight_ga.ga_len].sg_gui_fg = INVALCOLOR;
#endif
++highlight_ga.ga_len;
- --highlight_ga.ga_room;
return highlight_ga.ga_len; /* ID is index plus one */
}
@@ -7985,7 +7972,6 @@ syn_add_group(name)
syn_unadd_group()
{
--highlight_ga.ga_len;
- ++highlight_ga.ga_room;
vim_free(HL_TABLE()[highlight_ga.ga_len].sg_name);
vim_free(HL_TABLE()[highlight_ga.ga_len].sg_name_u);
}
diff --git a/src/tag.c b/src/tag.c
index b72cf03df..a3bed7a80 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -2174,7 +2174,6 @@ line_read_in:
{
((struct match_found **)(ga_match[mtt].ga_data))
[ga_match[mtt].ga_len++] = mfp;
- ga_match[mtt].ga_room--;
++match_count;
}
else
@@ -2345,11 +2344,8 @@ found_tagfile_cb(fname)
char_u *fname;
{
if (ga_grow(&tag_fnames, 1) == OK)
- {
((char_u **)(tag_fnames.ga_data))[tag_fnames.ga_len++] =
vim_strsave(fname);
- --tag_fnames.ga_room;
- }
}
/*
diff --git a/src/term.c b/src/term.c
index 8144fad53..a471c1e0c 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2978,6 +2978,9 @@ check_shellsize()
Rows = min_rows();
}
+/*
+ * Invoked just before the screen structures are going to be (re)allocated.
+ */
void
win_new_shellsize()
{