aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJames McCoy <jamessan@jamessan.com>2017-06-25 12:15:58 -0400
committerJames McCoy <jamessan@jamessan.com>2017-06-26 22:08:13 -0400
commit54d5e90a2b87736a3248300ed423374e88ce8e79 (patch)
tree7953336c8a7542a0107082233a08c15874d0c3a9 /src
parent3679752dbd9191f4067a43143da637478cc389f1 (diff)
downloadrneovim-54d5e90a2b87736a3248300ed423374e88ce8e79.tar.gz
rneovim-54d5e90a2b87736a3248300ed423374e88ce8e79.tar.bz2
rneovim-54d5e90a2b87736a3248300ed423374e88ce8e79.zip
vim-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. https://github.com/vim/vim/commit/dda933d06c06c2792bd686d059f6ad19191ad30b
Diffstat (limited to 'src')
-rw-r--r--src/nvim/ex_getln.c63
-rw-r--r--src/nvim/normal.c6
-rw-r--r--src/nvim/testdir/test_search.vim32
-rw-r--r--src/nvim/version.c2
4 files changed, 78 insertions, 25 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 45fff4f9d7..e8f9d9bf47 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -100,13 +100,18 @@ typedef struct command_line_state {
char_u *lookfor; // string to match
int hiscnt; // current history line in use
int histype; // history type to be used
- pos_T old_cursor;
+ pos_T search_start; // where 'incsearch' starts searching
+ pos_T save_cursor;
colnr_T old_curswant;
+ colnr_T init_curswant;
colnr_T old_leftcol;
+ colnr_T init_leftcol;
linenr_T old_topline;
+ linenr_T init_topline;
int old_topfill;
+ int init_topfill;
linenr_T old_botline;
- pos_T cursor_start;
+ linenr_T init_botline;
pos_T match_start;
pos_T match_end;
int did_incsearch;
@@ -171,6 +176,11 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
s->save_p_icm = vim_strsave(p_icm);
s->ignore_drag_release = true;
s->match_start = curwin->w_cursor;
+ s->init_curswant = curwin->w_curswant;
+ s->init_leftcol = curwin->w_leftcol;
+ s->init_topline = curwin->w_topline;
+ s->init_topfill = curwin->w_topfill;
+ s->init_botline = curwin->w_botline;
if (s->firstc == -1) {
s->firstc = NUL;
@@ -184,8 +194,8 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
ccline.overstrike = false; // always start in insert mode
clearpos(&s->match_end);
- s->old_cursor = curwin->w_cursor; // needs to be restored later
- s->cursor_start = s->old_cursor;
+ s->save_cursor = curwin->w_cursor; // may be restored later
+ s->search_start = curwin->w_cursor;
s->old_curswant = curwin->w_curswant;
s->old_leftcol = curwin->w_leftcol;
s->old_topline = curwin->w_topline;
@@ -288,9 +298,15 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
ccline.xpc = NULL;
if (s->did_incsearch) {
- curwin->w_cursor = s->old_cursor;
if (s->gotesc) {
- curwin->w_cursor = s->cursor_start;
+ curwin->w_cursor = s->save_cursor;
+ } else {
+ if (!equalpos(s->save_cursor, s->search_start)) {
+ // put the '" mark at the original position
+ curwin->w_cursor = s->save_cursor;
+ setpcmark();
+ }
+ curwin->w_cursor = s->search_start;
}
curwin->w_curswant = s->old_curswant;
curwin->w_leftcol = s->old_leftcol;
@@ -939,10 +955,14 @@ static int command_line_handle_key(CommandLineState *s)
// Truncate at the end, required for multi-byte chars.
ccline.cmdbuff[ccline.cmdlen] = NUL;
if (ccline.cmdlen == 0) {
- s->old_cursor = s->cursor_start;
- } else {
- s->old_cursor = s->match_start;
- decl(&s->old_cursor);
+ s->search_start = s->save_cursor;
+ // save view settings, so that the screen won't be restored at the
+ // wrong position
+ s->old_curswant = s->init_curswant;
+ s->old_leftcol = s->init_leftcol;
+ s->old_topline = s->init_topline;
+ s->old_topfill = s->init_topfill;
+ s->old_botline = s->init_botline;
}
redrawcmd();
} else if (ccline.cmdlen == 0 && s->c != Ctrl_W
@@ -962,6 +982,7 @@ static int command_line_handle_key(CommandLineState *s)
}
msg_putchar(' '); // delete ':'
}
+ s->search_start = s->save_cursor;
redraw_cmdline = true;
return 0; // back to cmd mode
}
@@ -1017,7 +1038,7 @@ static int command_line_handle_key(CommandLineState *s)
// Truncate at the end, required for multi-byte chars.
ccline.cmdbuff[ccline.cmdlen] = NUL;
if (ccline.cmdlen == 0) {
- s->old_cursor = s->cursor_start;
+ s->search_start = s->save_cursor;
}
redrawcmd();
return command_line_changed(s);
@@ -1250,7 +1271,7 @@ static int command_line_handle_key(CommandLineState *s)
// Add a character from under the cursor for 'incsearch'
if (s->did_incsearch) {
curwin->w_cursor = s->match_end;
- if (!equalpos(curwin->w_cursor, s->old_cursor)) {
+ if (!equalpos(curwin->w_cursor, s->search_start)) {
s->c = gchar_cursor();
// If 'ignorecase' and 'smartcase' are set and the
// command line has no uppercase characters, convert
@@ -1453,23 +1474,23 @@ static int command_line_handle_key(CommandLineState *s)
emsg_off--;
ui_busy_stop();
if (s->i) {
- s->old_cursor = s->match_start;
+ s->search_start = s->match_start;
s->match_end = t;
s->match_start = t;
if (s->c == Ctrl_T && s->firstc == '/') {
// move just before the current match, so that
// when nv_search finishes the cursor will be
// put back on the match
- s->old_cursor = t;
- (void)decl(&s->old_cursor);
+ s->search_start = t;
+ (void)decl(&s->search_start);
}
- if (lt(t, s->old_cursor) && s->c == Ctrl_G) {
+ if (lt(t, s->search_start) && s->c == Ctrl_G) {
// wrap around
- s->old_cursor = t;
+ s->search_start = t;
if (s->firstc == '?') {
- (void)incl(&s->old_cursor);
+ (void)incl(&s->search_start);
} else {
- (void)decl(&s->old_cursor);
+ (void)decl(&s->search_start);
}
}
@@ -1607,7 +1628,7 @@ static int command_line_changed(CommandLineState *s)
return 1;
}
s->incsearch_postponed = false;
- curwin->w_cursor = s->old_cursor; // start at old position
+ curwin->w_cursor = s->search_start; // start at old position
// If there is no command line, don't do anything
if (ccline.cmdlen == 0) {
@@ -1698,7 +1719,7 @@ static int command_line_changed(CommandLineState *s)
emsg_silent--; // Unblock error reporting
// Restore the window "view".
- curwin->w_cursor = s->old_cursor;
+ curwin->w_cursor = s->save_cursor;
curwin->w_curswant = s->old_curswant;
curwin->w_leftcol = s->old_leftcol;
curwin->w_topline = s->old_topline;
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 050020d79d..39cd2c6631 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -5231,6 +5231,7 @@ static void nv_dollar(cmdarg_T *cap)
static void 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) {
/* Translate "g??" to "g?g?" */
@@ -5240,6 +5241,8 @@ static void 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) {
@@ -5248,7 +5251,8 @@ static void 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/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim
index 28e504a883..2106fc2dec 100644
--- a/src/nvim/testdir/test_search.vim
+++ b/src/nvim/testdir/test_search.vim
@@ -33,6 +33,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')
@@ -61,6 +62,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
@@ -182,11 +184,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')
@@ -240,7 +242,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/nvim/version.c b/src/nvim/version.c
index 5a107f0023..094ca29b01 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -124,7 +124,7 @@ static const int included_patches[] = {
2323,
2322,
2321,
- // 2320,
+ 2320,
// 2319 NA
2318,
2317,