diff options
author | Ömer Sinan Ağacan <omeragacan@gmail.com> | 2017-10-30 11:07:35 +0300 |
---|---|---|
committer | Ömer Sinan Ağacan <omeragacan@gmail.com> | 2018-01-26 18:39:20 +0300 |
commit | 41394d82365b504c89bb4da9ed5adc11c6f619f0 (patch) | |
tree | c0632c87165c2a17e0a1df9b6de0d106565b9e0e | |
parent | 0a56bd33308d2c4ae45f261498d69cb44fbd13c8 (diff) | |
download | rneovim-41394d82365b504c89bb4da9ed5adc11c6f619f0.tar.gz rneovim-41394d82365b504c89bb4da9ed5adc11c6f619f0.tar.bz2 rneovim-41394d82365b504c89bb4da9ed5adc11c6f619f0.zip |
vim-patch:8.0.1238
Problem: Incremental search only shows one match.
Solution: When 'incsearch' and and 'hlsearch' are both set highlight all
matches. (haya14busa, closes vim/vim#2198)
https://github.com/vim/vim/commit/2e51d9a0972080b087d566608472928d5b7b35d7
-rw-r--r-- | runtime/doc/options.txt | 12 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 21 | ||||
-rw-r--r-- | src/nvim/search.c | 30 | ||||
-rw-r--r-- | test/functional/ui/searchhl_spec.lua | 22 |
4 files changed, 75 insertions, 10 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index ded9f7667a..2e584ea9bb 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -3299,7 +3299,17 @@ A jump table for the options with a short description can be found at |Q_op|. pattern and/or a lot of text the match may not be found. This is to avoid that Vim hangs while you are typing the pattern. The |hl-IncSearch| highlight group determines the highlighting. - See also: 'hlsearch'. + When 'hlsearch' is on, all matched strings are highlighted too while typing + a search command. See also: 'hlsearch'. + If you don't want turn 'hlsearch' on, but want to highlight all matches + while searching, you can turn on and off 'hlsearch' with autocmd. + Example: > + augroup vimrc-incsearch-highlight + autocmd! + autocmd CmdlineEnter [/\?] :set hlsearch + autocmd CmdlineLeave [/\?] :set nohlsearch + augroup END +< CTRL-L can be used to add one character from after the current match to the command line. If 'ignorecase' and 'smartcase' are set and the command line has no uppercase characters, the added character is 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. diff --git a/test/functional/ui/searchhl_spec.lua b/test/functional/ui/searchhl_spec.lua index 5af8b83a36..950989aab2 100644 --- a/test/functional/ui/searchhl_spec.lua +++ b/test/functional/ui/searchhl_spec.lua @@ -99,7 +99,7 @@ describe('search highlighting', function() feed("gg/li") screen:expect([[ the first {3:li}ne | - in a little file | + in a {2:li}ttle file | | {1:~ }| {1:~ }| @@ -132,7 +132,7 @@ describe('search highlighting', function() feed("/fir") screen:expect([[ the {3:fir}st line | - in a {2:lit}tle file | + in a little file | | {1:~ }| {1:~ }| @@ -144,13 +144,25 @@ describe('search highlighting', function() feed("<esc>/ttle") screen:expect([[ the first line | - in a {2:li}{3:ttle} file | + in a li{3:ttle} file | | {1:~ }| {1:~ }| {1:~ }| /ttle^ | ]]) + + -- cancelling search resets to the old search term + feed('<esc>') + screen:expect([[ + the first line | + in a {2:^lit}tle file | + | + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]) end) it('works with incsearch and offset', function() @@ -163,7 +175,7 @@ describe('search highlighting', function() feed("gg/mat/e") screen:expect([[ not the {3:mat}ch you're looking for | - the match is here | + the {2:mat}ch is here | {1:~ }| {1:~ }| {1:~ }| @@ -174,7 +186,7 @@ describe('search highlighting', function() -- Search with count and /e offset fixed in Vim patch 7.4.532. feed("<esc>2/mat/e") screen:expect([[ - not the match you're looking for | + not the {2:mat}ch you're looking for | the {3:mat}ch is here | {1:~ }| {1:~ }| |