mirror of
https://github.com/neovim/neovim.git
synced 2025-10-05 17:36:29 +00:00
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:
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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,
|
||||||
|
Reference in New Issue
Block a user