vim-patch:8.1.2207: "gn" doesn't work quite right

Problem:    "gn" doesn't work quite right. (Jaehwang Jerry Jung)
Solution:   Improve and simplify the search logic. (Christian Brabandt,
            closes vim/vim#5103, closes vim/vim#5075)
edaad6e0a0
This commit is contained in:
Jaehwang Jerry Jung
2019-10-25 21:25:23 +09:00
parent 034077ed1c
commit c26466ae8b
3 changed files with 31 additions and 19 deletions

View File

@@ -4049,23 +4049,20 @@ current_search(
pos_T pos; // position after the pattern pos_T pos; // position after the pattern
int result; // result of various function calls int result; // result of various function calls
if (VIsual_active) {
orig_pos = pos = curwin->w_cursor; orig_pos = pos = curwin->w_cursor;
if (VIsual_active) {
// Searching further will extend the match. // Searching further will extend the match.
if (forward) { if (forward) {
incl(&pos); incl(&pos);
} else { } else {
decl(&pos); decl(&pos);
} }
} else {
orig_pos = pos = curwin->w_cursor;
} }
// Is the pattern is zero-width?, this time, don't care about the direction // Is the pattern is zero-width?, this time, don't care about the direction
int one_char = is_one_char(spats[last_idx].pat, true, &curwin->w_cursor, int zero_width = is_zero_width(spats[last_idx].pat, true, &curwin->w_cursor,
FORWARD); FORWARD);
if (one_char == -1) { if (zero_width == -1) {
p_ws = old_p_ws; p_ws = old_p_ws;
return FAIL; /* pattern not found */ return FAIL; /* pattern not found */
} }
@@ -4079,7 +4076,7 @@ current_search(
int dir = forward ? i : !i; int dir = forward ? i : !i;
int flags = 0; int flags = 0;
if (!dir && !one_char) { if (!dir && !zero_width) {
flags = SEARCH_END; flags = SEARCH_END;
} }
end_pos = pos; end_pos = pos;
@@ -4109,7 +4106,6 @@ current_search(
ml_get(curwin->w_buffer->b_ml.ml_line_count)); ml_get(curwin->w_buffer->b_ml.ml_line_count));
} }
} }
p_ws = old_p_ws;
} }
pos_T start_pos = pos; pos_T start_pos = pos;
@@ -4124,11 +4120,12 @@ current_search(
curwin->w_cursor = end_pos; curwin->w_cursor = end_pos;
if (lt(VIsual, end_pos)) { if (lt(VIsual, end_pos)) {
dec_cursor(); dec_cursor();
} else if (VIsual_active && lt(curwin->w_cursor, VIsual)) {
curwin->w_cursor = pos; // put the cursor on the start of the match
} }
VIsual_active = true; VIsual_active = true;
VIsual_mode = 'v'; VIsual_mode = 'v';
redraw_curbuf_later(INVERTED); // Update the inversion.
if (*p_sel == 'e') { if (*p_sel == 'e') {
// Correction for exclusive selection depends on the direction. // Correction for exclusive selection depends on the direction.
if (forward && ltoreq(VIsual, curwin->w_cursor)) { if (forward && ltoreq(VIsual, curwin->w_cursor)) {
@@ -4155,8 +4152,8 @@ current_search(
/// else from position "cur". /// else from position "cur".
/// "direction" is FORWARD or BACKWARD. /// "direction" is FORWARD or BACKWARD.
/// Returns TRUE, FALSE or -1 for failure. /// Returns TRUE, FALSE or -1 for failure.
static int is_one_char(char_u *pattern, bool move, pos_T *cur, static int
Direction direction) is_zero_width(char_u *pattern, int move, pos_T *cur, Direction direction)
{ {
regmmatch_T regmatch; regmmatch_T regmatch;
int nmatched = 0; int nmatched = 0;
@@ -4204,13 +4201,6 @@ static int is_one_char(char_u *pattern, bool move, pos_T *cur,
result = (nmatched != 0 result = (nmatched != 0
&& regmatch.startpos[0].lnum == regmatch.endpos[0].lnum && regmatch.startpos[0].lnum == regmatch.endpos[0].lnum
&& regmatch.startpos[0].col == regmatch.endpos[0].col); && regmatch.startpos[0].col == regmatch.endpos[0].col);
// one char width
if (!result
&& nmatched != 0
&& inc(&pos) >= 0
&& pos.col == regmatch.endpos[0].col) {
result = true;
}
} }
} }

View File

@@ -129,6 +129,27 @@ func Test_gn_command()
call assert_equal([' nnoremap', '', 'match'], getline(1,'$')) call assert_equal([' nnoremap', '', 'match'], getline(1,'$'))
sil! %d_ sil! %d_
" make sure it works correctly for one-char wide search items
call setline('.', ['abcdefghi'])
let @/ = 'a'
exe "norm! 0fhvhhgNgU"
call assert_equal(['ABCDEFGHi'], getline(1,'$'))
call setline('.', ['abcdefghi'])
let @/ = 'b'
exe "norm! 0fhvhhgngU"
call assert_equal(['abcdefghi'], getline(1,'$'))
sil! %d _
call setline('.', ['abcdefghi'])
let @/ = 'f'
exe "norm! 0vllgngU"
call assert_equal(['ABCDEFghi'], getline(1,'$'))
sil! %d _
call setline('.', ['12345678'])
let @/ = '5'
norm! gg0f7vhhhhgnd
call assert_equal(['12348'], getline(1,'$'))
sil! %d _
set wrapscan&vim set wrapscan&vim
set belloff&vim set belloff&vim
endfu endfu

View File

@@ -68,6 +68,7 @@ NULL
// clang-format off // clang-format off
static const int included_patches[] = { static const int included_patches[] = {
2207,
2173, 2173,
1850, 1850,
1849, 1849,