diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2018-02-01 23:25:55 +0100 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2018-02-01 23:25:55 +0100 |
commit | 709a87d194971f187442caa2e551c781aba38d50 (patch) | |
tree | c7fc053abd52b0d4de1e93577557546555c1a488 /src | |
parent | 6710164c2c44335a916a728cc8eb329c69d155f4 (diff) | |
parent | 87e03c2b85cef0b31eee5aab5078cd6457dd3c9b (diff) | |
download | rneovim-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.c | 64 | ||||
-rw-r--r-- | src/nvim/search.c | 33 | ||||
-rw-r--r-- | src/nvim/version.c | 10 |
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, |