summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ex_getln.c90
-rw-r--r--src/testdir/dumps/Test_incsearch_substitute_02.dump9
-rw-r--r--src/testdir/dumps/Test_incsearch_substitute_03.dump9
-rw-r--r--src/testdir/test_search.vim15
-rw-r--r--src/version.c2
5 files changed, 89 insertions, 36 deletions
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 07032bb54..a1cea9baf 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -300,7 +300,7 @@ do_incsearch_highlighting(int firstc, incsearch_state_T *is_state,
{
delim = *p++;
end = skip_regexp(p, delim, p_magic, NULL);
- if (end > p)
+ if (end > p || *end == delim)
{
char_u *dummy;
exarg_T ea;
@@ -341,6 +341,37 @@ do_incsearch_highlighting(int firstc, incsearch_state_T *is_state,
return FALSE;
}
+ static void
+finish_incsearch_highlighting(
+ int gotesc,
+ incsearch_state_T *is_state,
+ int call_update_screen)
+{
+ if (is_state->did_incsearch)
+ {
+ is_state->did_incsearch = FALSE;
+ if (gotesc)
+ curwin->w_cursor = is_state->save_cursor;
+ else
+ {
+ if (!EQUAL_POS(is_state->save_cursor, is_state->search_start))
+ {
+ // put the '" mark at the original position
+ curwin->w_cursor = is_state->save_cursor;
+ setpcmark();
+ }
+ curwin->w_cursor = is_state->search_start;
+ }
+ restore_viewstate(&is_state->old_viewstate);
+ highlight_match = FALSE;
+ validate_cursor(); /* needed for TAB */
+ if (call_update_screen)
+ update_screen(SOME_VALID);
+ else
+ redraw_all_later(SOME_VALID);
+ }
+}
+
/*
* Do 'incsearch' highlighting if desired.
*/
@@ -357,10 +388,14 @@ may_do_incsearch_highlighting(
#ifdef FEAT_RELTIME
proftime_T tm;
#endif
- int c;
+ int next_char;
+ int use_last_pat;
if (!do_incsearch_highlighting(firstc, is_state, &skiplen, &patlen))
+ {
+ finish_incsearch_highlighting(FALSE, is_state, TRUE);
return;
+ }
// If there is a character waiting, search and redraw later.
if (char_avail())
@@ -381,8 +416,13 @@ may_do_incsearch_highlighting(
}
save_last_search_pattern();
- // If there is no command line, don't do anything.
- if (patlen == 0)
+ // Use the previous pattern for ":s//".
+ next_char = ccline.cmdbuff[skiplen + patlen];
+ use_last_pat = patlen == 0 && skiplen > 0
+ && ccline.cmdbuff[skiplen - 1] == next_char;
+
+ // If there is no pattern, don't do anything.
+ if (patlen == 0 && !use_last_pat)
{
i = 0;
set_no_hlsearch(TRUE); // turn off previous highlight
@@ -403,7 +443,6 @@ may_do_incsearch_highlighting(
search_flags += SEARCH_KEEP;
if (search_first_line != 0)
search_flags += SEARCH_START;
- c = ccline.cmdbuff[skiplen + patlen];
ccline.cmdbuff[skiplen + patlen] = NUL;
i = do_search(NULL, firstc == ':' ? '/' : firstc,
ccline.cmdbuff + skiplen, count, search_flags,
@@ -413,7 +452,7 @@ may_do_incsearch_highlighting(
NULL, NULL
#endif
);
- ccline.cmdbuff[skiplen + patlen] = c;
+ ccline.cmdbuff[skiplen + patlen] = next_char;
--emsg_off;
if (curwin->w_cursor.lnum < search_first_line
@@ -459,11 +498,14 @@ may_do_incsearch_highlighting(
// Disable 'hlsearch' highlighting if the pattern matches everything.
// Avoids a flash when typing "foo\|".
- c = ccline.cmdbuff[skiplen + patlen];
- ccline.cmdbuff[skiplen + patlen] = NUL;
- if (empty_pattern(ccline.cmdbuff))
- set_no_hlsearch(TRUE);
- ccline.cmdbuff[skiplen + patlen] = c;
+ if (!use_last_pat)
+ {
+ next_char = ccline.cmdbuff[skiplen + patlen];
+ ccline.cmdbuff[skiplen + patlen] = NUL;
+ if (empty_pattern(ccline.cmdbuff))
+ set_no_hlsearch(TRUE);
+ ccline.cmdbuff[skiplen + patlen] = next_char;
+ }
validate_cursor();
// May redraw the status line to show the cursor position.
@@ -628,30 +670,6 @@ may_add_char_to_search(int firstc, int *c, incsearch_state_T *is_state)
}
return OK;
}
-
- static void
-finish_incsearch_highlighting(int gotesc, incsearch_state_T *is_state)
-{
- if (is_state->did_incsearch)
- {
- if (gotesc)
- curwin->w_cursor = is_state->save_cursor;
- else
- {
- if (!EQUAL_POS(is_state->save_cursor, is_state->search_start))
- {
- // put the '" mark at the original position
- curwin->w_cursor = is_state->save_cursor;
- setpcmark();
- }
- curwin->w_cursor = is_state->search_start;
- }
- restore_viewstate(&is_state->old_viewstate);
- highlight_match = FALSE;
- validate_cursor(); /* needed for TAB */
- redraw_all_later(SOME_VALID);
- }
-}
#endif
/*
@@ -2301,7 +2319,7 @@ returncmd:
ccline.xpc = NULL;
#ifdef FEAT_SEARCH_EXTRA
- finish_incsearch_highlighting(gotesc, &is_state);
+ finish_incsearch_highlighting(gotesc, &is_state, FALSE);
#endif
if (ccline.cmdbuff != NULL)
diff --git a/src/testdir/dumps/Test_incsearch_substitute_02.dump b/src/testdir/dumps/Test_incsearch_substitute_02.dump
new file mode 100644
index 000000000..fd1f91235
--- /dev/null
+++ b/src/testdir/dumps/Test_incsearch_substitute_02.dump
@@ -0,0 +1,9 @@
+|f+0&#ffffff0|o@1| |1| @64
+|f|o@1| |2| @64
+|f|o@1| |3| @64
+|f+1&&|o@1| +0&&|4| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|5| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|6| @64
+|f|o@1| |7| @64
+|f|o@1| |8| @64
+|:|.|,|.|+|2|s|/@1> @60
diff --git a/src/testdir/dumps/Test_incsearch_substitute_03.dump b/src/testdir/dumps/Test_incsearch_substitute_03.dump
new file mode 100644
index 000000000..5d7afa0e0
--- /dev/null
+++ b/src/testdir/dumps/Test_incsearch_substitute_03.dump
@@ -0,0 +1,9 @@
+|f+0&#ffff4012|o@1| +0&#ffffff0|1| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|2| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|3| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|4| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|5| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|6| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|7| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|8| @64
+|:|.|,|.|+|2|s|/> @61
diff --git a/src/testdir/test_search.vim b/src/testdir/test_search.vim
index 20ffa0fbf..9b701269d 100644
--- a/src/testdir/test_search.vim
+++ b/src/testdir/test_search.vim
@@ -839,6 +839,7 @@ func Test_incsearch_substitute_dump()
sleep 100m
" Need to send one key at a time to force a redraw.
+ " Select three lines at the cursor with typed pattern.
call term_sendkeys(buf, ':.,.+2s/')
sleep 100m
call term_sendkeys(buf, 'f')
@@ -846,7 +847,21 @@ func Test_incsearch_substitute_dump()
call term_sendkeys(buf, 'o')
sleep 100m
call term_sendkeys(buf, 'o')
+ sleep 100m
call VerifyScreenDump(buf, 'Test_incsearch_substitute_01', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ " Select three lines at the cursor using previous pattern.
+ call term_sendkeys(buf, "/foo\<CR>")
+ sleep 100m
+ call term_sendkeys(buf, ':.,.+2s//')
+ sleep 100m
+ call VerifyScreenDump(buf, 'Test_incsearch_substitute_02', {})
+
+ " Deleting last slash should remove the match.
+ call term_sendkeys(buf, "\<BS>")
+ sleep 100m
+ call VerifyScreenDump(buf, 'Test_incsearch_substitute_03', {})
call term_sendkeys(buf, "\<Esc>")
call StopVimInTerminal(buf)
diff --git a/src/version.c b/src/version.c
index 98b233588..a3f81f072 100644
--- a/src/version.c
+++ b/src/version.c
@@ -795,6 +795,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 277,
+/**/
276,
/**/
275,