vim-patch:8.1.0356: using :s with 'incsearch' prevents CTRL-R CTRL-W

Problem:    Using :s with 'incsearch' prevents CTRL-R CTRL-W. (Boris Staletic)
Solution:   When past the pattern put cursor back in the start position.
            (closes vim/vim#3413)
99f043a57d
This commit is contained in:
Aufar Gilbran 2020-08-19 00:51:38 +08:00
parent e2dc2a6bd7
commit b0042cafc0
2 changed files with 52 additions and 11 deletions

View File

@ -447,7 +447,7 @@ static void may_do_incsearch_highlighting(int firstc, long count,
curwin->w_cursor.lnum = search_first_line; curwin->w_cursor.lnum = search_first_line;
curwin->w_cursor.col = 0; curwin->w_cursor.col = 0;
} }
int i; int found; // do_search() result
// Use the previous pattern for ":s//". // Use the previous pattern for ":s//".
next_char = ccline.cmdbuff[skiplen + patlen]; next_char = ccline.cmdbuff[skiplen + patlen];
@ -456,7 +456,7 @@ static void may_do_incsearch_highlighting(int firstc, long count,
// If there is no pattern, don't do anything. // If there is no pattern, don't do anything.
if (patlen == 0 && !use_last_pat) { if (patlen == 0 && !use_last_pat) {
i = 0; found = 0;
set_no_hlsearch(true); // turn off previous highlight set_no_hlsearch(true); // turn off previous highlight
redraw_all_later(SOME_VALID); redraw_all_later(SOME_VALID);
} else { } else {
@ -475,15 +475,15 @@ static void may_do_incsearch_highlighting(int firstc, long count,
ccline.cmdbuff[skiplen + patlen] = NUL; ccline.cmdbuff[skiplen + patlen] = NUL;
memset(&sia, 0, sizeof(sia)); memset(&sia, 0, sizeof(sia));
sia.sa_tm = &tm; sia.sa_tm = &tm;
i = do_search(NULL, firstc == ':' ? '/' : firstc, found = do_search(NULL, firstc == ':' ? '/' : firstc,
ccline.cmdbuff + skiplen, count, ccline.cmdbuff + skiplen, count,
search_flags, &sia); search_flags, &sia);
ccline.cmdbuff[skiplen + patlen] = next_char; ccline.cmdbuff[skiplen + patlen] = next_char;
emsg_off--; emsg_off--;
if (curwin->w_cursor.lnum < search_first_line if (curwin->w_cursor.lnum < search_first_line
|| curwin->w_cursor.lnum > search_last_line) { || curwin->w_cursor.lnum > search_last_line) {
// match outside of address range // match outside of address range
i = 0; found = 0;
curwin->w_cursor = s->search_start; curwin->w_cursor = s->search_start;
} }
@ -491,7 +491,7 @@ static void may_do_incsearch_highlighting(int firstc, long count,
if (got_int) { if (got_int) {
(void)vpeekc(); // remove <C-C> from input stream (void)vpeekc(); // remove <C-C> from input stream
got_int = false; // don't abandon the command line got_int = false; // don't abandon the command line
i = 0; found = 0;
} else if (char_avail()) { } else if (char_avail()) {
// cancelled searching because a char was typed // cancelled searching because a char was typed
s->incsearch_postponed = true; s->incsearch_postponed = true;
@ -499,7 +499,7 @@ static void may_do_incsearch_highlighting(int firstc, long count,
ui_busy_stop(); ui_busy_stop();
} }
if (i != 0) { if (found != 0) {
highlight_match = true; // highlight position highlight_match = true; // highlight position
} else { } else {
highlight_match = false; // remove highlight highlight_match = false; // remove highlight
@ -511,7 +511,7 @@ static void may_do_incsearch_highlighting(int firstc, long count,
changed_cline_bef_curs(); changed_cline_bef_curs();
update_topline(); update_topline();
if (i != 0) { if (found != 0) {
pos_T save_pos = curwin->w_cursor; pos_T save_pos = curwin->w_cursor;
s->match_start = curwin->w_cursor; s->match_start = curwin->w_cursor;
@ -544,8 +544,11 @@ static void may_do_incsearch_highlighting(int firstc, long count,
update_screen(SOME_VALID); update_screen(SOME_VALID);
restore_last_search_pattern(); restore_last_search_pattern();
// Leave it at the end to make CTRL-R CTRL-W work. // Leave it at the end to make CTRL-R CTRL-W work. But not when beyond the
if (i != 0) { // end of the pattern, e.g. for ":s/pat/".
if (ccline.cmdbuff[skiplen + patlen] != NUL) {
curwin->w_cursor = s->search_start;
} else if (found != 0) {
curwin->w_cursor = end_pos; curwin->w_cursor = end_pos;
} }

View File

@ -801,6 +801,44 @@ func Test_keep_last_search_pattern()
set noincsearch set noincsearch
endfunc endfunc
func Test_word_under_cursor_after_match()
throw 'skipped: Nvim does not support test_override()'
if !exists('+incsearch')
return
endif
new
call setline(1, 'foo bar')
set incsearch
call test_override("char_avail", 1)
try
call feedkeys("/foo\<C-R>\<C-W>\<CR>", 'ntx')
catch /E486:/
endtry
call assert_equal('foobar', @/)
bwipe!
call test_override("ALL", 0)
set noincsearch
endfunc
func Test_subst_word_under_cursor()
throw 'skipped: Nvim does not support test_override()'
if !exists('+incsearch')
return
endif
new
call setline(1, ['int SomeLongName;', 'for (xxx = 1; xxx < len; ++xxx)'])
set incsearch
call test_override("char_avail", 1)
call feedkeys("/LongName\<CR>", 'ntx')
call feedkeys(":%s/xxx/\<C-R>\<C-W>/g\<CR>", 'ntx')
call assert_equal('for (SomeLongName = 1; SomeLongName < len; ++SomeLongName)', getline(2))
bwipe!
call test_override("ALL", 0)
set noincsearch
endfunc
func Test_incsearch_with_change() func Test_incsearch_with_change()
if !has('timers') || !exists('+incsearch') || !CanRunVimInTerminal() if !has('timers') || !exists('+incsearch') || !CanRunVimInTerminal()
throw 'Skipped: cannot make screendumps and/or timers feature and/or incsearch option missing' throw 'Skipped: cannot make screendumps and/or timers feature and/or incsearch option missing'