aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/ex_getln.c21
-rw-r--r--src/nvim/search.c30
2 files changed, 47 insertions, 4 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 54bbe66620..81c6854459 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -1019,13 +1019,18 @@ static void command_line_next_incsearch(CommandLineState *s, bool next_match)
ui_flush();
pos_T t;
- int search_flags = SEARCH_KEEP + SEARCH_NOOF + SEARCH_PEEK;
+ int search_flags = SEARCH_NOOF;
+ save_last_search_pattern();
+
if (next_match) {
t = s->match_end;
search_flags += SEARCH_COL;
} else {
t = s->match_start;
}
+ if (!p_hls) {
+ search_flags += SEARCH_KEEP;
+ }
emsg_off++;
s->i = searchit(curwin, curbuf, &t,
next_match ? FORWARD : BACKWARD,
@@ -1066,6 +1071,7 @@ static void command_line_next_incsearch(CommandLineState *s, bool next_match)
s->old_topfill = curwin->w_topfill;
s->old_botline = curwin->w_botline;
update_screen(NOT_VALID);
+ restore_last_search_pattern();
redrawcmdline();
} else {
vim_beep(BO_ERROR);
@@ -1773,20 +1779,26 @@ static int command_line_changed(CommandLineState *s)
}
s->incsearch_postponed = false;
curwin->w_cursor = s->search_start; // start at old position
+ save_last_search_pattern();
// If there is no command line, don't do anything
if (ccline.cmdlen == 0) {
s->i = 0;
+ SET_NO_HLSEARCH(true); // turn off previous highlight
} else {
+ int search_flags = SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK;
ui_busy_start();
ui_flush();
++emsg_off; // So it doesn't beep if bad expr
// Set the time limit to half a second.
tm = profile_setlimit(500L);
+ if (!p_hls) {
+ search_flags += SEARCH_KEEP;
+ }
s->i = do_search(NULL, s->firstc, ccline.cmdbuff, s->count,
- SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK,
- &tm);
- --emsg_off;
+ search_flags,
+ &tm);
+ emsg_off--;
// if interrupted while searching, behave like it failed
if (got_int) {
(void)vpeekc(); // remove <C-C> from input stream
@@ -1836,6 +1848,7 @@ static int command_line_changed(CommandLineState *s)
save_cmdline(&s->save_ccline);
update_screen(SOME_VALID);
restore_cmdline(&s->save_ccline);
+ restore_last_search_pattern();
// Leave it at the end to make CTRL-R CTRL-W work.
if (s->i != 0) {
diff --git a/src/nvim/search.c b/src/nvim/search.c
index 0a266382ec..89a7752e9f 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -96,6 +96,9 @@ static int lastc_bytelen = 1; /* >1 for multi-byte char */
/* copy of spats[], for keeping the search patterns while executing autocmds */
static struct spat saved_spats[2];
+// copy of spats[RE_SEARCH], for keeping the search patterns while incremental
+// searching
+static struct spat saved_last_search_spat;
static int saved_last_idx = 0;
static int saved_no_hlsearch = 0;
@@ -305,6 +308,33 @@ void free_search_patterns(void)
#endif
+/// Save and restore the search pattern for incremental highlight search
+/// feature.
+///
+/// It's similar but different from save_search_patterns() and
+/// restore_search_patterns(), because the search pattern must be restored when
+/// cancelling incremental searching even if it's called inside user functions.
+ void
+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_idx = last_idx;
+ saved_no_hlsearch = no_hlsearch;
+}
+
+ void
+restore_last_search_pattern(void)
+{
+ xfree(spats[RE_SEARCH].pat);
+ spats[RE_SEARCH] = saved_last_search_spat;
+ set_vv_searchforward();
+ last_idx = saved_last_idx;
+ SET_NO_HLSEARCH(saved_no_hlsearch);
+}
+
/*
* Return TRUE when case should be ignored for search pattern "pat".
* Uses the 'ignorecase' and 'smartcase' options.