Bram,
this patch fixes a problem with the gn command. This behaviour has been 
noticed on https://vi.stackexchange.com/q/16276/71

It might happen, that the area being matched by the gn command is 
actually not correct, because of the last search wrapping around and 
matching at a previous match. Therefore, make sure to reset wrapscan 
later and also check the return value of the last searchit() function. 
If the last searchit() fails, try again from the position of the last 
match before failing.

Patch contains a test, that currently fails.

Best,
Christian
-- 
Denn das Gemeine ist's eigentlich, was den Herren Natur heißt! 
Aus sich schöpfen mag wohl heißen, mit dem eben fertig werden, was 
uns bequem wird!
                -- Goethe, Maximen und Reflektionen, Nr. 1143

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
From 294bb6c0ee579d7bb49190d2fda007bf25c0329a Mon Sep 17 00:00:00 2001
From: Christian Brabandt <[email protected]>
Date: Tue, 22 May 2018 07:51:45 +0200
Subject: [PATCH] gn might select the wrong match

found by https://vi.stackexchange.com/q/16276/71

Using the special atom \zs might actually cause vim to select the wrong
match. Part of the problem is, that wrapscan setting is too early reset.

To fix this, make sure the final search() does actually return something
useful and if not, try searching again from the position of the first
match we initially found.

Add a test to check the behaviour.
---
 src/search.c            | 25 ++++++++++++++++++++++---
 src/testdir/test_gn.vim |  9 +++++++++
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/src/search.c b/src/search.c
index 726013e62..2530db85e 100644
--- a/src/search.c
+++ b/src/search.c
@@ -4665,6 +4665,7 @@ current_search(
 {
     pos_T	start_pos;	/* position before the pattern */
     pos_T	orig_pos;	/* position of the cursor at beginning */
+    pos_T	first_match;	/* position of last match */
     pos_T	pos;		/* position after the pattern */
     int		i;
     int		dir;
@@ -4758,6 +4759,8 @@ current_search(
 				ml_get(curwin->w_buffer->b_ml.ml_line_count));
 	    }
 	}
+	if (!i)
+	    first_match = pos;
 	p_ws = old_p_ws;
     }
 
@@ -4774,9 +4777,25 @@ current_search(
     /* move to match, except for zero-width matches, in which case, we are
      * already on the next match */
     if (!one_char)
-	result = searchit(curwin, curbuf, &pos, direction,
-		    spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, 0,
-								   NULL, NULL);
+    {
+	p_ws = FALSE;
+	for (i = 0; i < 2; i++)
+	{
+	    result = searchit(curwin, curbuf, &pos, direction,
+			spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, 0,
+								    NULL, NULL);
+	    /* Search successfull, break out from the loop */
+	    if (result)
+		break;
+	    /* search failed, try again from the last search position match */
+	    pos = first_match;
+	}
+    }
+
+    p_ws = old_p_ws;
+    /* not found */
+    if (!result)
+	return FAIL;
 
     if (!VIsual_active)
 	VIsual = start_pos;
diff --git a/src/testdir/test_gn.vim b/src/testdir/test_gn.vim
index 7a77d9d88..96b531367 100644
--- a/src/testdir/test_gn.vim
+++ b/src/testdir/test_gn.vim
@@ -119,6 +119,15 @@ func Test_gn_command()
   call assert_equal(['foo', 'bar', '', 'baz'], getline(1,'$'))
   sil! %d_
 
+  " search using the \zs atom
+  call setline(1, [' nnoremap', '' , 'nnoremap'])
+  set wrapscan&vim
+  let @/='\_s\zsnnoremap'
+  $
+  norm! cgnmatch
+  call assert_equal([' nnoremap', '', 'match'], getline(1,'$'))
+  sil! %d_
+
   set wrapscan&vim
 endfu
 
-- 
2.17.0

Raspunde prin e-mail lui