diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buffer.c | 23 | ||||
-rw-r--r-- | src/charset.c | 2 | ||||
-rw-r--r-- | src/digraph.c | 4 | ||||
-rw-r--r-- | src/edit.c | 1 | ||||
-rw-r--r-- | src/eval.c | 15 | ||||
-rw-r--r-- | src/ex_cmds.c | 3 | ||||
-rw-r--r-- | src/ex_cmds.h | 6 | ||||
-rw-r--r-- | src/ex_cmds2.c | 60 | ||||
-rw-r--r-- | src/ex_docmd.c | 66 | ||||
-rw-r--r-- | src/ex_getln.c | 7 | ||||
-rw-r--r-- | src/fileio.c | 3 | ||||
-rw-r--r-- | src/fold.c | 10 | ||||
-rw-r--r-- | src/gui_gtk.c | 3 | ||||
-rw-r--r-- | src/if_xcmdsrv.c | 4 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/mbyte.c | 4 | ||||
-rw-r--r-- | src/menu.c | 1 | ||||
-rw-r--r-- | src/message.c | 1 | ||||
-rw-r--r-- | src/misc1.c | 39 | ||||
-rw-r--r-- | src/misc2.c | 25 | ||||
-rw-r--r-- | src/option.c | 9 | ||||
-rw-r--r-- | src/os_mswin.c | 3 | ||||
-rw-r--r-- | src/os_win32.c | 21 | ||||
-rw-r--r-- | src/proto/buffer.pro | 1 | ||||
-rw-r--r-- | src/proto/ex_cmds2.pro | 1 | ||||
-rw-r--r-- | src/proto/ex_docmd.pro | 4 | ||||
-rw-r--r-- | src/proto/quickfix.pro | 3 | ||||
-rw-r--r-- | src/quickfix.c | 242 | ||||
-rw-r--r-- | src/regexp.c | 5 | ||||
-rw-r--r-- | src/structs.h | 3 | ||||
-rw-r--r-- | src/syntax.c | 14 | ||||
-rw-r--r-- | src/tag.c | 4 | ||||
-rw-r--r-- | src/term.c | 3 |
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(®match, 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(®match, 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(®match, 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); } @@ -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() { |