aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2018-02-01 23:25:55 +0100
committerJustin M. Keyes <justinkz@gmail.com>2018-02-01 23:25:55 +0100
commit709a87d194971f187442caa2e551c781aba38d50 (patch)
treec7fc053abd52b0d4de1e93577557546555c1a488 /src
parent6710164c2c44335a916a728cc8eb329c69d155f4 (diff)
parent87e03c2b85cef0b31eee5aab5078cd6457dd3c9b (diff)
downloadrneovim-709a87d194971f187442caa2e551c781aba38d50.tar.gz
rneovim-709a87d194971f187442caa2e551c781aba38d50.tar.bz2
rneovim-709a87d194971f187442caa2e551c781aba38d50.zip
Merge #7463 'incsearch + hlsearch highlight all'
Diffstat (limited to 'src')
-rw-r--r--src/nvim/ex_getln.c64
-rw-r--r--src/nvim/search.c33
-rw-r--r--src/nvim/version.c10
3 files changed, 95 insertions, 12 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index c4e0827dad..ba51f18518 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -426,7 +426,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
curwin->w_botline = s->old_botline;
highlight_match = false;
validate_cursor(); // needed for TAB
- redraw_later(SOME_VALID);
+ redraw_all_later(SOME_VALID);
}
if (ccline.cmdbuff != NULL) {
@@ -1019,17 +1019,36 @@ 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;
+ char_u *pat;
+ int search_flags = SEARCH_NOOF;
+
+
+ if (s->firstc == ccline.cmdbuff[0]) {
+ pat = last_search_pattern();
+ } else {
+ pat = ccline.cmdbuff;
+ }
+
+ save_last_search_pattern();
+
if (next_match) {
t = s->match_end;
+ if (lt(s->match_start, s->match_end)) {
+ // start searching at the end of the match
+ // not at the beginning of the next column
+ (void)decl(&t);
+ }
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,
- ccline.cmdbuff, s->count, search_flags,
+ pat, s->count, search_flags,
RE_SEARCH, 0, NULL);
emsg_off--;
ui_busy_stop();
@@ -1070,6 +1089,7 @@ static void command_line_next_incsearch(CommandLineState *s, bool next_match)
} else {
vim_beep(BO_ERROR);
}
+ restore_last_search_pattern();
return;
}
@@ -1656,7 +1676,9 @@ static int command_line_handle_key(CommandLineState *s)
if (char_avail()) {
return 1;
}
- command_line_next_incsearch(s, s->c == Ctrl_G);
+ if (ccline.cmdlen != 0) {
+ command_line_next_incsearch(s, s->c == Ctrl_G);
+ }
return command_line_not_changed(s);
}
break;
@@ -1759,6 +1781,20 @@ static int command_line_not_changed(CommandLineState *s)
return command_line_changed(s);
}
+/// Guess that the pattern matches everything. Only finds specific cases, such
+/// as a trailing \|, which can happen while typing a pattern.
+static int empty_pattern(char_u *p)
+{
+ int n = STRLEN(p);
+
+ // remove trailing \v and the like
+ while (n >= 2 && p[n - 2] == '\\'
+ && vim_strchr((char_u *)"mMvVcCZ", p[n - 1]) != NULL) {
+ n -= 2;
+ }
+ return n == 0 || (n >= 2 && p[n - 2] == '\\' && p[n - 1] == '|');
+}
+
static int command_line_changed(CommandLineState *s)
{
// 'incsearch' highlighting.
@@ -1773,20 +1809,27 @@ 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
+ redraw_all_later(SOME_VALID);
} 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
@@ -1827,6 +1870,12 @@ static int command_line_changed(CommandLineState *s)
end_pos = curwin->w_cursor; // shutup gcc 4
}
+ // Disable 'hlsearch' highlighting if the pattern matches
+ // everything. Avoids a flash when typing "foo\|".
+ if (empty_pattern(ccline.cmdbuff)) {
+ SET_NO_HLSEARCH(true);
+ }
+
validate_cursor();
// May redraw the status line to show the cursor position.
if (p_ru && curwin->w_status_height > 0) {
@@ -1836,6 +1885,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 6e56f5f25d..bbcac45369 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,36 @@ 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);
+}
+
+char_u *last_search_pattern(void)
+{
+ return spats[RE_SEARCH].pat;
+}
+
/*
* Return TRUE when case should be ignored for search pattern "pat".
* Uses the 'ignorecase' and 'smartcase' options.
diff --git a/src/nvim/version.c b/src/nvim/version.c
index da08a029b4..c95be072cf 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -101,10 +101,10 @@ static const int included_patches[] = {
// 1399,
// 1398,
// 1397,
- // 1396,
+ 1396,
// 1395,
// 1394,
- // 1393,
+ 1393,
// 1392,
// 1391,
// 1390,
@@ -193,7 +193,7 @@ static const int included_patches[] = {
// 1307,
// 1306,
// 1305,
- // 1304,
+ 1304,
// 1303,
// 1302,
// 1301,
@@ -247,7 +247,7 @@ static const int included_patches[] = {
// 1253,
// 1252,
// 1251,
- // 1250,
+ 1250,
// 1249,
// 1248,
// 1247,
@@ -259,7 +259,7 @@ static const int included_patches[] = {
// 1241,
// 1240,
// 1239,
- // 1238,
+ 1238,
// 1237,
// 1236,
// 1235,