summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-09-03 21:04:58 +0200
committerBram Moolenaar <Bram@vim.org>2016-09-03 21:04:58 +0200
commitdda933d06c06c2792bd686d059f6ad19191ad30b (patch)
tree0452e843f90cf9289f01366c926169e8b9169faf /src
parentb07a82b6d5f904ed3e623e775c3458adb1cc0a3e (diff)
patch 7.4.2320v7.4.2320
Problem: Redraw problem when using 'incsearch'. Solution: Save the current view when deleting characters. (Christian Brabandt) Fix that the '" mark is set in the wrong position. Don't change the search start when using BS.
Diffstat (limited to 'src')
-rw-r--r--src/ex_getln.c62
-rw-r--r--src/normal.c6
-rw-r--r--src/testdir/test_search.vim32
-rw-r--r--src/version.c2
4 files changed, 78 insertions, 24 deletions
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 59fa288067..ed82f0fd3c 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -177,17 +177,22 @@ getcmdline(
int histype; /* history type to be used */
#endif
#ifdef FEAT_SEARCH_EXTRA
- pos_T old_cursor;
+ pos_T search_start; /* where 'incsearch' starts searching */
+ pos_T save_cursor;
colnr_T old_curswant;
+ colnr_T init_curswant = curwin->w_curswant;
colnr_T old_leftcol;
+ colnr_T init_leftcol = curwin->w_leftcol;
linenr_T old_topline;
- pos_T cursor_start;
+ linenr_T init_topline = curwin->w_topline;
pos_T match_start = curwin->w_cursor;
pos_T match_end;
# ifdef FEAT_DIFF
int old_topfill;
+ int init_topfill = curwin->w_topfill;
# endif
linenr_T old_botline;
+ linenr_T init_botline = curwin->w_botline;
int did_incsearch = FALSE;
int incsearch_postponed = FALSE;
#endif
@@ -230,8 +235,8 @@ getcmdline(
ccline.overstrike = FALSE; /* always start in insert mode */
#ifdef FEAT_SEARCH_EXTRA
clearpos(&match_end);
- old_cursor = curwin->w_cursor; /* needs to be restored later */
- cursor_start = old_cursor;
+ save_cursor = curwin->w_cursor; /* may be restored later */
+ search_start = curwin->w_cursor;
old_curswant = curwin->w_curswant;
old_leftcol = curwin->w_leftcol;
old_topline = curwin->w_topline;
@@ -1006,11 +1011,17 @@ getcmdline(
ccline.cmdbuff[ccline.cmdlen] = NUL;
#ifdef FEAT_SEARCH_EXTRA
if (ccline.cmdlen == 0)
- old_cursor = cursor_start;
- else
{
- old_cursor = match_start;
- decl(&old_cursor);
+ search_start = save_cursor;
+ /* save view settings, so that the screen
+ * won't be restored at the wrong position */
+ old_curswant = init_curswant;
+ old_leftcol = init_leftcol;
+ old_topline = init_topline;
+# ifdef FEAT_DIFF
+ old_topfill = init_topfill;
+# endif
+ old_botline = init_botline;
}
#endif
redrawcmd();
@@ -1040,7 +1051,7 @@ getcmdline(
}
#ifdef FEAT_SEARCH_EXTRA
if (ccline.cmdlen == 0)
- old_cursor = cursor_start;
+ search_start = save_cursor;
#endif
redraw_cmdline = TRUE;
goto returncmd; /* back to cmd mode */
@@ -1127,7 +1138,7 @@ getcmdline(
ccline.cmdbuff[ccline.cmdlen] = NUL;
#ifdef FEAT_SEARCH_EXTRA
if (ccline.cmdlen == 0)
- old_cursor = cursor_start;
+ search_start = save_cursor;
#endif
redrawcmd();
goto cmdline_changed;
@@ -1468,7 +1479,7 @@ getcmdline(
if (did_incsearch)
{
curwin->w_cursor = match_end;
- if (!equalpos(curwin->w_cursor, old_cursor))
+ if (!equalpos(curwin->w_cursor, search_start))
{
c = gchar_cursor();
/* If 'ignorecase' and 'smartcase' are set and the
@@ -1685,7 +1696,7 @@ getcmdline(
--emsg_off;
if (i)
{
- old_cursor = match_start;
+ search_start = match_start;
match_end = t;
match_start = t;
if (c == Ctrl_T && firstc == '/')
@@ -1693,17 +1704,17 @@ getcmdline(
/* move just before the current match, so that
* when nv_search finishes the cursor will be
* put back on the match */
- old_cursor = t;
- (void)decl(&old_cursor);
+ search_start = t;
+ (void)decl(&search_start);
}
- if (lt(t, old_cursor) && c == Ctrl_G)
+ if (lt(t, search_start) && c == Ctrl_G)
{
/* wrap around */
- old_cursor = t;
+ search_start = t;
if (firstc == '?')
- (void)incl(&old_cursor);
+ (void)incl(&search_start);
else
- (void)decl(&old_cursor);
+ (void)decl(&search_start);
}
set_search_match(&match_end);
@@ -1870,7 +1881,7 @@ cmdline_changed:
continue;
}
incsearch_postponed = FALSE;
- curwin->w_cursor = old_cursor; /* start at old position */
+ curwin->w_cursor = search_start; /* start at old position */
/* If there is no command line, don't do anything */
if (ccline.cmdlen == 0)
@@ -1988,9 +1999,18 @@ returncmd:
#ifdef FEAT_SEARCH_EXTRA
if (did_incsearch)
{
- curwin->w_cursor = old_cursor;
if (gotesc)
- curwin->w_cursor = cursor_start;
+ curwin->w_cursor = save_cursor;
+ else
+ {
+ if (!equalpos(save_cursor, search_start))
+ {
+ /* put the '" mark at the original position */
+ curwin->w_cursor = save_cursor;
+ setpcmark();
+ }
+ curwin->w_cursor = search_start;
+ }
curwin->w_curswant = old_curswant;
curwin->w_leftcol = old_leftcol;
curwin->w_topline = old_topline;
diff --git a/src/normal.c b/src/normal.c
index a185949531..0f9b23051d 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -6228,6 +6228,7 @@ nv_dollar(cmdarg_T *cap)
nv_search(cmdarg_T *cap)
{
oparg_T *oap = cap->oap;
+ pos_T save_cursor = curwin->w_cursor;
if (cap->cmdchar == '?' && cap->oap->op_type == OP_ROT13)
{
@@ -6238,6 +6239,8 @@ nv_search(cmdarg_T *cap)
return;
}
+ /* When using 'incsearch' the cursor may be moved to set a different search
+ * start position. */
cap->searchbuf = getcmdline(cap->cmdchar, cap->count1, 0);
if (cap->searchbuf == NULL)
@@ -6247,7 +6250,8 @@ nv_search(cmdarg_T *cap)
}
(void)normal_search(cap, cap->cmdchar, cap->searchbuf,
- (cap->arg ? 0 : SEARCH_MARK));
+ (cap->arg || !equalpos(save_cursor, curwin->w_cursor))
+ ? 0 : SEARCH_MARK);
}
/*
diff --git a/src/testdir/test_search.vim b/src/testdir/test_search.vim
index 6e5146079a..9c2d610513 100644
--- a/src/testdir/test_search.vim
+++ b/src/testdir/test_search.vim
@@ -31,6 +31,7 @@ func Test_search_cmdline()
" second match
call feedkeys("/the\<C-G>\<cr>", 'tx')
call assert_equal(' 3 the', getline('.'))
+ call assert_equal([0, 0, 0, 0], getpos('"'))
:1
" third match
call feedkeys("/the".repeat("\<C-G>", 2)."\<cr>", 'tx')
@@ -59,6 +60,7 @@ func Test_search_cmdline()
" no further match
call feedkeys("/the".repeat("\<C-G>", 8)."\<cr>", 'tx')
call assert_equal(' 9 these', getline('.'))
+ call assert_equal([0, 0, 0, 0], getpos('"'))
" Test 3
" Ctrl-G goes from one match to the next
@@ -180,11 +182,11 @@ func Test_search_cmdline()
1
" delete one char, add another
call feedkeys("/thei\<bs>s\<cr>", 'tx')
- call assert_equal(' 9 these', getline('.'))
+ call assert_equal(' 2 these', getline('.'))
1
" delete one char, add another, go to previous match, add one char
call feedkeys("/thei\<bs>s\<bs>\<C-T>\<c-l>\<cr>", 'tx')
- call assert_equal(' 8 them', getline('.'))
+ call assert_equal(' 9 these', getline('.'))
1
" delete all chars, start from the beginning again
call feedkeys("/them". repeat("\<bs>",4).'the\>'."\<cr>", 'tx')
@@ -236,7 +238,33 @@ func Test_search_cmdline2()
call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<C-T>\<cr>", 'tx')
call assert_equal(' 2 these', getline('.'))
+ " Test 2: keep the view,
+ " after deleting a character from the search cmd
+ call setline(1, [' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there', ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar'])
+ resize 5
+ 1
+ call feedkeys("/foo\<bs>\<cr>", 'tx')
+ redraw
+ call assert_equal({'lnum': 10, 'leftcol': 0, 'col': 4, 'topfill': 0, 'topline': 6, 'coladd': 0, 'skipcol': 0, 'curswant': 4}, winsaveview())
+
+ " remove all history entries
+ for i in range(10)
+ call histdel('/')
+ endfor
+
+ " Test 3: reset the view,
+ " after deleting all characters from the search cmd
+ norm! 1gg0
+ " unfortunately, neither "/foo\<c-w>\<cr>", nor "/foo\<bs>\<bs>\<bs>\<cr>",
+ " nor "/foo\<c-u>\<cr>" works to delete the commandline.
+ " In that case Vim should return "E35 no previous regular expression",
+ " but it looks like Vim still sees /foo and therefore the test fails.
+ " Therefore, disableing this test
+ "call assert_fails(feedkeys("/foo\<c-w>\<cr>", 'tx'), 'E35')
+ "call assert_equal({'lnum': 1, 'leftcol': 0, 'col': 0, 'topfill': 0, 'topline': 1, 'coladd': 0, 'skipcol': 0, 'curswant': 0}, winsaveview())
+
" clean up
+ set noincsearch
call test_disable_char_avail(0)
bw!
endfunc
diff --git a/src/version.c b/src/version.c
index 0fed162c71..de2d859ce8 100644
--- a/src/version.c
+++ b/src/version.c
@@ -764,6 +764,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2320,
+/**/
2319,
/**/
2318,