To: vim_dev@googlegroups.com Subject: Patch 8.1.0018 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.0018 Problem: Using "gn" may select wrong text when wrapping. Solution: Avoid wrapping when searching forward. (Christian Brabandt) Files: src/search.c, src/testdir/test_gn.vim *** ../vim-8.1.0017/src/search.c 2018-04-27 22:44:25.000000000 +0200 --- src/search.c 2018-05-22 17:45:10.884137772 +0200 *************** *** 4665,4670 **** --- 4665,4671 ---- { pos_T start_pos; /* position before the pattern */ 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 i; int dir; *************** *** 4758,4763 **** --- 4759,4766 ---- ml_get(curwin->w_buffer->b_ml.ml_line_count)); } } + if (i == 0) + first_match = pos; p_ws = old_p_ws; } *************** *** 4774,4782 **** /* 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); if (!VIsual_active) VIsual = start_pos; --- 4777,4801 ---- /* move to match, except for zero-width matches, in which case, we are * already on the next match */ if (!one_char) ! { ! 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; *** ../vim-8.1.0017/src/testdir/test_gn.vim 2017-10-15 22:02:53.000000000 +0200 --- src/testdir/test_gn.vim 2018-05-22 17:48:47.536062374 +0200 *************** *** 4,54 **** noautocmd new " replace a single char by itsself quoted: call setline('.', 'abc x def x ghi x jkl') ! let @/='x' exe "norm! cgn'x'\.." call assert_equal("abc 'x' def 'x' ghi 'x' jkl", getline('.')) sil! %d_ " simple search match call setline('.', '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' exe "norm! gnceins\zwei" call assert_equal(['','eins','zwei'], getline(1,'$')) sil! %d _ " test count argument call setline('.', ['', 'abcdx | abcdx | abcdx']) ! let @/='[a]bcdx' exe "norm! 2gnd" call assert_equal(['','abcdx | | abcdx'], getline(1,'$')) sil! %d _ " join lines call setline('.', ['join ', 'lines']) ! let @/='$' exe "norm! 0gnd" call assert_equal(['join lines'], getline(1,'$')) sil! %d _ " zero-width match call setline('.', ['', 'zero width pattern']) ! 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 @/='^' exe "norm! 0gnd$" ! let @/='\zs' exe "norm! gnd" call assert_equal(['elete first and last char'], getline(1,'$')) sil! %d _ --- 4,54 ---- noautocmd new " replace a single char by itsself quoted: call setline('.', 'abc x def x ghi x jkl') ! let @/ = 'x' exe "norm! cgn'x'\.." call assert_equal("abc 'x' def 'x' ghi 'x' jkl", getline('.')) sil! %d_ " simple search match call setline('.', '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' exe "norm! gnceins\zwei" call assert_equal(['','eins','zwei'], getline(1,'$')) sil! %d _ " test count argument call setline('.', ['', 'abcdx | abcdx | abcdx']) ! let @/ = '[a]bcdx' exe "norm! 2gnd" call assert_equal(['','abcdx | | abcdx'], getline(1,'$')) sil! %d _ " join lines call setline('.', ['join ', 'lines']) ! let @/ = '$' exe "norm! 0gnd" call assert_equal(['join lines'], getline(1,'$')) sil! %d _ " zero-width match call setline('.', ['', 'zero width pattern']) ! 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 @/ = '^' exe "norm! 0gnd$" ! let @/ = '\zs' exe "norm! gnd" call assert_equal(['elete first and last char'], getline(1,'$')) sil! %d _ *************** *** 61,74 **** " backwards search call setline('.', ['my very excellent mother just served us nachos']) ! 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' exe "norm! cgnj" call assert_equal(['','for (j=0; i<=10; i++)'], getline(1,'$')) sil! %d _ --- 61,74 ---- " backwards search call setline('.', ['my very excellent mother just served us nachos']) ! 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' exe "norm! cgnj" call assert_equal(['','for (j=0; i<=10; i++)'], getline(1,'$')) sil! %d _ *************** *** 76,103 **** " search hex char call setline('.', ['','Y']) set noignorecase ! let @/='\%x59' exe "norm! gnd" call assert_equal(['',''], getline(1,'$')) sil! %d _ " test repeating gdn call setline('.', ['', '1', 'Johnny', '2', 'Johnny', '3']) ! 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' 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\+' exe "norm! 2nygno\p" call assert_equal(['a:10', '', 'a:1', '1', '', 'a:20'], getline(1,'$')) sil! %d _ --- 76,103 ---- " search hex char call setline('.', ['','Y']) set noignorecase ! let @/ = '\%x59' exe "norm! gnd" call assert_equal(['',''], getline(1,'$')) sil! %d _ " test repeating gdn call setline('.', ['', '1', 'Johnny', '2', 'Johnny', '3']) ! 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' 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\+' exe "norm! 2nygno\p" call assert_equal(['a:10', '', 'a:1', '1', '', 'a:20'], getline(1,'$')) sil! %d _ *************** *** 113,124 **** " search upwards with nowrapscan set call setline('.', ['foo', 'bar', 'foo', 'baz']) set nowrapscan ! let @/='foo' $ norm! dgN call assert_equal(['foo', 'bar', '', 'baz'], getline(1,'$')) sil! %d_ set wrapscan&vim endfu --- 113,133 ---- " search upwards with nowrapscan set call setline('.', ['foo', 'bar', 'foo', 'baz']) set nowrapscan ! 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 endfu *** ../vim-8.1.0017/src/version.c 2018-05-22 16:58:43.979903077 +0200 --- src/version.c 2018-05-22 17:49:43.960023944 +0200 *************** *** 763,764 **** --- 763,766 ---- { /* Add new patch number below this line */ + /**/ + 18, /**/ -- Eye have a spelling checker, it came with my PC; It plainly marks four my revue mistakes I cannot sea. I've run this poem threw it, I'm sure your please to no, It's letter perfect in it's weigh, my checker tolled me sew! /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///