Skip to content

Commit dda933d

Browse files
committed
patch 7.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.
1 parent b07a82b commit dda933d

4 files changed

Lines changed: 78 additions & 24 deletions

File tree

src/ex_getln.c

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -177,17 +177,22 @@ getcmdline(
177177
int histype; /* history type to be used */
178178
#endif
179179
#ifdef FEAT_SEARCH_EXTRA
180-
pos_T old_cursor;
180+
pos_T search_start; /* where 'incsearch' starts searching */
181+
pos_T save_cursor;
181182
colnr_T old_curswant;
183+
colnr_T init_curswant = curwin->w_curswant;
182184
colnr_T old_leftcol;
185+
colnr_T init_leftcol = curwin->w_leftcol;
183186
linenr_T old_topline;
184-
pos_T cursor_start;
187+
linenr_T init_topline = curwin->w_topline;
185188
pos_T match_start = curwin->w_cursor;
186189
pos_T match_end;
187190
# ifdef FEAT_DIFF
188191
int old_topfill;
192+
int init_topfill = curwin->w_topfill;
189193
# endif
190194
linenr_T old_botline;
195+
linenr_T init_botline = curwin->w_botline;
191196
int did_incsearch = FALSE;
192197
int incsearch_postponed = FALSE;
193198
#endif
@@ -230,8 +235,8 @@ getcmdline(
230235
ccline.overstrike = FALSE; /* always start in insert mode */
231236
#ifdef FEAT_SEARCH_EXTRA
232237
clearpos(&match_end);
233-
old_cursor = curwin->w_cursor; /* needs to be restored later */
234-
cursor_start = old_cursor;
238+
save_cursor = curwin->w_cursor; /* may be restored later */
239+
search_start = curwin->w_cursor;
235240
old_curswant = curwin->w_curswant;
236241
old_leftcol = curwin->w_leftcol;
237242
old_topline = curwin->w_topline;
@@ -1006,11 +1011,17 @@ getcmdline(
10061011
ccline.cmdbuff[ccline.cmdlen] = NUL;
10071012
#ifdef FEAT_SEARCH_EXTRA
10081013
if (ccline.cmdlen == 0)
1009-
old_cursor = cursor_start;
1010-
else
10111014
{
1012-
old_cursor = match_start;
1013-
decl(&old_cursor);
1015+
search_start = save_cursor;
1016+
/* save view settings, so that the screen
1017+
* won't be restored at the wrong position */
1018+
old_curswant = init_curswant;
1019+
old_leftcol = init_leftcol;
1020+
old_topline = init_topline;
1021+
# ifdef FEAT_DIFF
1022+
old_topfill = init_topfill;
1023+
# endif
1024+
old_botline = init_botline;
10141025
}
10151026
#endif
10161027
redrawcmd();
@@ -1040,7 +1051,7 @@ getcmdline(
10401051
}
10411052
#ifdef FEAT_SEARCH_EXTRA
10421053
if (ccline.cmdlen == 0)
1043-
old_cursor = cursor_start;
1054+
search_start = save_cursor;
10441055
#endif
10451056
redraw_cmdline = TRUE;
10461057
goto returncmd; /* back to cmd mode */
@@ -1127,7 +1138,7 @@ getcmdline(
11271138
ccline.cmdbuff[ccline.cmdlen] = NUL;
11281139
#ifdef FEAT_SEARCH_EXTRA
11291140
if (ccline.cmdlen == 0)
1130-
old_cursor = cursor_start;
1141+
search_start = save_cursor;
11311142
#endif
11321143
redrawcmd();
11331144
goto cmdline_changed;
@@ -1468,7 +1479,7 @@ getcmdline(
14681479
if (did_incsearch)
14691480
{
14701481
curwin->w_cursor = match_end;
1471-
if (!equalpos(curwin->w_cursor, old_cursor))
1482+
if (!equalpos(curwin->w_cursor, search_start))
14721483
{
14731484
c = gchar_cursor();
14741485
/* If 'ignorecase' and 'smartcase' are set and the
@@ -1685,25 +1696,25 @@ getcmdline(
16851696
--emsg_off;
16861697
if (i)
16871698
{
1688-
old_cursor = match_start;
1699+
search_start = match_start;
16891700
match_end = t;
16901701
match_start = t;
16911702
if (c == Ctrl_T && firstc == '/')
16921703
{
16931704
/* move just before the current match, so that
16941705
* when nv_search finishes the cursor will be
16951706
* put back on the match */
1696-
old_cursor = t;
1697-
(void)decl(&old_cursor);
1707+
search_start = t;
1708+
(void)decl(&search_start);
16981709
}
1699-
if (lt(t, old_cursor) && c == Ctrl_G)
1710+
if (lt(t, search_start) && c == Ctrl_G)
17001711
{
17011712
/* wrap around */
1702-
old_cursor = t;
1713+
search_start = t;
17031714
if (firstc == '?')
1704-
(void)incl(&old_cursor);
1715+
(void)incl(&search_start);
17051716
else
1706-
(void)decl(&old_cursor);
1717+
(void)decl(&search_start);
17071718
}
17081719

17091720
set_search_match(&match_end);
@@ -1870,7 +1881,7 @@ getcmdline(
18701881
continue;
18711882
}
18721883
incsearch_postponed = FALSE;
1873-
curwin->w_cursor = old_cursor; /* start at old position */
1884+
curwin->w_cursor = search_start; /* start at old position */
18741885

18751886
/* If there is no command line, don't do anything */
18761887
if (ccline.cmdlen == 0)
@@ -1988,9 +1999,18 @@ getcmdline(
19881999
#ifdef FEAT_SEARCH_EXTRA
19892000
if (did_incsearch)
19902001
{
1991-
curwin->w_cursor = old_cursor;
19922002
if (gotesc)
1993-
curwin->w_cursor = cursor_start;
2003+
curwin->w_cursor = save_cursor;
2004+
else
2005+
{
2006+
if (!equalpos(save_cursor, search_start))
2007+
{
2008+
/* put the '" mark at the original position */
2009+
curwin->w_cursor = save_cursor;
2010+
setpcmark();
2011+
}
2012+
curwin->w_cursor = search_start;
2013+
}
19942014
curwin->w_curswant = old_curswant;
19952015
curwin->w_leftcol = old_leftcol;
19962016
curwin->w_topline = old_topline;

src/normal.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6228,6 +6228,7 @@ nv_dollar(cmdarg_T *cap)
62286228
nv_search(cmdarg_T *cap)
62296229
{
62306230
oparg_T *oap = cap->oap;
6231+
pos_T save_cursor = curwin->w_cursor;
62316232

62326233
if (cap->cmdchar == '?' && cap->oap->op_type == OP_ROT13)
62336234
{
@@ -6238,6 +6239,8 @@ nv_search(cmdarg_T *cap)
62386239
return;
62396240
}
62406241

6242+
/* When using 'incsearch' the cursor may be moved to set a different search
6243+
* start position. */
62416244
cap->searchbuf = getcmdline(cap->cmdchar, cap->count1, 0);
62426245

62436246
if (cap->searchbuf == NULL)
@@ -6247,7 +6250,8 @@ nv_search(cmdarg_T *cap)
62476250
}
62486251

62496252
(void)normal_search(cap, cap->cmdchar, cap->searchbuf,
6250-
(cap->arg ? 0 : SEARCH_MARK));
6253+
(cap->arg || !equalpos(save_cursor, curwin->w_cursor))
6254+
? 0 : SEARCH_MARK);
62516255
}
62526256

62536257
/*

src/testdir/test_search.vim

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ func Test_search_cmdline()
3131
" second match
3232
call feedkeys("/the\<C-G>\<cr>", 'tx')
3333
call assert_equal(' 3 the', getline('.'))
34+
call assert_equal([0, 0, 0, 0], getpos('"'))
3435
:1
3536
" third match
3637
call feedkeys("/the".repeat("\<C-G>", 2)."\<cr>", 'tx')
@@ -59,6 +60,7 @@ func Test_search_cmdline()
5960
" no further match
6061
call feedkeys("/the".repeat("\<C-G>", 8)."\<cr>", 'tx')
6162
call assert_equal(' 9 these', getline('.'))
63+
call assert_equal([0, 0, 0, 0], getpos('"'))
6264

6365
" Test 3
6466
" Ctrl-G goes from one match to the next
@@ -180,11 +182,11 @@ func Test_search_cmdline()
180182
1
181183
" delete one char, add another
182184
call feedkeys("/thei\<bs>s\<cr>", 'tx')
183-
call assert_equal(' 9 these', getline('.'))
185+
call assert_equal(' 2 these', getline('.'))
184186
1
185187
" delete one char, add another, go to previous match, add one char
186188
call feedkeys("/thei\<bs>s\<bs>\<C-T>\<c-l>\<cr>", 'tx')
187-
call assert_equal(' 8 them', getline('.'))
189+
call assert_equal(' 9 these', getline('.'))
188190
1
189191
" delete all chars, start from the beginning again
190192
call feedkeys("/them". repeat("\<bs>",4).'the\>'."\<cr>", 'tx')
@@ -236,7 +238,33 @@ func Test_search_cmdline2()
236238
call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<C-T>\<cr>", 'tx')
237239
call assert_equal(' 2 these', getline('.'))
238240

241+
" Test 2: keep the view,
242+
" after deleting a character from the search cmd
243+
call setline(1, [' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there', ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar'])
244+
resize 5
245+
1
246+
call feedkeys("/foo\<bs>\<cr>", 'tx')
247+
redraw
248+
call assert_equal({'lnum': 10, 'leftcol': 0, 'col': 4, 'topfill': 0, 'topline': 6, 'coladd': 0, 'skipcol': 0, 'curswant': 4}, winsaveview())
249+
250+
" remove all history entries
251+
for i in range(10)
252+
call histdel('/')
253+
endfor
254+
255+
" Test 3: reset the view,
256+
" after deleting all characters from the search cmd
257+
norm! 1gg0
258+
" unfortunately, neither "/foo\<c-w>\<cr>", nor "/foo\<bs>\<bs>\<bs>\<cr>",
259+
" nor "/foo\<c-u>\<cr>" works to delete the commandline.
260+
" In that case Vim should return "E35 no previous regular expression",
261+
" but it looks like Vim still sees /foo and therefore the test fails.
262+
" Therefore, disableing this test
263+
"call assert_fails(feedkeys("/foo\<c-w>\<cr>", 'tx'), 'E35')
264+
"call assert_equal({'lnum': 1, 'leftcol': 0, 'col': 0, 'topfill': 0, 'topline': 1, 'coladd': 0, 'skipcol': 0, 'curswant': 0}, winsaveview())
265+
239266
" clean up
267+
set noincsearch
240268
call test_disable_char_avail(0)
241269
bw!
242270
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,8 @@ static char *(features[]) =
763763

764764
static int included_patches[] =
765765
{ /* Add new patch number below this line */
766+
/**/
767+
2320,
766768
/**/
767769
2319,
768770
/**/

0 commit comments

Comments
 (0)