aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/search.c36
-rw-r--r--src/nvim/testdir/test_gn.vim16
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, [