mirror of
https://github.com/vim/vim
synced 2025-07-16 09:12:00 +00:00
patch 9.1.0426: too many strlen() calls in search.c
Problem: too many strlen() calls in search.c Solution: refactor code and remove more strlen() calls, use explicit variable to remember strlen (John Marriott) closes: #14796 Signed-off-by: John Marriott <basilisk@internode.on.net> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
69dff00dfb
commit
8c85a2a49a
@ -297,11 +297,11 @@ static int last_maptick = -1; // last seen maptick
|
||||
add_to_history(
|
||||
int histype,
|
||||
char_u *new_entry,
|
||||
size_t new_entrylen,
|
||||
int in_map, // consider maptick when inside a mapping
|
||||
int sep) // separator character used (search hist)
|
||||
{
|
||||
histentry_T *hisptr;
|
||||
int len;
|
||||
|
||||
if (hislen == 0) // no history
|
||||
return;
|
||||
@ -336,10 +336,9 @@ add_to_history(
|
||||
vim_free(hisptr->hisstr);
|
||||
|
||||
// Store the separator after the NUL of the string.
|
||||
len = (int)STRLEN(new_entry);
|
||||
hisptr->hisstr = vim_strnsave(new_entry, len + 2);
|
||||
hisptr->hisstr = vim_strnsave(new_entry, new_entrylen + 2);
|
||||
if (hisptr->hisstr != NULL)
|
||||
hisptr->hisstr[len + 1] = sep;
|
||||
hisptr->hisstr[new_entrylen + 1] = sep;
|
||||
|
||||
hisptr->hisnum = ++hisnum[histype];
|
||||
hisptr->viminfo = FALSE;
|
||||
@ -566,7 +565,7 @@ f_histadd(typval_T *argvars UNUSED, typval_T *rettv)
|
||||
return;
|
||||
|
||||
init_history();
|
||||
add_to_history(histype, str, FALSE, NUL);
|
||||
add_to_history(histype, str, STRLEN(str), FALSE, NUL);
|
||||
rettv->vval.v_number = TRUE;
|
||||
}
|
||||
|
||||
|
@ -9712,6 +9712,7 @@ search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
|
||||
{
|
||||
int flags;
|
||||
char_u *pat;
|
||||
size_t patlen;
|
||||
pos_T pos;
|
||||
pos_T save_cursor;
|
||||
int save_p_ws = p_ws;
|
||||
@ -9786,10 +9787,12 @@ search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
|
||||
sia.sa_tm = time_limit;
|
||||
#endif
|
||||
|
||||
patlen = STRLEN(pat);
|
||||
|
||||
// Repeat until {skip} returns FALSE.
|
||||
for (;;)
|
||||
{
|
||||
subpatnum = searchit(curwin, curbuf, &pos, NULL, dir, pat, 1L,
|
||||
subpatnum = searchit(curwin, curbuf, &pos, NULL, dir, pat, patlen, 1L,
|
||||
options, RE_SEARCH, &sia);
|
||||
// finding the first match again means there is no match where {skip}
|
||||
// evaluates to zero.
|
||||
@ -10202,6 +10205,13 @@ do_searchpair(
|
||||
{
|
||||
char_u *save_cpo;
|
||||
char_u *pat, *pat2 = NULL, *pat3 = NULL;
|
||||
size_t patlen;
|
||||
size_t spatlen;
|
||||
size_t epatlen;
|
||||
size_t pat2size;
|
||||
size_t pat2len;
|
||||
size_t pat3size;
|
||||
size_t pat3len;
|
||||
long retval = 0;
|
||||
pos_T pos;
|
||||
pos_T firstpos;
|
||||
@ -10221,15 +10231,24 @@ do_searchpair(
|
||||
|
||||
// Make two search patterns: start/end (pat2, for in nested pairs) and
|
||||
// start/middle/end (pat3, for the top pair).
|
||||
pat2 = alloc(STRLEN(spat) + STRLEN(epat) + 17);
|
||||
pat3 = alloc(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 25);
|
||||
if (pat2 == NULL || pat3 == NULL)
|
||||
spatlen = STRLEN(spat);
|
||||
epatlen = STRLEN(epat);
|
||||
pat2size = spatlen + epatlen + 17;
|
||||
pat2 = alloc(pat2size);
|
||||
if (pat2 == NULL)
|
||||
goto theend;
|
||||
sprintf((char *)pat2, "\\m\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
|
||||
pat3size = spatlen + STRLEN(mpat) + epatlen + 25;
|
||||
pat3 = alloc(pat3size);
|
||||
if (pat3 == NULL)
|
||||
goto theend;
|
||||
pat2len = vim_snprintf((char *)pat2, pat2size, "\\m\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
|
||||
if (*mpat == NUL)
|
||||
{
|
||||
STRCPY(pat3, pat2);
|
||||
pat3len = pat2len;
|
||||
}
|
||||
else
|
||||
sprintf((char *)pat3, "\\m\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)",
|
||||
pat3len = vim_snprintf((char *)pat3, pat3size, "\\m\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)",
|
||||
spat, epat, mpat);
|
||||
if (flags & SP_START)
|
||||
options |= SEARCH_START;
|
||||
@ -10246,13 +10265,14 @@ do_searchpair(
|
||||
CLEAR_POS(&firstpos);
|
||||
CLEAR_POS(&foundpos);
|
||||
pat = pat3;
|
||||
patlen = pat3len;
|
||||
for (;;)
|
||||
{
|
||||
searchit_arg_T sia;
|
||||
|
||||
CLEAR_FIELD(sia);
|
||||
sia.sa_stop_lnum = lnum_stop;
|
||||
n = searchit(curwin, curbuf, &pos, NULL, dir, pat, 1L,
|
||||
n = searchit(curwin, curbuf, &pos, NULL, dir, pat, patlen, 1L,
|
||||
options, RE_SEARCH, &sia);
|
||||
if (n == FAIL || (firstpos.lnum != 0 && EQUAL_POS(pos, firstpos)))
|
||||
// didn't find it or found the first match again: FAIL
|
||||
|
@ -3750,6 +3750,7 @@ ex_substitute(exarg_T *eap)
|
||||
int save_do_all; // remember user specified 'g' flag
|
||||
int save_do_ask; // remember user specified 'c' flag
|
||||
char_u *pat = NULL, *sub = NULL; // init for GCC
|
||||
size_t patlen = 0;
|
||||
int delimiter;
|
||||
int sublen;
|
||||
int got_quit = FALSE;
|
||||
@ -3823,6 +3824,7 @@ ex_substitute(exarg_T *eap)
|
||||
if (*cmd != '&')
|
||||
which_pat = RE_SEARCH; // use last '/' pattern
|
||||
pat = (char_u *)""; // empty search pattern
|
||||
patlen = 0;
|
||||
delimiter = *cmd++; // remember delimiter character
|
||||
}
|
||||
else // find the end of the regexp
|
||||
@ -3830,6 +3832,7 @@ ex_substitute(exarg_T *eap)
|
||||
which_pat = RE_LAST; // use last used regexp
|
||||
delimiter = *cmd++; // remember delimiter character
|
||||
pat = cmd; // remember start of search pat
|
||||
patlen = STRLEN(pat);
|
||||
cmd = skip_regexp_ex(cmd, delimiter, magic_isset(),
|
||||
&eap->arg, NULL, NULL);
|
||||
if (cmd[0] == delimiter) // end delimiter found
|
||||
@ -3883,6 +3886,7 @@ ex_substitute(exarg_T *eap)
|
||||
return;
|
||||
}
|
||||
pat = NULL; // search_regcomp() will use previous pattern
|
||||
patlen = 0;
|
||||
sub = vim_strsave(old_sub);
|
||||
|
||||
// Vi compatibility quirk: repeating with ":s" keeps the cursor in the
|
||||
@ -3929,9 +3933,9 @@ ex_substitute(exarg_T *eap)
|
||||
}
|
||||
|
||||
if ((cmdmod.cmod_flags & CMOD_KEEPPATTERNS) == 0)
|
||||
save_re_pat(RE_SUBST, pat, magic_isset());
|
||||
save_re_pat(RE_SUBST, pat, patlen, magic_isset());
|
||||
// put pattern in history
|
||||
add_to_history(HIST_SEARCH, pat, TRUE, NUL);
|
||||
add_to_history(HIST_SEARCH, pat, patlen, TRUE, NUL);
|
||||
vim_free(sub);
|
||||
|
||||
return;
|
||||
@ -4066,7 +4070,7 @@ ex_substitute(exarg_T *eap)
|
||||
return;
|
||||
}
|
||||
|
||||
if (search_regcomp(pat, NULL, RE_SUBST, which_pat, SEARCH_HIS, ®match) == FAIL)
|
||||
if (search_regcomp(pat, patlen, NULL, RE_SUBST, which_pat, SEARCH_HIS, ®match) == FAIL)
|
||||
{
|
||||
if (subflags.do_error)
|
||||
emsg(_(e_invalid_command));
|
||||
@ -5104,6 +5108,7 @@ ex_global(exarg_T *eap)
|
||||
|
||||
char_u delim; // delimiter, normally '/'
|
||||
char_u *pat;
|
||||
size_t patlen;
|
||||
char_u *used_pat;
|
||||
regmmatch_T regmatch;
|
||||
int match;
|
||||
@ -5150,6 +5155,7 @@ ex_global(exarg_T *eap)
|
||||
which_pat = RE_SEARCH; // use previous search pattern
|
||||
++cmd;
|
||||
pat = (char_u *)"";
|
||||
patlen = 0;
|
||||
}
|
||||
else if (*cmd == NUL)
|
||||
{
|
||||
@ -5165,12 +5171,13 @@ ex_global(exarg_T *eap)
|
||||
delim = *cmd; // get the delimiter
|
||||
++cmd; // skip delimiter if there is one
|
||||
pat = cmd; // remember start of pattern
|
||||
patlen = STRLEN(pat);
|
||||
cmd = skip_regexp_ex(cmd, delim, magic_isset(), &eap->arg, NULL, NULL);
|
||||
if (cmd[0] == delim) // end delimiter found
|
||||
*cmd++ = NUL; // replace it with a NUL
|
||||
}
|
||||
|
||||
if (search_regcomp(pat, &used_pat, RE_BOTH, which_pat, SEARCH_HIS,
|
||||
if (search_regcomp(pat, patlen, &used_pat, RE_BOTH, which_pat, SEARCH_HIS,
|
||||
®match) == FAIL)
|
||||
{
|
||||
emsg(_(e_invalid_command));
|
||||
|
@ -4567,7 +4567,7 @@ get_address(
|
||||
curwin->w_cursor.col = 0;
|
||||
searchcmdlen = 0;
|
||||
flags = silent ? 0 : SEARCH_HIS | SEARCH_MSG;
|
||||
if (!do_search(NULL, c, c, cmd, 1L, flags, NULL))
|
||||
if (!do_search(NULL, c, c, cmd, STRLEN(cmd), 1L, flags, NULL))
|
||||
{
|
||||
curwin->w_cursor = pos;
|
||||
cmd = NULL;
|
||||
@ -4621,7 +4621,7 @@ get_address(
|
||||
pos.coladd = 0;
|
||||
if (searchit(curwin, curbuf, &pos, NULL,
|
||||
*cmd == '?' ? BACKWARD : FORWARD,
|
||||
(char_u *)"", 1L, SEARCH_MSG, i, NULL) != FAIL)
|
||||
(char_u *)"", 0, 1L, SEARCH_MSG, i, NULL) != FAIL)
|
||||
lnum = pos.lnum;
|
||||
else
|
||||
{
|
||||
|
@ -493,7 +493,7 @@ may_do_incsearch_highlighting(
|
||||
sia.sa_tm = 500;
|
||||
#endif
|
||||
found = do_search(NULL, firstc == ':' ? '/' : firstc, search_delim,
|
||||
ccline.cmdbuff + skiplen, count, search_flags,
|
||||
ccline.cmdbuff + skiplen, patlen, count, search_flags,
|
||||
#ifdef FEAT_RELTIME
|
||||
&sia
|
||||
#else
|
||||
@ -654,7 +654,7 @@ may_adjust_incsearch_highlighting(
|
||||
pat[patlen] = NUL;
|
||||
i = searchit(curwin, curbuf, &t, NULL,
|
||||
c == Ctrl_G ? FORWARD : BACKWARD,
|
||||
pat, count, search_flags, RE_SEARCH, NULL);
|
||||
pat, patlen, count, search_flags, RE_SEARCH, NULL);
|
||||
--emsg_off;
|
||||
pat[patlen] = save;
|
||||
if (i)
|
||||
@ -2539,12 +2539,14 @@ returncmd:
|
||||
if (ccline.cmdlen && firstc != NUL
|
||||
&& (some_key_typed || histype == HIST_SEARCH))
|
||||
{
|
||||
add_to_history(histype, ccline.cmdbuff, TRUE,
|
||||
size_t cmdbufflen = STRLEN(ccline.cmdbuff);
|
||||
|
||||
add_to_history(histype, ccline.cmdbuff, cmdbufflen, TRUE,
|
||||
histype == HIST_SEARCH ? firstc : NUL);
|
||||
if (firstc == ':')
|
||||
{
|
||||
vim_free(new_last_cmdline);
|
||||
new_last_cmdline = vim_strsave(ccline.cmdbuff);
|
||||
new_last_cmdline = vim_strnsave(ccline.cmdbuff, cmdbufflen);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5312,7 +5312,7 @@ gui_do_findrepl(
|
||||
i = msg_scroll;
|
||||
if (down)
|
||||
{
|
||||
(void)do_search(NULL, '/', '/', ga.ga_data, 1L, searchflags, NULL);
|
||||
(void)do_search(NULL, '/', '/', ga.ga_data, STRLEN(ga.ga_data), 1L, searchflags, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -5320,7 +5320,7 @@ gui_do_findrepl(
|
||||
// direction
|
||||
p = vim_strsave_escaped(ga.ga_data, (char_u *)"?");
|
||||
if (p != NULL)
|
||||
(void)do_search(NULL, '?', '?', p, 1L, searchflags, NULL);
|
||||
(void)do_search(NULL, '?', '?', p, STRLEN(p), 1L, searchflags, NULL);
|
||||
vim_free(p);
|
||||
}
|
||||
|
||||
|
@ -176,6 +176,7 @@ static int ctrl_x_mode = CTRL_X_NORMAL;
|
||||
|
||||
static int compl_matches = 0; // number of completion matches
|
||||
static char_u *compl_pattern = NULL;
|
||||
static size_t compl_patternlen = 0;
|
||||
static int compl_direction = FORWARD;
|
||||
static int compl_shows_dir = FORWARD;
|
||||
static int compl_pending = 0; // > 1 for postponed CTRL-N
|
||||
@ -1708,6 +1709,7 @@ ins_compl_free(void)
|
||||
int i;
|
||||
|
||||
VIM_CLEAR(compl_pattern);
|
||||
compl_patternlen = 0;
|
||||
VIM_CLEAR(compl_leader);
|
||||
|
||||
if (compl_first_match == NULL)
|
||||
@ -1747,6 +1749,7 @@ ins_compl_clear(void)
|
||||
compl_started = FALSE;
|
||||
compl_matches = 0;
|
||||
VIM_CLEAR(compl_pattern);
|
||||
compl_patternlen = 0;
|
||||
VIM_CLEAR(compl_leader);
|
||||
edit_submode_extra = NULL;
|
||||
VIM_CLEAR(compl_orig_text);
|
||||
@ -3374,7 +3377,7 @@ done:
|
||||
get_next_include_file_completion(int compl_type)
|
||||
{
|
||||
find_pattern_in_path(compl_pattern, compl_direction,
|
||||
(int)STRLEN(compl_pattern), FALSE, FALSE,
|
||||
compl_patternlen, FALSE, FALSE,
|
||||
(compl_type == CTRL_X_PATH_DEFINES
|
||||
&& !(compl_cont_status & CONT_SOL))
|
||||
? FIND_DEFINE : FIND_ANY, 1L, ACTION_EXPAND,
|
||||
@ -3478,8 +3481,7 @@ get_next_cmdline_completion(void)
|
||||
int num_matches;
|
||||
|
||||
if (expand_cmdline(&compl_xp, compl_pattern,
|
||||
(int)STRLEN(compl_pattern),
|
||||
&num_matches, &matches) == EXPAND_OK)
|
||||
compl_patternlen, &num_matches, &matches) == EXPAND_OK)
|
||||
ins_compl_add_matches(num_matches, matches, FALSE);
|
||||
}
|
||||
|
||||
@ -3644,8 +3646,8 @@ get_next_default_completion(ins_compl_next_state_T *st, pos_T *start_pos)
|
||||
st->cur_match_pos, compl_direction, compl_pattern);
|
||||
else
|
||||
found_new_match = searchit(NULL, st->ins_buf, st->cur_match_pos,
|
||||
NULL, compl_direction, compl_pattern, 1L,
|
||||
SEARCH_KEEP + SEARCH_NFMSG, RE_LAST, NULL);
|
||||
NULL, compl_direction, compl_pattern, compl_patternlen,
|
||||
1L, SEARCH_KEEP + SEARCH_NFMSG, RE_LAST, NULL);
|
||||
--msg_silent;
|
||||
if (!compl_started || st->set_match_pos)
|
||||
{
|
||||
@ -4383,7 +4385,8 @@ ins_compl_use_match(int c)
|
||||
/*
|
||||
* Get the pattern, column and length for normal completion (CTRL-N CTRL-P
|
||||
* completion)
|
||||
* Sets the global variables: compl_col, compl_length and compl_pattern.
|
||||
* Sets the global variables: compl_col, compl_length, compl_pattern and
|
||||
* compl_patternlen.
|
||||
* Uses the global variables: compl_cont_status and ctrl_x_mode
|
||||
*/
|
||||
static int
|
||||
@ -4404,32 +4407,45 @@ get_normal_compl_info(char_u *line, int startcol, colnr_T curs_col)
|
||||
else
|
||||
compl_pattern = vim_strnsave(line + compl_col, compl_length);
|
||||
if (compl_pattern == NULL)
|
||||
{
|
||||
compl_patternlen = 0;
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
else if (compl_status_adding())
|
||||
{
|
||||
char_u *prefix = (char_u *)"\\<";
|
||||
size_t prefixlen = STRLEN_LITERAL("\\<");
|
||||
|
||||
// we need up to 2 extra chars for the prefix
|
||||
compl_pattern = alloc(quote_meta(NULL, line + compl_col,
|
||||
compl_length) + 2);
|
||||
compl_length) + prefixlen);
|
||||
if (compl_pattern == NULL)
|
||||
{
|
||||
compl_patternlen = 0;
|
||||
return FAIL;
|
||||
}
|
||||
if (!vim_iswordp(line + compl_col)
|
||||
|| (compl_col > 0
|
||||
&& (vim_iswordp(mb_prevptr(line, line + compl_col)))))
|
||||
{
|
||||
prefix = (char_u *)"";
|
||||
prefixlen = 0;
|
||||
}
|
||||
STRCPY((char *)compl_pattern, prefix);
|
||||
(void)quote_meta(compl_pattern + STRLEN(prefix),
|
||||
(void)quote_meta(compl_pattern + prefixlen,
|
||||
line + compl_col, compl_length);
|
||||
}
|
||||
else if (--startcol < 0
|
||||
|| !vim_iswordp(mb_prevptr(line, line + startcol + 1)))
|
||||
{
|
||||
// Match any word of at least two chars
|
||||
compl_pattern = vim_strsave((char_u *)"\\<\\k\\k");
|
||||
compl_pattern = vim_strnsave((char_u *)"\\<\\k\\k", STRLEN_LITERAL("\\<\\k\\k"));
|
||||
if (compl_pattern == NULL)
|
||||
{
|
||||
compl_patternlen = 0;
|
||||
return FAIL;
|
||||
}
|
||||
compl_col += curs_col;
|
||||
compl_length = 0;
|
||||
}
|
||||
@ -4465,7 +4481,10 @@ get_normal_compl_info(char_u *line, int startcol, colnr_T curs_col)
|
||||
// alloc(7) is enough -- Acevedo
|
||||
compl_pattern = alloc(7);
|
||||
if (compl_pattern == NULL)
|
||||
{
|
||||
compl_patternlen = 0;
|
||||
return FAIL;
|
||||
}
|
||||
STRCPY((char *)compl_pattern, "\\<");
|
||||
(void)quote_meta(compl_pattern + 2, line + compl_col, 1);
|
||||
STRCAT((char *)compl_pattern, "\\k");
|
||||
@ -4475,13 +4494,18 @@ get_normal_compl_info(char_u *line, int startcol, colnr_T curs_col)
|
||||
compl_pattern = alloc(quote_meta(NULL, line + compl_col,
|
||||
compl_length) + 2);
|
||||
if (compl_pattern == NULL)
|
||||
{
|
||||
compl_patternlen = 0;
|
||||
return FAIL;
|
||||
}
|
||||
STRCPY((char *)compl_pattern, "\\<");
|
||||
(void)quote_meta(compl_pattern + 2, line + compl_col,
|
||||
compl_length);
|
||||
}
|
||||
}
|
||||
|
||||
compl_patternlen = STRLEN(compl_pattern);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -4503,7 +4527,12 @@ get_wholeline_compl_info(char_u *line, colnr_T curs_col)
|
||||
else
|
||||
compl_pattern = vim_strnsave(line + compl_col, compl_length);
|
||||
if (compl_pattern == NULL)
|
||||
{
|
||||
compl_patternlen = 0;
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
compl_patternlen = STRLEN(compl_pattern);
|
||||
|
||||
return OK;
|
||||
}
|
||||
@ -4533,7 +4562,12 @@ get_filename_compl_info(char_u *line, int startcol, colnr_T curs_col)
|
||||
compl_length = (int)curs_col - startcol;
|
||||
compl_pattern = addstar(line + compl_col, compl_length, EXPAND_FILES);
|
||||
if (compl_pattern == NULL)
|
||||
{
|
||||
compl_patternlen = 0;
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
compl_patternlen = STRLEN(compl_pattern);
|
||||
|
||||
return OK;
|
||||
}
|
||||
@ -4547,9 +4581,13 @@ get_cmdline_compl_info(char_u *line, colnr_T curs_col)
|
||||
{
|
||||
compl_pattern = vim_strnsave(line, curs_col);
|
||||
if (compl_pattern == NULL)
|
||||
{
|
||||
compl_patternlen = 0;
|
||||
return FAIL;
|
||||
}
|
||||
compl_patternlen = curs_col;
|
||||
set_cmd_context(&compl_xp, compl_pattern,
|
||||
(int)STRLEN(compl_pattern), curs_col, FALSE);
|
||||
compl_patternlen, curs_col, FALSE);
|
||||
if (compl_xp.xp_context == EXPAND_UNSUCCESSFUL
|
||||
|| compl_xp.xp_context == EXPAND_NOTHING)
|
||||
// No completion possible, use an empty pattern to get a
|
||||
@ -4647,8 +4685,12 @@ get_userdefined_compl_info(colnr_T curs_col UNUSED)
|
||||
compl_length = curs_col - compl_col;
|
||||
compl_pattern = vim_strnsave(line + compl_col, compl_length);
|
||||
if (compl_pattern == NULL)
|
||||
{
|
||||
compl_patternlen = 0;
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
compl_patternlen = compl_length;
|
||||
ret = OK;
|
||||
#endif
|
||||
|
||||
@ -4685,8 +4727,12 @@ get_spell_compl_info(int startcol UNUSED, colnr_T curs_col UNUSED)
|
||||
line = ml_get(curwin->w_cursor.lnum);
|
||||
compl_pattern = vim_strnsave(line + compl_col, compl_length);
|
||||
if (compl_pattern == NULL)
|
||||
{
|
||||
compl_patternlen = 0;
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
compl_patternlen = compl_length;
|
||||
ret = OK;
|
||||
#endif
|
||||
|
||||
@ -4907,6 +4953,7 @@ ins_compl_start(void)
|
||||
-1, NULL, NULL, NULL, 0, flags, FALSE) != OK)
|
||||
{
|
||||
VIM_CLEAR(compl_pattern);
|
||||
compl_patternlen = 0;
|
||||
VIM_CLEAR(compl_orig_text);
|
||||
return FAIL;
|
||||
}
|
||||
|
99
src/normal.c
99
src/normal.c
@ -61,7 +61,7 @@ static void nv_end(cmdarg_T *cap);
|
||||
static void nv_dollar(cmdarg_T *cap);
|
||||
static void nv_search(cmdarg_T *cap);
|
||||
static void nv_next(cmdarg_T *cap);
|
||||
static int normal_search(cmdarg_T *cap, int dir, char_u *pat, int opt, int *wrapped);
|
||||
static int normal_search(cmdarg_T *cap, int dir, char_u *pat, size_t patlen, int opt, int *wrapped);
|
||||
static void nv_csearch(cmdarg_T *cap);
|
||||
static void nv_brackets(cmdarg_T *cap);
|
||||
static void nv_percent(cmdarg_T *cap);
|
||||
@ -2169,6 +2169,7 @@ find_decl(
|
||||
int flags_arg) // flags passed to searchit()
|
||||
{
|
||||
char_u *pat;
|
||||
size_t patlen;
|
||||
pos_T old_pos;
|
||||
pos_T par_pos;
|
||||
pos_T found_pos;
|
||||
@ -2185,8 +2186,9 @@ find_decl(
|
||||
|
||||
// Put "\V" before the pattern to avoid that the special meaning of "."
|
||||
// and "~" causes trouble.
|
||||
sprintf((char *)pat, vim_iswordp(ptr) ? "\\V\\<%.*s\\>" : "\\V%.*s",
|
||||
len, ptr);
|
||||
patlen = vim_snprintf((char *)pat, len + 7,
|
||||
vim_iswordp(ptr) ? "\\V\\<%.*s\\>" : "\\V%.*s", len, ptr);
|
||||
|
||||
old_pos = curwin->w_cursor;
|
||||
save_p_ws = p_ws;
|
||||
save_p_scs = p_scs;
|
||||
@ -2215,7 +2217,7 @@ find_decl(
|
||||
for (;;)
|
||||
{
|
||||
t = searchit(curwin, curbuf, &curwin->w_cursor, NULL, FORWARD,
|
||||
pat, 1L, searchflags, RE_LAST, NULL);
|
||||
pat, patlen, 1L, searchflags, RE_LAST, NULL);
|
||||
if (curwin->w_cursor.lnum >= old_pos.lnum)
|
||||
t = FAIL; // match after start is failure too
|
||||
|
||||
@ -3332,7 +3334,8 @@ nv_K_getcmd(
|
||||
char_u **ptr_arg,
|
||||
int n,
|
||||
char_u *buf,
|
||||
unsigned buflen)
|
||||
size_t bufsize,
|
||||
size_t *buflen)
|
||||
{
|
||||
char_u *ptr = *ptr_arg;
|
||||
int isman;
|
||||
@ -3342,6 +3345,7 @@ nv_K_getcmd(
|
||||
{
|
||||
// in the help buffer
|
||||
STRCPY(buf, "he! ");
|
||||
*buflen = STRLEN_LITERAL("he! ");
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -3349,10 +3353,9 @@ nv_K_getcmd(
|
||||
{
|
||||
// 'keywordprog' is an ex command
|
||||
if (cap->count0 != 0)
|
||||
vim_snprintf((char *)buf, buflen, "%s %ld", kp, cap->count0);
|
||||
*buflen = vim_snprintf((char *)buf, bufsize, "%s %ld ", kp, cap->count0);
|
||||
else
|
||||
STRCPY(buf, kp);
|
||||
STRCAT(buf, " ");
|
||||
*buflen = vim_snprintf((char *)buf, bufsize, "%s ", kp);
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -3377,19 +3380,16 @@ nv_K_getcmd(
|
||||
isman = (STRCMP(kp, "man") == 0);
|
||||
isman_s = (STRCMP(kp, "man -s") == 0);
|
||||
if (cap->count0 != 0 && !(isman || isman_s))
|
||||
sprintf((char *)buf, ".,.+%ld", cap->count0 - 1);
|
||||
|
||||
STRCAT(buf, "! ");
|
||||
if (cap->count0 == 0 && isman_s)
|
||||
STRCAT(buf, "man");
|
||||
*buflen = vim_snprintf((char *)buf, bufsize, ".,.+%ld! ", cap->count0 - 1);
|
||||
else
|
||||
STRCAT(buf, kp);
|
||||
STRCAT(buf, " ");
|
||||
*buflen = vim_snprintf((char *)buf, bufsize, "! ");
|
||||
|
||||
if (cap->count0 == 0 && isman_s)
|
||||
*buflen += vim_snprintf((char *)buf + *buflen, bufsize - *buflen, "man ");
|
||||
else
|
||||
*buflen += vim_snprintf((char *)buf + *buflen, bufsize - *buflen, "%s ", kp);
|
||||
if (cap->count0 != 0 && (isman || isman_s))
|
||||
{
|
||||
sprintf((char *)buf + STRLEN(buf), "%ld", cap->count0);
|
||||
STRCAT(buf, " ");
|
||||
}
|
||||
*buflen += vim_snprintf((char *)buf + *buflen, bufsize - *buflen, "%ld ", cap->count0);
|
||||
|
||||
*ptr_arg = ptr;
|
||||
return n;
|
||||
@ -3408,7 +3408,8 @@ nv_ident(cmdarg_T *cap)
|
||||
{
|
||||
char_u *ptr = NULL;
|
||||
char_u *buf;
|
||||
unsigned buflen;
|
||||
size_t bufsize;
|
||||
size_t buflen;
|
||||
char_u *newbuf;
|
||||
char_u *p;
|
||||
char_u *kp; // value of 'keywordprg'
|
||||
@ -3463,11 +3464,12 @@ nv_ident(cmdarg_T *cap)
|
||||
return;
|
||||
}
|
||||
kp_ex = (*kp == ':');
|
||||
buflen = (unsigned)(n * 2 + 30 + STRLEN(kp));
|
||||
buf = alloc(buflen);
|
||||
bufsize = (size_t)(n * 2 + 30 + STRLEN(kp));
|
||||
buf = alloc(bufsize);
|
||||
if (buf == NULL)
|
||||
return;
|
||||
buf[0] = NUL;
|
||||
buflen = 0;
|
||||
|
||||
switch (cmdchar)
|
||||
{
|
||||
@ -3481,12 +3483,15 @@ nv_ident(cmdarg_T *cap)
|
||||
curwin->w_cursor.col = (colnr_T) (ptr - ml_get_curline());
|
||||
|
||||
if (!g_cmd && vim_iswordp(ptr))
|
||||
{
|
||||
STRCPY(buf, "\\<");
|
||||
buflen = STRLEN_LITERAL("\\<");
|
||||
}
|
||||
no_smartcase = TRUE; // don't use 'smartcase' now
|
||||
break;
|
||||
|
||||
case 'K':
|
||||
n = nv_K_getcmd(cap, kp, kp_help, kp_ex, &ptr, n, buf, buflen);
|
||||
n = nv_K_getcmd(cap, kp, kp_help, kp_ex, &ptr, n, buf, bufsize, &buflen);
|
||||
if (n == 0)
|
||||
return;
|
||||
break;
|
||||
@ -3495,30 +3500,47 @@ nv_ident(cmdarg_T *cap)
|
||||
tag_cmd = TRUE;
|
||||
#ifdef FEAT_CSCOPE
|
||||
if (p_cst)
|
||||
{
|
||||
STRCPY(buf, "cstag ");
|
||||
buflen = STRLEN_LITERAL("cstag ");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
STRCPY(buf, "ts ");
|
||||
buflen = STRLEN_LITERAL("ts ");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
tag_cmd = TRUE;
|
||||
if (curbuf->b_help)
|
||||
{
|
||||
STRCPY(buf, "he! ");
|
||||
buflen = STRLEN_LITERAL("he! ");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_cmd)
|
||||
{
|
||||
STRCPY(buf, "tj ");
|
||||
buflen = STRLEN_LITERAL("tj ");
|
||||
}
|
||||
else if (cap->count0 == 0)
|
||||
{
|
||||
STRCPY(buf, "ta ");
|
||||
buflen = STRLEN_LITERAL("ta ");
|
||||
}
|
||||
else
|
||||
sprintf((char *)buf, ":%ldta ", cap->count0);
|
||||
buflen = vim_snprintf((char *)buf, bufsize, ":%ldta ", cap->count0);
|
||||
}
|
||||
}
|
||||
|
||||
// Now grab the chars in the identifier
|
||||
if (cmdchar == 'K' && !kp_help)
|
||||
{
|
||||
size_t plen;
|
||||
|
||||
ptr = vim_strnsave(ptr, n);
|
||||
if (kp_ex)
|
||||
// Escape the argument properly for an Ex command
|
||||
@ -3532,7 +3554,8 @@ nv_ident(cmdarg_T *cap)
|
||||
vim_free(buf);
|
||||
return;
|
||||
}
|
||||
newbuf = vim_realloc(buf, STRLEN(buf) + STRLEN(p) + 1);
|
||||
plen = STRLEN(p);
|
||||
newbuf = vim_realloc(buf, buflen + plen + 1);
|
||||
if (newbuf == NULL)
|
||||
{
|
||||
vim_free(buf);
|
||||
@ -3540,7 +3563,8 @@ nv_ident(cmdarg_T *cap)
|
||||
return;
|
||||
}
|
||||
buf = newbuf;
|
||||
STRCAT(buf, p);
|
||||
STRCPY(buf + buflen, p);
|
||||
buflen += plen;
|
||||
vim_free(p);
|
||||
}
|
||||
else
|
||||
@ -3560,12 +3584,13 @@ nv_ident(cmdarg_T *cap)
|
||||
else
|
||||
aux_ptr = (char_u *)"\\|\"\n*?[";
|
||||
|
||||
p = buf + STRLEN(buf);
|
||||
p = buf + buflen;
|
||||
while (n-- > 0)
|
||||
{
|
||||
// put a backslash before \ and some others
|
||||
if (vim_strchr(aux_ptr, *ptr) != NULL)
|
||||
*p++ = '\\';
|
||||
|
||||
// When current byte is a part of multibyte character, copy all
|
||||
// bytes of that character.
|
||||
if (has_mbyte)
|
||||
@ -3579,6 +3604,7 @@ nv_ident(cmdarg_T *cap)
|
||||
*p++ = *ptr++;
|
||||
}
|
||||
*p = NUL;
|
||||
buflen = p - buf;
|
||||
}
|
||||
|
||||
// Execute the command.
|
||||
@ -3587,13 +3613,16 @@ nv_ident(cmdarg_T *cap)
|
||||
if (!g_cmd && (has_mbyte
|
||||
? vim_iswordp(mb_prevptr(ml_get_curline(), ptr))
|
||||
: vim_iswordc(ptr[-1])))
|
||||
STRCAT(buf, "\\>");
|
||||
{
|
||||
STRCPY(buf + buflen, "\\>");
|
||||
buflen += STRLEN_LITERAL("\\>");
|
||||
}
|
||||
|
||||
// put pattern in search history
|
||||
init_history();
|
||||
add_to_history(HIST_SEARCH, buf, TRUE, NUL);
|
||||
add_to_history(HIST_SEARCH, buf, buflen, TRUE, NUL);
|
||||
|
||||
(void)normal_search(cap, cmdchar == '*' ? '/' : '?', buf, 0, NULL);
|
||||
(void)normal_search(cap, cmdchar == '*' ? '/' : '?', buf, buflen, 0, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4117,7 +4146,7 @@ nv_search(cmdarg_T *cap)
|
||||
return;
|
||||
}
|
||||
|
||||
(void)normal_search(cap, cap->cmdchar, cap->searchbuf,
|
||||
(void)normal_search(cap, cap->cmdchar, cap->searchbuf, STRLEN(cap->searchbuf),
|
||||
(cap->arg || !EQUAL_POS(save_cursor, curwin->w_cursor))
|
||||
? 0 : SEARCH_MARK, NULL);
|
||||
}
|
||||
@ -4132,7 +4161,7 @@ nv_next(cmdarg_T *cap)
|
||||
{
|
||||
pos_T old = curwin->w_cursor;
|
||||
int wrapped = FALSE;
|
||||
int i = normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg, &wrapped);
|
||||
int i = normal_search(cap, 0, NULL, 0, SEARCH_MARK | cap->arg, &wrapped);
|
||||
|
||||
if (i == 1 && !wrapped && EQUAL_POS(old, curwin->w_cursor))
|
||||
{
|
||||
@ -4140,7 +4169,7 @@ nv_next(cmdarg_T *cap)
|
||||
// happen when an offset is given and the cursor is on the last char
|
||||
// in the buffer: Repeat with count + 1.
|
||||
cap->count1 += 1;
|
||||
(void)normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg, NULL);
|
||||
(void)normal_search(cap, 0, NULL, 0, SEARCH_MARK | cap->arg, NULL);
|
||||
cap->count1 -= 1;
|
||||
}
|
||||
|
||||
@ -4161,6 +4190,7 @@ normal_search(
|
||||
cmdarg_T *cap,
|
||||
int dir,
|
||||
char_u *pat,
|
||||
size_t patlen,
|
||||
int opt, // extra flags for do_search()
|
||||
int *wrapped)
|
||||
{
|
||||
@ -4176,7 +4206,7 @@ normal_search(
|
||||
curwin->w_set_curswant = TRUE;
|
||||
|
||||
CLEAR_FIELD(sia);
|
||||
i = do_search(cap->oap, dir, dir, pat, cap->count1,
|
||||
i = do_search(cap->oap, dir, dir, pat, patlen, cap->count1,
|
||||
opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, &sia);
|
||||
if (wrapped != NULL)
|
||||
*wrapped = sia.sa_wrapped;
|
||||
@ -4201,6 +4231,7 @@ normal_search(
|
||||
// "/$" will put the cursor after the end of the line, may need to
|
||||
// correct that here
|
||||
check_cursor();
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ char_u *get_history_arg(expand_T *xp, int idx);
|
||||
void init_history(void);
|
||||
void clear_hist_entry(histentry_T *hisptr);
|
||||
int in_history(int type, char_u *str, int move_to_front, int sep, int writing);
|
||||
void add_to_history(int histype, char_u *new_entry, int in_map, int sep);
|
||||
void add_to_history(int histype, char_u *new_entry, size_t new_entrylen, int in_map, int sep);
|
||||
void f_histadd(typval_T *argvars, typval_T *rettv);
|
||||
void f_histdel(typval_T *argvars, typval_T *rettv);
|
||||
void f_histget(typval_T *argvars, typval_T *rettv);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* search.c */
|
||||
int search_regcomp(char_u *pat, char_u **used_pat, int pat_save, int pat_use, int options, regmmatch_T *regmatch);
|
||||
int search_regcomp(char_u *pat, size_t patlen, char_u **used_pat, int pat_save, int pat_use, int options, regmmatch_T *regmatch);
|
||||
char_u *get_search_pat(void);
|
||||
void save_re_pat(int idx, char_u *pat, int magic);
|
||||
void save_re_pat(int idx, char_u *pat, size_t patlen, int magic);
|
||||
void save_search_patterns(void);
|
||||
void restore_search_patterns(void);
|
||||
void free_search_patterns(void);
|
||||
@ -21,9 +21,9 @@ char_u *last_search_pat(void);
|
||||
void reset_search_dir(void);
|
||||
void set_last_search_pat(char_u *s, int idx, int magic, int setlast);
|
||||
void last_pat_prog(regmmatch_T *regmatch);
|
||||
int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, int dir, char_u *pat, long count, int options, int pat_use, searchit_arg_T *extra_arg);
|
||||
int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, int dir, char_u *pat, size_t patlen, long count, int options, int pat_use, searchit_arg_T *extra_arg);
|
||||
void set_search_direction(int cdir);
|
||||
int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count, int options, searchit_arg_T *sia);
|
||||
int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, size_t patlen, long count, int options, searchit_arg_T *sia);
|
||||
int search_for_exact_line(buf_T *buf, pos_T *pos, int dir, char_u *pat);
|
||||
int searchc(cmdarg_T *cap, int t_cmd);
|
||||
pos_T *findmatch(oparg_T *oap, int initc);
|
||||
|
@ -3388,7 +3388,7 @@ qf_jump_goto_line(
|
||||
// Move the cursor to the first line in the buffer
|
||||
save_cursor = curwin->w_cursor;
|
||||
curwin->w_cursor.lnum = 0;
|
||||
if (!do_search(NULL, '/', '/', qf_pattern, (long)1, SEARCH_KEEP, NULL))
|
||||
if (!do_search(NULL, '/', '/', qf_pattern, STRLEN(qf_pattern), (long)1, SEARCH_KEEP, NULL))
|
||||
curwin->w_cursor = save_cursor;
|
||||
}
|
||||
}
|
||||
|
297
src/search.c
297
src/search.c
@ -17,8 +17,8 @@ static void set_vv_searchforward(void);
|
||||
static int first_submatch(regmmatch_T *rp);
|
||||
#endif
|
||||
#ifdef FEAT_FIND_ID
|
||||
static void show_pat_in_path(char_u *, int,
|
||||
int, int, FILE *, linenr_T *, long);
|
||||
static char_u *get_line_and_copy(linenr_T lnum, char_u *buf);
|
||||
static void show_pat_in_path(char_u *, int, int, int, FILE *, linenr_T *, long);
|
||||
#endif
|
||||
|
||||
typedef struct searchstat
|
||||
@ -32,8 +32,27 @@ typedef struct searchstat
|
||||
int last_maxcount; // the max count of the last search
|
||||
} searchstat_T;
|
||||
|
||||
static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, int show_top_bot_msg, char_u *msgbuf, int recompute, int maxcount, long timeout);
|
||||
#ifdef FEAT_SEARCH_EXTRA
|
||||
static void save_incsearch_state(void);
|
||||
static void restore_incsearch_state(void);
|
||||
#endif
|
||||
static int check_prevcol(char_u *linep, int col, int ch, int *prevcol);
|
||||
static int find_rawstring_end(char_u *linep, pos_T *startpos, pos_T *endpos);
|
||||
static void find_mps_values(int *initc, int *findc, int *backwards, int switchit);
|
||||
static int is_zero_width(char_u *pattern, size_t patternlen, int move, pos_T *cur, int direction);
|
||||
static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, int show_top_bot_msg, char_u *msgbuf, size_t msgbuflen, int recompute, int maxcount, long timeout);
|
||||
static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchstat_T *stat, int recompute, int maxcount, long timeout);
|
||||
static int fuzzy_match_compute_score(char_u *str, int strSz, int_u *matches, int numMatches);
|
||||
static int fuzzy_match_recursive(char_u *fuzpat, char_u *str, int_u strIdx, int *outScore, char_u *strBegin, int strLen, int_u *srcMatches, int_u *matches, int maxMatches, int nextMatch, int *recursionCount);
|
||||
#if defined(FEAT_EVAL) || defined(FEAT_PROTO)
|
||||
static int fuzzy_match_item_compare(const void *s1, const void *s2);
|
||||
static void fuzzy_match_in_list(list_T *l, char_u *str, int matchseq, char_u *key, callback_T *item_cb, int retmatchpos, list_T *fmatchlist, long max_matches);
|
||||
static void do_fuzzymatch(typval_T *argvars, typval_T *rettv, int retmatchpos);
|
||||
#endif
|
||||
static int fuzzy_match_str_compare(const void *s1, const void *s2);
|
||||
static void fuzzy_match_str_sort(fuzmatch_str_T *fm, int sz);
|
||||
static int fuzzy_match_func_compare(const void *s1, const void *s2);
|
||||
static void fuzzy_match_func_sort(fuzmatch_str_T *fm, int sz);
|
||||
|
||||
#define SEARCH_STAT_DEF_TIMEOUT 40L
|
||||
#define SEARCH_STAT_DEF_MAX_COUNT 99
|
||||
@ -69,8 +88,8 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst
|
||||
*/
|
||||
static spat_T spats[2] =
|
||||
{
|
||||
{NULL, TRUE, FALSE, {'/', 0, 0, 0L}}, // last used search pat
|
||||
{NULL, TRUE, FALSE, {'/', 0, 0, 0L}} // last used substitute pat
|
||||
{NULL, 0, TRUE, FALSE, {'/', 0, 0, 0L}}, // last used search pat
|
||||
{NULL, 0, TRUE, FALSE, {'/', 0, 0, 0L}} // last used substitute pat
|
||||
};
|
||||
|
||||
static int last_idx = 0; // index in spats[] for RE_LAST
|
||||
@ -82,8 +101,9 @@ static char_u lastc_bytes[MB_MAXBYTES + 1];
|
||||
static int lastc_bytelen = 1; // >1 for multi-byte char
|
||||
|
||||
// copy of spats[], for keeping the search patterns while executing autocmds
|
||||
static spat_T saved_spats[2];
|
||||
static spat_T saved_spats[ARRAY_LENGTH(spats)];
|
||||
static char_u *saved_mr_pattern = NULL;
|
||||
static size_t saved_mr_patternlen = 0;
|
||||
# ifdef FEAT_SEARCH_EXTRA
|
||||
static int saved_spats_last_idx = 0;
|
||||
static int saved_spats_no_hlsearch = 0;
|
||||
@ -91,6 +111,7 @@ static int saved_spats_no_hlsearch = 0;
|
||||
|
||||
// allocated copy of pattern used by search_regcomp()
|
||||
static char_u *mr_pattern = NULL;
|
||||
static size_t mr_patternlen = 0;
|
||||
|
||||
#ifdef FEAT_FIND_ID
|
||||
/*
|
||||
@ -123,6 +144,7 @@ typedef struct SearchedFile
|
||||
int
|
||||
search_regcomp(
|
||||
char_u *pat,
|
||||
size_t patlen,
|
||||
char_u **used_pat,
|
||||
int pat_save,
|
||||
int pat_use,
|
||||
@ -130,7 +152,6 @@ search_regcomp(
|
||||
regmmatch_T *regmatch) // return: pattern and ignore-case flag
|
||||
{
|
||||
int magic;
|
||||
int i;
|
||||
|
||||
rc_did_emsg = FALSE;
|
||||
magic = magic_isset();
|
||||
@ -140,6 +161,8 @@ search_regcomp(
|
||||
*/
|
||||
if (pat == NULL || *pat == NUL)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (pat_use == RE_LAST)
|
||||
i = last_idx;
|
||||
else
|
||||
@ -154,11 +177,12 @@ search_regcomp(
|
||||
return FAIL;
|
||||
}
|
||||
pat = spats[i].pat;
|
||||
patlen = spats[i].patlen;
|
||||
magic = spats[i].magic;
|
||||
no_smartcase = spats[i].no_scs;
|
||||
}
|
||||
else if (options & SEARCH_HIS) // put new pattern in history
|
||||
add_to_history(HIST_SEARCH, pat, TRUE, NUL);
|
||||
add_to_history(HIST_SEARCH, pat, patlen, TRUE, NUL);
|
||||
|
||||
if (used_pat)
|
||||
*used_pat = pat;
|
||||
@ -169,7 +193,11 @@ search_regcomp(
|
||||
mr_pattern = reverse_text(pat);
|
||||
else
|
||||
#endif
|
||||
mr_pattern = vim_strsave(pat);
|
||||
mr_pattern = vim_strnsave(pat, patlen);
|
||||
if (mr_pattern == NULL)
|
||||
mr_patternlen = 0;
|
||||
else
|
||||
mr_patternlen = patlen;
|
||||
|
||||
/*
|
||||
* Save the currently used pattern in the appropriate place,
|
||||
@ -180,10 +208,10 @@ search_regcomp(
|
||||
{
|
||||
// search or global command
|
||||
if (pat_save == RE_SEARCH || pat_save == RE_BOTH)
|
||||
save_re_pat(RE_SEARCH, pat, magic);
|
||||
save_re_pat(RE_SEARCH, pat, patlen, magic);
|
||||
// substitute or global command
|
||||
if (pat_save == RE_SUBST || pat_save == RE_BOTH)
|
||||
save_re_pat(RE_SUBST, pat, magic);
|
||||
save_re_pat(RE_SUBST, pat, patlen, magic);
|
||||
}
|
||||
|
||||
regmatch->rmm_ic = ignorecase(pat);
|
||||
@ -204,13 +232,17 @@ get_search_pat(void)
|
||||
}
|
||||
|
||||
void
|
||||
save_re_pat(int idx, char_u *pat, int magic)
|
||||
save_re_pat(int idx, char_u *pat, size_t patlen, int magic)
|
||||
{
|
||||
if (spats[idx].pat == pat)
|
||||
return;
|
||||
|
||||
vim_free(spats[idx].pat);
|
||||
spats[idx].pat = vim_strsave(pat);
|
||||
spats[idx].pat = vim_strnsave(pat, patlen);
|
||||
if (spats[idx].pat == NULL)
|
||||
spats[idx].patlen = 0;
|
||||
else
|
||||
spats[idx].patlen = patlen;
|
||||
spats[idx].magic = magic;
|
||||
spats[idx].no_scs = no_smartcase;
|
||||
last_idx = idx;
|
||||
@ -231,19 +263,31 @@ static int save_level = 0;
|
||||
void
|
||||
save_search_patterns(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (save_level++ != 0)
|
||||
return;
|
||||
|
||||
saved_spats[0] = spats[0];
|
||||
if (spats[0].pat != NULL)
|
||||
saved_spats[0].pat = vim_strsave(spats[0].pat);
|
||||
saved_spats[1] = spats[1];
|
||||
if (spats[1].pat != NULL)
|
||||
saved_spats[1].pat = vim_strsave(spats[1].pat);
|
||||
for (i = 0; i < (int)ARRAY_LENGTH(spats); ++i)
|
||||
{
|
||||
saved_spats[i] = spats[i];
|
||||
if (spats[i].pat != NULL)
|
||||
{
|
||||
saved_spats[i].pat = vim_strnsave(spats[i].pat, spats[i].patlen);
|
||||
if (saved_spats[i].pat == NULL)
|
||||
saved_spats[i].patlen = 0;
|
||||
else
|
||||
saved_spats[i].patlen = spats[i].patlen;
|
||||
}
|
||||
}
|
||||
if (mr_pattern == NULL)
|
||||
saved_mr_pattern = NULL;
|
||||
else
|
||||
saved_mr_pattern = vim_strsave(mr_pattern);
|
||||
saved_mr_pattern = vim_strnsave(mr_pattern, mr_patternlen);
|
||||
if (saved_mr_pattern == NULL)
|
||||
saved_mr_patternlen = 0;
|
||||
else
|
||||
saved_mr_patternlen = mr_patternlen;
|
||||
#ifdef FEAT_SEARCH_EXTRA
|
||||
saved_spats_last_idx = last_idx;
|
||||
saved_spats_no_hlsearch = no_hlsearch;
|
||||
@ -253,18 +297,22 @@ save_search_patterns(void)
|
||||
void
|
||||
restore_search_patterns(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (--save_level != 0)
|
||||
return;
|
||||
|
||||
vim_free(spats[0].pat);
|
||||
spats[0] = saved_spats[0];
|
||||
for (i = 0; i < (int)ARRAY_LENGTH(spats); ++i)
|
||||
{
|
||||
vim_free(spats[i].pat);
|
||||
spats[i] = saved_spats[i];
|
||||
}
|
||||
#if defined(FEAT_EVAL)
|
||||
set_vv_searchforward();
|
||||
#endif
|
||||
vim_free(spats[1].pat);
|
||||
spats[1] = saved_spats[1];
|
||||
vim_free(mr_pattern);
|
||||
mr_pattern = saved_mr_pattern;
|
||||
mr_patternlen = saved_mr_patternlen;
|
||||
#ifdef FEAT_SEARCH_EXTRA
|
||||
last_idx = saved_spats_last_idx;
|
||||
set_no_hlsearch(saved_spats_no_hlsearch);
|
||||
@ -275,9 +323,15 @@ restore_search_patterns(void)
|
||||
void
|
||||
free_search_patterns(void)
|
||||
{
|
||||
vim_free(spats[0].pat);
|
||||
vim_free(spats[1].pat);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < (int)ARRAY_LENGTH(spats); ++i)
|
||||
{
|
||||
VIM_CLEAR(spats[i].pat);
|
||||
spats[i].patlen = 0;
|
||||
}
|
||||
VIM_CLEAR(mr_pattern);
|
||||
mr_patternlen = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -308,7 +362,13 @@ save_last_search_pattern(void)
|
||||
|
||||
saved_last_search_spat = spats[RE_SEARCH];
|
||||
if (spats[RE_SEARCH].pat != NULL)
|
||||
saved_last_search_spat.pat = vim_strsave(spats[RE_SEARCH].pat);
|
||||
{
|
||||
saved_last_search_spat.pat = vim_strnsave(spats[RE_SEARCH].pat, spats[RE_SEARCH].patlen);
|
||||
if (saved_last_search_spat.pat == NULL)
|
||||
saved_last_search_spat.patlen = 0;
|
||||
else
|
||||
saved_last_search_spat.patlen = spats[RE_SEARCH].patlen;
|
||||
}
|
||||
saved_last_idx = last_idx;
|
||||
saved_no_hlsearch = no_hlsearch;
|
||||
}
|
||||
@ -328,6 +388,7 @@ restore_last_search_pattern(void)
|
||||
vim_free(spats[RE_SEARCH].pat);
|
||||
spats[RE_SEARCH] = saved_last_search_spat;
|
||||
saved_last_search_spat.pat = NULL;
|
||||
saved_last_search_spat.patlen = 0;
|
||||
# if defined(FEAT_EVAL)
|
||||
set_vv_searchforward();
|
||||
# endif
|
||||
@ -513,7 +574,12 @@ set_last_search_pat(
|
||||
if (*s == NUL)
|
||||
spats[idx].pat = NULL;
|
||||
else
|
||||
spats[idx].pat = vim_strsave(s);
|
||||
{
|
||||
spats[idx].patlen = STRLEN(s);
|
||||
spats[idx].pat = vim_strnsave(s, spats[idx].patlen);
|
||||
}
|
||||
if (spats[idx].pat == NULL)
|
||||
spats[idx].patlen = 0;
|
||||
spats[idx].magic = magic;
|
||||
spats[idx].no_scs = FALSE;
|
||||
spats[idx].off.dir = '/';
|
||||
@ -532,7 +598,11 @@ set_last_search_pat(
|
||||
if (spats[idx].pat == NULL)
|
||||
saved_spats[idx].pat = NULL;
|
||||
else
|
||||
saved_spats[idx].pat = vim_strsave(spats[idx].pat);
|
||||
saved_spats[idx].pat = vim_strnsave(spats[idx].pat, spats[idx].patlen);
|
||||
if (saved_spats[idx].pat == NULL)
|
||||
saved_spats[idx].patlen = 0;
|
||||
else
|
||||
saved_spats[idx].patlen = spats[idx].patlen;
|
||||
# ifdef FEAT_SEARCH_EXTRA
|
||||
saved_spats_last_idx = last_idx;
|
||||
# endif
|
||||
@ -560,7 +630,7 @@ last_pat_prog(regmmatch_T *regmatch)
|
||||
return;
|
||||
}
|
||||
++emsg_off; // So it doesn't beep if bad expr
|
||||
(void)search_regcomp((char_u *)"", NULL, 0, last_idx, SEARCH_KEEP, regmatch);
|
||||
(void)search_regcomp((char_u *)"", 0, NULL, 0, last_idx, SEARCH_KEEP, regmatch);
|
||||
--emsg_off;
|
||||
}
|
||||
#endif
|
||||
@ -594,6 +664,7 @@ searchit(
|
||||
pos_T *end_pos, // set to end of the match, unless NULL
|
||||
int dir,
|
||||
char_u *pat,
|
||||
size_t patlen,
|
||||
long count,
|
||||
int options,
|
||||
int pat_use, // which pattern to use when "pat" is empty
|
||||
@ -623,8 +694,9 @@ searchit(
|
||||
linenr_T stop_lnum = 0; // stop after this line number when != 0
|
||||
int unused_timeout_flag = FALSE;
|
||||
int *timed_out = &unused_timeout_flag; // set when timed out.
|
||||
int search_from_match_end; // vi-compatible search?
|
||||
|
||||
if (search_regcomp(pat, NULL, RE_SEARCH, pat_use,
|
||||
if (search_regcomp(pat, patlen, NULL, RE_SEARCH, pat_use,
|
||||
(options & (SEARCH_HIS + SEARCH_KEEP)), ®match) == FAIL)
|
||||
{
|
||||
if ((options & SEARCH_MSG) && !rc_did_emsg)
|
||||
@ -632,6 +704,8 @@ searchit(
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
search_from_match_end = vim_strchr(p_cpo, CPO_SEARCH) != NULL;
|
||||
|
||||
if (extra_arg != NULL)
|
||||
{
|
||||
stop_lnum = extra_arg->sa_stop_lnum;
|
||||
@ -778,7 +852,7 @@ searchit(
|
||||
* of the match, otherwise continue one position
|
||||
* forward.
|
||||
*/
|
||||
if (vim_strchr(p_cpo, CPO_SEARCH) != NULL)
|
||||
if (search_from_match_end)
|
||||
{
|
||||
if (nmatched > 1)
|
||||
{
|
||||
@ -890,7 +964,7 @@ searchit(
|
||||
* of the match, otherwise continue one position
|
||||
* forward.
|
||||
*/
|
||||
if (vim_strchr(p_cpo, CPO_SEARCH) != NULL)
|
||||
if (search_from_match_end)
|
||||
{
|
||||
if (nmatched > 1)
|
||||
break;
|
||||
@ -1173,12 +1247,14 @@ do_search(
|
||||
int search_delim, // the delimiter for the search, e.g. '%' in
|
||||
// s%regex%replacement%
|
||||
char_u *pat,
|
||||
size_t patlen,
|
||||
long count,
|
||||
int options,
|
||||
searchit_arg_T *sia) // optional arguments or NULL
|
||||
{
|
||||
pos_T pos; // position of the last match
|
||||
char_u *searchstr;
|
||||
size_t searchstrlen;
|
||||
soffset_T old_off;
|
||||
int retval; // Return value
|
||||
char_u *p;
|
||||
@ -1186,10 +1262,13 @@ do_search(
|
||||
char_u *dircp;
|
||||
char_u *strcopy = NULL;
|
||||
char_u *ps;
|
||||
int show_search_stats;
|
||||
char_u *msgbuf = NULL;
|
||||
size_t len;
|
||||
size_t msgbuflen = 0;
|
||||
int has_offset = FALSE;
|
||||
|
||||
searchcmdlen = 0;
|
||||
|
||||
/*
|
||||
* A line offset is not remembered, this is vi compatible.
|
||||
*/
|
||||
@ -1267,24 +1346,28 @@ do_search(
|
||||
int show_top_bot_msg = FALSE;
|
||||
|
||||
searchstr = pat;
|
||||
searchstrlen = patlen;
|
||||
|
||||
dircp = NULL;
|
||||
// use previous pattern
|
||||
if (pat == NULL || *pat == NUL || *pat == search_delim)
|
||||
{
|
||||
if (spats[RE_SEARCH].pat == NULL) // no previous pattern
|
||||
{
|
||||
searchstr = spats[RE_SUBST].pat;
|
||||
if (searchstr == NULL)
|
||||
if (spats[RE_SUBST].pat == NULL)
|
||||
{
|
||||
emsg(_(e_no_previous_regular_expression));
|
||||
retval = 0;
|
||||
goto end_do_search;
|
||||
}
|
||||
searchstr = spats[RE_SUBST].pat;
|
||||
searchstrlen = spats[RE_SUBST].patlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
// make search_regcomp() use spats[RE_SEARCH].pat
|
||||
searchstr = (char_u *)"";
|
||||
searchstrlen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1299,13 +1382,17 @@ do_search(
|
||||
&strcopy, NULL, NULL);
|
||||
if (strcopy != ps)
|
||||
{
|
||||
size_t len = STRLEN(strcopy);
|
||||
// made a copy of "pat" to change "\?" to "?"
|
||||
searchcmdlen += (int)(STRLEN(pat) - STRLEN(strcopy));
|
||||
searchcmdlen += (int)(patlen - len);
|
||||
pat = strcopy;
|
||||
patlen = len;
|
||||
searchstr = strcopy;
|
||||
searchstrlen = len;
|
||||
}
|
||||
if (*p == search_delim)
|
||||
{
|
||||
searchstrlen = p - pat;
|
||||
dircp = p; // remember where we put the NUL
|
||||
*p++ = NUL;
|
||||
}
|
||||
@ -1344,16 +1431,19 @@ do_search(
|
||||
// compute length of search command for get_address()
|
||||
searchcmdlen += (int)(p - pat);
|
||||
|
||||
patlen -= p - pat;
|
||||
pat = p; // put pat after search command
|
||||
}
|
||||
|
||||
show_search_stats = FALSE;
|
||||
if ((options & SEARCH_ECHO) && messaging()
|
||||
&& !msg_silent
|
||||
&& (!cmd_silent || !shortmess(SHM_SEARCHCOUNT)))
|
||||
{
|
||||
char_u *trunc;
|
||||
char_u off_buf[40];
|
||||
size_t off_len = 0;
|
||||
size_t plen;
|
||||
size_t msgbufsize;
|
||||
|
||||
// Compute msg_row early.
|
||||
msg_start();
|
||||
@ -1362,24 +1452,28 @@ do_search(
|
||||
if (!cmd_silent &&
|
||||
(spats[0].off.line || spats[0].off.end || spats[0].off.off))
|
||||
{
|
||||
p = off_buf;
|
||||
*p++ = dirc;
|
||||
off_buf[off_len++] = dirc;
|
||||
if (spats[0].off.end)
|
||||
*p++ = 'e';
|
||||
off_buf[off_len++] = 'e';
|
||||
else if (!spats[0].off.line)
|
||||
*p++ = 's';
|
||||
off_buf[off_len++] = 's';
|
||||
if (spats[0].off.off > 0 || spats[0].off.line)
|
||||
*p++ = '+';
|
||||
*p = NUL;
|
||||
off_buf[off_len++] = '+';
|
||||
off_buf[off_len] = NUL;
|
||||
if (spats[0].off.off != 0 || spats[0].off.line)
|
||||
sprintf((char *)p, "%ld", spats[0].off.off);
|
||||
off_len = STRLEN(off_buf);
|
||||
off_len += vim_snprintf((char *)off_buf + off_len, sizeof(off_buf) - off_len, "%ld", spats[0].off.off);
|
||||
}
|
||||
|
||||
if (*searchstr == NUL)
|
||||
{
|
||||
p = spats[0].pat;
|
||||
plen = spats[0].patlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = searchstr;
|
||||
plen = searchstrlen;
|
||||
}
|
||||
|
||||
if (!shortmess(SHM_SEARCHCOUNT) || cmd_silent)
|
||||
{
|
||||
@ -1389,45 +1483,53 @@ do_search(
|
||||
// msg_strtrunc() will shorten in the middle.
|
||||
if (msg_scrolled != 0 && !cmd_silent)
|
||||
// Use all the columns.
|
||||
len = (int)(Rows - msg_row) * Columns - 1;
|
||||
msgbufsize = (int)(Rows - msg_row) * Columns - 1;
|
||||
else
|
||||
// Use up to 'showcmd' column.
|
||||
len = (int)(Rows - msg_row - 1) * Columns + sc_col - 1;
|
||||
if (len < STRLEN(p) + off_len + SEARCH_STAT_BUF_LEN + 3)
|
||||
len = STRLEN(p) + off_len + SEARCH_STAT_BUF_LEN + 3;
|
||||
msgbufsize = (int)(Rows - msg_row - 1) * Columns + sc_col - 1;
|
||||
if (msgbufsize < plen + off_len + SEARCH_STAT_BUF_LEN + 3)
|
||||
msgbufsize = plen + off_len + SEARCH_STAT_BUF_LEN + 3;
|
||||
}
|
||||
else
|
||||
// Reserve enough space for the search pattern + offset.
|
||||
len = STRLEN(p) + off_len + 3;
|
||||
msgbufsize = plen + off_len + 3;
|
||||
|
||||
vim_free(msgbuf);
|
||||
msgbuf = alloc(len);
|
||||
if (msgbuf != NULL)
|
||||
msgbuf = alloc(msgbufsize);
|
||||
if (msgbuf == NULL)
|
||||
{
|
||||
vim_memset(msgbuf, ' ', len);
|
||||
msgbuf[len - 1] = NUL;
|
||||
msgbuflen = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vim_memset(msgbuf, ' ', msgbufsize);
|
||||
msgbuflen = msgbufsize - 1;
|
||||
msgbuf[msgbuflen] = NUL;
|
||||
// do not fill the msgbuf buffer, if cmd_silent is set, leave it
|
||||
// empty for the search_stat feature.
|
||||
if (!cmd_silent)
|
||||
{
|
||||
char_u *trunc;
|
||||
|
||||
msgbuf[0] = dirc;
|
||||
|
||||
if (enc_utf8 && utf_iscomposing(utf_ptr2char(p)))
|
||||
{
|
||||
// Use a space to draw the composing char on.
|
||||
msgbuf[1] = ' ';
|
||||
mch_memmove(msgbuf + 2, p, STRLEN(p));
|
||||
mch_memmove(msgbuf + 2, p, plen);
|
||||
}
|
||||
else
|
||||
mch_memmove(msgbuf + 1, p, STRLEN(p));
|
||||
mch_memmove(msgbuf + 1, p, plen);
|
||||
if (off_len > 0)
|
||||
mch_memmove(msgbuf + STRLEN(p) + 1, off_buf, off_len);
|
||||
mch_memmove(msgbuf + plen + 1, off_buf, off_len);
|
||||
|
||||
trunc = msg_strtrunc(msgbuf, TRUE);
|
||||
if (trunc != NULL)
|
||||
{
|
||||
vim_free(msgbuf);
|
||||
msgbuf = trunc;
|
||||
msgbuflen = STRLEN(msgbuf);
|
||||
}
|
||||
|
||||
#ifdef FEAT_RIGHTLEFT
|
||||
@ -1448,7 +1550,7 @@ do_search(
|
||||
// move reversed text to beginning of buffer
|
||||
while (*r != NUL && *r == ' ')
|
||||
r++;
|
||||
pat_len = msgbuf + STRLEN(msgbuf) - r;
|
||||
pat_len = msgbuf + msgbuflen - r;
|
||||
mch_memmove(msgbuf, r, pat_len);
|
||||
// overwrite old text
|
||||
if ((size_t)(r - msgbuf) >= pat_len)
|
||||
@ -1466,7 +1568,10 @@ do_search(
|
||||
out_flush();
|
||||
msg_nowait = TRUE; // don't wait for this message
|
||||
}
|
||||
}
|
||||
|
||||
if (!shortmess(SHM_SEARCHCOUNT))
|
||||
show_search_stats = TRUE;
|
||||
} // msgbuf != NULL
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1507,7 +1612,7 @@ do_search(
|
||||
*/
|
||||
c = searchit(curwin, curbuf, &pos, NULL,
|
||||
dirc == '/' ? FORWARD : BACKWARD,
|
||||
searchstr, count, spats[0].off.end + (options &
|
||||
searchstr, searchstrlen, count, spats[0].off.end + (options &
|
||||
(SEARCH_KEEP + SEARCH_PEEK + SEARCH_HIS
|
||||
+ SEARCH_MSG + SEARCH_START
|
||||
+ ((pat != NULL && *pat == ';') ? 0 : SEARCH_NOOF))),
|
||||
@ -1574,14 +1679,9 @@ do_search(
|
||||
}
|
||||
|
||||
// Show [1/15] if 'S' is not in 'shortmess'.
|
||||
if ((options & SEARCH_ECHO)
|
||||
&& messaging()
|
||||
&& !msg_silent
|
||||
&& c != FAIL
|
||||
&& !shortmess(SHM_SEARCHCOUNT)
|
||||
&& msgbuf != NULL)
|
||||
if (show_search_stats)
|
||||
cmdline_search_stat(dirc, &pos, &curwin->w_cursor,
|
||||
show_top_bot_msg, msgbuf,
|
||||
show_top_bot_msg, msgbuf, msgbuflen,
|
||||
(count != 1 || has_offset
|
||||
#ifdef FEAT_FOLDING
|
||||
|| (!(fdo_flags & FDO_SEARCH)
|
||||
@ -1612,6 +1712,7 @@ do_search(
|
||||
goto end_do_search;
|
||||
}
|
||||
++pat;
|
||||
--patlen;
|
||||
}
|
||||
|
||||
if (options & SEARCH_MARK)
|
||||
@ -2825,7 +2926,7 @@ showmatch(
|
||||
* Returns TRUE, FALSE or -1 for failure.
|
||||
*/
|
||||
static int
|
||||
is_zero_width(char_u *pattern, int move, pos_T *cur, int direction)
|
||||
is_zero_width(char_u *pattern, size_t patternlen, int move, pos_T *cur, int direction)
|
||||
{
|
||||
regmmatch_T regmatch;
|
||||
int nmatched = 0;
|
||||
@ -2835,9 +2936,12 @@ is_zero_width(char_u *pattern, int move, pos_T *cur, int direction)
|
||||
int flag = 0;
|
||||
|
||||
if (pattern == NULL)
|
||||
{
|
||||
pattern = spats[last_idx].pat;
|
||||
patternlen = spats[last_idx].patlen;
|
||||
}
|
||||
|
||||
if (search_regcomp(pattern, NULL, RE_SEARCH, RE_SEARCH,
|
||||
if (search_regcomp(pattern, patternlen, NULL, RE_SEARCH, RE_SEARCH,
|
||||
SEARCH_KEEP, ®match) == FAIL)
|
||||
return -1;
|
||||
|
||||
@ -2855,7 +2959,7 @@ is_zero_width(char_u *pattern, int move, pos_T *cur, int direction)
|
||||
flag = SEARCH_START;
|
||||
}
|
||||
|
||||
if (searchit(curwin, curbuf, &pos, NULL, direction, pattern, 1,
|
||||
if (searchit(curwin, curbuf, &pos, NULL, direction, pattern, patternlen, 1,
|
||||
SEARCH_KEEP + flag, RE_SEARCH, NULL) != FAIL)
|
||||
{
|
||||
// Zero-width pattern should match somewhere, then we can check if
|
||||
@ -2925,8 +3029,8 @@ current_search(
|
||||
}
|
||||
|
||||
// Is the pattern is zero-width?, this time, don't care about the direction
|
||||
zero_width = is_zero_width(spats[last_idx].pat, TRUE, &curwin->w_cursor,
|
||||
FORWARD);
|
||||
zero_width = is_zero_width(spats[last_idx].pat, spats[last_idx].patlen,
|
||||
TRUE, &curwin->w_cursor, FORWARD);
|
||||
if (zero_width == -1)
|
||||
return FAIL; // pattern not found
|
||||
|
||||
@ -2957,7 +3061,7 @@ current_search(
|
||||
|
||||
result = searchit(curwin, curbuf, &pos, &end_pos,
|
||||
(dir ? FORWARD : BACKWARD),
|
||||
spats[last_idx].pat, (long) (i ? count : 1),
|
||||
spats[last_idx].pat, spats[last_idx].patlen, (long) (i ? count : 1),
|
||||
SEARCH_KEEP | flags, RE_SEARCH, NULL);
|
||||
|
||||
p_ws = old_p_ws;
|
||||
@ -3061,6 +3165,7 @@ cmdline_search_stat(
|
||||
pos_T *cursor_pos,
|
||||
int show_top_bot_msg,
|
||||
char_u *msgbuf,
|
||||
size_t msgbuflen,
|
||||
int recompute,
|
||||
int maxcount,
|
||||
long timeout)
|
||||
@ -3079,34 +3184,33 @@ cmdline_search_stat(
|
||||
if (curwin->w_p_rl && *curwin->w_p_rlc == 's')
|
||||
{
|
||||
if (stat.incomplete == 1)
|
||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
|
||||
len = vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
|
||||
else if (stat.cnt > maxcount && stat.cur > maxcount)
|
||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
|
||||
len = vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
|
||||
maxcount, maxcount);
|
||||
else if (stat.cnt > maxcount)
|
||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/%d]",
|
||||
len = vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/%d]",
|
||||
maxcount, stat.cur);
|
||||
else
|
||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
|
||||
len = vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
|
||||
stat.cnt, stat.cur);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (stat.incomplete == 1)
|
||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
|
||||
len = vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
|
||||
else if (stat.cnt > maxcount && stat.cur > maxcount)
|
||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
|
||||
len = vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
|
||||
maxcount, maxcount);
|
||||
else if (stat.cnt > maxcount)
|
||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/>%d]",
|
||||
len = vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/>%d]",
|
||||
stat.cur, maxcount);
|
||||
else
|
||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
|
||||
len = vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
|
||||
stat.cur, stat.cnt);
|
||||
}
|
||||
|
||||
len = STRLEN(t);
|
||||
if (show_top_bot_msg && len + 2 < SEARCH_STAT_BUF_LEN)
|
||||
{
|
||||
mch_memmove(t + 2, t, len);
|
||||
@ -3115,10 +3219,9 @@ cmdline_search_stat(
|
||||
len += 2;
|
||||
}
|
||||
|
||||
size_t msgbuf_len = STRLEN(msgbuf);
|
||||
if (len > msgbuf_len)
|
||||
len = msgbuf_len;
|
||||
mch_memmove(msgbuf + msgbuf_len - len, t, len);
|
||||
if (len > msgbuflen)
|
||||
len = msgbuflen;
|
||||
mch_memmove(msgbuf + msgbuflen - len, t, len);
|
||||
|
||||
if (dirc == '?' && stat.cur == maxcount + 1)
|
||||
stat.cur = -1;
|
||||
@ -3214,7 +3317,7 @@ update_search_stat(
|
||||
profile_setlimit(timeout, &start);
|
||||
#endif
|
||||
while (!got_int && searchit(curwin, curbuf, &lastpos, &endpos,
|
||||
FORWARD, NULL, 1, SEARCH_KEEP, RE_LAST, NULL) != FAIL)
|
||||
FORWARD, NULL, 0, 1, SEARCH_KEEP, RE_LAST, NULL) != FAIL)
|
||||
{
|
||||
done_search = TRUE;
|
||||
#ifdef FEAT_RELTIME
|
||||
@ -3342,7 +3445,7 @@ find_pattern_in_path(
|
||||
pat = alloc(len + 5);
|
||||
if (pat == NULL)
|
||||
goto fpip_end;
|
||||
sprintf((char *)pat, whole ? "\\<%.*s\\>" : "%.*s", len, ptr);
|
||||
vim_snprintf((char *)pat, len + 5, whole ? "\\<%.*s\\>" : "%.*s", len, ptr);
|
||||
// ignore case according to p_ic, p_scs and pat
|
||||
regmatch.rm_ic = ignorecase(pat);
|
||||
regmatch.regprog = vim_regcomp(pat, magic_isset() ? RE_MAGIC : 0);
|
||||
@ -3361,8 +3464,7 @@ find_pattern_in_path(
|
||||
}
|
||||
if (type == FIND_DEFINE && (*curbuf->b_p_def != NUL || *p_def != NUL))
|
||||
{
|
||||
def_regmatch.regprog = vim_regcomp(*curbuf->b_p_def == NUL
|
||||
? p_def : curbuf->b_p_def,
|
||||
def_regmatch.regprog = vim_regcomp(*curbuf->b_p_def == NUL ? p_def : curbuf->b_p_def,
|
||||
magic_isset() ? RE_MAGIC : 0);
|
||||
if (def_regmatch.regprog == NULL)
|
||||
goto fpip_end;
|
||||
@ -3879,7 +3981,7 @@ exit_matched:
|
||||
&& action == ACTION_EXPAND
|
||||
&& !compl_status_sol()
|
||||
&& *startp != NUL
|
||||
&& *(p = startp + mb_ptr2len(startp)) != NUL)
|
||||
&& *(startp + mb_ptr2len(startp)) != NUL)
|
||||
goto search_line;
|
||||
}
|
||||
line_breakcheck();
|
||||
@ -3976,6 +4078,7 @@ show_pat_in_path(
|
||||
long count)
|
||||
{
|
||||
char_u *p;
|
||||
size_t linelen;
|
||||
|
||||
if (did_show)
|
||||
msg_putchar('\n'); // cursor below last one
|
||||
@ -3983,9 +4086,10 @@ show_pat_in_path(
|
||||
gotocmdline(TRUE); // cursor at status line
|
||||
if (got_int) // 'q' typed at "--more--" message
|
||||
return;
|
||||
linelen = STRLEN(line);
|
||||
for (;;)
|
||||
{
|
||||
p = line + STRLEN(line) - 1;
|
||||
p = line + linelen - 1;
|
||||
if (fp != NULL)
|
||||
{
|
||||
// We used fgets(), so get rid of newline at end
|
||||
@ -4015,6 +4119,7 @@ show_pat_in_path(
|
||||
{
|
||||
if (vim_fgets(line, LSIZE, fp)) // end of file
|
||||
break;
|
||||
linelen = STRLEN(line);
|
||||
++*lnum;
|
||||
}
|
||||
else
|
||||
@ -4022,6 +4127,7 @@ show_pat_in_path(
|
||||
if (++*lnum > curbuf->b_ml.ml_line_count)
|
||||
break;
|
||||
line = ml_get(*lnum);
|
||||
linelen = ml_get_len(*lnum);
|
||||
}
|
||||
msg_putchar('\n');
|
||||
}
|
||||
@ -4149,7 +4255,10 @@ f_searchcount(typval_T *argvars, typval_T *rettv)
|
||||
if (*pattern == NUL)
|
||||
goto the_end;
|
||||
vim_free(spats[last_idx].pat);
|
||||
spats[last_idx].pat = vim_strsave(pattern);
|
||||
spats[last_idx].patlen = STRLEN(pattern);
|
||||
spats[last_idx].pat = vim_strnsave(pattern, spats[last_idx].patlen);
|
||||
if (spats[last_idx].pat == NULL)
|
||||
spats[last_idx].patlen = 0;
|
||||
}
|
||||
if (spats[last_idx].pat == NULL || *spats[last_idx].pat == NUL)
|
||||
goto the_end; // the previous pattern was never defined
|
||||
|
@ -2955,6 +2955,7 @@ ex_spellrepall(exarg_T *eap UNUSED)
|
||||
{
|
||||
pos_T pos = curwin->w_cursor;
|
||||
char_u *frompat;
|
||||
size_t frompatlen;
|
||||
char_u *line;
|
||||
char_u *p;
|
||||
int save_ws = p_ws;
|
||||
@ -2972,7 +2973,7 @@ ex_spellrepall(exarg_T *eap UNUSED)
|
||||
frompat = alloc(repl_from_len + 7);
|
||||
if (frompat == NULL)
|
||||
return;
|
||||
sprintf((char *)frompat, "\\V\\<%s\\>", repl_from);
|
||||
frompatlen = vim_snprintf((char *)frompat, repl_from_len + 7, "\\V\\<%s\\>", repl_from);
|
||||
p_ws = FALSE;
|
||||
|
||||
sub_nsubs = 0;
|
||||
@ -2980,7 +2981,7 @@ ex_spellrepall(exarg_T *eap UNUSED)
|
||||
curwin->w_cursor.lnum = 0;
|
||||
while (!got_int)
|
||||
{
|
||||
if (do_search(NULL, '/', '/', frompat, 1L, SEARCH_KEEP, NULL) == 0
|
||||
if (do_search(NULL, '/', '/', frompat, frompatlen, 1L, SEARCH_KEEP, NULL) == 0
|
||||
|| u_save_cursor() == FAIL)
|
||||
break;
|
||||
|
||||
|
@ -4795,6 +4795,7 @@ typedef struct soffset
|
||||
typedef struct spat
|
||||
{
|
||||
char_u *pat; // the pattern (in allocated memory) or NULL
|
||||
size_t patlen; // the length of the patten (0 is pat is NULL)
|
||||
int magic; // magicness of the pattern
|
||||
int no_scs; // no smartcase for this pattern
|
||||
soffset_T off;
|
||||
|
14
src/tag.c
14
src/tag.c
@ -3901,6 +3901,8 @@ jumpto_tag(
|
||||
str = skip_regexp(pbuf + 1, pbuf[0], FALSE) + 1;
|
||||
if (str > pbuf_end - 1) // search command with nothing following
|
||||
{
|
||||
size_t pbuflen = pbuf_end - pbuf;
|
||||
|
||||
save_p_ws = p_ws;
|
||||
save_p_ic = p_ic;
|
||||
save_p_scs = p_scs;
|
||||
@ -3914,7 +3916,7 @@ jumpto_tag(
|
||||
else
|
||||
// start search before first line
|
||||
curwin->w_cursor.lnum = 0;
|
||||
if (do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, (long)1,
|
||||
if (do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, pbuflen - 1, (long)1,
|
||||
search_options, NULL))
|
||||
retval = OK;
|
||||
else
|
||||
@ -3926,7 +3928,7 @@ jumpto_tag(
|
||||
* try again, ignore case now
|
||||
*/
|
||||
p_ic = TRUE;
|
||||
if (!do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, (long)1,
|
||||
if (!do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, pbuflen - 1, (long)1,
|
||||
search_options, NULL))
|
||||
{
|
||||
/*
|
||||
@ -3936,14 +3938,14 @@ jumpto_tag(
|
||||
(void)test_for_static(&tagp);
|
||||
cc = *tagp.tagname_end;
|
||||
*tagp.tagname_end = NUL;
|
||||
sprintf((char *)pbuf, "^%s\\s\\*(", tagp.tagname);
|
||||
if (!do_search(NULL, '/', '/', pbuf, (long)1,
|
||||
pbuflen = vim_snprintf((char *)pbuf, LSIZE, "^%s\\s\\*(", tagp.tagname);
|
||||
if (!do_search(NULL, '/', '/', pbuf, pbuflen, (long)1,
|
||||
search_options, NULL))
|
||||
{
|
||||
// Guess again: "^char * \<func ("
|
||||
sprintf((char *)pbuf, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(",
|
||||
pbuflen = vim_snprintf((char *)pbuf, LSIZE, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(",
|
||||
tagp.tagname);
|
||||
if (!do_search(NULL, '/', '/', pbuf, (long)1,
|
||||
if (!do_search(NULL, '/', '/', pbuf, len, (long)1,
|
||||
search_options, NULL))
|
||||
found = 0;
|
||||
}
|
||||
|
@ -704,6 +704,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
426,
|
||||
/**/
|
||||
425,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user