diff options
-rw-r--r-- | src/nvim/search.c | 36 | ||||
-rw-r--r-- | src/nvim/testdir/test_gn.vim | 16 |
2 files changed, 43 insertions, 9 deletions
diff --git a/src/nvim/search.c b/src/nvim/search.c index 82f2cf28ab..faa66ea0ea 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -4097,7 +4097,7 @@ abort_search: int current_search( long count, - int forward // true for forward, false for backward + bool forward // true for forward, false for backward ) { bool old_p_ws = p_ws; @@ -4112,6 +4112,11 @@ current_search( pos_T pos; // position after the pattern int result; // result of various function calls + // When searching forward and the cursor is at the start of the Visual + // area, skip the first search backward, otherwise it doesn't move. + const bool skip_first_backward = forward && VIsual_active + && lt(curwin->w_cursor, VIsual); + orig_pos = pos = curwin->w_cursor; if (VIsual_active) { // Searching further will extend the match. @@ -4129,13 +4134,20 @@ current_search( return FAIL; // pattern not found } - /* - * The trick is to first search backwards and then search forward again, - * so that a match at the current cursor position will be correctly - * captured. - */ + // The trick is to first search backwards and then search forward again, + // so that a match at the current cursor position will be correctly + // captured. When "forward" is false do it the other way around. for (int i = 0; i < 2; i++) { - int dir = forward ? i : !i; + int dir; + if (forward) { + if (i == 0 && skip_first_backward) { + continue; + } + dir = i; + } else { + dir = !i; + } + int flags = 0; if (!dir && !zero_width) { @@ -4182,10 +4194,16 @@ current_search( VIsual = start_pos; } - // put cursor on last character of match + // put the cursor after the match curwin->w_cursor = end_pos; if (lt(VIsual, end_pos) && forward) { - dec_cursor(); + if (skip_first_backward) { + // put the cursor on the start of the match + curwin->w_cursor = pos; + } else { + // put the cursor on last character of match + dec_cursor(); + } } else if (VIsual_active && lt(curwin->w_cursor, VIsual) && forward) { curwin->w_cursor = pos; // put the cursor on the start of the match } diff --git a/src/nvim/testdir/test_gn.vim b/src/nvim/testdir/test_gn.vim index 8f800a7c79..9acec51913 100644 --- a/src/nvim/testdir/test_gn.vim +++ b/src/nvim/testdir/test_gn.vim @@ -169,6 +169,22 @@ func Test_gN_repeat() bwipe! endfunc +func Test_gN_then_gn() + new + + call setline(1, 'this list is a list with a list of a last.') + /l.st + normal $gNgNgnx + call assert_equal('last', @") + + call setline(1, 'this list is a list with a lust of a last.') + /l.st + normal $gNgNgNgnx + call assert_equal('lust of a last', @") + + bwipe! +endfunc + func Test_gn_multi_line() new call setline(1, [ |