From 41394d82365b504c89bb4da9ed5adc11c6f619f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Mon, 30 Oct 2017 11:07:35 +0300 Subject: [PATCH 1/7] 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 --- runtime/doc/options.txt | 12 ++++++++++- src/nvim/ex_getln.c | 21 +++++++++++++++---- src/nvim/search.c | 30 ++++++++++++++++++++++++++++ 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 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("/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('') + 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("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:~ }| From cd973be11bfcdee286017f83e04c3d6c3be2f19a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Fri, 3 Nov 2017 08:28:36 +0300 Subject: [PATCH 2/7] vim-patch:8.0.1250 Problem: 'hlsearch' highlighting not removed after incsearch (lacygoill) Solution: Redraw all windows. Start search at the end of the match. Improve how CTRL-G works with incremental search. Add tests. (Christian Brabandt, Hirohito Higashi, haya14busa, closes vim/vim#2267) https://github.com/vim/vim/commit/f8f8b2eadbaf3090fcfccbab560de5dbd501833d --- runtime/doc/options.txt | 4 ++-- src/nvim/ex_getln.c | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 2e584ea9bb..6a36202177 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -3306,8 +3306,8 @@ A jump table for the options with a short description can be found at |Q_op|. Example: > augroup vimrc-incsearch-highlight autocmd! - autocmd CmdlineEnter [/\?] :set hlsearch - autocmd CmdlineLeave [/\?] :set nohlsearch + autocmd CmdlineEnter /,\? :set hlsearch + autocmd CmdlineLeave /,\? :set nohlsearch augroup END < CTRL-L can be used to add one character from after the current match diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 81c6854459..692a8893ae 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) { @@ -1024,6 +1024,11 @@ static void command_line_next_incsearch(CommandLineState *s, bool next_match) 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; @@ -1662,7 +1667,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; @@ -1785,6 +1792,7 @@ static int command_line_changed(CommandLineState *s) 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(); From 660bfb3fb3e5f7ba92cbcac7e4f6b47097303a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Fri, 3 Nov 2017 08:35:43 +0300 Subject: [PATCH 3/7] Update included_patches --- src/nvim/version.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nvim/version.c b/src/nvim/version.c index ed6dc0fb2a..b6a7150f73 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -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, From 997fc8b13371fac89f8e445275c4aaad2afd37a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Fri, 3 Nov 2017 10:42:26 +0300 Subject: [PATCH 4/7] Add tests --- test/functional/ui/searchhl_spec.lua | 80 ++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/test/functional/ui/searchhl_spec.lua b/test/functional/ui/searchhl_spec.lua index 950989aab2..9fe9c2e6bd 100644 --- a/test/functional/ui/searchhl_spec.lua +++ b/test/functional/ui/searchhl_spec.lua @@ -107,6 +107,29 @@ describe('search highlighting', function() /li^ | ]]) + -- check that consecutive matches are caught by C-g/C-t + feed("") + screen:expect([[ + the first {2:li}ne | + in a {3:li}ttle file | + | + {1:~ }| + {1:~ }| + {1:~ }| + /li^ | + ]]) + + feed("") + screen:expect([[ + the first {3:li}ne | + in a {2:li}ttle file | + | + {1:~ }| + {1:~ }| + {1:~ }| + /li^ | + ]]) + feed("t") screen:expect([[ the first line | @@ -163,6 +186,63 @@ describe('search highlighting', function() {1:~ }| | ]]) + + -- cancelling inc search restores the hl state + feed(':noh') + screen:expect([[ + the first line | + in a ^little file | + | + {1:~ }| + {1:~ }| + {1:~ }| + :noh | + ]]) + + feed('/first') + screen:expect([[ + the {3:first} line | + in a little file | + | + {1:~ }| + {1:~ }| + {1:~ }| + /first^ | + ]]) + feed('') + screen:expect([[ + the first line | + in a ^little file | + | + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]) + + -- test that pressing C-g in an empty command line does not move the cursor + feed('/') + screen:expect([[ + the first line | + in a little file | + | + {1:~ }| + {1:~ }| + {1:~ }| + /^ | + ]]) + + -- same, for C-t + feed('/') + screen:expect([[ + the first line | + in a little file | + | + {1:~ }| + {1:~ }| + {1:~ }| + /^ | + ]]) end) it('works with incsearch and offset', function() From cd59577d576d71aa788a873ce779ce6dc3e7bc21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Sun, 21 Jan 2018 14:46:54 +0300 Subject: [PATCH 5/7] vim-patch:8.0.1396: memory leak when CTRL-G in search command line fails Problem: Memory leak when CTRL-G in search command line fails. Solution: Move restore_last_search_pattern to after "if". https://github.com/vim/vim/commit/a1d5c154dbd5fbe317726bbf2ba99632b91878f4 --- src/nvim/ex_getln.c | 2 +- src/nvim/version.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 692a8893ae..e396a179a1 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -1076,11 +1076,11 @@ 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); } + restore_last_search_pattern(); return; } diff --git a/src/nvim/version.c b/src/nvim/version.c index b6a7150f73..370c8ab5d3 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -101,7 +101,7 @@ static const int included_patches[] = { // 1399, // 1398, // 1397, - // 1396, + 1396, // 1395, // 1394, // 1393, From 9bc1410ee1a467a8058a8de585c0e68d64ef8521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Sun, 21 Jan 2018 15:09:17 +0300 Subject: [PATCH 6/7] vim-patch:8.0.1304: CTRL-G/CTRL-T don't work with incsearch and empty pattern Problem: CTRL-G/CTRL-T don't work with incsearch and empty pattern. Solution: Use the last search pattern. (Christian Brabandt, closes vim/vim#2292) https://github.com/vim/vim/commit/d0480097177369a6ed91d47aba189ae647afcd68 --- src/nvim/ex_getln.c | 11 ++++++++++- src/nvim/search.c | 6 ++++++ src/nvim/version.c | 2 +- test/functional/ui/searchhl_spec.lua | 24 ++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index e396a179a1..2178505874 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -1019,7 +1019,16 @@ static void command_line_next_incsearch(CommandLineState *s, bool next_match) ui_flush(); pos_T t; + 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) { @@ -1039,7 +1048,7 @@ static void command_line_next_incsearch(CommandLineState *s, bool next_match) 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(); diff --git a/src/nvim/search.c b/src/nvim/search.c index 89a7752e9f..9ae5754f80 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -335,6 +335,12 @@ restore_last_search_pattern(void) 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 370c8ab5d3..ba2912ef29 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -193,7 +193,7 @@ static const int included_patches[] = { // 1307, // 1306, // 1305, - // 1304, + 1304, // 1303, // 1302, // 1301, diff --git a/test/functional/ui/searchhl_spec.lua b/test/functional/ui/searchhl_spec.lua index 9fe9c2e6bd..b15a577585 100644 --- a/test/functional/ui/searchhl_spec.lua +++ b/test/functional/ui/searchhl_spec.lua @@ -243,6 +243,30 @@ describe('search highlighting', function() {1:~ }| /^ | ]]) + + -- 8.0.1304, test that C-g and C-t works with incsearch and empty pattern + feed('/fi') + feed('//') + screen:expect([[ + the {3:fi}rst line | + in a little {2:fi}le | + | + {1:~ }| + {1:~ }| + {1:~ }| + //^ | + ]]) + + feed('') + screen:expect([[ + the {2:fi}rst line | + in a little {3:fi}le | + | + {1:~ }| + {1:~ }| + {1:~ }| + //^ | + ]]) end) it('works with incsearch and offset', function() From 87e03c2b85cef0b31eee5aab5078cd6457dd3c9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Sun, 21 Jan 2018 16:03:35 +0300 Subject: [PATCH 7/7] vim-patch:8.0.1393: too much highlighting with 'hlsearch' and 'incsearch' set Problem: Too much highlighting with 'hlsearch' and 'incsearch' set. Solution: Do not highlight matches when the pattern matches everything. https://github.com/vim/vim/commit/6621605eb97cf5fbc481282fd4d349a76e168f16 --- src/nvim/ex_getln.c | 21 +++++++++++++++++++++ src/nvim/version.c | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 2178505874..a2f8994403 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -1781,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. @@ -1856,6 +1870,13 @@ static int command_line_changed(CommandLineState *s) end_pos = curwin->w_cursor; // shutup gcc 4 } + + // Disable 'hlsearch' highlighting if the pattern matches8.0.1304 + // 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) { diff --git a/src/nvim/version.c b/src/nvim/version.c index ba2912ef29..e627022ea6 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -104,7 +104,7 @@ static const int included_patches[] = { 1396, // 1395, // 1394, - // 1393, + 1393, // 1392, // 1391, // 1390,