diff options
author | Ghjuvan Lacambre <code@lacamb.re> | 2021-04-04 20:43:22 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-04 14:43:22 -0400 |
commit | 0f187700ab1437e949f03d6915df7c76f8287304 (patch) | |
tree | 235da971e8133a11ad3b3aa3ef077370564521ea | |
parent | 76f5c72860b237d66c949dcdeb6967047810b956 (diff) | |
download | rneovim-0f187700ab1437e949f03d6915df7c76f8287304.tar.gz rneovim-0f187700ab1437e949f03d6915df7c76f8287304.tar.bz2 rneovim-0f187700ab1437e949f03d6915df7c76f8287304.zip |
vim-patch:8.2.0295: highlighting for :s wrong when using different separator (#14286)
Problem: Highlighting for :s wrong when using different separator.
Solution: Use separat argument for search direction and separator. (Rob
Pilling, closes vim/vim#5665)
https://github.com/vim/vim/commit/c036e87bd7001238ab7cc5d9e30e59bbf989a5fd
-rw-r--r-- | src/nvim/ex_docmd.c | 2 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 26 | ||||
-rw-r--r-- | src/nvim/normal.c | 2 | ||||
-rw-r--r-- | src/nvim/quickfix.c | 2 | ||||
-rw-r--r-- | src/nvim/search.c | 18 | ||||
-rw-r--r-- | src/nvim/spell.c | 2 | ||||
-rw-r--r-- | src/nvim/tag.c | 11 | ||||
-rw-r--r-- | src/nvim/testdir/test_search.vim | 24 | ||||
-rw-r--r-- | test/functional/ui/searchhl_spec.lua | 14 |
9 files changed, 75 insertions, 26 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 3aaf171b2c..d1eddfc74f 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -3928,7 +3928,7 @@ static linenr_T get_address(exarg_T *eap, } searchcmdlen = 0; flags = silent ? 0 : SEARCH_HIS | SEARCH_MSG; - if (!do_search(NULL, c, cmd, 1L, flags, NULL)) { + if (!do_search(NULL, c, c, cmd, 1L, flags, NULL)) { curwin->w_cursor = pos; cmd = NULL; goto error; diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 38385d19b2..e6b2b231f9 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -275,8 +275,9 @@ static void init_incsearch_state(incsearch_state_T *s) // Return true when 'incsearch' highlighting is to be done. // Sets search_first_line and search_last_line to the address range. -static bool do_incsearch_highlighting(int firstc, incsearch_state_T *s, - int *skiplen, int *patlen) +static bool do_incsearch_highlighting(int firstc, int *search_delim, + incsearch_state_T *s, int *skiplen, + int *patlen) FUNC_ATTR_NONNULL_ALL { char_u *cmd; @@ -303,6 +304,7 @@ static bool do_incsearch_highlighting(int firstc, incsearch_state_T *s, search_last_line = MAXLNUM; if (firstc == '/' || firstc == '?') { + *search_delim = firstc; return true; } if (firstc != ':') { @@ -371,6 +373,7 @@ static bool do_incsearch_highlighting(int firstc, incsearch_state_T *s, p = skipwhite(p); delim = (delim_optional && vim_isIDc(*p)) ? ' ' : *p++; + *search_delim = delim; end = skip_regexp(p, delim, p_magic, NULL); use_last_pat = end == p && *end == delim; @@ -431,12 +434,14 @@ static void may_do_incsearch_highlighting(int firstc, long count, int skiplen, patlen; char_u next_char; char_u use_last_pat; + int search_delim; // Parsing range may already set the last search pattern. // NOTE: must call restore_last_search_pattern() before returning! save_last_search_pattern(); - if (!do_incsearch_highlighting(firstc, s, &skiplen, &patlen)) { + if (!do_incsearch_highlighting(firstc, &search_delim, s, &skiplen, + &patlen)) { restore_last_search_pattern(); finish_incsearch_highlighting(false, s, true); return; @@ -490,7 +495,7 @@ static void may_do_incsearch_highlighting(int firstc, long count, ccline.cmdbuff[skiplen + patlen] = NUL; memset(&sia, 0, sizeof(sia)); sia.sa_tm = &tm; - found = do_search(NULL, firstc == ':' ? '/' : firstc, + found = do_search(NULL, firstc == ':' ? '/' : firstc, search_delim, ccline.cmdbuff + skiplen, count, search_flags, &sia); ccline.cmdbuff[skiplen + patlen] = next_char; @@ -581,13 +586,15 @@ static int may_add_char_to_search(int firstc, int *c, incsearch_state_T *s) FUNC_ATTR_NONNULL_ALL { int skiplen, patlen; + int search_delim; // Parsing range may already set the last search pattern. // NOTE: must call restore_last_search_pattern() before returning! save_last_search_pattern(); // Add a character from under the cursor for 'incsearch' - if (!do_incsearch_highlighting(firstc, s, &skiplen, &patlen)) { + if (!do_incsearch_highlighting(firstc, &search_delim, s, &skiplen, + &patlen)) { restore_last_search_pattern(); return FAIL; } @@ -604,7 +611,7 @@ static int may_add_char_to_search(int firstc, int *c, incsearch_state_T *s) && !pat_has_uppercase(ccline.cmdbuff + skiplen)) { *c = mb_tolower(*c); } - if (*c == firstc + if (*c == search_delim || vim_strchr((char_u *)(p_magic ? "\\~^$.*[" : "\\^$"), *c) != NULL) { // put a backslash before special characters @@ -1465,13 +1472,14 @@ static int may_do_command_line_next_incsearch(int firstc, long count, bool next_match) FUNC_ATTR_NONNULL_ALL { - int skiplen, patlen; + int skiplen, patlen, search_delim; // Parsing range may already set the last search pattern. // NOTE: must call restore_last_search_pattern() before returning! save_last_search_pattern(); - if (!do_incsearch_highlighting(firstc, s, &skiplen, &patlen)) { + if (!do_incsearch_highlighting(firstc, &search_delim, s, &skiplen, + &patlen)) { restore_last_search_pattern(); return OK; } @@ -1489,7 +1497,7 @@ static int may_do_command_line_next_incsearch(int firstc, long count, char_u save; - if (firstc == ccline.cmdbuff[skiplen]) { + if (search_delim == ccline.cmdbuff[skiplen]) { pat = last_search_pattern(); skiplen = 0; patlen = (int)STRLEN(pat); diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 3587b12277..3b40689f3e 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -5459,7 +5459,7 @@ static int normal_search( curwin->w_set_curswant = true; memset(&sia, 0, sizeof(sia)); - i = do_search(cap->oap, dir, pat, cap->count1, + i = do_search(cap->oap, dir, dir, pat, cap->count1, opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, &sia); if (wrapped != NULL) { *wrapped = sia.sa_wrapped; diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 0785fa703d..464d72eccb 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -2798,7 +2798,7 @@ static void qf_jump_goto_line(linenr_T qf_lnum, int qf_col, char_u qf_viscol, // Move the cursor to the first line in the buffer pos_T save_cursor = curwin->w_cursor; curwin->w_cursor.lnum = 0; - if (!do_search(NULL, '/', qf_pattern, (long)1, SEARCH_KEEP, NULL)) { + if (!do_search(NULL, '/', '/', qf_pattern, (long)1, SEARCH_KEEP, NULL)) { curwin->w_cursor = save_cursor; } } diff --git a/src/nvim/search.c b/src/nvim/search.c index 9d3d3061e4..c4479a077e 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -1021,8 +1021,9 @@ static int first_submatch(regmmatch_T *rp) * Return 0 for failure, 1 for found, 2 for found and line offset added. */ int do_search( - oparg_T *oap, /* can be NULL */ - int dirc, /* '/' or '?' */ + oparg_T *oap, // can be NULL + int dirc, // '/' or '?' + int search_delim, // delimiter for search, e.g. '%' in s%regex%replacement char_u *pat, long count, int options, @@ -1101,8 +1102,8 @@ int do_search( searchstr = pat; dircp = NULL; - /* use previous pattern */ - if (pat == NULL || *pat == NUL || *pat == dirc) { + // use previous pattern + if (pat == NULL || *pat == NUL || *pat == search_delim) { if (spats[RE_SEARCH].pat == NULL) { // no previous pattern searchstr = spats[RE_SUBST].pat; if (searchstr == NULL) { @@ -1122,15 +1123,15 @@ int do_search( * If there is a matching '/' or '?', toss it. */ ps = strcopy; - p = skip_regexp(pat, dirc, p_magic, &strcopy); + p = skip_regexp(pat, search_delim, p_magic, &strcopy); if (strcopy != ps) { /* made a copy of "pat" to change "\?" to "?" */ searchcmdlen += (int)(STRLEN(pat) - STRLEN(strcopy)); pat = strcopy; searchstr = strcopy; } - if (*p == dirc) { - dircp = p; /* remember where we put the NUL */ + if (*p == search_delim) { + dircp = p; // remember where we put the NUL *p++ = NUL; } spats[0].off.line = FALSE; @@ -1320,7 +1321,7 @@ int do_search( RE_LAST, sia); if (dircp != NULL) { - *dircp = dirc; // restore second '/' or '?' for normal_cmd() + *dircp = search_delim; // restore second '/' or '?' for normal_cmd() } if (!shortmess(SHM_SEARCH) @@ -1400,6 +1401,7 @@ int do_search( } dirc = *++pat; + search_delim = dirc; if (dirc != '?' && dirc != '/') { retval = 0; EMSG(_("E386: Expected '?' or '/' after ';'")); diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 55f9594de2..f6dc3a04a7 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -3035,7 +3035,7 @@ void ex_spellrepall(exarg_T *eap) sub_nlines = 0; curwin->w_cursor.lnum = 0; while (!got_int) { - if (do_search(NULL, '/', frompat, 1L, SEARCH_KEEP, NULL) == 0 + if (do_search(NULL, '/', '/', frompat, 1L, SEARCH_KEEP, NULL) == 0 || u_save_cursor() == FAIL) { break; } diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 6b8f393572..588821f260 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -2811,7 +2811,7 @@ static int jumpto_tag( // start search before first line curwin->w_cursor.lnum = 0; } - if (do_search(NULL, pbuf[0], pbuf + 1, (long)1, + if (do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, (long)1, search_options, NULL)) { retval = OK; } else { @@ -2821,8 +2821,8 @@ static int jumpto_tag( /* * try again, ignore case now */ - p_ic = TRUE; - if (!do_search(NULL, pbuf[0], pbuf + 1, (long)1, + p_ic = true; + if (!do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, (long)1, search_options, NULL)) { // Failed to find pattern, take a guess: "^func (" found = 2; @@ -2830,11 +2830,12 @@ static int jumpto_tag( cc = *tagp.tagname_end; *tagp.tagname_end = NUL; snprintf((char *)pbuf, LSIZE, "^%s\\s\\*(", tagp.tagname); - if (!do_search(NULL, '/', pbuf, (long)1, search_options, NULL)) { + if (!do_search(NULL, '/', '/', pbuf, (long)1, search_options, NULL)) { // Guess again: "^char * \<func (" snprintf((char *)pbuf, LSIZE, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(", tagp.tagname); - if (!do_search(NULL, '/', pbuf, (long)1, search_options, NULL)) { + if (!do_search(NULL, '/', '/', pbuf, (long)1, + search_options, NULL)) { found = 0; } } diff --git a/src/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim index d4d529e4b9..7aa01c61ca 100644 --- a/src/nvim/testdir/test_search.vim +++ b/src/nvim/testdir/test_search.vim @@ -723,6 +723,30 @@ func Test_incsearch_substitute_dump() call delete('Xis_subst_script') endfunc +func Test_incsearch_highlighting() + if !exists('+incsearch') + return + endif + if !CanRunVimInTerminal() + throw 'Skipped: cannot make screendumps' + endif + + call writefile([ + \ 'set incsearch hlsearch', + \ 'call setline(1, "hello/there")', + \ ], 'Xis_subst_hl_script') + let buf = RunVimInTerminal('-S Xis_subst_hl_script', {'rows': 4, 'cols': 20}) + " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by + " the 'ambiwidth' check. + sleep 300m + + " Using a different search delimiter should still highlight matches + " that contain a '/'. + call term_sendkeys(buf, ":%s;ello/the") + call VerifyScreenDump(buf, 'Test_incsearch_substitute_15', {}) + call term_sendkeys(buf, "<Esc>") +endfunc + " Similar to Test_incsearch_substitute_dump() for :sort func Test_incsearch_sort_dump() if !exists('+incsearch') diff --git a/test/functional/ui/searchhl_spec.lua b/test/functional/ui/searchhl_spec.lua index 656f613c6a..5540b3c2dc 100644 --- a/test/functional/ui/searchhl_spec.lua +++ b/test/functional/ui/searchhl_spec.lua @@ -507,7 +507,21 @@ describe('search highlighting', function() {1:~ }| :syntax keyword MyGroup special | ]]) + end) + it('highlights entire pattern on :%g@a/b', function() + command('set inccommand=nosplit') + feed('ia/b/c<Esc>') + feed(':%g@a/b') + screen:expect([[ + {3:a/b}/c | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :%g@a/b^ | + ]]) end) end) |