diff options
Diffstat (limited to 'src/nvim')
| -rw-r--r-- | src/nvim/search.c | 30 | ||||
| -rw-r--r-- | src/nvim/testdir/test_gn.vim | 39 | 
2 files changed, 50 insertions, 19 deletions
| diff --git a/src/nvim/search.c b/src/nvim/search.c index e9d8f92226..457a6c309d 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -3953,7 +3953,9 @@ current_search(      dec_cursor();    pos_T orig_pos;               /* position of the cursor at beginning */ +  pos_T first_match;            // position of first match    pos_T pos;                    /* position after the pattern */ +  int result;                   // result of various function calls    if (VIsual_active) {      orig_pos = pos = curwin->w_cursor; @@ -3988,7 +3990,7 @@ current_search(      if (!dir && !one_char)        flags = SEARCH_END; -    int result = searchit(curwin, curbuf, &pos, (dir ? FORWARD : BACKWARD), +    result = searchit(curwin, curbuf, &pos, (dir ? FORWARD : BACKWARD),          spats[last_idx].pat, i ? count : 1,          SEARCH_KEEP | flags, RE_SEARCH, 0, NULL); @@ -4012,6 +4014,9 @@ current_search(              ml_get(curwin->w_buffer->b_ml.ml_line_count));        }      } +    if (i == 0) { +      first_match = pos; +    }      p_ws = old_p_ws;    } @@ -4029,9 +4034,26 @@ current_search(    /* move to match, except for zero-width matches, in which case, we are     * already on the next match */ -  if (!one_char) -    searchit(curwin, curbuf, &pos, direction, -        spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, 0, NULL); +  if (!one_char) { +    p_ws = false; +    for (int i = 0; i < 2; i++) { +      result = searchit(curwin, curbuf, &pos, direction, +                        spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, +                        0, 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/nvim/testdir/test_gn.vim b/src/nvim/testdir/test_gn.vim index f56e707da1..405425a42b 100644 --- a/src/nvim/testdir/test_gn.vim +++ b/src/nvim/testdir/test_gn.vim @@ -5,51 +5,51 @@ func Test_gn_command()    noautocmd new    " replace a single char by itsself quoted:    call setline('.', 'abc x def x ghi x jkl') -  let @/='x' +  let @/ = 'x'    exe "norm! cgn'x'\<esc>.."    call assert_equal("abc 'x' def 'x' ghi 'x' jkl", getline('.'))    sil! %d_    " simple search match    call setline('.', 'foobar') -  let @/='foobar' +  let @/ = 'foobar'    exe "norm! gncsearchmatch"    call assert_equal('searchmatch', getline('.'))    sil! %d _    " replace a multi-line match    call setline('.', ['', 'one', 'two']) -  let @/='one\_s*two\_s' +  let @/ = 'one\_s*two\_s'    exe "norm! gnceins\<CR>zwei"    call assert_equal(['','eins','zwei'], getline(1,'$'))    sil! %d _    " test count argument    call setline('.', ['', 'abcdx | abcdx | abcdx']) -  let @/='[a]bcdx' +  let @/ = '[a]bcdx'    exe "norm! 2gnd"    call assert_equal(['','abcdx |  | abcdx'], getline(1,'$'))    sil! %d _    " join lines    call setline('.', ['join ', 'lines']) -  let @/='$' +  let @/ = '$'    exe "norm! 0gnd"    call assert_equal(['join lines'], getline(1,'$'))    sil! %d _    " zero-width match    call setline('.', ['', 'zero width pattern']) -  let @/='\>\zs' +  let @/ = '\>\zs'    exe "norm! 0gnd"    call assert_equal(['', 'zerowidth pattern'], getline(1,'$'))    sil! %d _    " delete first and last chars    call setline('.', ['delete first and last chars']) -  let @/='^' +  let @/ = '^'    exe "norm! 0gnd$" -  let @/='\zs' +  let @/ = '\zs'    exe "norm! gnd"    call assert_equal(['elete first and last char'], getline(1,'$'))    sil! %d _ @@ -62,14 +62,14 @@ func Test_gn_command()    " backwards search    call setline('.', ['my very excellent mother just served us nachos']) -  let @/='mother' +  let @/ = 'mother'    exe "norm! $cgNmongoose"    call assert_equal(['my very excellent mongoose just served us nachos'], getline(1,'$'))    sil! %d _    " search for single char    call setline('.', ['','for (i=0; i<=10; i++)']) -  let @/='i' +  let @/ = 'i'    exe "norm! cgnj"    call assert_equal(['','for (j=0; i<=10; i++)'], getline(1,'$'))    sil! %d _ @@ -77,28 +77,28 @@ func Test_gn_command()    " search hex char    call setline('.', ['','Y'])    set noignorecase -  let @/='\%x59' +  let @/ = '\%x59'    exe "norm! gnd"    call assert_equal(['',''], getline(1,'$'))    sil! %d _    " test repeating gdn    call setline('.', ['', '1', 'Johnny', '2', 'Johnny', '3']) -  let @/='Johnny' +  let @/ = 'Johnny'    exe "norm! dgn."    call assert_equal(['','1', '', '2', '', '3'], getline(1,'$'))    sil! %d _    " test repeating gUgn    call setline('.', ['', '1', 'Depp', '2', 'Depp', '3']) -  let @/='Depp' +  let @/ = 'Depp'    exe "norm! gUgn."    call assert_equal(['', '1', 'DEPP', '2', 'DEPP', '3'], getline(1,'$'))    sil! %d _    " test using look-ahead assertions    call setline('.', ['a:10', '', 'a:1', '', 'a:20']) -  let @/='a:0\@!\zs\d\+' +  let @/ = 'a:0\@!\zs\d\+'    exe "norm! 2nygno\<esc>p"    call assert_equal(['a:10', '', 'a:1', '1', '', 'a:20'], getline(1,'$'))    sil! %d _ @@ -114,12 +114,21 @@ func Test_gn_command()    " search upwards with nowrapscan set    call setline('.', ['foo', 'bar', 'foo', 'baz'])    set nowrapscan -  let @/='foo' +  let @/ = 'foo'    $    norm! dgN    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    set belloff&vim  endfu | 
