summaryrefslogtreecommitdiff
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
parentb07a82b6d5f904ed3e623e775c3458adb1cc0a3e (diff)
downloadvim-git-dda933d06c06c2792bd686d059f6ad19191ad30b.tar.gz
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.
-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 59fa28806..ed82f0fd3 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 a18594953..0f9b23051 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 6e5146079..9c2d61051 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 0fed162c7..de2d859ce 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,