mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-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: vim/vim#14796
8c85a2a49a
Co-authored-by: John Marriott <basilisk@internode.on.net>
This commit is contained in:
parent
879d17ea8d
commit
b86381f425
@ -294,7 +294,7 @@ static int last_maptick = -1; // last seen maptick
|
|||||||
/// @param histype may be one of the HIST_ values.
|
/// @param histype may be one of the HIST_ values.
|
||||||
/// @param in_map consider maptick when inside a mapping
|
/// @param in_map consider maptick when inside a mapping
|
||||||
/// @param sep separator character used (search hist)
|
/// @param sep separator character used (search hist)
|
||||||
void add_to_history(int histype, const char *new_entry, int in_map, int sep)
|
void add_to_history(int histype, const char *new_entry, size_t new_entrylen, bool in_map, int sep)
|
||||||
{
|
{
|
||||||
histentry_T *hisptr;
|
histentry_T *hisptr;
|
||||||
|
|
||||||
@ -334,11 +334,10 @@ void add_to_history(int histype, const char *new_entry, int in_map, int sep)
|
|||||||
hist_free_entry(hisptr);
|
hist_free_entry(hisptr);
|
||||||
|
|
||||||
// Store the separator after the NUL of the string.
|
// Store the separator after the NUL of the string.
|
||||||
size_t len = strlen(new_entry);
|
hisptr->hisstr = xstrnsave(new_entry, new_entrylen + 2);
|
||||||
hisptr->hisstr = xstrnsave(new_entry, len + 2);
|
|
||||||
hisptr->timestamp = os_time();
|
hisptr->timestamp = os_time();
|
||||||
hisptr->additional_elements = NULL;
|
hisptr->additional_elements = NULL;
|
||||||
hisptr->hisstr[len + 1] = (char)sep;
|
hisptr->hisstr[new_entrylen + 1] = (char)sep;
|
||||||
|
|
||||||
hisptr->hisnum = ++hisnum[histype];
|
hisptr->hisnum = ++hisnum[histype];
|
||||||
if (histype == HIST_SEARCH && in_map) {
|
if (histype == HIST_SEARCH && in_map) {
|
||||||
@ -536,7 +535,7 @@ void f_histadd(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
init_history();
|
init_history();
|
||||||
add_to_history(histype, str, false, NUL);
|
add_to_history(histype, str, strlen(str), false, NUL);
|
||||||
rettv->vval.v_number = true;
|
rettv->vval.v_number = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7076,12 +7076,13 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
|
|||||||
.sa_tm = &tm,
|
.sa_tm = &tm,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const size_t patlen = strlen(pat);
|
||||||
int subpatnum;
|
int subpatnum;
|
||||||
|
|
||||||
// Repeat until {skip} returns false.
|
// Repeat until {skip} returns false.
|
||||||
while (true) {
|
while (true) {
|
||||||
subpatnum
|
subpatnum = searchit(curwin, curbuf, &pos, NULL, dir, (char *)pat, patlen, 1,
|
||||||
= searchit(curwin, curbuf, &pos, NULL, dir, (char *)pat, 1, options, RE_SEARCH, &sia);
|
options, RE_SEARCH, &sia);
|
||||||
// finding the first match again means there is no match where {skip}
|
// finding the first match again means there is no match where {skip}
|
||||||
// evaluates to zero.
|
// evaluates to zero.
|
||||||
if (firstpos.lnum != 0 && equalpos(pos, firstpos)) {
|
if (firstpos.lnum != 0 && equalpos(pos, firstpos)) {
|
||||||
@ -7636,16 +7637,20 @@ int do_searchpair(const char *spat, const char *mpat, const char *epat, int dir,
|
|||||||
|
|
||||||
// Make two search patterns: start/end (pat2, for in nested pairs) and
|
// Make two search patterns: start/end (pat2, for in nested pairs) and
|
||||||
// start/middle/end (pat3, for the top pair).
|
// start/middle/end (pat3, for the top pair).
|
||||||
const size_t pat2_len = strlen(spat) + strlen(epat) + 17;
|
const size_t spatlen = strlen(spat);
|
||||||
char *pat2 = xmalloc(pat2_len);
|
const size_t epatlen = strlen(epat);
|
||||||
const size_t pat3_len = strlen(spat) + strlen(mpat) + strlen(epat) + 25;
|
const size_t pat2size = spatlen + epatlen + 17;
|
||||||
char *pat3 = xmalloc(pat3_len);
|
char *pat2 = xmalloc(pat2size);
|
||||||
snprintf(pat2, pat2_len, "\\m\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
|
const size_t pat3size = spatlen + strlen(mpat) + epatlen + 25;
|
||||||
|
char *pat3 = xmalloc(pat3size);
|
||||||
|
int pat2len = snprintf(pat2, pat2size, "\\m\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
|
||||||
|
int pat3len;
|
||||||
if (*mpat == NUL) {
|
if (*mpat == NUL) {
|
||||||
STRCPY(pat3, pat2);
|
STRCPY(pat3, pat2);
|
||||||
|
pat3len = pat2len;
|
||||||
} else {
|
} else {
|
||||||
snprintf(pat3, pat3_len,
|
pat3len = snprintf(pat3, pat3size,
|
||||||
"\\m\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat, mpat);
|
"\\m\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat, mpat);
|
||||||
}
|
}
|
||||||
if (flags & SP_START) {
|
if (flags & SP_START) {
|
||||||
options |= SEARCH_START;
|
options |= SEARCH_START;
|
||||||
@ -7662,13 +7667,15 @@ int do_searchpair(const char *spat, const char *mpat, const char *epat, int dir,
|
|||||||
pos_T foundpos;
|
pos_T foundpos;
|
||||||
clearpos(&foundpos);
|
clearpos(&foundpos);
|
||||||
char *pat = pat3;
|
char *pat = pat3;
|
||||||
|
assert(pat3len >= 0);
|
||||||
|
size_t patlen = (size_t)pat3len;
|
||||||
while (true) {
|
while (true) {
|
||||||
searchit_arg_T sia = {
|
searchit_arg_T sia = {
|
||||||
.sa_stop_lnum = lnum_stop,
|
.sa_stop_lnum = lnum_stop,
|
||||||
.sa_tm = &tm,
|
.sa_tm = &tm,
|
||||||
};
|
};
|
||||||
|
|
||||||
int n = searchit(curwin, curbuf, &pos, NULL, dir, pat, 1,
|
int n = searchit(curwin, curbuf, &pos, NULL, dir, pat, patlen, 1,
|
||||||
options, RE_SEARCH, &sia);
|
options, RE_SEARCH, &sia);
|
||||||
if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) {
|
if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) {
|
||||||
// didn't find it or found the first match again: FAIL
|
// didn't find it or found the first match again: FAIL
|
||||||
|
@ -3099,8 +3099,9 @@ void sub_set_replacement(SubReplacementString sub)
|
|||||||
/// @param[in] save Save pattern to options, history
|
/// @param[in] save Save pattern to options, history
|
||||||
///
|
///
|
||||||
/// @returns true if :substitute can be replaced with a join command
|
/// @returns true if :substitute can be replaced with a join command
|
||||||
static bool sub_joining_lines(exarg_T *eap, char *pat, const char *sub, const char *cmd, bool save)
|
static bool sub_joining_lines(exarg_T *eap, char *pat, size_t patlen, const char *sub,
|
||||||
FUNC_ATTR_NONNULL_ARG(1, 3, 4)
|
const char *cmd, bool save)
|
||||||
|
FUNC_ATTR_NONNULL_ARG(1, 4, 5)
|
||||||
{
|
{
|
||||||
// TODO(vim): find a generic solution to make line-joining operations more
|
// TODO(vim): find a generic solution to make line-joining operations more
|
||||||
// efficient, avoid allocating a string that grows in size.
|
// efficient, avoid allocating a string that grows in size.
|
||||||
@ -3138,10 +3139,10 @@ static bool sub_joining_lines(exarg_T *eap, char *pat, const char *sub, const ch
|
|||||||
|
|
||||||
if (save) {
|
if (save) {
|
||||||
if ((cmdmod.cmod_flags & CMOD_KEEPPATTERNS) == 0) {
|
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
|
// put pattern in history
|
||||||
add_to_history(HIST_SEARCH, pat, true, NUL);
|
add_to_history(HIST_SEARCH, pat, patlen, true, NUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -3332,6 +3333,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
|
|||||||
};
|
};
|
||||||
char *pat = NULL;
|
char *pat = NULL;
|
||||||
char *sub = NULL; // init for GCC
|
char *sub = NULL; // init for GCC
|
||||||
|
size_t patlen = 0;
|
||||||
int delimiter;
|
int delimiter;
|
||||||
bool has_second_delim = false;
|
bool has_second_delim = false;
|
||||||
int sublen;
|
int sublen;
|
||||||
@ -3383,12 +3385,14 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
|
|||||||
which_pat = RE_SEARCH; // use last '/' pattern
|
which_pat = RE_SEARCH; // use last '/' pattern
|
||||||
}
|
}
|
||||||
pat = ""; // empty search pattern
|
pat = ""; // empty search pattern
|
||||||
|
patlen = 0;
|
||||||
delimiter = (uint8_t)(*cmd++); // remember delimiter character
|
delimiter = (uint8_t)(*cmd++); // remember delimiter character
|
||||||
has_second_delim = true;
|
has_second_delim = true;
|
||||||
} else { // find the end of the regexp
|
} else { // find the end of the regexp
|
||||||
which_pat = RE_LAST; // use last used regexp
|
which_pat = RE_LAST; // use last used regexp
|
||||||
delimiter = (uint8_t)(*cmd++); // remember delimiter character
|
delimiter = (uint8_t)(*cmd++); // remember delimiter character
|
||||||
pat = cmd; // remember start of search pat
|
pat = cmd; // remember start of search pat
|
||||||
|
patlen = strlen(pat);
|
||||||
cmd = skip_regexp_ex(cmd, delimiter, magic_isset(), &eap->arg, NULL, NULL);
|
cmd = skip_regexp_ex(cmd, delimiter, magic_isset(), &eap->arg, NULL, NULL);
|
||||||
if (cmd[0] == delimiter) { // end delimiter found
|
if (cmd[0] == delimiter) { // end delimiter found
|
||||||
*cmd++ = NUL; // replace it with a NUL
|
*cmd++ = NUL; // replace it with a NUL
|
||||||
@ -3415,6 +3419,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
pat = NULL; // search_regcomp() will use previous pattern
|
pat = NULL; // search_regcomp() will use previous pattern
|
||||||
|
patlen = 0;
|
||||||
sub = xstrdup(old_sub.sub);
|
sub = xstrdup(old_sub.sub);
|
||||||
|
|
||||||
// Vi compatibility quirk: repeating with ":s" keeps the cursor in the
|
// Vi compatibility quirk: repeating with ":s" keeps the cursor in the
|
||||||
@ -3422,7 +3427,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
|
|||||||
endcolumn = (curwin->w_curswant == MAXCOL);
|
endcolumn = (curwin->w_curswant == MAXCOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sub != NULL && sub_joining_lines(eap, pat, sub, cmd, cmdpreview_ns <= 0)) {
|
if (sub != NULL && sub_joining_lines(eap, pat, patlen, sub, cmd, cmdpreview_ns <= 0)) {
|
||||||
xfree(sub);
|
xfree(sub);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -3477,7 +3482,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (search_regcomp(pat, NULL, RE_SUBST, which_pat,
|
if (search_regcomp(pat, patlen, NULL, RE_SUBST, which_pat,
|
||||||
(cmdpreview_ns > 0 ? 0 : SEARCH_HIS), ®match) == FAIL) {
|
(cmdpreview_ns > 0 ? 0 : SEARCH_HIS), ®match) == FAIL) {
|
||||||
if (subflags.do_error) {
|
if (subflags.do_error) {
|
||||||
emsg(_(e_invcmd));
|
emsg(_(e_invcmd));
|
||||||
@ -4390,6 +4395,7 @@ void ex_global(exarg_T *eap)
|
|||||||
|
|
||||||
char delim; // delimiter, normally '/'
|
char delim; // delimiter, normally '/'
|
||||||
char *pat;
|
char *pat;
|
||||||
|
size_t patlen;
|
||||||
regmmatch_T regmatch;
|
regmmatch_T regmatch;
|
||||||
|
|
||||||
// When nesting the command works on one line. This allows for
|
// When nesting the command works on one line. This allows for
|
||||||
@ -4425,6 +4431,7 @@ void ex_global(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
cmd++;
|
cmd++;
|
||||||
pat = "";
|
pat = "";
|
||||||
|
patlen = 0;
|
||||||
} else if (*cmd == NUL) {
|
} else if (*cmd == NUL) {
|
||||||
emsg(_("E148: Regular expression missing from global"));
|
emsg(_("E148: Regular expression missing from global"));
|
||||||
return;
|
return;
|
||||||
@ -4434,6 +4441,7 @@ void ex_global(exarg_T *eap)
|
|||||||
delim = *cmd; // get the delimiter
|
delim = *cmd; // get the delimiter
|
||||||
cmd++; // skip delimiter if there is one
|
cmd++; // skip delimiter if there is one
|
||||||
pat = cmd; // remember start of pattern
|
pat = cmd; // remember start of pattern
|
||||||
|
patlen = strlen(pat);
|
||||||
cmd = skip_regexp_ex(cmd, delim, magic_isset(), &eap->arg, NULL, NULL);
|
cmd = skip_regexp_ex(cmd, delim, magic_isset(), &eap->arg, NULL, NULL);
|
||||||
if (cmd[0] == delim) { // end delimiter found
|
if (cmd[0] == delim) { // end delimiter found
|
||||||
*cmd++ = NUL; // replace it with a NUL
|
*cmd++ = NUL; // replace it with a NUL
|
||||||
@ -4441,7 +4449,7 @@ void ex_global(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *used_pat;
|
char *used_pat;
|
||||||
if (search_regcomp(pat, &used_pat, RE_BOTH, which_pat,
|
if (search_regcomp(pat, patlen, &used_pat, RE_BOTH, which_pat,
|
||||||
SEARCH_HIS, ®match) == FAIL) {
|
SEARCH_HIS, ®match) == FAIL) {
|
||||||
emsg(_(e_invcmd));
|
emsg(_(e_invcmd));
|
||||||
return;
|
return;
|
||||||
|
@ -3506,7 +3506,7 @@ static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, bool
|
|||||||
}
|
}
|
||||||
searchcmdlen = 0;
|
searchcmdlen = 0;
|
||||||
flags = silent ? 0 : SEARCH_HIS | SEARCH_MSG;
|
flags = silent ? 0 : SEARCH_HIS | SEARCH_MSG;
|
||||||
if (!do_search(NULL, c, c, cmd, 1, flags, NULL)) {
|
if (!do_search(NULL, c, c, cmd, strlen(cmd), 1, flags, NULL)) {
|
||||||
curwin->w_cursor = pos;
|
curwin->w_cursor = pos;
|
||||||
cmd = NULL;
|
cmd = NULL;
|
||||||
goto error;
|
goto error;
|
||||||
@ -3543,7 +3543,7 @@ static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, bool
|
|||||||
pos.coladd = 0;
|
pos.coladd = 0;
|
||||||
if (searchit(curwin, curbuf, &pos, NULL,
|
if (searchit(curwin, curbuf, &pos, NULL,
|
||||||
*cmd == '?' ? BACKWARD : FORWARD,
|
*cmd == '?' ? BACKWARD : FORWARD,
|
||||||
"", 1, SEARCH_MSG, i, NULL) != FAIL) {
|
"", 0, 1, SEARCH_MSG, i, NULL) != FAIL) {
|
||||||
lnum = pos.lnum;
|
lnum = pos.lnum;
|
||||||
} else {
|
} else {
|
||||||
cmd = NULL;
|
cmd = NULL;
|
||||||
|
@ -470,7 +470,7 @@ static void may_do_incsearch_highlighting(int firstc, int count, incsearch_state
|
|||||||
.sa_tm = &tm,
|
.sa_tm = &tm,
|
||||||
};
|
};
|
||||||
found = do_search(NULL, firstc == ':' ? '/' : firstc, search_delim,
|
found = do_search(NULL, firstc == ':' ? '/' : firstc, search_delim,
|
||||||
ccline.cmdbuff + skiplen, count,
|
ccline.cmdbuff + skiplen, (size_t)patlen, count,
|
||||||
search_flags, &sia);
|
search_flags, &sia);
|
||||||
ccline.cmdbuff[skiplen + patlen] = next_char;
|
ccline.cmdbuff[skiplen + patlen] = next_char;
|
||||||
emsg_off--;
|
emsg_off--;
|
||||||
@ -884,11 +884,12 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear
|
|||||||
&& ccline.cmdlen
|
&& ccline.cmdlen
|
||||||
&& s->firstc != NUL
|
&& s->firstc != NUL
|
||||||
&& (s->some_key_typed || s->histype == HIST_SEARCH)) {
|
&& (s->some_key_typed || s->histype == HIST_SEARCH)) {
|
||||||
add_to_history(s->histype, ccline.cmdbuff, true,
|
size_t cmdbufflen = strlen(ccline.cmdbuff);
|
||||||
|
add_to_history(s->histype, ccline.cmdbuff, cmdbufflen, true,
|
||||||
s->histype == HIST_SEARCH ? s->firstc : NUL);
|
s->histype == HIST_SEARCH ? s->firstc : NUL);
|
||||||
if (s->firstc == ':') {
|
if (s->firstc == ':') {
|
||||||
xfree(new_last_cmdline);
|
xfree(new_last_cmdline);
|
||||||
new_last_cmdline = xstrdup(ccline.cmdbuff);
|
new_last_cmdline = xstrnsave(ccline.cmdbuff, cmdbufflen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1451,7 +1452,7 @@ static int may_do_command_line_next_incsearch(int firstc, int count, incsearch_s
|
|||||||
pat[patlen] = NUL;
|
pat[patlen] = NUL;
|
||||||
int found = searchit(curwin, curbuf, &t, NULL,
|
int found = searchit(curwin, curbuf, &t, NULL,
|
||||||
next_match ? FORWARD : BACKWARD,
|
next_match ? FORWARD : BACKWARD,
|
||||||
pat, count, search_flags,
|
pat, (size_t)patlen, count, search_flags,
|
||||||
RE_SEARCH, NULL);
|
RE_SEARCH, NULL);
|
||||||
emsg_off--;
|
emsg_off--;
|
||||||
pat[patlen] = save;
|
pat[patlen] = save;
|
||||||
|
@ -253,6 +253,7 @@ static int ctrl_x_mode = CTRL_X_NORMAL;
|
|||||||
|
|
||||||
static int compl_matches = 0; ///< number of completion matches
|
static int compl_matches = 0; ///< number of completion matches
|
||||||
static char *compl_pattern = NULL;
|
static char *compl_pattern = NULL;
|
||||||
|
static size_t compl_patternlen = 0;
|
||||||
static Direction compl_direction = FORWARD;
|
static Direction compl_direction = FORWARD;
|
||||||
static Direction compl_shows_dir = FORWARD;
|
static Direction compl_shows_dir = FORWARD;
|
||||||
static int compl_pending = 0; ///< > 1 for postponed CTRL-N
|
static int compl_pending = 0; ///< > 1 for postponed CTRL-N
|
||||||
@ -1583,6 +1584,7 @@ static char *find_line_end(char *ptr)
|
|||||||
static void ins_compl_free(void)
|
static void ins_compl_free(void)
|
||||||
{
|
{
|
||||||
XFREE_CLEAR(compl_pattern);
|
XFREE_CLEAR(compl_pattern);
|
||||||
|
compl_patternlen = 0;
|
||||||
XFREE_CLEAR(compl_leader);
|
XFREE_CLEAR(compl_leader);
|
||||||
|
|
||||||
if (compl_first_match == NULL) {
|
if (compl_first_match == NULL) {
|
||||||
@ -1617,6 +1619,7 @@ void ins_compl_clear(void)
|
|||||||
compl_started = false;
|
compl_started = false;
|
||||||
compl_matches = 0;
|
compl_matches = 0;
|
||||||
XFREE_CLEAR(compl_pattern);
|
XFREE_CLEAR(compl_pattern);
|
||||||
|
compl_patternlen = 0;
|
||||||
XFREE_CLEAR(compl_leader);
|
XFREE_CLEAR(compl_leader);
|
||||||
edit_submode_extra = NULL;
|
edit_submode_extra = NULL;
|
||||||
kv_destroy(compl_orig_extmarks);
|
kv_destroy(compl_orig_extmarks);
|
||||||
@ -2991,7 +2994,7 @@ done:
|
|||||||
static void get_next_include_file_completion(int compl_type)
|
static void get_next_include_file_completion(int compl_type)
|
||||||
{
|
{
|
||||||
find_pattern_in_path(compl_pattern, compl_direction,
|
find_pattern_in_path(compl_pattern, compl_direction,
|
||||||
strlen(compl_pattern), false, false,
|
compl_patternlen, false, false,
|
||||||
((compl_type == CTRL_X_PATH_DEFINES
|
((compl_type == CTRL_X_PATH_DEFINES
|
||||||
&& !(compl_cont_status & CONT_SOL))
|
&& !(compl_cont_status & CONT_SOL))
|
||||||
? FIND_DEFINE : FIND_ANY),
|
? FIND_DEFINE : FIND_ANY),
|
||||||
@ -3074,8 +3077,7 @@ static void get_next_cmdline_completion(void)
|
|||||||
char **matches;
|
char **matches;
|
||||||
int num_matches;
|
int num_matches;
|
||||||
if (expand_cmdline(&compl_xp, compl_pattern,
|
if (expand_cmdline(&compl_xp, compl_pattern,
|
||||||
(int)strlen(compl_pattern),
|
(int)compl_patternlen, &num_matches, &matches) == EXPAND_OK) {
|
||||||
&num_matches, &matches) == EXPAND_OK) {
|
|
||||||
ins_compl_add_matches(num_matches, matches, false);
|
ins_compl_add_matches(num_matches, matches, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3217,8 +3219,8 @@ static int get_next_default_completion(ins_compl_next_state_T *st, pos_T *start_
|
|||||||
compl_direction, compl_pattern);
|
compl_direction, compl_pattern);
|
||||||
} else {
|
} else {
|
||||||
found_new_match = searchit(NULL, st->ins_buf, st->cur_match_pos,
|
found_new_match = searchit(NULL, st->ins_buf, st->cur_match_pos,
|
||||||
NULL, compl_direction, compl_pattern, 1,
|
NULL, compl_direction, compl_pattern, compl_patternlen,
|
||||||
SEARCH_KEEP + SEARCH_NFMSG, RE_LAST, NULL);
|
1, SEARCH_KEEP + SEARCH_NFMSG, RE_LAST, NULL);
|
||||||
}
|
}
|
||||||
msg_silent--;
|
msg_silent--;
|
||||||
if (!compl_started || st->set_match_pos) {
|
if (!compl_started || st->set_match_pos) {
|
||||||
@ -3902,7 +3904,8 @@ static bool ins_compl_use_match(int c)
|
|||||||
|
|
||||||
/// Get the pattern, column and length for normal completion (CTRL-N CTRL-P
|
/// Get the pattern, column and length for normal completion (CTRL-N CTRL-P
|
||||||
/// completion)
|
/// 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
|
/// Uses the global variables: compl_cont_status and ctrl_x_mode
|
||||||
static int get_normal_compl_info(char *line, int startcol, colnr_T curs_col)
|
static int get_normal_compl_info(char *line, int startcol, colnr_T curs_col)
|
||||||
{
|
{
|
||||||
@ -3919,21 +3922,23 @@ static int get_normal_compl_info(char *line, int startcol, colnr_T curs_col)
|
|||||||
}
|
}
|
||||||
} else if (compl_status_adding()) {
|
} else if (compl_status_adding()) {
|
||||||
char *prefix = "\\<";
|
char *prefix = "\\<";
|
||||||
|
size_t prefixlen = STRLEN_LITERAL("\\<");
|
||||||
|
|
||||||
// we need up to 2 extra chars for the prefix
|
// we need up to 2 extra chars for the prefix
|
||||||
compl_pattern = xmalloc(quote_meta(NULL, line + compl_col, compl_length) + 2);
|
compl_pattern = xmalloc(quote_meta(NULL, line + compl_col,
|
||||||
|
compl_length) + prefixlen);
|
||||||
if (!vim_iswordp(line + compl_col)
|
if (!vim_iswordp(line + compl_col)
|
||||||
|| (compl_col > 0
|
|| (compl_col > 0
|
||||||
&& (vim_iswordp(mb_prevptr(line, line + compl_col))))) {
|
&& (vim_iswordp(mb_prevptr(line, line + compl_col))))) {
|
||||||
prefix = "";
|
prefix = "";
|
||||||
|
prefixlen = 0;
|
||||||
}
|
}
|
||||||
STRCPY(compl_pattern, prefix);
|
STRCPY(compl_pattern, prefix);
|
||||||
quote_meta(compl_pattern + strlen(prefix),
|
quote_meta(compl_pattern + prefixlen, line + compl_col, compl_length);
|
||||||
line + compl_col, compl_length);
|
|
||||||
} else if (--startcol < 0
|
} else if (--startcol < 0
|
||||||
|| !vim_iswordp(mb_prevptr(line, line + startcol + 1))) {
|
|| !vim_iswordp(mb_prevptr(line, line + startcol + 1))) {
|
||||||
// Match any word of at least two chars
|
// Match any word of at least two chars
|
||||||
compl_pattern = xstrdup("\\<\\k\\k");
|
compl_pattern = xstrnsave(S_LEN("\\<\\k\\k"));
|
||||||
compl_col += curs_col;
|
compl_col += curs_col;
|
||||||
compl_length = 0;
|
compl_length = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -3965,6 +3970,8 @@ static int get_normal_compl_info(char *line, int startcol, colnr_T curs_col)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compl_patternlen = strlen(compl_pattern);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3984,6 +3991,8 @@ static int get_wholeline_compl_info(char *line, colnr_T curs_col)
|
|||||||
compl_pattern = xstrnsave(line + compl_col, (size_t)compl_length);
|
compl_pattern = xstrnsave(line + compl_col, (size_t)compl_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compl_patternlen = strlen(compl_pattern);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4009,6 +4018,7 @@ static int get_filename_compl_info(char *line, int startcol, colnr_T curs_col)
|
|||||||
compl_col += startcol;
|
compl_col += startcol;
|
||||||
compl_length = (int)curs_col - startcol;
|
compl_length = (int)curs_col - startcol;
|
||||||
compl_pattern = addstar(line + compl_col, (size_t)compl_length, EXPAND_FILES);
|
compl_pattern = addstar(line + compl_col, (size_t)compl_length, EXPAND_FILES);
|
||||||
|
compl_patternlen = strlen(compl_pattern);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -4018,7 +4028,8 @@ static int get_filename_compl_info(char *line, int startcol, colnr_T curs_col)
|
|||||||
static int get_cmdline_compl_info(char *line, colnr_T curs_col)
|
static int get_cmdline_compl_info(char *line, colnr_T curs_col)
|
||||||
{
|
{
|
||||||
compl_pattern = xstrnsave(line, (size_t)curs_col);
|
compl_pattern = xstrnsave(line, (size_t)curs_col);
|
||||||
set_cmd_context(&compl_xp, compl_pattern, (int)strlen(compl_pattern), curs_col, false);
|
compl_patternlen = (size_t)curs_col;
|
||||||
|
set_cmd_context(&compl_xp, compl_pattern, (int)compl_patternlen, curs_col, false);
|
||||||
if (compl_xp.xp_context == EXPAND_UNSUCCESSFUL
|
if (compl_xp.xp_context == EXPAND_UNSUCCESSFUL
|
||||||
|| compl_xp.xp_context == EXPAND_NOTHING) {
|
|| compl_xp.xp_context == EXPAND_NOTHING) {
|
||||||
// No completion possible, use an empty pattern to get a
|
// No completion possible, use an empty pattern to get a
|
||||||
@ -4104,6 +4115,7 @@ static int get_userdefined_compl_info(colnr_T curs_col)
|
|||||||
char *line = ml_get(curwin->w_cursor.lnum);
|
char *line = ml_get(curwin->w_cursor.lnum);
|
||||||
compl_length = curs_col - compl_col;
|
compl_length = curs_col - compl_col;
|
||||||
compl_pattern = xstrnsave(line + compl_col, (size_t)compl_length);
|
compl_pattern = xstrnsave(line + compl_col, (size_t)compl_length);
|
||||||
|
compl_patternlen = (size_t)compl_length;
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -4129,6 +4141,7 @@ static int get_spell_compl_info(int startcol, colnr_T curs_col)
|
|||||||
// Need to obtain "line" again, it may have become invalid.
|
// Need to obtain "line" again, it may have become invalid.
|
||||||
char *line = ml_get(curwin->w_cursor.lnum);
|
char *line = ml_get(curwin->w_cursor.lnum);
|
||||||
compl_pattern = xstrnsave(line + compl_col, (size_t)compl_length);
|
compl_pattern = xstrnsave(line + compl_col, (size_t)compl_length);
|
||||||
|
compl_patternlen = (size_t)compl_length;
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -4324,6 +4337,7 @@ static int ins_compl_start(void)
|
|||||||
if (ins_compl_add(compl_orig_text, -1, NULL, NULL, false, NULL, 0,
|
if (ins_compl_add(compl_orig_text, -1, NULL, NULL, false, NULL, 0,
|
||||||
flags, false) != OK) {
|
flags, false) != OK) {
|
||||||
XFREE_CLEAR(compl_pattern);
|
XFREE_CLEAR(compl_pattern);
|
||||||
|
compl_patternlen = 0;
|
||||||
XFREE_CLEAR(compl_orig_text);
|
XFREE_CLEAR(compl_orig_text);
|
||||||
kv_destroy(compl_orig_extmarks);
|
kv_destroy(compl_orig_extmarks);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
@ -2349,13 +2349,15 @@ bool find_decl(char *ptr, size_t len, bool locally, bool thisblock, int flags_ar
|
|||||||
bool incll;
|
bool incll;
|
||||||
int searchflags = flags_arg;
|
int searchflags = flags_arg;
|
||||||
|
|
||||||
size_t patlen = len + 7;
|
size_t patsize = len + 7;
|
||||||
char *pat = xmalloc(patlen);
|
char *pat = xmalloc(patsize);
|
||||||
|
|
||||||
// Put "\V" before the pattern to avoid that the special meaning of "."
|
// Put "\V" before the pattern to avoid that the special meaning of "."
|
||||||
// and "~" causes trouble.
|
// and "~" causes trouble.
|
||||||
assert(patlen <= INT_MAX);
|
assert(patsize <= INT_MAX);
|
||||||
snprintf(pat, patlen, vim_iswordp(ptr) ? "\\V\\<%.*s\\>" : "\\V%.*s", (int)len, ptr);
|
size_t patlen = (size_t)snprintf(pat, patsize,
|
||||||
|
vim_iswordp(ptr) ? "\\V\\<%.*s\\>" : "\\V%.*s",
|
||||||
|
(int)len, ptr);
|
||||||
pos_T old_pos = curwin->w_cursor;
|
pos_T old_pos = curwin->w_cursor;
|
||||||
bool save_p_ws = p_ws;
|
bool save_p_ws = p_ws;
|
||||||
bool save_p_scs = p_scs;
|
bool save_p_scs = p_scs;
|
||||||
@ -2382,7 +2384,7 @@ bool find_decl(char *ptr, size_t len, bool locally, bool thisblock, int flags_ar
|
|||||||
clearpos(&found_pos);
|
clearpos(&found_pos);
|
||||||
while (true) {
|
while (true) {
|
||||||
t = searchit(curwin, curbuf, &curwin->w_cursor, NULL, FORWARD,
|
t = searchit(curwin, curbuf, &curwin->w_cursor, NULL, FORWARD,
|
||||||
pat, 1, searchflags, RE_LAST, NULL);
|
pat, patlen, 1, searchflags, RE_LAST, NULL);
|
||||||
if (curwin->w_cursor.lnum >= old_pos.lnum) {
|
if (curwin->w_cursor.lnum >= old_pos.lnum) {
|
||||||
t = false; // match after start is failure too
|
t = false; // match after start is failure too
|
||||||
}
|
}
|
||||||
@ -3296,21 +3298,22 @@ void do_nv_ident(int c1, int c2)
|
|||||||
/// 'K' normal-mode command. Get the command to lookup the keyword under the
|
/// 'K' normal-mode command. Get the command to lookup the keyword under the
|
||||||
/// cursor.
|
/// cursor.
|
||||||
static size_t nv_K_getcmd(cmdarg_T *cap, char *kp, bool kp_help, bool kp_ex, char **ptr_arg,
|
static size_t nv_K_getcmd(cmdarg_T *cap, char *kp, bool kp_help, bool kp_ex, char **ptr_arg,
|
||||||
size_t n, char *buf, size_t buf_size)
|
size_t n, char *buf, size_t bufsize, size_t *buflen)
|
||||||
{
|
{
|
||||||
if (kp_help) {
|
if (kp_help) {
|
||||||
// in the help buffer
|
// in the help buffer
|
||||||
STRCPY(buf, "he! ");
|
STRCPY(buf, "he! ");
|
||||||
|
*buflen = STRLEN_LITERAL("he! ");
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kp_ex) {
|
if (kp_ex) {
|
||||||
|
*buflen = 0;
|
||||||
// 'keywordprg' is an ex command
|
// 'keywordprg' is an ex command
|
||||||
if (cap->count0 != 0) { // Send the count to the ex command.
|
if (cap->count0 != 0) { // Send the count to the ex command.
|
||||||
snprintf(buf, buf_size, "%" PRId64, (int64_t)(cap->count0));
|
*buflen = (size_t)snprintf(buf, bufsize, "%" PRId64, (int64_t)(cap->count0));
|
||||||
}
|
}
|
||||||
STRCAT(buf, kp);
|
*buflen += (size_t)snprintf(buf + *buflen, bufsize - *buflen, "%s ", kp);
|
||||||
STRCAT(buf, " ");
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3335,21 +3338,19 @@ static size_t nv_K_getcmd(cmdarg_T *cap, char *kp, bool kp_help, bool kp_ex, cha
|
|||||||
bool isman = (strcmp(kp, "man") == 0);
|
bool isman = (strcmp(kp, "man") == 0);
|
||||||
bool isman_s = (strcmp(kp, "man -s") == 0);
|
bool isman_s = (strcmp(kp, "man -s") == 0);
|
||||||
if (cap->count0 != 0 && !(isman || isman_s)) {
|
if (cap->count0 != 0 && !(isman || isman_s)) {
|
||||||
snprintf(buf, buf_size, ".,.+%" PRId64, (int64_t)(cap->count0 - 1));
|
*buflen = (size_t)snprintf(buf, bufsize, ".,.+%" PRId64, (int64_t)(cap->count0 - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
do_cmdline_cmd("tabnew");
|
do_cmdline_cmd("tabnew");
|
||||||
STRCAT(buf, "terminal ");
|
*buflen += (size_t)snprintf(buf + *buflen, bufsize - *buflen, "terminal ");
|
||||||
if (cap->count0 == 0 && isman_s) {
|
if (cap->count0 == 0 && isman_s) {
|
||||||
STRCAT(buf, "man");
|
*buflen += (size_t)snprintf(buf + *buflen, bufsize - *buflen, "man ");
|
||||||
} else {
|
} else {
|
||||||
STRCAT(buf, kp);
|
*buflen += (size_t)snprintf(buf + *buflen, bufsize - *buflen, "%s ", kp);
|
||||||
}
|
}
|
||||||
STRCAT(buf, " ");
|
|
||||||
if (cap->count0 != 0 && (isman || isman_s)) {
|
if (cap->count0 != 0 && (isman || isman_s)) {
|
||||||
snprintf(buf + strlen(buf), buf_size - strlen(buf), "%" PRId64,
|
*buflen += (size_t)snprintf(buf + *buflen, bufsize - *buflen,
|
||||||
(int64_t)cap->count0);
|
"%" PRId64 " ", (int64_t)cap->count0);
|
||||||
STRCAT(buf, " ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*ptr_arg = ptr;
|
*ptr_arg = ptr;
|
||||||
@ -3412,9 +3413,10 @@ static void nv_ident(cmdarg_T *cap)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool kp_ex = (*kp == ':'); // 'keywordprg' is an ex command
|
bool kp_ex = (*kp == ':'); // 'keywordprg' is an ex command
|
||||||
size_t buf_size = n * 2 + 30 + strlen(kp);
|
size_t bufsize = n * 2 + 30 + strlen(kp);
|
||||||
char *buf = xmalloc(buf_size);
|
char *buf = xmalloc(bufsize);
|
||||||
buf[0] = NUL;
|
buf[0] = NUL;
|
||||||
|
size_t buflen = 0;
|
||||||
|
|
||||||
switch (cmdchar) {
|
switch (cmdchar) {
|
||||||
case '*':
|
case '*':
|
||||||
@ -3428,12 +3430,13 @@ static void nv_ident(cmdarg_T *cap)
|
|||||||
|
|
||||||
if (!g_cmd && vim_iswordp(ptr)) {
|
if (!g_cmd && vim_iswordp(ptr)) {
|
||||||
STRCPY(buf, "\\<");
|
STRCPY(buf, "\\<");
|
||||||
|
buflen = STRLEN_LITERAL("\\<");
|
||||||
}
|
}
|
||||||
no_smartcase = true; // don't use 'smartcase' now
|
no_smartcase = true; // don't use 'smartcase' now
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'K':
|
case 'K':
|
||||||
n = nv_K_getcmd(cap, kp, kp_help, kp_ex, &ptr, n, buf, buf_size);
|
n = nv_K_getcmd(cap, kp, kp_help, kp_ex, &ptr, n, buf, bufsize, &buflen);
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -3442,19 +3445,23 @@ static void nv_ident(cmdarg_T *cap)
|
|||||||
case ']':
|
case ']':
|
||||||
tag_cmd = true;
|
tag_cmd = true;
|
||||||
STRCPY(buf, "ts ");
|
STRCPY(buf, "ts ");
|
||||||
|
buflen = STRLEN_LITERAL("ts ");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
tag_cmd = true;
|
tag_cmd = true;
|
||||||
if (curbuf->b_help) {
|
if (curbuf->b_help) {
|
||||||
STRCPY(buf, "he! ");
|
STRCPY(buf, "he! ");
|
||||||
|
buflen = STRLEN_LITERAL("he! ");
|
||||||
} else {
|
} else {
|
||||||
if (g_cmd) {
|
if (g_cmd) {
|
||||||
STRCPY(buf, "tj ");
|
STRCPY(buf, "tj ");
|
||||||
|
buflen = STRLEN_LITERAL("tj ");
|
||||||
} else if (cap->count0 == 0) {
|
} else if (cap->count0 == 0) {
|
||||||
STRCPY(buf, "ta ");
|
STRCPY(buf, "ta ");
|
||||||
|
buflen = STRLEN_LITERAL("ta ");
|
||||||
} else {
|
} else {
|
||||||
snprintf(buf, buf_size, ":%" PRId64 "ta ", (int64_t)cap->count0);
|
buflen = (size_t)snprintf(buf, bufsize, ":%" PRId64 "ta ", (int64_t)cap->count0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3470,9 +3477,11 @@ static void nv_ident(cmdarg_T *cap)
|
|||||||
p = vim_strsave_shellescape(ptr, true, true);
|
p = vim_strsave_shellescape(ptr, true, true);
|
||||||
}
|
}
|
||||||
xfree(ptr);
|
xfree(ptr);
|
||||||
char *newbuf = xrealloc(buf, strlen(buf) + strlen(p) + 1);
|
size_t plen = strlen(p);
|
||||||
|
char *newbuf = xrealloc(buf, buflen + plen + 1);
|
||||||
buf = newbuf;
|
buf = newbuf;
|
||||||
STRCAT(buf, p);
|
STRCPY(buf + buflen, p);
|
||||||
|
buflen += plen;
|
||||||
xfree(p);
|
xfree(p);
|
||||||
} else {
|
} else {
|
||||||
char *aux_ptr;
|
char *aux_ptr;
|
||||||
@ -3491,12 +3500,13 @@ static void nv_ident(cmdarg_T *cap)
|
|||||||
aux_ptr = "\\|\"\n*?[";
|
aux_ptr = "\\|\"\n*?[";
|
||||||
}
|
}
|
||||||
|
|
||||||
p = buf + strlen(buf);
|
p = buf + buflen;
|
||||||
while (n-- > 0) {
|
while (n-- > 0) {
|
||||||
// put a backslash before \ and some others
|
// put a backslash before \ and some others
|
||||||
if (vim_strchr(aux_ptr, (uint8_t)(*ptr)) != NULL) {
|
if (vim_strchr(aux_ptr, (uint8_t)(*ptr)) != NULL) {
|
||||||
*p++ = '\\';
|
*p++ = '\\';
|
||||||
}
|
}
|
||||||
|
|
||||||
// When current byte is a part of multibyte character, copy all
|
// When current byte is a part of multibyte character, copy all
|
||||||
// bytes of that character.
|
// bytes of that character.
|
||||||
const size_t len = (size_t)(utfc_ptr2len(ptr) - 1);
|
const size_t len = (size_t)(utfc_ptr2len(ptr) - 1);
|
||||||
@ -3506,20 +3516,21 @@ static void nv_ident(cmdarg_T *cap)
|
|||||||
*p++ = *ptr++;
|
*p++ = *ptr++;
|
||||||
}
|
}
|
||||||
*p = NUL;
|
*p = NUL;
|
||||||
|
buflen = (size_t)(p - buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute the command.
|
// Execute the command.
|
||||||
if (cmdchar == '*' || cmdchar == '#') {
|
if (cmdchar == '*' || cmdchar == '#') {
|
||||||
if (!g_cmd
|
if (!g_cmd && vim_iswordp(mb_prevptr(get_cursor_line_ptr(), ptr))) {
|
||||||
&& vim_iswordp(mb_prevptr(get_cursor_line_ptr(), ptr))) {
|
STRCPY(buf + buflen, "\\>");
|
||||||
STRCAT(buf, "\\>");
|
buflen += STRLEN_LITERAL("\\>");
|
||||||
}
|
}
|
||||||
|
|
||||||
// put pattern in search history
|
// put pattern in search history
|
||||||
init_history();
|
init_history();
|
||||||
add_to_history(HIST_SEARCH, buf, true, NUL);
|
add_to_history(HIST_SEARCH, buf, buflen, true, NUL);
|
||||||
|
|
||||||
normal_search(cap, cmdchar == '*' ? '/' : '?', buf, 0, NULL);
|
normal_search(cap, cmdchar == '*' ? '/' : '?', buf, buflen, 0, NULL);
|
||||||
} else {
|
} else {
|
||||||
g_tag_at_cursor = true;
|
g_tag_at_cursor = true;
|
||||||
do_cmdline_cmd(buf);
|
do_cmdline_cmd(buf);
|
||||||
@ -3940,7 +3951,7 @@ static void nv_search(cmdarg_T *cap)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
normal_search(cap, cap->cmdchar, cap->searchbuf,
|
normal_search(cap, cap->cmdchar, cap->searchbuf, strlen(cap->searchbuf),
|
||||||
(cap->arg || !equalpos(save_cursor, curwin->w_cursor))
|
(cap->arg || !equalpos(save_cursor, curwin->w_cursor))
|
||||||
? 0 : SEARCH_MARK, NULL);
|
? 0 : SEARCH_MARK, NULL);
|
||||||
}
|
}
|
||||||
@ -3951,14 +3962,14 @@ static void nv_next(cmdarg_T *cap)
|
|||||||
{
|
{
|
||||||
pos_T old = curwin->w_cursor;
|
pos_T old = curwin->w_cursor;
|
||||||
int wrapped = false;
|
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 && equalpos(old, curwin->w_cursor)) {
|
if (i == 1 && !wrapped && equalpos(old, curwin->w_cursor)) {
|
||||||
// Avoid getting stuck on the current cursor position, which can happen when
|
// Avoid getting stuck on the current cursor position, which can happen when
|
||||||
// an offset is given and the cursor is on the last char in the buffer:
|
// an offset is given and the cursor is on the last char in the buffer:
|
||||||
// Repeat with count + 1.
|
// Repeat with count + 1.
|
||||||
cap->count1 += 1;
|
cap->count1 += 1;
|
||||||
normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg, NULL);
|
normal_search(cap, 0, NULL, 0, SEARCH_MARK | cap->arg, NULL);
|
||||||
cap->count1 -= 1;
|
cap->count1 -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3969,7 +3980,7 @@ static void nv_next(cmdarg_T *cap)
|
|||||||
/// @param opt extra flags for do_search()
|
/// @param opt extra flags for do_search()
|
||||||
///
|
///
|
||||||
/// @return 0 for failure, 1 for found, 2 for found and line offset added.
|
/// @return 0 for failure, 1 for found, 2 for found and line offset added.
|
||||||
static int normal_search(cmdarg_T *cap, int dir, char *pat, int opt, int *wrapped)
|
static int normal_search(cmdarg_T *cap, int dir, char *pat, size_t patlen, int opt, int *wrapped)
|
||||||
{
|
{
|
||||||
searchit_arg_T sia;
|
searchit_arg_T sia;
|
||||||
|
|
||||||
@ -3979,7 +3990,7 @@ static int normal_search(cmdarg_T *cap, int dir, char *pat, int opt, int *wrappe
|
|||||||
curwin->w_set_curswant = true;
|
curwin->w_set_curswant = true;
|
||||||
|
|
||||||
CLEAR_FIELD(sia);
|
CLEAR_FIELD(sia);
|
||||||
int i = do_search(cap->oap, dir, dir, pat, cap->count1,
|
int i = do_search(cap->oap, dir, dir, pat, patlen, cap->count1,
|
||||||
opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, &sia);
|
opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, &sia);
|
||||||
if (wrapped != NULL) {
|
if (wrapped != NULL) {
|
||||||
*wrapped = sia.sa_wrapped;
|
*wrapped = sia.sa_wrapped;
|
||||||
@ -3999,6 +4010,7 @@ static int normal_search(cmdarg_T *cap, int dir, char *pat, int opt, int *wrappe
|
|||||||
// "/$" will put the cursor after the end of the line, may need to
|
// "/$" will put the cursor after the end of the line, may need to
|
||||||
// correct that here
|
// correct that here
|
||||||
check_cursor(curwin);
|
check_cursor(curwin);
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2902,7 +2902,7 @@ static void qf_jump_goto_line(linenr_T qf_lnum, int qf_col, char qf_viscol, char
|
|||||||
// Move the cursor to the first line in the buffer
|
// Move the cursor to the first line in the buffer
|
||||||
pos_T save_cursor = curwin->w_cursor;
|
pos_T save_cursor = curwin->w_cursor;
|
||||||
curwin->w_cursor.lnum = 0;
|
curwin->w_cursor.lnum = 0;
|
||||||
if (!do_search(NULL, '/', '/', qf_pattern, 1, SEARCH_KEEP, NULL)) {
|
if (!do_search(NULL, '/', '/', qf_pattern, strlen(qf_pattern), 1, SEARCH_KEEP, NULL)) {
|
||||||
curwin->w_cursor = save_cursor;
|
curwin->w_cursor = save_cursor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,9 +99,9 @@ static const char e_search_hit_bottom_without_match_for_str[]
|
|||||||
|
|
||||||
static SearchPattern spats[2] = {
|
static SearchPattern spats[2] = {
|
||||||
// Last used search pattern
|
// Last used search pattern
|
||||||
[0] = { NULL, true, false, 0, { '/', false, false, 0 }, NULL },
|
[0] = { NULL, 0, true, false, 0, { '/', false, false, 0 }, NULL },
|
||||||
// Last used substitute pattern
|
// Last used substitute pattern
|
||||||
[1] = { NULL, true, false, 0, { '/', false, false, 0 }, NULL }
|
[1] = { NULL, 0, true, false, 0, { '/', false, false, 0 }, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static int last_idx = 0; // index in spats[] for RE_LAST
|
static int last_idx = 0; // index in spats[] for RE_LAST
|
||||||
@ -113,13 +113,15 @@ static char lastc_bytes[MB_MAXBYTES + 1];
|
|||||||
static int lastc_bytelen = 1; // >1 for multi-byte char
|
static int lastc_bytelen = 1; // >1 for multi-byte char
|
||||||
|
|
||||||
// copy of spats[], for keeping the search patterns while executing autocmds
|
// copy of spats[], for keeping the search patterns while executing autocmds
|
||||||
static SearchPattern saved_spats[2];
|
static SearchPattern saved_spats[ARRAY_SIZE(spats)];
|
||||||
static char *saved_mr_pattern = NULL;
|
static char *saved_mr_pattern = NULL;
|
||||||
|
static size_t saved_mr_patternlen = 0;
|
||||||
static int saved_spats_last_idx = 0;
|
static int saved_spats_last_idx = 0;
|
||||||
static bool saved_spats_no_hlsearch = false;
|
static bool saved_spats_no_hlsearch = false;
|
||||||
|
|
||||||
// allocated copy of pattern used by search_regcomp()
|
// allocated copy of pattern used by search_regcomp()
|
||||||
static char *mr_pattern = NULL;
|
static char *mr_pattern = NULL;
|
||||||
|
static size_t mr_patternlen = 0;
|
||||||
|
|
||||||
// Type used by find_pattern_in_path() to remember which included files have
|
// Type used by find_pattern_in_path() to remember which included files have
|
||||||
// been searched already.
|
// been searched already.
|
||||||
@ -144,8 +146,8 @@ typedef struct {
|
|||||||
/// @param regmatch return: pattern and ignore-case flag
|
/// @param regmatch return: pattern and ignore-case flag
|
||||||
///
|
///
|
||||||
/// @return FAIL if failed, OK otherwise.
|
/// @return FAIL if failed, OK otherwise.
|
||||||
int search_regcomp(char *pat, char **used_pat, int pat_save, int pat_use, int options,
|
int search_regcomp(char *pat, size_t patlen, char **used_pat, int pat_save, int pat_use,
|
||||||
regmmatch_T *regmatch)
|
int options, regmmatch_T *regmatch)
|
||||||
{
|
{
|
||||||
rc_did_emsg = false;
|
rc_did_emsg = false;
|
||||||
int magic = magic_isset();
|
int magic = magic_isset();
|
||||||
@ -168,10 +170,11 @@ int search_regcomp(char *pat, char **used_pat, int pat_save, int pat_use, int op
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
pat = spats[i].pat;
|
pat = spats[i].pat;
|
||||||
|
patlen = spats[i].patlen;
|
||||||
magic = spats[i].magic;
|
magic = spats[i].magic;
|
||||||
no_smartcase = spats[i].no_scs;
|
no_smartcase = spats[i].no_scs;
|
||||||
} else if (options & SEARCH_HIS) { // put new pattern in history
|
} 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) {
|
if (used_pat) {
|
||||||
@ -182,19 +185,20 @@ int search_regcomp(char *pat, char **used_pat, int pat_save, int pat_use, int op
|
|||||||
if (curwin->w_p_rl && *curwin->w_p_rlc == 's') {
|
if (curwin->w_p_rl && *curwin->w_p_rlc == 's') {
|
||||||
mr_pattern = reverse_text(pat);
|
mr_pattern = reverse_text(pat);
|
||||||
} else {
|
} else {
|
||||||
mr_pattern = xstrdup(pat);
|
mr_pattern = xstrnsave(pat, patlen);
|
||||||
}
|
}
|
||||||
|
mr_patternlen = patlen;
|
||||||
|
|
||||||
// Save the currently used pattern in the appropriate place,
|
// Save the currently used pattern in the appropriate place,
|
||||||
// unless the pattern should not be remembered.
|
// unless the pattern should not be remembered.
|
||||||
if (!(options & SEARCH_KEEP) && (cmdmod.cmod_flags & CMOD_KEEPPATTERNS) == 0) {
|
if (!(options & SEARCH_KEEP) && (cmdmod.cmod_flags & CMOD_KEEPPATTERNS) == 0) {
|
||||||
// search or global command
|
// search or global command
|
||||||
if (pat_save == RE_SEARCH || pat_save == RE_BOTH) {
|
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
|
// substitute or global command
|
||||||
if (pat_save == RE_SUBST || pat_save == RE_BOTH) {
|
if (pat_save == RE_SUBST || pat_save == RE_BOTH) {
|
||||||
save_re_pat(RE_SUBST, pat, magic);
|
save_re_pat(RE_SUBST, pat, patlen, magic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,14 +217,15 @@ char *get_search_pat(void)
|
|||||||
return mr_pattern;
|
return mr_pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_re_pat(int idx, char *pat, int magic)
|
void save_re_pat(int idx, char *pat, size_t patlen, int magic)
|
||||||
{
|
{
|
||||||
if (spats[idx].pat == pat) {
|
if (spats[idx].pat == pat) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_spat(&spats[idx]);
|
free_spat(&spats[idx]);
|
||||||
spats[idx].pat = xstrdup(pat);
|
spats[idx].pat = xstrnsave(pat, patlen);
|
||||||
|
spats[idx].patlen = patlen;
|
||||||
spats[idx].magic = magic;
|
spats[idx].magic = magic;
|
||||||
spats[idx].no_scs = no_smartcase;
|
spats[idx].no_scs = no_smartcase;
|
||||||
spats[idx].timestamp = os_time();
|
spats[idx].timestamp = os_time();
|
||||||
@ -243,18 +248,19 @@ void save_search_patterns(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
saved_spats[0] = spats[0];
|
for (size_t i = 0; i < ARRAY_SIZE(spats); i++) {
|
||||||
if (spats[0].pat != NULL) {
|
saved_spats[i] = spats[i];
|
||||||
saved_spats[0].pat = xstrdup(spats[0].pat);
|
if (spats[i].pat != NULL) {
|
||||||
}
|
saved_spats[i].pat = xstrnsave(spats[i].pat, spats[i].patlen);
|
||||||
saved_spats[1] = spats[1];
|
saved_spats[i].patlen = spats[i].patlen;
|
||||||
if (spats[1].pat != NULL) {
|
}
|
||||||
saved_spats[1].pat = xstrdup(spats[1].pat);
|
|
||||||
}
|
}
|
||||||
if (mr_pattern == NULL) {
|
if (mr_pattern == NULL) {
|
||||||
saved_mr_pattern = NULL;
|
saved_mr_pattern = NULL;
|
||||||
|
saved_mr_patternlen = 0;
|
||||||
} else {
|
} else {
|
||||||
saved_mr_pattern = xstrdup(mr_pattern);
|
saved_mr_pattern = xstrnsave(mr_pattern, mr_patternlen);
|
||||||
|
saved_mr_patternlen = mr_patternlen;
|
||||||
}
|
}
|
||||||
saved_spats_last_idx = last_idx;
|
saved_spats_last_idx = last_idx;
|
||||||
saved_spats_no_hlsearch = no_hlsearch;
|
saved_spats_no_hlsearch = no_hlsearch;
|
||||||
@ -266,13 +272,14 @@ void restore_search_patterns(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_spat(&spats[0]);
|
for (size_t i = 0; i < ARRAY_SIZE(spats); i++) {
|
||||||
spats[0] = saved_spats[0];
|
free_spat(&spats[i]);
|
||||||
|
spats[i] = saved_spats[i];
|
||||||
|
}
|
||||||
set_vv_searchforward();
|
set_vv_searchforward();
|
||||||
free_spat(&spats[1]);
|
|
||||||
spats[1] = saved_spats[1];
|
|
||||||
xfree(mr_pattern);
|
xfree(mr_pattern);
|
||||||
mr_pattern = saved_mr_pattern;
|
mr_pattern = saved_mr_pattern;
|
||||||
|
mr_patternlen = saved_mr_patternlen;
|
||||||
last_idx = saved_spats_last_idx;
|
last_idx = saved_spats_last_idx;
|
||||||
set_no_hlsearch(saved_spats_no_hlsearch);
|
set_no_hlsearch(saved_spats_no_hlsearch);
|
||||||
}
|
}
|
||||||
@ -286,12 +293,13 @@ static inline void free_spat(SearchPattern *const spat)
|
|||||||
#if defined(EXITFREE)
|
#if defined(EXITFREE)
|
||||||
void free_search_patterns(void)
|
void free_search_patterns(void)
|
||||||
{
|
{
|
||||||
free_spat(&spats[0]);
|
for (size_t i = 0; i < ARRAY_SIZE(spats); i++) {
|
||||||
free_spat(&spats[1]);
|
free_spat(&spats[i]);
|
||||||
|
}
|
||||||
CLEAR_FIELD(spats);
|
CLEAR_FIELD(spats);
|
||||||
|
|
||||||
XFREE_CLEAR(mr_pattern);
|
XFREE_CLEAR(mr_pattern);
|
||||||
|
mr_patternlen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -320,7 +328,8 @@ void save_last_search_pattern(void)
|
|||||||
|
|
||||||
saved_last_search_spat = spats[RE_SEARCH];
|
saved_last_search_spat = spats[RE_SEARCH];
|
||||||
if (spats[RE_SEARCH].pat != NULL) {
|
if (spats[RE_SEARCH].pat != NULL) {
|
||||||
saved_last_search_spat.pat = xstrdup(spats[RE_SEARCH].pat);
|
saved_last_search_spat.pat = xstrnsave(spats[RE_SEARCH].pat, spats[RE_SEARCH].patlen);
|
||||||
|
saved_last_search_spat.patlen = spats[RE_SEARCH].patlen;
|
||||||
}
|
}
|
||||||
saved_last_idx = last_idx;
|
saved_last_idx = last_idx;
|
||||||
saved_no_hlsearch = no_hlsearch;
|
saved_no_hlsearch = no_hlsearch;
|
||||||
@ -341,6 +350,7 @@ void restore_last_search_pattern(void)
|
|||||||
xfree(spats[RE_SEARCH].pat);
|
xfree(spats[RE_SEARCH].pat);
|
||||||
spats[RE_SEARCH] = saved_last_search_spat;
|
spats[RE_SEARCH] = saved_last_search_spat;
|
||||||
saved_last_search_spat.pat = NULL;
|
saved_last_search_spat.pat = NULL;
|
||||||
|
saved_last_search_spat.patlen = 0;
|
||||||
set_vv_searchforward();
|
set_vv_searchforward();
|
||||||
last_idx = saved_last_idx;
|
last_idx = saved_last_idx;
|
||||||
set_no_hlsearch(saved_no_hlsearch);
|
set_no_hlsearch(saved_no_hlsearch);
|
||||||
@ -487,8 +497,10 @@ void set_last_search_pat(const char *s, int idx, int magic, bool setlast)
|
|||||||
// An empty string means that nothing should be matched.
|
// An empty string means that nothing should be matched.
|
||||||
if (*s == NUL) {
|
if (*s == NUL) {
|
||||||
spats[idx].pat = NULL;
|
spats[idx].pat = NULL;
|
||||||
|
spats[idx].patlen = 0;
|
||||||
} else {
|
} else {
|
||||||
spats[idx].pat = xstrdup(s);
|
spats[idx].patlen = strlen(s);
|
||||||
|
spats[idx].pat = xstrnsave(s, spats[idx].patlen);
|
||||||
}
|
}
|
||||||
spats[idx].timestamp = os_time();
|
spats[idx].timestamp = os_time();
|
||||||
spats[idx].additional_data = NULL;
|
spats[idx].additional_data = NULL;
|
||||||
@ -507,8 +519,10 @@ void set_last_search_pat(const char *s, int idx, int magic, bool setlast)
|
|||||||
saved_spats[idx] = spats[0];
|
saved_spats[idx] = spats[0];
|
||||||
if (spats[idx].pat == NULL) {
|
if (spats[idx].pat == NULL) {
|
||||||
saved_spats[idx].pat = NULL;
|
saved_spats[idx].pat = NULL;
|
||||||
|
saved_spats[idx].patlen = 0;
|
||||||
} else {
|
} else {
|
||||||
saved_spats[idx].pat = xstrdup(spats[idx].pat);
|
saved_spats[idx].pat = xstrnsave(spats[idx].pat, spats[idx].patlen);
|
||||||
|
saved_spats[idx].patlen = spats[idx].patlen;
|
||||||
}
|
}
|
||||||
saved_spats_last_idx = last_idx;
|
saved_spats_last_idx = last_idx;
|
||||||
}
|
}
|
||||||
@ -528,7 +542,7 @@ void last_pat_prog(regmmatch_T *regmatch)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emsg_off++; // So it doesn't beep if bad expr
|
emsg_off++; // So it doesn't beep if bad expr
|
||||||
search_regcomp("", NULL, 0, last_idx, SEARCH_KEEP, regmatch);
|
search_regcomp("", 0, NULL, 0, last_idx, SEARCH_KEEP, regmatch);
|
||||||
emsg_off--;
|
emsg_off--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -556,7 +570,7 @@ void last_pat_prog(regmmatch_T *regmatch)
|
|||||||
/// the index of the first matching
|
/// the index of the first matching
|
||||||
/// subpattern plus one; one if there was none.
|
/// subpattern plus one; one if there was none.
|
||||||
int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, char *pat,
|
int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, char *pat,
|
||||||
int count, int options, int pat_use, searchit_arg_T *extra_arg)
|
size_t patlen, int count, int options, int pat_use, searchit_arg_T *extra_arg)
|
||||||
{
|
{
|
||||||
int found;
|
int found;
|
||||||
linenr_T lnum; // no init to shut up Apollo cc
|
linenr_T lnum; // no init to shut up Apollo cc
|
||||||
@ -584,7 +598,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
|
|||||||
timed_out = &extra_arg->sa_timed_out;
|
timed_out = &extra_arg->sa_timed_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
(options & (SEARCH_HIS + SEARCH_KEEP)), ®match) == FAIL) {
|
||||||
if ((options & SEARCH_MSG) && !rc_did_emsg) {
|
if ((options & SEARCH_MSG) && !rc_did_emsg) {
|
||||||
semsg(_("E383: Invalid search string: %s"), mr_pattern);
|
semsg(_("E383: Invalid search string: %s"), mr_pattern);
|
||||||
@ -592,6 +606,8 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool search_from_match_end = vim_strchr(p_cpo, CPO_SEARCH) != NULL;
|
||||||
|
|
||||||
// find the string
|
// find the string
|
||||||
do { // loop for count
|
do { // loop for count
|
||||||
// When not accepting a match at the start position set "extra_col" to a
|
// When not accepting a match at the start position set "extra_col" to a
|
||||||
@ -699,7 +715,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
|
|||||||
// If vi-compatible searching, continue at the end
|
// If vi-compatible searching, continue at the end
|
||||||
// of the match, otherwise continue one position
|
// of the match, otherwise continue one position
|
||||||
// forward.
|
// forward.
|
||||||
if (vim_strchr(p_cpo, CPO_SEARCH) != NULL) {
|
if (search_from_match_end) {
|
||||||
if (nmatched > 1) {
|
if (nmatched > 1) {
|
||||||
// end is in next line, thus no match in
|
// end is in next line, thus no match in
|
||||||
// this line
|
// this line
|
||||||
@ -791,7 +807,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
|
|||||||
// If vi-compatible searching, continue at the end
|
// If vi-compatible searching, continue at the end
|
||||||
// of the match, otherwise continue one position
|
// of the match, otherwise continue one position
|
||||||
// forward.
|
// forward.
|
||||||
if (vim_strchr(p_cpo, CPO_SEARCH) != NULL) {
|
if (search_from_match_end) {
|
||||||
if (nmatched > 1) {
|
if (nmatched > 1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1031,11 +1047,12 @@ static int first_submatch(regmmatch_T *rp)
|
|||||||
/// @param sia optional arguments or NULL
|
/// @param sia optional arguments or NULL
|
||||||
///
|
///
|
||||||
/// @return 0 for failure, 1 for found, 2 for found and line offset added.
|
/// @return 0 for failure, 1 for found, 2 for found and line offset added.
|
||||||
int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, int options,
|
int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, size_t patlen, int count,
|
||||||
searchit_arg_T *sia)
|
int options, searchit_arg_T *sia)
|
||||||
{
|
{
|
||||||
pos_T pos; // position of the last match
|
pos_T pos; // position of the last match
|
||||||
char *searchstr;
|
char *searchstr;
|
||||||
|
size_t searchstrlen;
|
||||||
int retval; // Return value
|
int retval; // Return value
|
||||||
char *p;
|
char *p;
|
||||||
int64_t c;
|
int64_t c;
|
||||||
@ -1043,9 +1060,11 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
|||||||
char *strcopy = NULL;
|
char *strcopy = NULL;
|
||||||
char *ps;
|
char *ps;
|
||||||
char *msgbuf = NULL;
|
char *msgbuf = NULL;
|
||||||
size_t len;
|
size_t msgbuflen = 0;
|
||||||
bool has_offset = false;
|
bool has_offset = false;
|
||||||
|
|
||||||
|
searchcmdlen = 0;
|
||||||
|
|
||||||
// A line offset is not remembered, this is vi compatible.
|
// A line offset is not remembered, this is vi compatible.
|
||||||
if (spats[0].off.line && vim_strchr(p_cpo, CPO_LINEOFF) != NULL) {
|
if (spats[0].off.line && vim_strchr(p_cpo, CPO_LINEOFF) != NULL) {
|
||||||
spats[0].off.line = false;
|
spats[0].off.line = false;
|
||||||
@ -1096,19 +1115,23 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
|||||||
bool show_top_bot_msg = false;
|
bool show_top_bot_msg = false;
|
||||||
|
|
||||||
searchstr = pat;
|
searchstr = pat;
|
||||||
|
searchstrlen = patlen;
|
||||||
|
|
||||||
dircp = NULL;
|
dircp = NULL;
|
||||||
// use previous pattern
|
// use previous pattern
|
||||||
if (pat == NULL || *pat == NUL || *pat == search_delim) {
|
if (pat == NULL || *pat == NUL || *pat == search_delim) {
|
||||||
if (spats[RE_SEARCH].pat == NULL) { // no previous pattern
|
if (spats[RE_SEARCH].pat == NULL) { // no previous pattern
|
||||||
searchstr = spats[RE_SUBST].pat;
|
if (spats[RE_SUBST].pat == NULL) {
|
||||||
if (searchstr == NULL) {
|
|
||||||
emsg(_(e_noprevre));
|
emsg(_(e_noprevre));
|
||||||
retval = 0;
|
retval = 0;
|
||||||
goto end_do_search;
|
goto end_do_search;
|
||||||
}
|
}
|
||||||
|
searchstr = spats[RE_SUBST].pat;
|
||||||
|
searchstrlen = spats[RE_SUBST].patlen;
|
||||||
} else {
|
} else {
|
||||||
// make search_regcomp() use spats[RE_SEARCH].pat
|
// make search_regcomp() use spats[RE_SEARCH].pat
|
||||||
searchstr = "";
|
searchstr = "";
|
||||||
|
searchstrlen = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1118,12 +1141,16 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
|||||||
ps = strcopy;
|
ps = strcopy;
|
||||||
p = skip_regexp_ex(pat, search_delim, magic_isset(), &strcopy, NULL, NULL);
|
p = skip_regexp_ex(pat, search_delim, magic_isset(), &strcopy, NULL, NULL);
|
||||||
if (strcopy != ps) {
|
if (strcopy != ps) {
|
||||||
|
size_t len = strlen(strcopy);
|
||||||
// made a copy of "pat" to change "\?" to "?"
|
// made a copy of "pat" to change "\?" to "?"
|
||||||
searchcmdlen += (int)(strlen(pat) - strlen(strcopy));
|
searchcmdlen += (int)(patlen - len);
|
||||||
pat = strcopy;
|
pat = strcopy;
|
||||||
|
patlen = len;
|
||||||
searchstr = strcopy;
|
searchstr = strcopy;
|
||||||
|
searchstrlen = len;
|
||||||
}
|
}
|
||||||
if (*p == search_delim) {
|
if (*p == search_delim) {
|
||||||
|
searchstrlen = (size_t)(p - pat);
|
||||||
dircp = p; // remember where we put the NUL
|
dircp = p; // remember where we put the NUL
|
||||||
*p++ = NUL;
|
*p++ = NUL;
|
||||||
}
|
}
|
||||||
@ -1161,12 +1188,13 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
|||||||
// compute length of search command for get_address()
|
// compute length of search command for get_address()
|
||||||
searchcmdlen += (int)(p - pat);
|
searchcmdlen += (int)(p - pat);
|
||||||
|
|
||||||
|
patlen -= (size_t)(p - pat);
|
||||||
pat = p; // put pat after search command
|
pat = p; // put pat after search command
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool show_search_stats = false;
|
||||||
if ((options & SEARCH_ECHO) && messaging() && !msg_silent
|
if ((options & SEARCH_ECHO) && messaging() && !msg_silent
|
||||||
&& (!cmd_silent || !shortmess(SHM_SEARCHCOUNT))) {
|
&& (!cmd_silent || !shortmess(SHM_SEARCHCOUNT))) {
|
||||||
char *trunc;
|
|
||||||
char off_buf[40];
|
char off_buf[40];
|
||||||
size_t off_len = 0;
|
size_t off_len = 0;
|
||||||
|
|
||||||
@ -1176,56 +1204,59 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
|||||||
// Get the offset, so we know how long it is.
|
// Get the offset, so we know how long it is.
|
||||||
if (!cmd_silent
|
if (!cmd_silent
|
||||||
&& (spats[0].off.line || spats[0].off.end || spats[0].off.off)) {
|
&& (spats[0].off.line || spats[0].off.end || spats[0].off.off)) {
|
||||||
p = off_buf;
|
off_buf[off_len++] = (char)dirc;
|
||||||
*p++ = (char)dirc;
|
|
||||||
if (spats[0].off.end) {
|
if (spats[0].off.end) {
|
||||||
*p++ = 'e';
|
off_buf[off_len++] = 'e';
|
||||||
} else if (!spats[0].off.line) {
|
} else if (!spats[0].off.line) {
|
||||||
*p++ = 's';
|
off_buf[off_len++] = 's';
|
||||||
}
|
}
|
||||||
if (spats[0].off.off > 0 || spats[0].off.line) {
|
if (spats[0].off.off > 0 || spats[0].off.line) {
|
||||||
*p++ = '+';
|
off_buf[off_len++] = '+';
|
||||||
}
|
}
|
||||||
*p = NUL;
|
off_buf[off_len] = NUL;
|
||||||
if (spats[0].off.off != 0 || spats[0].off.line) {
|
if (spats[0].off.off != 0 || spats[0].off.line) {
|
||||||
snprintf(p, sizeof(off_buf) - 1 - (size_t)(p - off_buf),
|
off_len += (size_t)snprintf(off_buf + off_len, sizeof(off_buf) - off_len,
|
||||||
"%" PRId64, spats[0].off.off);
|
"%" PRId64, spats[0].off.off);
|
||||||
}
|
}
|
||||||
off_len = strlen(off_buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t plen;
|
||||||
if (*searchstr == NUL) {
|
if (*searchstr == NUL) {
|
||||||
p = spats[0].pat;
|
p = spats[0].pat;
|
||||||
|
plen = spats[0].patlen;
|
||||||
} else {
|
} else {
|
||||||
p = searchstr;
|
p = searchstr;
|
||||||
|
plen = searchstrlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t msgbufsize;
|
||||||
if (!shortmess(SHM_SEARCHCOUNT) || cmd_silent) {
|
if (!shortmess(SHM_SEARCHCOUNT) || cmd_silent) {
|
||||||
// Reserve enough space for the search pattern + offset +
|
// Reserve enough space for the search pattern + offset +
|
||||||
// search stat. Use all the space available, so that the
|
// search stat. Use all the space available, so that the
|
||||||
// search state is right aligned. If there is not enough space
|
// search state is right aligned. If there is not enough space
|
||||||
// msg_strtrunc() will shorten in the middle.
|
// msg_strtrunc() will shorten in the middle.
|
||||||
if (ui_has(kUIMessages)) {
|
if (ui_has(kUIMessages)) {
|
||||||
len = 0; // adjusted below
|
msgbufsize = 0; // adjusted below
|
||||||
} else if (msg_scrolled != 0 && !cmd_silent) {
|
} else if (msg_scrolled != 0 && !cmd_silent) {
|
||||||
// Use all the columns.
|
// Use all the columns.
|
||||||
len = (size_t)((Rows - msg_row) * Columns - 1);
|
msgbufsize = (size_t)((Rows - msg_row) * Columns - 1);
|
||||||
} else {
|
} else {
|
||||||
// Use up to 'showcmd' column.
|
// Use up to 'showcmd' column.
|
||||||
len = (size_t)((Rows - msg_row - 1) * Columns + sc_col - 1);
|
msgbufsize = (size_t)((Rows - msg_row - 1) * Columns + sc_col - 1);
|
||||||
}
|
}
|
||||||
if (len < strlen(p) + off_len + SEARCH_STAT_BUF_LEN + 3) {
|
if (msgbufsize < plen + off_len + SEARCH_STAT_BUF_LEN + 3) {
|
||||||
len = strlen(p) + off_len + SEARCH_STAT_BUF_LEN + 3;
|
msgbufsize = plen + off_len + SEARCH_STAT_BUF_LEN + 3;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Reserve enough space for the search pattern + offset.
|
// Reserve enough space for the search pattern + offset.
|
||||||
len = strlen(p) + off_len + 3;
|
msgbufsize = plen + off_len + 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
xfree(msgbuf);
|
xfree(msgbuf);
|
||||||
msgbuf = xmalloc(len);
|
msgbuf = xmalloc(msgbufsize);
|
||||||
memset(msgbuf, ' ', len);
|
memset(msgbuf, ' ', msgbufsize);
|
||||||
msgbuf[len - 1] = NUL;
|
msgbuflen = msgbufsize - 1;
|
||||||
|
msgbuf[msgbuflen] = NUL;
|
||||||
|
|
||||||
// do not fill the msgbuf buffer, if cmd_silent is set, leave it
|
// do not fill the msgbuf buffer, if cmd_silent is set, leave it
|
||||||
// empty for the search_stat feature.
|
// empty for the search_stat feature.
|
||||||
@ -1234,18 +1265,19 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
|||||||
if (utf_iscomposing(utf_ptr2char(p))) {
|
if (utf_iscomposing(utf_ptr2char(p))) {
|
||||||
// Use a space to draw the composing char on.
|
// Use a space to draw the composing char on.
|
||||||
msgbuf[1] = ' ';
|
msgbuf[1] = ' ';
|
||||||
memmove(msgbuf + 2, p, strlen(p));
|
memmove(msgbuf + 2, p, plen);
|
||||||
} else {
|
} else {
|
||||||
memmove(msgbuf + 1, p, strlen(p));
|
memmove(msgbuf + 1, p, plen);
|
||||||
}
|
}
|
||||||
if (off_len > 0) {
|
if (off_len > 0) {
|
||||||
memmove(msgbuf + strlen(p) + 1, off_buf, off_len);
|
memmove(msgbuf + plen + 1, off_buf, off_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
trunc = msg_strtrunc(msgbuf, true);
|
char *trunc = msg_strtrunc(msgbuf, true);
|
||||||
if (trunc != NULL) {
|
if (trunc != NULL) {
|
||||||
xfree(msgbuf);
|
xfree(msgbuf);
|
||||||
msgbuf = trunc;
|
msgbuf = trunc;
|
||||||
|
msgbuflen = strlen(msgbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The search pattern could be shown on the right in rightleft
|
// The search pattern could be shown on the right in rightleft
|
||||||
@ -1260,7 +1292,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
|||||||
while (*r == ' ') {
|
while (*r == ' ') {
|
||||||
r++;
|
r++;
|
||||||
}
|
}
|
||||||
size_t pat_len = (size_t)(msgbuf + strlen(msgbuf) - r);
|
size_t pat_len = (size_t)(msgbuf + msgbuflen - r);
|
||||||
memmove(msgbuf, r, pat_len);
|
memmove(msgbuf, r, pat_len);
|
||||||
// overwrite old text
|
// overwrite old text
|
||||||
if ((size_t)(r - msgbuf) >= pat_len) {
|
if ((size_t)(r - msgbuf) >= pat_len) {
|
||||||
@ -1277,6 +1309,10 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
|||||||
ui_flush();
|
ui_flush();
|
||||||
msg_nowait = true; // don't wait for this message
|
msg_nowait = true; // don't wait for this message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!shortmess(SHM_SEARCHCOUNT)) {
|
||||||
|
show_search_stats = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is a character offset, subtract it from the current
|
// If there is a character offset, subtract it from the current
|
||||||
@ -1309,7 +1345,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
|||||||
}
|
}
|
||||||
|
|
||||||
c = searchit(curwin, curbuf, &pos, NULL, dirc == '/' ? FORWARD : BACKWARD,
|
c = searchit(curwin, curbuf, &pos, NULL, dirc == '/' ? FORWARD : BACKWARD,
|
||||||
searchstr, count,
|
searchstr, searchstrlen, count,
|
||||||
(spats[0].off.end * SEARCH_END
|
(spats[0].off.end * SEARCH_END
|
||||||
+ (options
|
+ (options
|
||||||
& (SEARCH_KEEP + SEARCH_PEEK + SEARCH_HIS + SEARCH_MSG
|
& (SEARCH_KEEP + SEARCH_PEEK + SEARCH_HIS + SEARCH_MSG
|
||||||
@ -1379,14 +1415,9 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Show [1/15] if 'S' is not in 'shortmess'.
|
// Show [1/15] if 'S' is not in 'shortmess'.
|
||||||
if ((options & SEARCH_ECHO)
|
if (show_search_stats) {
|
||||||
&& messaging()
|
|
||||||
&& !msg_silent
|
|
||||||
&& c != FAIL
|
|
||||||
&& !shortmess(SHM_SEARCHCOUNT)
|
|
||||||
&& msgbuf != NULL) {
|
|
||||||
cmdline_search_stat(dirc, &pos, &curwin->w_cursor,
|
cmdline_search_stat(dirc, &pos, &curwin->w_cursor,
|
||||||
show_top_bot_msg, msgbuf,
|
show_top_bot_msg, msgbuf, msgbuflen,
|
||||||
(count != 1 || has_offset
|
(count != 1 || has_offset
|
||||||
|| (!(fdo_flags & FDO_SEARCH)
|
|| (!(fdo_flags & FDO_SEARCH)
|
||||||
&& hasFolding(curwin, curwin->w_cursor.lnum, NULL,
|
&& hasFolding(curwin, curwin->w_cursor.lnum, NULL,
|
||||||
@ -1413,6 +1444,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, in
|
|||||||
goto end_do_search;
|
goto end_do_search;
|
||||||
}
|
}
|
||||||
pat++;
|
pat++;
|
||||||
|
patlen--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options & SEARCH_MARK) {
|
if (options & SEARCH_MARK) {
|
||||||
@ -2418,7 +2450,8 @@ int current_search(int count, bool forward)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Is the pattern is zero-width?, this time, don't care about the direction
|
// Is the pattern is zero-width?, this time, don't care about the direction
|
||||||
int zero_width = is_zero_width(spats[last_idx].pat, true, &curwin->w_cursor, FORWARD);
|
int zero_width = is_zero_width(spats[last_idx].pat, spats[last_idx].patlen,
|
||||||
|
true, &curwin->w_cursor, FORWARD);
|
||||||
if (zero_width == -1) {
|
if (zero_width == -1) {
|
||||||
return FAIL; // pattern not found
|
return FAIL; // pattern not found
|
||||||
}
|
}
|
||||||
@ -2451,7 +2484,7 @@ int current_search(int count, bool forward)
|
|||||||
|
|
||||||
result = searchit(curwin, curbuf, &pos, &end_pos,
|
result = searchit(curwin, curbuf, &pos, &end_pos,
|
||||||
(dir ? FORWARD : BACKWARD),
|
(dir ? FORWARD : BACKWARD),
|
||||||
spats[last_idx].pat, i ? count : 1,
|
spats[last_idx].pat, spats[last_idx].patlen, i ? count : 1,
|
||||||
SEARCH_KEEP | flags, RE_SEARCH, NULL);
|
SEARCH_KEEP | flags, RE_SEARCH, NULL);
|
||||||
|
|
||||||
p_ws = old_p_ws;
|
p_ws = old_p_ws;
|
||||||
@ -2525,7 +2558,8 @@ int current_search(int count, bool forward)
|
|||||||
/// else from position "cur".
|
/// else from position "cur".
|
||||||
/// "direction" is FORWARD or BACKWARD.
|
/// "direction" is FORWARD or BACKWARD.
|
||||||
/// Returns true, false or -1 for failure.
|
/// Returns true, false or -1 for failure.
|
||||||
static int is_zero_width(char *pattern, bool move, pos_T *cur, Direction direction)
|
static int is_zero_width(char *pattern, size_t patternlen, bool move, pos_T *cur,
|
||||||
|
Direction direction)
|
||||||
{
|
{
|
||||||
regmmatch_T regmatch;
|
regmmatch_T regmatch;
|
||||||
int result = -1;
|
int result = -1;
|
||||||
@ -2535,9 +2569,10 @@ static int is_zero_width(char *pattern, bool move, pos_T *cur, Direction directi
|
|||||||
|
|
||||||
if (pattern == NULL) {
|
if (pattern == NULL) {
|
||||||
pattern = spats[last_idx].pat;
|
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) {
|
SEARCH_KEEP, ®match) == FAIL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -2552,7 +2587,7 @@ static int is_zero_width(char *pattern, bool move, pos_T *cur, Direction directi
|
|||||||
// accept a match at the cursor position
|
// accept a match at the cursor position
|
||||||
flag = SEARCH_START;
|
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) {
|
SEARCH_KEEP + flag, RE_SEARCH, NULL) != FAIL) {
|
||||||
int nmatched = 0;
|
int nmatched = 0;
|
||||||
// Zero-width pattern should match somewhere, then we can check if
|
// Zero-width pattern should match somewhere, then we can check if
|
||||||
@ -2591,7 +2626,8 @@ bool linewhite(linenr_T lnum)
|
|||||||
/// Add the search count "[3/19]" to "msgbuf".
|
/// Add the search count "[3/19]" to "msgbuf".
|
||||||
/// See update_search_stat() for other arguments.
|
/// See update_search_stat() for other arguments.
|
||||||
static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool show_top_bot_msg,
|
static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool show_top_bot_msg,
|
||||||
char *msgbuf, bool recompute, int maxcount, int timeout)
|
char *msgbuf, size_t msgbuflen, bool recompute, int maxcount,
|
||||||
|
int timeout)
|
||||||
{
|
{
|
||||||
searchstat_T stat;
|
searchstat_T stat;
|
||||||
|
|
||||||
@ -2602,36 +2638,36 @@ static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool sh
|
|||||||
}
|
}
|
||||||
|
|
||||||
char t[SEARCH_STAT_BUF_LEN];
|
char t[SEARCH_STAT_BUF_LEN];
|
||||||
|
size_t len;
|
||||||
|
|
||||||
if (curwin->w_p_rl && *curwin->w_p_rlc == 's') {
|
if (curwin->w_p_rl && *curwin->w_p_rlc == 's') {
|
||||||
if (stat.incomplete == 1) {
|
if (stat.incomplete == 1) {
|
||||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
|
len = (size_t)vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
|
||||||
} else if (stat.cnt > maxcount && stat.cur > maxcount) {
|
} else if (stat.cnt > maxcount && stat.cur > maxcount) {
|
||||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
|
len = (size_t)vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
|
||||||
maxcount, maxcount);
|
maxcount, maxcount);
|
||||||
} else if (stat.cnt > maxcount) {
|
} else if (stat.cnt > maxcount) {
|
||||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/%d]",
|
len = (size_t)vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/%d]",
|
||||||
maxcount, stat.cur);
|
maxcount, stat.cur);
|
||||||
} else {
|
} else {
|
||||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
|
len = (size_t)vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
|
||||||
stat.cnt, stat.cur);
|
stat.cnt, stat.cur);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (stat.incomplete == 1) {
|
if (stat.incomplete == 1) {
|
||||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
|
len = (size_t)vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
|
||||||
} else if (stat.cnt > maxcount && stat.cur > maxcount) {
|
} else if (stat.cnt > maxcount && stat.cur > maxcount) {
|
||||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
|
len = (size_t)vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
|
||||||
maxcount, maxcount);
|
maxcount, maxcount);
|
||||||
} else if (stat.cnt > maxcount) {
|
} else if (stat.cnt > maxcount) {
|
||||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/>%d]",
|
len = (size_t)vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/>%d]",
|
||||||
stat.cur, maxcount);
|
stat.cur, maxcount);
|
||||||
} else {
|
} else {
|
||||||
vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
|
len = (size_t)vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
|
||||||
stat.cur, stat.cnt);
|
stat.cur, stat.cnt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t len = strlen(t);
|
|
||||||
if (show_top_bot_msg && len + 2 < SEARCH_STAT_BUF_LEN) {
|
if (show_top_bot_msg && len + 2 < SEARCH_STAT_BUF_LEN) {
|
||||||
memmove(t + 2, t, len);
|
memmove(t + 2, t, len);
|
||||||
t[0] = 'W';
|
t[0] = 'W';
|
||||||
@ -2639,11 +2675,10 @@ static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool sh
|
|||||||
len += 2;
|
len += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t msgbuf_len = strlen(msgbuf);
|
if (len > msgbuflen) {
|
||||||
if (len > msgbuf_len) {
|
len = msgbuflen;
|
||||||
len = msgbuf_len;
|
|
||||||
}
|
}
|
||||||
memmove(msgbuf + msgbuf_len - len, t, len);
|
memmove(msgbuf + msgbuflen - len, t, len);
|
||||||
|
|
||||||
if (dirc == '?' && stat.cur == maxcount + 1) {
|
if (dirc == '?' && stat.cur == maxcount + 1) {
|
||||||
stat.cur = -1;
|
stat.cur = -1;
|
||||||
@ -2726,7 +2761,7 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst
|
|||||||
start = profile_setlimit(timeout);
|
start = profile_setlimit(timeout);
|
||||||
}
|
}
|
||||||
while (!got_int && searchit(curwin, curbuf, &lastpos, &endpos,
|
while (!got_int && searchit(curwin, curbuf, &lastpos, &endpos,
|
||||||
FORWARD, NULL, 1, SEARCH_KEEP, RE_LAST,
|
FORWARD, NULL, 0, 1, SEARCH_KEEP, RE_LAST,
|
||||||
NULL) != FAIL) {
|
NULL) != FAIL) {
|
||||||
done_search = true;
|
done_search = true;
|
||||||
// Stop after passing the time limit.
|
// Stop after passing the time limit.
|
||||||
@ -2860,7 +2895,8 @@ void f_searchcount(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
goto the_end;
|
goto the_end;
|
||||||
}
|
}
|
||||||
xfree(spats[last_idx].pat);
|
xfree(spats[last_idx].pat);
|
||||||
spats[last_idx].pat = xstrdup(pattern);
|
spats[last_idx].patlen = strlen(pattern);
|
||||||
|
spats[last_idx].pat = xstrnsave(pattern, spats[last_idx].patlen);
|
||||||
}
|
}
|
||||||
if (spats[last_idx].pat == NULL || *spats[last_idx].pat == NUL) {
|
if (spats[last_idx].pat == NULL || *spats[last_idx].pat == NUL) {
|
||||||
goto the_end; // the previous pattern was never defined
|
goto the_end; // the previous pattern was never defined
|
||||||
@ -3602,10 +3638,10 @@ void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool
|
|||||||
// when CONT_SOL is set compare "ptr" with the beginning of the
|
// when CONT_SOL is set compare "ptr" with the beginning of the
|
||||||
// line is faster than quote_meta/regcomp/regexec "ptr" -- Acevedo
|
// line is faster than quote_meta/regcomp/regexec "ptr" -- Acevedo
|
||||||
&& !compl_status_sol()) {
|
&& !compl_status_sol()) {
|
||||||
size_t patlen = len + 5;
|
size_t patsize = len + 5;
|
||||||
char *pat = xmalloc(patlen);
|
char *pat = xmalloc(patsize);
|
||||||
assert(len <= INT_MAX);
|
assert(len <= INT_MAX);
|
||||||
snprintf(pat, patlen, whole ? "\\<%.*s\\>" : "%.*s", (int)len, ptr);
|
snprintf(pat, patsize, whole ? "\\<%.*s\\>" : "%.*s", (int)len, ptr);
|
||||||
// ignore case according to p_ic, p_scs and pat
|
// ignore case according to p_ic, p_scs and pat
|
||||||
regmatch.rm_ic = ignorecase(pat);
|
regmatch.rm_ic = ignorecase(pat);
|
||||||
regmatch.regprog = vim_regcomp(pat, magic_isset() ? RE_MAGIC : 0);
|
regmatch.regprog = vim_regcomp(pat, magic_isset() ? RE_MAGIC : 0);
|
||||||
@ -3623,8 +3659,7 @@ void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool
|
|||||||
incl_regmatch.rm_ic = false; // don't ignore case in incl. pat.
|
incl_regmatch.rm_ic = false; // don't ignore case in incl. pat.
|
||||||
}
|
}
|
||||||
if (type == FIND_DEFINE && (*curbuf->b_p_def != NUL || *p_def != NUL)) {
|
if (type == FIND_DEFINE && (*curbuf->b_p_def != NUL || *p_def != NUL)) {
|
||||||
def_regmatch.regprog = vim_regcomp(*curbuf->b_p_def == NUL
|
def_regmatch.regprog = vim_regcomp(*curbuf->b_p_def == NUL ? p_def : curbuf->b_p_def,
|
||||||
? p_def : curbuf->b_p_def,
|
|
||||||
magic_isset() ? RE_MAGIC : 0);
|
magic_isset() ? RE_MAGIC : 0);
|
||||||
if (def_regmatch.regprog == NULL) {
|
if (def_regmatch.regprog == NULL) {
|
||||||
goto fpip_end;
|
goto fpip_end;
|
||||||
@ -4066,7 +4101,7 @@ exit_matched:
|
|||||||
&& action == ACTION_EXPAND
|
&& action == ACTION_EXPAND
|
||||||
&& !compl_status_sol()
|
&& !compl_status_sol()
|
||||||
&& *startp != NUL
|
&& *startp != NUL
|
||||||
&& *(p = startp + utfc_ptr2len(startp)) != NUL) {
|
&& *(startp + utfc_ptr2len(startp)) != NUL) {
|
||||||
goto search_line;
|
goto search_line;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4165,8 +4200,9 @@ static void show_pat_in_path(char *line, int type, bool did_show, int action, FI
|
|||||||
if (got_int) { // 'q' typed at "--more--" message
|
if (got_int) { // 'q' typed at "--more--" message
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
size_t linelen = strlen(line);
|
||||||
while (true) {
|
while (true) {
|
||||||
char *p = line + strlen(line) - 1;
|
char *p = line + linelen - 1;
|
||||||
if (fp != NULL) {
|
if (fp != NULL) {
|
||||||
// We used fgets(), so get rid of newline at end
|
// We used fgets(), so get rid of newline at end
|
||||||
if (p >= line && *p == '\n') {
|
if (p >= line && *p == '\n') {
|
||||||
@ -4196,12 +4232,14 @@ static void show_pat_in_path(char *line, int type, bool did_show, int action, FI
|
|||||||
if (vim_fgets(line, LSIZE, fp)) { // end of file
|
if (vim_fgets(line, LSIZE, fp)) { // end of file
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
linelen = strlen(line);
|
||||||
(*lnum)++;
|
(*lnum)++;
|
||||||
} else {
|
} else {
|
||||||
if (++*lnum > curbuf->b_ml.ml_line_count) {
|
if (++*lnum > curbuf->b_ml.ml_line_count) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
line = ml_get(*lnum);
|
line = ml_get(*lnum);
|
||||||
|
linelen = (size_t)ml_get_len(*lnum);
|
||||||
}
|
}
|
||||||
msg_putchar('\n');
|
msg_putchar('\n');
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,7 @@ typedef struct {
|
|||||||
/// Structure containing last search pattern and its attributes.
|
/// Structure containing last search pattern and its attributes.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *pat; ///< The pattern (in allocated memory) or NULL.
|
char *pat; ///< The pattern (in allocated memory) or NULL.
|
||||||
|
size_t patlen; ///< The length of the patten (0 is pat is NULL).
|
||||||
bool magic; ///< Magicness of the pattern.
|
bool magic; ///< Magicness of the pattern.
|
||||||
bool no_scs; ///< No smartcase for this pattern.
|
bool no_scs; ///< No smartcase for this pattern.
|
||||||
Timestamp timestamp; ///< Time of the last change.
|
Timestamp timestamp; ///< Time of the last change.
|
||||||
|
@ -2665,16 +2665,16 @@ void ex_spellrepall(exarg_T *eap)
|
|||||||
const size_t repl_to_len = strlen(repl_to);
|
const size_t repl_to_len = strlen(repl_to);
|
||||||
const int addlen = (int)(repl_to_len - repl_from_len);
|
const int addlen = (int)(repl_to_len - repl_from_len);
|
||||||
|
|
||||||
const size_t frompatlen = repl_from_len + 7;
|
const size_t frompatsize = repl_from_len + 7;
|
||||||
char *frompat = xmalloc(frompatlen);
|
char *frompat = xmalloc(frompatsize);
|
||||||
snprintf(frompat, frompatlen, "\\V\\<%s\\>", repl_from);
|
size_t frompatlen = (size_t)snprintf(frompat, frompatsize, "\\V\\<%s\\>", repl_from);
|
||||||
p_ws = false;
|
p_ws = false;
|
||||||
|
|
||||||
sub_nsubs = 0;
|
sub_nsubs = 0;
|
||||||
sub_nlines = 0;
|
sub_nlines = 0;
|
||||||
curwin->w_cursor.lnum = 0;
|
curwin->w_cursor.lnum = 0;
|
||||||
while (!got_int) {
|
while (!got_int) {
|
||||||
if (do_search(NULL, '/', '/', frompat, 1, SEARCH_KEEP, NULL) == 0
|
if (do_search(NULL, '/', '/', frompat, frompatlen, 1, SEARCH_KEEP, NULL) == 0
|
||||||
|| u_save_cursor() == FAIL) {
|
|| u_save_cursor() == FAIL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2942,6 +2942,8 @@ static int jumpto_tag(const char *lbuf_arg, int forceit, bool keep_help)
|
|||||||
str = skip_regexp(pbuf + 1, pbuf[0], false) + 1;
|
str = skip_regexp(pbuf + 1, pbuf[0], false) + 1;
|
||||||
}
|
}
|
||||||
if (str > pbuf_end - 1) { // search command with nothing following
|
if (str > pbuf_end - 1) { // search command with nothing following
|
||||||
|
size_t pbuflen = (size_t)(pbuf_end - pbuf);
|
||||||
|
|
||||||
bool save_p_ws = p_ws;
|
bool save_p_ws = p_ws;
|
||||||
int save_p_ic = p_ic;
|
int save_p_ic = p_ic;
|
||||||
int save_p_scs = p_scs;
|
int save_p_scs = p_scs;
|
||||||
@ -2956,25 +2958,27 @@ static int jumpto_tag(const char *lbuf_arg, int forceit, bool keep_help)
|
|||||||
// start search before first line
|
// start search before first line
|
||||||
curwin->w_cursor.lnum = 0;
|
curwin->w_cursor.lnum = 0;
|
||||||
}
|
}
|
||||||
if (do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, 1, search_options, NULL)) {
|
if (do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, pbuflen - 1, 1,
|
||||||
|
search_options, NULL)) {
|
||||||
retval = OK;
|
retval = OK;
|
||||||
} else {
|
} else {
|
||||||
int found = 1;
|
int found = 1;
|
||||||
|
|
||||||
// try again, ignore case now
|
// try again, ignore case now
|
||||||
p_ic = true;
|
p_ic = true;
|
||||||
if (!do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, 1, search_options, NULL)) {
|
if (!do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, pbuflen - 1, 1,
|
||||||
|
search_options, NULL)) {
|
||||||
// Failed to find pattern, take a guess: "^func ("
|
// Failed to find pattern, take a guess: "^func ("
|
||||||
found = 2;
|
found = 2;
|
||||||
test_for_static(&tagp);
|
test_for_static(&tagp);
|
||||||
char cc = *tagp.tagname_end;
|
char cc = *tagp.tagname_end;
|
||||||
*tagp.tagname_end = NUL;
|
*tagp.tagname_end = NUL;
|
||||||
snprintf(pbuf, LSIZE, "^%s\\s\\*(", tagp.tagname);
|
pbuflen = (size_t)snprintf(pbuf, LSIZE, "^%s\\s\\*(", tagp.tagname);
|
||||||
if (!do_search(NULL, '/', '/', pbuf, 1, search_options, NULL)) {
|
if (!do_search(NULL, '/', '/', pbuf, pbuflen, 1, search_options, NULL)) {
|
||||||
// Guess again: "^char * \<func ("
|
// Guess again: "^char * \<func ("
|
||||||
snprintf(pbuf, LSIZE, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(",
|
pbuflen = (size_t)snprintf(pbuf, LSIZE, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(",
|
||||||
tagp.tagname);
|
tagp.tagname);
|
||||||
if (!do_search(NULL, '/', '/', pbuf, 1, search_options, NULL)) {
|
if (!do_search(NULL, '/', '/', pbuf, len, 1, search_options, NULL)) {
|
||||||
found = 0;
|
found = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,9 +35,10 @@ itp('pat_has_uppercase', function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
describe('search_regcomp', function()
|
describe('search_regcomp', function()
|
||||||
local search_regcomp = function(pat, pat_save, pat_use, options)
|
local search_regcomp = function(pat, patlen, pat_save, pat_use, options)
|
||||||
local regmatch = ffi.new('regmmatch_T')
|
local regmatch = ffi.new('regmmatch_T')
|
||||||
local fail = search.search_regcomp(to_cstr(pat), nil, pat_save, pat_use, options, regmatch)
|
local fail =
|
||||||
|
search.search_regcomp(to_cstr(pat), patlen, nil, pat_save, pat_use, options, regmatch)
|
||||||
return fail, regmatch
|
return fail, regmatch
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ describe('search_regcomp', function()
|
|||||||
globals.curwin.w_onebuf_opt.wo_rl = 1
|
globals.curwin.w_onebuf_opt.wo_rl = 1
|
||||||
globals.curwin.w_onebuf_opt.wo_rlc = to_cstr('s')
|
globals.curwin.w_onebuf_opt.wo_rlc = to_cstr('s')
|
||||||
globals.cmdmod.cmod_flags = globals.CMOD_KEEPPATTERNS
|
globals.cmdmod.cmod_flags = globals.CMOD_KEEPPATTERNS
|
||||||
local fail = search_regcomp('a\192', 0, 0, 0)
|
local fail = search_regcomp('a\192', 2, 0, 0, 0)
|
||||||
eq(1, fail)
|
eq(1, fail)
|
||||||
eq('\192a', get_search_pat())
|
eq('\192a', get_search_pat())
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user