aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/testdir/test_search.vim
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/testdir/test_search.vim')
-rw-r--r--src/nvim/testdir/test_search.vim530
1 files changed, 509 insertions, 21 deletions
diff --git a/src/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim
index c796f1f676..3d1bbfb726 100644
--- a/src/nvim/testdir/test_search.vim
+++ b/src/nvim/testdir/test_search.vim
@@ -19,9 +19,9 @@ func Test_search_cmdline()
set noincsearch
:1
call feedkeys("/foobar\<cr>", 'tx')
- call feedkeys("/the\<cr>",'tx')
+ call feedkeys("/the\<cr>", 'tx')
call assert_equal('the', @/)
- call feedkeys("/thes\<C-P>\<C-P>\<cr>",'tx')
+ call feedkeys("/thes\<C-P>\<C-P>\<cr>", 'tx')
call assert_equal('foobar', @/)
" Test 2
@@ -292,15 +292,84 @@ endfunc
func Test_searchpair()
new
- call setline(1, ['other code here', '', '[', '" cursor here', ']'])
+ call setline(1, ['other code', 'here [', ' [', ' " cursor here', ' ]]'])
+
+ 4
+ call assert_equal(3, searchpair('\[', '', ']', 'bW'))
+ call assert_equal([0, 3, 2, 0], getpos('.'))
+ 4
+ call assert_equal(2, searchpair('\[', '', ']', 'bWr'))
+ call assert_equal([0, 2, 6, 0], getpos('.'))
+ 4
+ call assert_equal(1, searchpair('\[', '', ']', 'bWm'))
+ call assert_equal([0, 3, 2, 0], getpos('.'))
+ 4|norm ^
+ call assert_equal(5, searchpair('\[', '', ']', 'Wn'))
+ call assert_equal([0, 4, 2, 0], getpos('.'))
+ 4
+ call assert_equal(2, searchpair('\[', '', ']', 'bW',
+ \ 'getline(".") =~ "^\\s*\["'))
+ call assert_equal([0, 2, 6, 0], getpos('.'))
+ set nomagic
+ 4
+ call assert_equal(3, searchpair('\[', '', ']', 'bW'))
+ call assert_equal([0, 3, 2, 0], getpos('.'))
+ set magic
+ 4|norm ^
+ call assert_equal(0, searchpair('{', '', '}', 'bW'))
+ call assert_equal([0, 4, 2, 0], getpos('.'))
+
+ %d
+ call setline(1, ['if 1', ' if 2', ' else', ' endif 2', 'endif 1'])
+
+ /\<if 1
+ call assert_equal(5, searchpair('\<if\>', '\<else\>', '\<endif\>', 'W'))
+ call assert_equal([0, 5, 1, 0], getpos('.'))
+ /\<if 2
+ call assert_equal(3, searchpair('\<if\>', '\<else\>', '\<endif\>', 'W'))
+ call assert_equal([0, 3, 3, 0], getpos('.'))
+
+ q!
+endfunc
+
+func Test_searchpairpos()
+ new
+ call setline(1, ['other code', 'here [', ' [', ' " cursor here', ' ]]'])
+
4
- let a = searchpair('\[','',']','bW')
- call assert_equal(3, a)
+ call assert_equal([3, 2], searchpairpos('\[', '', ']', 'bW'))
+ call assert_equal([0, 3, 2, 0], getpos('.'))
+ 4
+ call assert_equal([2, 6], searchpairpos('\[', '', ']', 'bWr'))
+ call assert_equal([0, 2, 6, 0], getpos('.'))
+ 4|norm ^
+ call assert_equal([5, 2], searchpairpos('\[', '', ']', 'Wn'))
+ call assert_equal([0, 4, 2, 0], getpos('.'))
+ 4
+ call assert_equal([2, 6], searchpairpos('\[', '', ']', 'bW',
+ \ 'getline(".") =~ "^\\s*\["'))
+ call assert_equal([0, 2, 6, 0], getpos('.'))
+ 4
+ call assert_equal([2, 6], searchpairpos('\[', '', ']', 'bWr'))
+ call assert_equal([0, 2, 6, 0], getpos('.'))
set nomagic
4
- let a = searchpair('\[','',']','bW')
- call assert_equal(3, a)
+ call assert_equal([3, 2], searchpairpos('\[', '', ']', 'bW'))
+ call assert_equal([0, 3, 2, 0], getpos('.'))
set magic
+ 4|norm ^
+ call assert_equal([0, 0], searchpairpos('{', '', '}', 'bW'))
+ call assert_equal([0, 4, 2, 0], getpos('.'))
+
+ %d
+ call setline(1, ['if 1', ' if 2', ' else', ' endif 2', 'endif 1'])
+ /\<if 1
+ call assert_equal([5, 1], searchpairpos('\<if\>', '\<else\>', '\<endif\>', 'W'))
+ call assert_equal([0, 5, 1, 0], getpos('.'))
+ /\<if 2
+ call assert_equal([3, 3], searchpairpos('\<if\>', '\<else\>', '\<endif\>', 'W'))
+ call assert_equal([0, 3, 3, 0], getpos('.'))
+
q!
endfunc
@@ -309,17 +378,29 @@ func Test_searchpair_errors()
call assert_fails("call searchpair('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: using Funcref as a String')
call assert_fails("call searchpair('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: using Dictionary as a String')
call assert_fails("call searchpair('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags')
- call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 0, 99, 100)", 'E475: Invalid argument: 0')
call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99')
call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100')
+ call assert_fails("call searchpair('start', 'middle', 'end', 'e')", 'E475: Invalid argument: e')
+ call assert_fails("call searchpair('start', 'middle', 'end', 'sn')", 'E475: Invalid argument: sn')
+endfunc
+
+func Test_searchpairpos_errors()
+ call assert_fails("call searchpairpos([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: using List as a String')
+ call assert_fails("call searchpairpos('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: using Funcref as a String')
+ call assert_fails("call searchpairpos('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: using Dictionary as a String')
+ call assert_fails("call searchpairpos('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags')
+ call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99')
+ call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100')
+ call assert_fails("call searchpairpos('start', 'middle', 'end', 'e')", 'E475: Invalid argument: e')
+ call assert_fails("call searchpairpos('start', 'middle', 'end', 'sn')", 'E475: Invalid argument: sn')
endfunc
func Test_searchpair_skip()
func Zero()
- return 0
+ return 0
endfunc
func Partial(x)
- return a:x
+ return a:x
endfunc
new
call setline(1, ['{', 'foo', 'foo', 'foo', '}'])
@@ -574,10 +655,49 @@ func Test_search_cmdline7()
bw!
endfunc
-" Tests for regexp with various magic settings
-func Test_search_regexp()
- enew!
+func Test_search_cmdline8()
+ " Highlighting is cleared in all windows
+ " since hls applies to all windows
+ CheckOption incsearch
+ CheckFeature terminal
+ CheckNotGui
+ if has("win32")
+ throw "Skipped: Bug with sending <ESC> to terminal window not fixed yet"
+ endif
+ let h = winheight(0)
+ if h < 3
+ return
+ endif
+ " Prepare buffer text
+ let lines = ['abb vim vim vi', 'vimvivim']
+ call writefile(lines, 'Xsearch.txt')
+ let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
+
+ call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])})
+
+ call term_sendkeys(buf, ":set incsearch hlsearch\<cr>")
+ call term_sendkeys(buf, ":14vsp\<cr>")
+ call term_sendkeys(buf, "/vim\<cr>")
+ call term_sendkeys(buf, "/b\<esc>")
+ call term_sendkeys(buf, "gg0")
+ call TermWait(buf, 250)
+ let screen_line = term_scrape(buf, 1)
+ let [a0,a1,a2,a3] = [screen_line[3].attr, screen_line[4].attr,
+ \ screen_line[18].attr, screen_line[19].attr]
+ call assert_notequal(a0, a1)
+ call assert_notequal(a0, a3)
+ call assert_notequal(a1, a2)
+ call assert_equal(a0, a2)
+ call assert_equal(a1, a3)
+ " clean up
+ call delete('Xsearch.txt')
+
+ bwipe!
+endfunc
+
+" Tests for regexp with various magic settings
+func Run_search_regexp_magic_opt()
put ='1 a aa abb abbccc'
exe 'normal! /a*b\{2}c\+/e' . "\<CR>"
call assert_equal([0, 2, 17, 0], getpos('.'))
@@ -612,6 +732,18 @@ func Test_search_regexp()
exe 'normal! /\V[ab]\(\[xy]\)\1' . "\<CR>"
call assert_equal([0, 9, 7, 0], getpos('.'))
+ %d
+endfunc
+
+func Test_search_regexp()
+ enew!
+
+ set regexpengine=1
+ call Run_search_regexp_magic_opt()
+ set regexpengine=2
+ call Run_search_regexp_magic_opt()
+ set regexpengine&
+
set undolevels=100
put ='9 foobar'
put =''
@@ -619,12 +751,12 @@ func Test_search_regexp()
normal G
exe 'normal! dv?bar?' . "\<CR>"
call assert_equal('9 foo', getline('.'))
- call assert_equal([0, 10, 5, 0], getpos('.'))
- call assert_equal(10, line('$'))
+ call assert_equal([0, 2, 5, 0], getpos('.'))
+ call assert_equal(2, line('$'))
normal u
call assert_equal('9 foobar', getline('.'))
- call assert_equal([0, 10, 6, 0], getpos('.'))
- call assert_equal(11, line('$'))
+ call assert_equal([0, 2, 6, 0], getpos('.'))
+ call assert_equal(3, line('$'))
set undolevels&
enew!
@@ -844,6 +976,26 @@ func Test_hlsearch_block_visual_match()
call delete('Xhlsearch_block')
endfunc
+func Test_hlsearch_and_visual()
+ CheckOption hlsearch
+ CheckScreendump
+
+ call writefile([
+ \ 'set hlsearch',
+ \ 'call setline(1, repeat(["xxx yyy zzz"], 3))',
+ \ 'hi Search cterm=bold',
+ \ '/yyy',
+ \ 'call cursor(1, 6)',
+ \ ], 'Xhlvisual_script')
+ let buf = RunVimInTerminal('-S Xhlvisual_script', {'rows': 6, 'cols': 40})
+ call term_sendkeys(buf, "vjj")
+ call VerifyScreenDump(buf, 'Test_hlsearch_visual_1', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ call StopVimInTerminal(buf)
+ call delete('Xhlvisual_script')
+endfunc
+
func Test_incsearch_substitute()
CheckFunction test_override
CheckOption incsearch
@@ -865,6 +1017,51 @@ func Test_incsearch_substitute()
call Incsearch_cleanup()
endfunc
+func Test_hlsearch_cursearch()
+ CheckScreendump
+
+ let lines =<< trim END
+ set hlsearch scrolloff=0
+ call setline(1, ['one', 'foo', 'bar', 'baz', 'foo the foo and foo', 'bar'])
+ hi Search ctermbg=yellow
+ hi CurSearch ctermbg=blue
+ END
+ call writefile(lines, 'Xhlsearch_cursearch')
+ let buf = RunVimInTerminal('-S Xhlsearch_cursearch', {'rows': 9, 'cols': 60})
+
+ call term_sendkeys(buf, "gg/foo\<CR>")
+ call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_1', {})
+
+ call term_sendkeys(buf, "n")
+ call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2', {})
+
+ call term_sendkeys(buf, "n")
+ call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2a', {})
+
+ call term_sendkeys(buf, "n")
+ call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2b', {})
+
+ call term_sendkeys(buf, ":call setline(5, 'foo')\<CR>")
+ call term_sendkeys(buf, "0?\<CR>")
+ call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_3', {})
+
+ call term_sendkeys(buf, "gg/foo\\nbar\<CR>")
+ call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_1', {})
+
+ call term_sendkeys(buf, ":call setline(1, ['---', 'abcdefg', 'hijkl', '---', 'abcdefg', 'hijkl'])\<CR>")
+ call term_sendkeys(buf, "gg/efg\\nhij\<CR>")
+ call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_2', {})
+ call term_sendkeys(buf, "h\<C-L>")
+ call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_3', {})
+ call term_sendkeys(buf, "j\<C-L>")
+ call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_4', {})
+ call term_sendkeys(buf, "h\<C-L>")
+ call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_5', {})
+
+ call StopVimInTerminal(buf)
+ call delete('Xhlsearch_cursearch')
+endfunc
+
" Similar to Test_incsearch_substitute() but with a screendump halfway.
func Test_incsearch_substitute_dump()
CheckOption incsearch
@@ -1192,7 +1389,7 @@ endfunc
" This was causing E874. Also causes an invalid read?
func Test_look_behind()
new
- call setline(1, '0\|\&\n\@<=')
+ call setline(1, '0\|\&\n\@<=')
call search(getline("."))
bwipe!
endfunc
@@ -1236,11 +1433,11 @@ endfunc
func Test_search_Ctrl_L_combining()
" Make sure, that Ctrl-L works correctly with combining characters.
" It uses an artificial example of an 'a' with 4 combining chars:
- " 'a' U+0061 Dec:97 LATIN SMALL LETTER A &#x61; /\%u61\Z "\u0061"
+ " 'a' U+0061 Dec:97 LATIN SMALL LETTER A &#x61; /\%u61\Z "\u0061"
" ' ̀' U+0300 Dec:768 COMBINING GRAVE ACCENT &#x300; /\%u300\Z "\u0300"
" ' ́' U+0301 Dec:769 COMBINING ACUTE ACCENT &#x301; /\%u301\Z "\u0301"
" ' ̇' U+0307 Dec:775 COMBINING DOT ABOVE &#x307; /\%u307\Z "\u0307"
- " ' ̣' U+0323 Dec:803 COMBINING DOT BELOW &#x323; /\%u323 "\u0323"
+ " ' ̣' U+0323 Dec:803 COMBINING DOT BELOW &#x323; /\%u323 "\u0323"
" Those should also appear on the commandline
CheckOption incsearch
@@ -1287,7 +1484,7 @@ func Test_large_hex_chars2()
endfunc
func Test_one_error_msg()
- " This was also giving an internal error
+ " This was also giving an internal error
call assert_fails('call search(" \\((\\v[[=P=]]){185}+ ")', 'E871:')
endfunc
@@ -1332,6 +1529,20 @@ func Test_search_match_at_curpos()
close!
endfunc
+" Test for error cases with the search() function
+func Test_search_errors()
+ call assert_fails("call search('pat', [])", 'E730:')
+ call assert_fails("call search('pat', 'b', {})", 'E728:')
+ call assert_fails("call search('pat', 'b', 1, [])", 'E745:')
+ call assert_fails("call search('pat', 'ns')", 'E475:')
+ call assert_fails("call search('pat', 'mr')", 'E475:')
+
+ new
+ call setline(1, ['foo', 'bar'])
+ call assert_fails('call feedkeys("/foo/;/bar/;\<CR>", "tx")', 'E386:')
+ bwipe!
+endfunc
+
func Test_search_display_pattern()
new
call setline(1, ['foo', 'bar', 'foobar'])
@@ -1395,6 +1606,160 @@ func Test_search_special()
exe "norm /\x80PS"
endfunc
+" Test for command failures when the last search pattern is not set.
+" Need to run this in a new vim instance where last search pattern is not set.
+func Test_search_with_no_last_pat()
+ let lines =<< trim [SCRIPT]
+ call assert_fails("normal i\<C-R>/\e", 'E35:')
+ call assert_fails("exe '/'", 'E35:')
+ call assert_fails("exe '?'", 'E35:')
+ call assert_fails("/", 'E35:')
+ call assert_fails("?", 'E35:')
+ call assert_fails("normal n", 'E35:')
+ call assert_fails("normal N", 'E35:')
+ call assert_fails("normal gn", 'E35:')
+ call assert_fails("normal gN", 'E35:')
+ call assert_fails("normal cgn", 'E35:')
+ call assert_fails("normal cgN", 'E35:')
+ let p = []
+ let p = @/
+ call assert_equal('', p)
+ call assert_fails("normal :\<C-R>/", 'E35:')
+ call assert_fails("//p", 'E35:')
+ call assert_fails(";//p", 'E35:')
+ call assert_fails("??p", 'E35:')
+ call assert_fails(";??p", 'E35:')
+ call assert_fails('g//p', 'E476:')
+ call assert_fails('v//p', 'E476:')
+ call writefile(v:errors, 'Xresult')
+ qall!
+ [SCRIPT]
+ call writefile(lines, 'Xscript')
+
+ if RunVim([], [], '--clean -S Xscript')
+ call assert_equal([], readfile('Xresult'))
+ endif
+ call delete('Xscript')
+ call delete('Xresult')
+endfunc
+
+" Test for using tilde (~) atom in search. This should use the last used
+" substitute pattern
+func Test_search_tilde_pat()
+ let lines =<< trim [SCRIPT]
+ set regexpengine=1
+ call assert_fails('exe "normal /~\<CR>"', 'E33:')
+ call assert_fails('exe "normal ?~\<CR>"', 'E33:')
+ set regexpengine=2
+ call assert_fails('exe "normal /~\<CR>"', 'E383:')
+ call assert_fails('exe "normal ?~\<CR>"', 'E383:')
+ set regexpengine&
+ call writefile(v:errors, 'Xresult')
+ qall!
+ [SCRIPT]
+ call writefile(lines, 'Xscript')
+ if RunVim([], [], '--clean -S Xscript')
+ call assert_equal([], readfile('Xresult'))
+ endif
+ call delete('Xscript')
+ call delete('Xresult')
+endfunc
+
+" Test for searching a pattern that is not present with 'nowrapscan'
+func Test_search_pat_not_found()
+ new
+ set nowrapscan
+ let @/ = '1abcxyz2'
+ call assert_fails('normal n', 'E385:')
+ call assert_fails('normal N', 'E384:')
+ set wrapscan&
+ close
+endfunc
+
+" Test for v:searchforward variable
+func Test_searchforward_var()
+ new
+ call setline(1, ['foo', '', 'foo'])
+ call cursor(2, 1)
+ let @/ = 'foo'
+ let v:searchforward = 0
+ normal N
+ call assert_equal(3, line('.'))
+ call cursor(2, 1)
+ let v:searchforward = 1
+ normal N
+ call assert_equal(1, line('.'))
+ close!
+endfunc
+
+" Test for invalid regular expressions
+func Test_invalid_regexp()
+ set regexpengine=1
+ call assert_fails("call search(repeat('\\(.\\)', 10))", 'E51:')
+ call assert_fails("call search('\\%(')", 'E53:')
+ call assert_fails("call search('\\(')", 'E54:')
+ call assert_fails("call search('\\)')", 'E55:')
+ call assert_fails("call search('x\\@#')", 'E59:')
+ call assert_fails('call search(''\v%(%(%(%(%(%(%(%(%(%(%(a){1}){1}){1}){1}){1}){1}){1}){1}){1}){1}){1}'')', 'E60:')
+ call assert_fails("call search('a\\+*')", 'E61:')
+ call assert_fails("call search('\\_m')", 'E63:')
+ call assert_fails("call search('\\+')", 'E64:')
+ call assert_fails("call search('\\1')", 'E65:')
+ call assert_fails("call search('\\z\\(\\)')", 'E66:')
+ call assert_fails("call search('\\z2')", 'E67:')
+ call assert_fails("call search('\\zx')", 'E68:')
+ call assert_fails("call search('\\%[ab')", 'E69:')
+ call assert_fails("call search('\\%[]')", 'E70:')
+ call assert_fails("call search('\\%a')", 'E71:')
+ call assert_fails("call search('ab\\%[\\(cd\\)]')", 'E369:')
+ call assert_fails("call search('ab\\%[\\%(cd\\)]')", 'E369:')
+ set regexpengine=2
+ call assert_fails("call search('\\_')", 'E865:')
+ call assert_fails("call search('\\+')", 'E866:')
+ call assert_fails("call search('\\zx')", 'E867:')
+ call assert_fails("call search('\\%a')", 'E867:')
+ call assert_fails("call search('x\\@#')", 'E869:')
+ call assert_fails("call search(repeat('\\(.\\)', 10))", 'E872:')
+ call assert_fails("call search('\\_m')", 'E877:')
+ call assert_fails("call search('\\%(')", 'E53:')
+ call assert_fails("call search('\\(')", 'E54:')
+ call assert_fails("call search('\\)')", 'E55:')
+ call assert_fails("call search('\\z\\(\\)')", 'E66:')
+ call assert_fails("call search('\\%[ab')", 'E69:')
+ call assert_fails("call search('\\%[]')", 'E70:')
+ call assert_fails("call search('\\%9999999999999999999999999999v')", 'E951:')
+ set regexpengine&
+ call assert_fails("call search('\\%#=3ab')", 'E864:')
+endfunc
+
+" Test for searching with 'smartcase' and 'ignorecase'
+func Test_search_smartcase()
+ new
+ call setline(1, ['', 'Hello'])
+ set noignorecase nosmartcase
+ call assert_fails('exe "normal /\\a\\_.\\(.*\\)O\<CR>"', 'E486:')
+
+ set ignorecase nosmartcase
+ exe "normal /\\a\\_.\\(.*\\)O\<CR>"
+ call assert_equal([2, 1], [line('.'), col('.')])
+
+ call cursor(1, 1)
+ set ignorecase smartcase
+ call assert_fails('exe "normal /\\a\\_.\\(.*\\)O\<CR>"', 'E486:')
+
+ exe "normal /\\a\\_.\\(.*\\)o\<CR>"
+ call assert_equal([2, 1], [line('.'), col('.')])
+
+ " Test for using special atoms with 'smartcase'
+ call setline(1, ['', ' Hello\ '])
+ call cursor(1, 1)
+ call feedkeys('/\_.\%(\uello\)\' .. "\<CR>", 'xt')
+ call assert_equal([2, 4], [line('.'), col('.')])
+
+ set ignorecase& smartcase&
+ close!
+endfun
+
" Test 'smartcase' with utf-8.
func Test_search_smartcase_utf8()
new
@@ -1414,6 +1779,102 @@ func Test_search_smartcase_utf8()
close!
endfunc
+" Test searching past the end of a file
+func Test_search_past_eof()
+ new
+ call setline(1, ['Line'])
+ exe "normal /\\n\\zs\<CR>"
+ call assert_equal([1, 4], [line('.'), col('.')])
+ close!
+endfunc
+
+" Test for various search offsets
+func Test_search_offset()
+ " With /e, for a match in the first column of a line, the cursor should be
+ " placed at the end of the previous line.
+ new
+ call setline(1, ['one two', 'three four'])
+ call search('two\_.', 'e')
+ call assert_equal([1, 7], [line('.'), col('.')])
+
+ " with cursor at the beginning of the file, use /s+1
+ call cursor(1, 1)
+ exe "normal /two/s+1\<CR>"
+ call assert_equal([1, 6], [line('.'), col('.')])
+
+ " with cursor at the end of the file, use /e-1
+ call cursor(2, 10)
+ exe "normal ?three?e-1\<CR>"
+ call assert_equal([2, 4], [line('.'), col('.')])
+
+ " line offset - after the last line
+ call cursor(1, 1)
+ exe "normal /three/+1\<CR>"
+ call assert_equal([2, 1], [line('.'), col('.')])
+
+ " line offset - before the first line
+ call cursor(2, 1)
+ exe "normal ?one?-1\<CR>"
+ call assert_equal([1, 1], [line('.'), col('.')])
+
+ " character offset - before the first character in the file
+ call cursor(2, 1)
+ exe "normal ?one?s-1\<CR>"
+ call assert_equal([1, 1], [line('.'), col('.')])
+ call cursor(2, 1)
+ exe "normal ?one?e-3\<CR>"
+ call assert_equal([1, 1], [line('.'), col('.')])
+
+ " character offset - after the last character in the file
+ call cursor(1, 1)
+ exe "normal /four/s+4\<CR>"
+ call assert_equal([2, 10], [line('.'), col('.')])
+ call cursor(1, 1)
+ exe "normal /four/e+1\<CR>"
+ call assert_equal([2, 10], [line('.'), col('.')])
+
+ close!
+endfunc
+
+" Test for searching for matching parenthesis using %
+func Test_search_match_paren()
+ new
+ call setline(1, "abc(def')'ghi'('jk'\\t'lm)no")
+ " searching for a matching parenthesis should skip single quoted characters
+ call cursor(1, 4)
+ normal %
+ call assert_equal([1, 25], [line('.'), col('.')])
+ normal %
+ call assert_equal([1, 4], [line('.'), col('.')])
+ call cursor(1, 5)
+ normal ])
+ call assert_equal([1, 25], [line('.'), col('.')])
+ call cursor(1, 24)
+ normal [(
+ call assert_equal([1, 4], [line('.'), col('.')])
+
+ " matching parenthesis in 'virtualedit' mode with cursor after the eol
+ call setline(1, 'abc(defgh)')
+ set virtualedit=all
+ normal 20|%
+ call assert_equal(4, col('.'))
+ set virtualedit&
+ close!
+endfunc
+
+" Test for searching a pattern and stopping before a specified line
+func Test_search_stopline()
+ new
+ call setline(1, ['', '', '', 'vim'])
+ call assert_equal(0, search('vim', 'n', 3))
+ call assert_equal(4, search('vim', 'n', 4))
+ call setline(1, ['vim', '', '', ''])
+ call cursor(4, 1)
+ call assert_equal(0, search('vim', 'bn', 2))
+ call assert_equal(1, search('vim', 'bn', 1))
+ close!
+endfunc
+
func Test_incsearch_highlighting_newline()
CheckRunVimInTerminal
CheckOption incsearch
@@ -1446,4 +1907,31 @@ func Test_incsearch_highlighting_newline()
bw
endfunc
+func Test_no_last_search_pattern()
+ CheckOption incsearch
+
+ let @/ = ""
+ set incsearch
+ " these were causing a crash
+ call feedkeys("//\<C-G>", 'xt')
+ call feedkeys("//\<C-T>", 'xt')
+ call feedkeys("??\<C-G>", 'xt')
+ call feedkeys("??\<C-T>", 'xt')
+endfunc
+
+func Test_search_with_invalid_range()
+ new
+ let lines =<< trim END
+ /\%.v
+ 5/
+ c
+ END
+ call writefile(lines, 'Xrangesearch')
+ source Xrangesearch
+
+ bwipe!
+ call delete('Xrangesearch')
+endfunc
+
+
" vim: shiftwidth=2 sts=2 expandtab