neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

test_search.vim (69442B)


      1 " Test for the search command
      2 
      3 source shared.vim
      4 source screendump.vim
      5 source check.vim
      6 
      7 func Test_search_cmdline()
      8  CheckOption incsearch
      9 
     10  " need to disable char_avail,
     11  " so that expansion of commandline works
     12  call Ntest_override("char_avail", 1)
     13  new
     14  call setline(1, ['  1', '  2 these', '  3 the', '  4 their', '  5 there', '  6 their', '  7 the', '  8 them', '  9 these', ' 10 foobar'])
     15  " Test 1
     16  " CTRL-N / CTRL-P skips through the previous search history
     17  set noincsearch
     18  :1
     19  call feedkeys("/foobar\<cr>", 'tx')
     20  call feedkeys("/the\<cr>", 'tx')
     21  call assert_equal('the', @/)
     22  call feedkeys("/thes\<C-P>\<C-P>\<cr>", 'tx')
     23  call assert_equal('foobar', @/)
     24 
     25  " Test 2
     26  " Ctrl-G goes from one match to the next
     27  " until the end of the buffer
     28  set incsearch nowrapscan
     29  :1
     30  " first match
     31  call feedkeys("/the\<cr>", 'tx')
     32  call assert_equal('  2 these', getline('.'))
     33  :1
     34  " second match
     35  call feedkeys("/the\<C-G>\<cr>", 'tx')
     36  call assert_equal('  3 the', getline('.'))
     37  call assert_equal([0, 0, 0, 0], getpos('"'))
     38  :1
     39  " third match
     40  call feedkeys("/the".repeat("\<C-G>", 2)."\<cr>", 'tx')
     41  call assert_equal('  4 their', getline('.'))
     42  :1
     43  " fourth match
     44  call feedkeys("/the".repeat("\<C-G>", 3)."\<cr>", 'tx')
     45  call assert_equal('  5 there', getline('.'))
     46  :1
     47  " fifth match
     48  call feedkeys("/the".repeat("\<C-G>", 4)."\<cr>", 'tx')
     49  call assert_equal('  6 their', getline('.'))
     50  :1
     51  " sixth match
     52  call feedkeys("/the".repeat("\<C-G>", 5)."\<cr>", 'tx')
     53  call assert_equal('  7 the', getline('.'))
     54  :1
     55  " seventh match
     56  call feedkeys("/the".repeat("\<C-G>", 6)."\<cr>", 'tx')
     57  call assert_equal('  8 them', getline('.'))
     58  :1
     59  " eighth match
     60  call feedkeys("/the".repeat("\<C-G>", 7)."\<cr>", 'tx')
     61  call assert_equal('  9 these', getline('.'))
     62  :1
     63  " no further match
     64  call feedkeys("/the".repeat("\<C-G>", 8)."\<cr>", 'tx')
     65  call assert_equal('  9 these', getline('.'))
     66  call assert_equal([0, 0, 0, 0], getpos('"'))
     67 
     68  " Test 3
     69  " Ctrl-G goes from one match to the next
     70  " and continues back at the top
     71  set incsearch wrapscan
     72  :1
     73  " first match
     74  call feedkeys("/the\<cr>", 'tx')
     75  call assert_equal('  2 these', getline('.'))
     76  :1
     77  " second match
     78  call feedkeys("/the\<C-G>\<cr>", 'tx')
     79  call assert_equal('  3 the', getline('.'))
     80  :1
     81  " third match
     82  call feedkeys("/the".repeat("\<C-G>", 2)."\<cr>", 'tx')
     83  call assert_equal('  4 their', getline('.'))
     84  :1
     85  " fourth match
     86  call feedkeys("/the".repeat("\<C-G>", 3)."\<cr>", 'tx')
     87  call assert_equal('  5 there', getline('.'))
     88  :1
     89  " fifth match
     90  call feedkeys("/the".repeat("\<C-G>", 4)."\<cr>", 'tx')
     91  call assert_equal('  6 their', getline('.'))
     92  :1
     93  " sixth match
     94  call feedkeys("/the".repeat("\<C-G>", 5)."\<cr>", 'tx')
     95  call assert_equal('  7 the', getline('.'))
     96  :1
     97  " seventh match
     98  call feedkeys("/the".repeat("\<C-G>", 6)."\<cr>", 'tx')
     99  call assert_equal('  8 them', getline('.'))
    100  :1
    101  " eighth match
    102  call feedkeys("/the".repeat("\<C-G>", 7)."\<cr>", 'tx')
    103  call assert_equal('  9 these', getline('.'))
    104  :1
    105  " back at first match
    106  call feedkeys("/the".repeat("\<C-G>", 8)."\<cr>", 'tx')
    107  call assert_equal('  2 these', getline('.'))
    108 
    109  " Test 4
    110  " CTRL-T goes to the previous match
    111  set incsearch nowrapscan
    112  $
    113  " first match
    114  call feedkeys("?the\<cr>", 'tx')
    115  call assert_equal('  9 these', getline('.'))
    116  $
    117  " first match
    118  call feedkeys("?the\<C-G>\<cr>", 'tx')
    119  call assert_equal('  9 these', getline('.'))
    120  $
    121  " second match
    122  call feedkeys("?the".repeat("\<C-T>", 1)."\<cr>", 'tx')
    123  call assert_equal('  8 them', getline('.'))
    124  $
    125  " last match
    126  call feedkeys("?the".repeat("\<C-T>", 7)."\<cr>", 'tx')
    127  call assert_equal('  2 these', getline('.'))
    128  $
    129  " last match
    130  call feedkeys("?the".repeat("\<C-T>", 8)."\<cr>", 'tx')
    131  call assert_equal('  2 these', getline('.'))
    132 
    133  " Test 5
    134  " CTRL-T goes to the previous match
    135  set incsearch wrapscan
    136  $
    137  " first match
    138  call feedkeys("?the\<cr>", 'tx')
    139  call assert_equal('  9 these', getline('.'))
    140  $
    141  " first match at the top
    142  call feedkeys("?the\<C-G>\<cr>", 'tx')
    143  call assert_equal('  2 these', getline('.'))
    144  $
    145  " second match
    146  call feedkeys("?the".repeat("\<C-T>", 1)."\<cr>", 'tx')
    147  call assert_equal('  8 them', getline('.'))
    148  $
    149  " last match
    150  call feedkeys("?the".repeat("\<C-T>", 7)."\<cr>", 'tx')
    151  call assert_equal('  2 these', getline('.'))
    152  $
    153  " back at the bottom of the buffer
    154  call feedkeys("?the".repeat("\<C-T>", 8)."\<cr>", 'tx')
    155  call assert_equal('  9 these', getline('.'))
    156 
    157  " Test 6
    158  " CTRL-L adds to the search pattern
    159  set incsearch wrapscan
    160  1
    161  " first match
    162  call feedkeys("/the\<c-l>\<cr>", 'tx')
    163  call assert_equal('  2 these', getline('.'))
    164  1
    165  " go to next match of 'thes'
    166  call feedkeys("/the\<c-l>\<C-G>\<cr>", 'tx')
    167  call assert_equal('  9 these', getline('.'))
    168  1
    169  " wrap around
    170  call feedkeys("/the\<c-l>\<C-G>\<C-G>\<cr>", 'tx')
    171  call assert_equal('  2 these', getline('.'))
    172  1
    173  " wrap around
    174  set nowrapscan
    175  call feedkeys("/the\<c-l>\<C-G>\<C-G>\<cr>", 'tx')
    176  call assert_equal('  9 these', getline('.'))
    177 
    178  " Test 7
    179  " <bs> remove from match, but stay at current match
    180  set incsearch wrapscan
    181  1
    182  " first match
    183  call feedkeys("/thei\<cr>", 'tx')
    184  call assert_equal('  4 their', getline('.'))
    185  1
    186  " delete one char, add another
    187  call feedkeys("/thei\<bs>s\<cr>", 'tx')
    188  call assert_equal('  2 these', getline('.'))
    189  1
    190  " delete one char, add another,  go to previous match, add one char
    191  call feedkeys("/thei\<bs>s\<bs>\<C-T>\<c-l>\<cr>", 'tx')
    192  call assert_equal('  9 these', getline('.'))
    193  1
    194  " delete all chars, start from the beginning again
    195  call feedkeys("/them". repeat("\<bs>",4).'the\>'."\<cr>", 'tx')
    196  call assert_equal('  3 the', getline('.'))
    197 
    198  " clean up
    199  call Ntest_override("char_avail", 0)
    200  bw!
    201 endfunc
    202 
    203 func Test_search_cmdline2()
    204  CheckOption incsearch
    205 
    206  " need to disable char_avail,
    207  " so that expansion of commandline works
    208  call Ntest_override("char_avail", 1)
    209  new
    210  call setline(1, ['  1', '  2 these', '  3 the theother'])
    211  " Test 1
    212  " Ctrl-T goes correctly back and forth
    213  set incsearch
    214  1
    215  " first match
    216  call feedkeys("/the\<cr>", 'tx')
    217  call assert_equal('  2 these', getline('.'))
    218  1
    219  " go to next match (on next line)
    220  call feedkeys("/the\<C-G>\<cr>", 'tx')
    221  call assert_equal('  3 the theother', getline('.'))
    222  1
    223  " go to next match (still on line 3)
    224  call feedkeys("/the\<C-G>\<C-G>\<cr>", 'tx')
    225  call assert_equal('  3 the theother', getline('.'))
    226  1
    227  " go to next match (still on line 3)
    228  call feedkeys("/the\<C-G>\<C-G>\<C-G>\<cr>", 'tx')
    229  call assert_equal('  3 the theother', getline('.'))
    230  1
    231  " go to previous match (on line 3)
    232  call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<cr>", 'tx')
    233  call assert_equal('  3 the theother', getline('.'))
    234  1
    235  " go to previous match (on line 3)
    236  call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<cr>", 'tx')
    237  call assert_equal('  3 the theother', getline('.'))
    238  1
    239  " go to previous match (on line 2)
    240  call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<C-T>\<cr>", 'tx')
    241  call assert_equal('  2 these', getline('.'))
    242  1
    243  " go to previous match (on line 2)
    244  call feedkeys("/the\<C-G>\<C-R>\<C-W>\<cr>", 'tx')
    245  call assert_equal('theother', @/)
    246 
    247  " Test 2: keep the view,
    248  " after deleting a character from the search cmd
    249  call setline(1, ['  1', '  2 these', '  3 the', '  4 their', '  5 there', '  6 their', '  7 the', '  8 them', '  9 these', ' 10 foobar'])
    250  resize 5
    251  1
    252  call feedkeys("/foo\<bs>\<cr>", 'tx')
    253  redraw
    254  call assert_equal({'lnum': 10, 'leftcol': 0, 'col': 4, 'topfill': 0, 'topline': 6, 'coladd': 0, 'skipcol': 0, 'curswant': 4}, winsaveview())
    255 
    256  " remove all history entries
    257  for i in range(11)
    258      call histdel('/')
    259  endfor
    260 
    261  " Test 3: reset the view,
    262  " after deleting all characters from the search cmd
    263  norm! 1gg0
    264  " unfortunately, neither "/foo\<c-w>\<cr>", nor "/foo\<bs>\<bs>\<bs>\<cr>",
    265  " nor "/foo\<c-u>\<cr>" works to delete the commandline.
    266  " In that case Vim should return "E35 no previous regular expression",
    267  " but it looks like Vim still sees /foo and therefore the test fails.
    268  " Therefore, disabling this test
    269  "call assert_fails(feedkeys("/foo\<c-w>\<cr>", 'tx'), 'E35')
    270  "call assert_equal({'lnum': 1, 'leftcol': 0, 'col': 0, 'topfill': 0, 'topline': 1, 'coladd': 0, 'skipcol': 0, 'curswant': 0}, winsaveview())
    271 
    272  " clean up
    273  set noincsearch
    274  call Ntest_override("char_avail", 0)
    275  bw!
    276 endfunc
    277 
    278 func Test_use_sub_pat()
    279  split
    280  let @/ = ''
    281  func X()
    282    s/^/a/
    283    /
    284  endfunc
    285  call X()
    286  bwipe!
    287 endfunc
    288 
    289 func Test_searchpair()
    290  new
    291  call setline(1, ['other code', 'here [', ' [', ' " cursor here', ' ]]'])
    292 
    293  " should not give an error for using "42"
    294  call assert_equal(0, searchpair('a', 'b', 'c', '', 42))
    295 
    296  4
    297  call assert_equal(3, searchpair('\[', '', ']', 'bW'))
    298  call assert_equal([0, 3, 2, 0], getpos('.'))
    299  4
    300  call assert_equal(2, searchpair('\[', '', ']', 'bWr'))
    301  call assert_equal([0, 2, 6, 0], getpos('.'))
    302  4
    303  call assert_equal(1, searchpair('\[', '', ']', 'bWm'))
    304  call assert_equal([0, 3, 2, 0], getpos('.'))
    305  4|norm ^
    306  call assert_equal(5, searchpair('\[', '', ']', 'Wn'))
    307  call assert_equal([0, 4, 2, 0], getpos('.'))
    308  4
    309  call assert_equal(2, searchpair('\[', '', ']', 'bW',
    310        \                         'getline(".") =~ "^\\s*\["'))
    311  call assert_equal([0, 2, 6, 0], getpos('.'))
    312  set nomagic
    313  4
    314  call assert_equal(3, searchpair('\[', '', ']', 'bW'))
    315  call assert_equal([0, 3, 2, 0], getpos('.'))
    316  set magic
    317  4|norm ^
    318  call assert_equal(0, searchpair('{', '', '}', 'bW'))
    319  call assert_equal([0, 4, 2, 0], getpos('.'))
    320 
    321  %d
    322  call setline(1, ['if 1', '  if 2', '  else', '  endif 2', 'endif 1'])
    323 
    324  /\<if 1
    325  call assert_equal(5, searchpair('\<if\>', '\<else\>', '\<endif\>', 'W'))
    326  call assert_equal([0, 5, 1, 0], getpos('.'))
    327  /\<if 2
    328  call assert_equal(3, searchpair('\<if\>', '\<else\>', '\<endif\>', 'W'))
    329  call assert_equal([0, 3, 3, 0], getpos('.'))
    330 
    331  q!
    332 endfunc
    333 
    334 func Test_searchpairpos()
    335  new
    336  call setline(1, ['other code', 'here [', ' [', ' " cursor here', ' ]]'])
    337 
    338  4
    339  call assert_equal([3, 2], searchpairpos('\[', '', ']', 'bW'))
    340  call assert_equal([0, 3, 2, 0], getpos('.'))
    341  4
    342  call assert_equal([2, 6], searchpairpos('\[', '', ']', 'bWr'))
    343  call assert_equal([0, 2, 6, 0], getpos('.'))
    344  4|norm ^
    345  call assert_equal([5, 2], searchpairpos('\[', '', ']', 'Wn'))
    346  call assert_equal([0, 4, 2, 0], getpos('.'))
    347  4
    348  call assert_equal([2, 6], searchpairpos('\[', '', ']', 'bW',
    349        \                                 'getline(".") =~ "^\\s*\["'))
    350  call assert_equal([0, 2, 6, 0], getpos('.'))
    351  4
    352  call assert_equal([2, 6], searchpairpos('\[', '', ']', 'bWr'))
    353  call assert_equal([0, 2, 6, 0], getpos('.'))
    354  set nomagic
    355  4
    356  call assert_equal([3, 2], searchpairpos('\[', '', ']', 'bW'))
    357  call assert_equal([0, 3, 2, 0], getpos('.'))
    358  set magic
    359  4|norm ^
    360  call assert_equal([0, 0], searchpairpos('{', '', '}', 'bW'))
    361  call assert_equal([0, 4, 2, 0], getpos('.'))
    362 
    363  %d
    364  call setline(1, ['if 1', '  if 2', '  else', '  endif 2', 'endif 1'])
    365  /\<if 1
    366  call assert_equal([5, 1], searchpairpos('\<if\>', '\<else\>', '\<endif\>', 'W'))
    367  call assert_equal([0, 5, 1, 0], getpos('.'))
    368  /\<if 2
    369  call assert_equal([3, 3], searchpairpos('\<if\>', '\<else\>', '\<endif\>', 'W'))
    370  call assert_equal([0, 3, 3, 0], getpos('.'))
    371 
    372  q!
    373 endfunc
    374 
    375 func Test_searchpair_errors()
    376  call assert_fails("call searchpair([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: Using a List as a String')
    377  call assert_fails("call searchpair('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: Using a Funcref as a String')
    378  call assert_fails("call searchpair('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: Using a Dictionary as a String')
    379  call assert_fails("call searchpair('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags')
    380  call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99')
    381  call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100')
    382  call assert_fails("call searchpair('start', 'middle', 'end', 'e')", 'E475: Invalid argument: e')
    383  call assert_fails("call searchpair('start', 'middle', 'end', 'sn')", 'E475: Invalid argument: sn')
    384 endfunc
    385 
    386 func Test_searchpairpos_errors()
    387  call assert_fails("call searchpairpos([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: Using a List as a String')
    388  call assert_fails("call searchpairpos('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: Using a Funcref as a String')
    389  call assert_fails("call searchpairpos('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: Using a Dictionary as a String')
    390  call assert_fails("call searchpairpos('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags')
    391  call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99')
    392  call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100')
    393  call assert_fails("call searchpairpos('start', 'middle', 'end', 'e')", 'E475: Invalid argument: e')
    394  call assert_fails("call searchpairpos('start', 'middle', 'end', 'sn')", 'E475: Invalid argument: sn')
    395 endfunc
    396 
    397 func Test_searchpair_skip()
    398    func Zero()
    399      return 0
    400    endfunc
    401    func Partial(x)
    402      return a:x
    403    endfunc
    404    new
    405    call setline(1, ['{', 'foo', 'foo', 'foo', '}'])
    406    3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', ''))
    407    3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', '0'))
    408    3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', {-> 0}))
    409    3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Zero')))
    410    3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Partial', [0])))
    411    bw!
    412 endfunc
    413 
    414 func Test_searchpair_leak()
    415  new
    416  call setline(1, 'if one else another endif')
    417 
    418  " The error in the skip expression caused memory to leak.
    419  call assert_fails("call searchpair('\\<if\\>', '\\<else\\>', '\\<endif\\>', '', '\"foo\" 2')", 'E15:')
    420 
    421  bwipe!
    422 endfunc
    423 
    424 func Test_searchc()
    425  " These commands used to cause memory overflow in searchc().
    426  new
    427  norm ixx
    428  exe "norm 0t\u93cf"
    429  bw!
    430 endfunc
    431 
    432 func Cmdline3_prep()
    433  " need to disable char_avail,
    434  " so that expansion of commandline works
    435  call Ntest_override("char_avail", 1)
    436  new
    437  call setline(1, ['  1', '  2 the~e', '  3 the theother'])
    438  set incsearch
    439 endfunc
    440 
    441 func Incsearch_cleanup()
    442  set noincsearch
    443  call Ntest_override("char_avail", 0)
    444  bw!
    445 endfunc
    446 
    447 func Test_search_cmdline3()
    448  CheckOption incsearch
    449 
    450  call Cmdline3_prep()
    451  1
    452  " first match
    453  call feedkeys("/the\<c-l>\<cr>", 'tx')
    454  call assert_equal('  2 the~e', getline('.'))
    455 
    456  call Incsearch_cleanup()
    457 endfunc
    458 
    459 func Test_search_cmdline3s()
    460  CheckOption incsearch
    461 
    462  call Cmdline3_prep()
    463  1
    464  call feedkeys(":%s/the\<c-l>/xxx\<cr>", 'tx')
    465  call assert_equal('  2 xxxe', getline('.'))
    466  undo
    467  call feedkeys(":%subs/the\<c-l>/xxx\<cr>", 'tx')
    468  call assert_equal('  2 xxxe', getline('.'))
    469  undo
    470  call feedkeys(":%substitute/the\<c-l>/xxx\<cr>", 'tx')
    471  call assert_equal('  2 xxxe', getline('.'))
    472  undo
    473  call feedkeys(":%smagic/the.e/xxx\<cr>", 'tx')
    474  call assert_equal('  2 xxx', getline('.'))
    475  undo
    476  call assert_fails(":%snomagic/the.e/xxx\<cr>", 'E486')
    477  "
    478  call feedkeys(":%snomagic/the\\.e/xxx\<cr>", 'tx')
    479  call assert_equal('  2 xxx', getline('.'))
    480 
    481  call Incsearch_cleanup()
    482 endfunc
    483 
    484 func Test_search_cmdline3g()
    485  CheckOption incsearch
    486 
    487  call Cmdline3_prep()
    488  1
    489  call feedkeys(":g/the\<c-l>/d\<cr>", 'tx')
    490  call assert_equal('  3 the theother', getline(2))
    491  undo
    492  call feedkeys(":global/the\<c-l>/d\<cr>", 'tx')
    493  call assert_equal('  3 the theother', getline(2))
    494  undo
    495  call feedkeys(":g!/the\<c-l>/d\<cr>", 'tx')
    496  call assert_equal(1, line('$'))
    497  call assert_equal('  2 the~e', getline(1))
    498  undo
    499  call feedkeys(":global!/the\<c-l>/d\<cr>", 'tx')
    500  call assert_equal(1, line('$'))
    501  call assert_equal('  2 the~e', getline(1))
    502 
    503  call Incsearch_cleanup()
    504 endfunc
    505 
    506 func Test_search_cmdline3v()
    507  CheckOption incsearch
    508 
    509  call Cmdline3_prep()
    510  1
    511  call feedkeys(":v/the\<c-l>/d\<cr>", 'tx')
    512  call assert_equal(1, line('$'))
    513  call assert_equal('  2 the~e', getline(1))
    514  undo
    515  call feedkeys(":vglobal/the\<c-l>/d\<cr>", 'tx')
    516  call assert_equal(1, line('$'))
    517  call assert_equal('  2 the~e', getline(1))
    518 
    519  call Incsearch_cleanup()
    520 endfunc
    521 
    522 func Test_search_cmdline4()
    523  CheckOption incsearch
    524 
    525  " need to disable char_avail,
    526  " so that expansion of commandline works
    527  call Ntest_override("char_avail", 1)
    528  new
    529  call setline(1, ['  1 the first', '  2 the second', '  3 the third'])
    530  set incsearch
    531  $
    532  call feedkeys("?the\<c-g>\<cr>", 'tx')
    533  call assert_equal('  3 the third', getline('.'))
    534  $
    535  call feedkeys("?the\<c-g>\<c-g>\<cr>", 'tx')
    536  call assert_equal('  1 the first', getline('.'))
    537  $
    538  call feedkeys("?the\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
    539  call assert_equal('  2 the second', getline('.'))
    540  $
    541  call feedkeys("?the\<c-t>\<cr>", 'tx')
    542  call assert_equal('  1 the first', getline('.'))
    543  $
    544  call feedkeys("?the\<c-t>\<c-t>\<cr>", 'tx')
    545  call assert_equal('  3 the third', getline('.'))
    546  $
    547  call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
    548  call assert_equal('  2 the second', getline('.'))
    549  " clean up
    550  set noincsearch
    551  call Ntest_override("char_avail", 0)
    552  bw!
    553 endfunc
    554 
    555 func Test_search_cmdline5()
    556  CheckOption incsearch
    557 
    558  " Do not call test_override("char_avail", 1) so that <C-g> and <C-t> work
    559  " regardless char_avail.
    560  new
    561  call setline(1, ['  1 the first', '  2 the second', '  3 the third', ''])
    562  set incsearch
    563  1
    564  call feedkeys("/the\<c-g>\<c-g>\<cr>", 'tx')
    565  call assert_equal('  3 the third', getline('.'))
    566  $
    567  call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
    568  call assert_equal('  1 the first', getline('.'))
    569  " clean up
    570  set noincsearch
    571  bw!
    572 endfunc
    573 
    574 func Test_search_cmdline6()
    575  " Test that consecutive matches
    576  " are caught by <c-g>/<c-t>
    577  CheckOption incsearch
    578 
    579  " need to disable char_avail,
    580  " so that expansion of commandline works
    581  call Ntest_override("char_avail", 1)
    582  new
    583  call setline(1, [' bbvimb', ''])
    584  set incsearch
    585  " first match
    586  norm! gg0
    587  call feedkeys("/b\<cr>", 'tx')
    588  call assert_equal([0,1,2,0], getpos('.'))
    589  " second match
    590  norm! gg0
    591  call feedkeys("/b\<c-g>\<cr>", 'tx')
    592  call assert_equal([0,1,3,0], getpos('.'))
    593  " third match
    594  norm! gg0
    595  call feedkeys("/b\<c-g>\<c-g>\<cr>", 'tx')
    596  call assert_equal([0,1,7,0], getpos('.'))
    597  " first match again
    598  norm! gg0
    599  call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
    600  call assert_equal([0,1,2,0], getpos('.'))
    601  set nowrapscan
    602  " last match
    603  norm! gg0
    604  call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
    605  call assert_equal([0,1,7,0], getpos('.'))
    606  " clean up
    607  set wrapscan&vim
    608  set noincsearch
    609  call Ntest_override("char_avail", 0)
    610  bw!
    611 endfunc
    612 
    613 func Test_search_cmdline7()
    614  " Test that pressing <c-g> in an empty command line
    615  " does not move the cursor
    616  if !exists('+incsearch')
    617    return
    618  endif
    619  " need to disable char_avail,
    620  " so that expansion of commandline works
    621  call Ntest_override("char_avail", 1)
    622  new
    623  let @/ = 'b'
    624  call setline(1, [' bbvimb', ''])
    625  set incsearch
    626  " first match
    627  norm! gg0
    628  " moves to next match of previous search pattern, just like /<cr>
    629  call feedkeys("/\<c-g>\<cr>", 'tx')
    630  call assert_equal([0,1,2,0], getpos('.'))
    631  " moves to next match of previous search pattern, just like /<cr>
    632  call feedkeys("/\<cr>", 'tx')
    633  call assert_equal([0,1,3,0], getpos('.'))
    634  " moves to next match of previous search pattern, just like /<cr>
    635  call feedkeys("/\<c-t>\<cr>", 'tx')
    636  call assert_equal([0,1,7,0], getpos('.'))
    637 
    638  " using an offset uses the last search pattern
    639  call cursor(1, 1)
    640  call setline(1, ['1 bbvimb', ' 2 bbvimb'])
    641  let @/ = 'b'
    642  call feedkeys("//e\<c-g>\<cr>", 'tx')
    643  call assert_equal('1 bbvimb', getline('.'))
    644  call assert_equal(4, col('.'))
    645 
    646  set noincsearch
    647  call Ntest_override("char_avail", 0)
    648  bw!
    649 endfunc
    650 
    651 func Test_search_cmdline8()
    652  " Highlighting is cleared in all windows
    653  " since hls applies to all windows
    654  CheckOption incsearch
    655  CheckFeature terminal
    656  CheckNotGui
    657  if has("win32")
    658    throw "Skipped: Bug with sending <ESC> to terminal window not fixed yet"
    659  endif
    660 
    661  let h = winheight(0)
    662  if h < 3
    663    return
    664  endif
    665  " Prepare buffer text
    666  let lines = ['abb vim vim vi', 'vimvivim']
    667  call writefile(lines, 'Xsearch.txt', 'D')
    668  let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
    669 
    670  call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])})
    671 
    672  call term_sendkeys(buf, ":set incsearch hlsearch\<cr>")
    673  call term_sendkeys(buf, ":14vsp\<cr>")
    674  call term_sendkeys(buf, "/vim\<cr>")
    675  call term_sendkeys(buf, "/b\<esc>")
    676  call term_sendkeys(buf, "gg0")
    677  call TermWait(buf, 250)
    678  let screen_line = term_scrape(buf, 1)
    679  let [a0,a1,a2,a3] = [screen_line[3].attr, screen_line[4].attr,
    680        \ screen_line[18].attr, screen_line[19].attr]
    681  call assert_notequal(a0, a1)
    682  call assert_notequal(a0, a3)
    683  call assert_notequal(a1, a2)
    684  call assert_equal(a0, a2)
    685  call assert_equal(a1, a3)
    686 
    687  " clean up
    688  bwipe!
    689 endfunc
    690 
    691 " Tests for regexp with various magic settings
    692 func Run_search_regexp_magic_opt()
    693  put ='1 a aa abb abbccc'
    694  exe 'normal! /a*b\{2}c\+/e' . "\<CR>"
    695  call assert_equal([0, 2, 17, 0], getpos('.'))
    696 
    697  put ='2 d dd dee deefff'
    698  exe 'normal! /\Md\*e\{2}f\+/e' . "\<CR>"
    699  call assert_equal([0, 3, 17, 0], getpos('.'))
    700 
    701  set nomagic
    702  put ='3 g gg ghh ghhiii'
    703  exe 'normal! /g\*h\{2}i\+/e' . "\<CR>"
    704  call assert_equal([0, 4, 17, 0], getpos('.'))
    705 
    706  put ='4 j jj jkk jkklll'
    707  exe 'normal! /\mj*k\{2}l\+/e' . "\<CR>"
    708  call assert_equal([0, 5, 17, 0], getpos('.'))
    709 
    710  put ='5 m mm mnn mnnooo'
    711  exe 'normal! /\vm*n{2}o+/e' . "\<CR>"
    712  call assert_equal([0, 6, 17, 0], getpos('.'))
    713 
    714  put ='6 x ^aa$ x'
    715  exe 'normal! /\V^aa$' . "\<CR>"
    716  call assert_equal([0, 7, 5, 0], getpos('.'))
    717 
    718  set magic
    719  put ='7 (a)(b) abbaa'
    720  exe 'normal! /\v(a)(b)\2\1\1/e' . "\<CR>"
    721  call assert_equal([0, 8, 14, 0], getpos('.'))
    722 
    723  put ='8 axx [ab]xx'
    724  exe 'normal! /\V[ab]\(\[xy]\)\1' . "\<CR>"
    725  call assert_equal([0, 9, 7, 0], getpos('.'))
    726 
    727  %d
    728 endfunc
    729 
    730 func Test_search_regexp()
    731  enew!
    732 
    733  set regexpengine=1
    734  call Run_search_regexp_magic_opt()
    735  set regexpengine=2
    736  call Run_search_regexp_magic_opt()
    737  set regexpengine&
    738 
    739  set undolevels=100
    740  put ='9 foobar'
    741  put =''
    742  exe "normal! a\<C-G>u\<Esc>"
    743  normal G
    744  exe 'normal! dv?bar?' . "\<CR>"
    745  call assert_equal('9 foo', getline('.'))
    746  call assert_equal([0, 2, 5, 0], getpos('.'))
    747  call assert_equal(2, line('$'))
    748  normal u
    749  call assert_equal('9 foobar', getline('.'))
    750  call assert_equal([0, 2, 6, 0], getpos('.'))
    751  call assert_equal(3, line('$'))
    752 
    753  set undolevels&
    754  enew!
    755 endfunc
    756 
    757 func Test_search_cmdline_incsearch_highlight()
    758  CheckOption incsearch
    759 
    760  set incsearch hlsearch
    761  " need to disable char_avail,
    762  " so that expansion of commandline works
    763  call Ntest_override("char_avail", 1)
    764  new
    765  call setline(1, ['aaa  1 the first', '  2 the second', '  3 the third'])
    766 
    767  1
    768  call feedkeys("/second\<cr>", 'tx')
    769  call assert_equal('second', @/)
    770  call assert_equal('  2 the second', getline('.'))
    771 
    772  " Canceling search won't change @/
    773  1
    774  let @/ = 'last pattern'
    775  call feedkeys("/third\<C-c>", 'tx')
    776  call assert_equal('last pattern', @/)
    777  call feedkeys("/third\<Esc>", 'tx')
    778  call assert_equal('last pattern', @/)
    779  call feedkeys("/3\<bs>\<bs>", 'tx')
    780  call assert_equal('last pattern', @/)
    781  call feedkeys("/third\<c-g>\<c-t>\<Esc>", 'tx')
    782  call assert_equal('last pattern', @/)
    783 
    784  " clean up
    785  set noincsearch nohlsearch
    786  call Ntest_override("char_avail", 0)
    787  bw!
    788 endfunc
    789 
    790 func Test_search_cmdline_incsearch_highlight_attr()
    791  CheckOption incsearch
    792  CheckFeature terminal
    793  CheckNotGui
    794 
    795  let h = winheight(0)
    796  if h < 3
    797    return
    798  endif
    799 
    800  " Prepare buffer text
    801  let lines = ['abb vim vim vi', 'vimvivim']
    802  call writefile(lines, 'Xsearch.txt', 'D')
    803  let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
    804 
    805  call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])})
    806  " wait for vim to complete initialization
    807  call TermWait(buf)
    808 
    809  " Get attr of normal(a0), incsearch(a1), hlsearch(a2) highlight
    810  call term_sendkeys(buf, ":set incsearch hlsearch\<cr>")
    811  call term_sendkeys(buf, '/b')
    812  call TermWait(buf, 100)
    813  let screen_line1 = term_scrape(buf, 1)
    814  call assert_true(len(screen_line1) > 2)
    815  " a0: attr_normal
    816  let a0 = screen_line1[0].attr
    817  " a1: attr_incsearch
    818  let a1 = screen_line1[1].attr
    819  " a2: attr_hlsearch
    820  let a2 = screen_line1[2].attr
    821  call assert_notequal(a0, a1)
    822  call assert_notequal(a0, a2)
    823  call assert_notequal(a1, a2)
    824  call term_sendkeys(buf, "\<cr>gg0")
    825 
    826  " Test incremental highlight search
    827  call term_sendkeys(buf, "/vim")
    828  call TermWait(buf, 100)
    829  " Buffer:
    830  " abb vim vim vi
    831  " vimvivim
    832  " Search: /vim
    833  let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a2,a2,a2,a0,a0,a0]
    834  let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
    835  call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
    836  call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
    837 
    838  " Test <C-g>
    839  call term_sendkeys(buf, "\<C-g>\<C-g>")
    840  call TermWait(buf, 100)
    841  let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
    842  let attr_line2 = [a1,a1,a1,a0,a0,a2,a2,a2]
    843  call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
    844  call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
    845 
    846  " Test <C-t>
    847  call term_sendkeys(buf, "\<C-t>")
    848  call TermWait(buf, 100)
    849  let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a1,a1,a1,a0,a0,a0]
    850  let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
    851  call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
    852  call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
    853 
    854  " Type Enter and a1(incsearch highlight) should become a2(hlsearch highlight)
    855  call term_sendkeys(buf, "\<cr>")
    856  call TermWait(buf, 100)
    857  let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
    858  let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
    859  call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
    860  call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
    861 
    862  " Test nohlsearch. a2(hlsearch highlight) should become a0(normal highlight)
    863  call term_sendkeys(buf, ":1\<cr>")
    864  call term_sendkeys(buf, ":set nohlsearch\<cr>")
    865  call term_sendkeys(buf, "/vim")
    866  call TermWait(buf, 100)
    867  let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a0,a0,a0,a0,a0,a0]
    868  let attr_line2 = [a0,a0,a0,a0,a0,a0,a0,a0]
    869  call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
    870  call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
    871 
    872  bwipe!
    873 endfunc
    874 
    875 func Test_incsearch_cmdline_modifier()
    876  CheckOption incsearch
    877 
    878  call Ntest_override("char_avail", 1)
    879  new
    880  call setline(1, ['foo'])
    881  set incsearch
    882  " Test that error E14 does not occur in parsing command modifier.
    883  call feedkeys("V:tab", 'tx')
    884 
    885  call Incsearch_cleanup()
    886 endfunc
    887 
    888 func Test_incsearch_scrolling()
    889  CheckScreendump
    890  CheckRunVimInTerminal
    891  call assert_equal(0, &scrolloff)
    892  call writefile([
    893 \ 'let dots = repeat(".", 120)',
    894 \ 'set incsearch cmdheight=2 scrolloff=0',
    895 \ 'call setline(1, [dots, dots, dots, "", "target", dots, dots])',
    896 \ 'normal gg',
    897 \ 'redraw',
    898 \ ], 'Xscript', 'D')
    899  let buf = RunVimInTerminal('-S Xscript', {'rows': 9, 'cols': 70})
    900  " Need to send one key at a time to force a redraw
    901  call term_sendkeys(buf, '/')
    902  sleep 100m
    903  call term_sendkeys(buf, 't')
    904  sleep 100m
    905  call term_sendkeys(buf, 'a')
    906  sleep 100m
    907  call term_sendkeys(buf, 'r')
    908  sleep 100m
    909  call term_sendkeys(buf, 'g')
    910  call VerifyScreenDump(buf, 'Test_incsearch_scrolling_01', {})
    911 
    912  call term_sendkeys(buf, "\<Esc>")
    913  call StopVimInTerminal(buf)
    914 endfunc
    915 
    916 func Test_incsearch_search_dump()
    917  CheckOption incsearch
    918  CheckScreendump
    919 
    920  call writefile([
    921 \ 'set incsearch hlsearch scrolloff=0',
    922 \ 'for n in range(1, 8)',
    923 \ '  call setline(n, "foo " . n)',
    924 \ 'endfor',
    925 \ '3',
    926 \ ], 'Xis_search_script', 'D')
    927  let buf = RunVimInTerminal('-S Xis_search_script', {'rows': 9, 'cols': 70})
    928  " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
    929  " the 'ambiwidth' check.
    930  sleep 100m
    931 
    932  " Need to send one key at a time to force a redraw.
    933  call term_sendkeys(buf, '/fo')
    934  call VerifyScreenDump(buf, 'Test_incsearch_search_01', {})
    935  call term_sendkeys(buf, "\<Esc>")
    936  sleep 100m
    937 
    938  call term_sendkeys(buf, '/\v')
    939  call VerifyScreenDump(buf, 'Test_incsearch_search_02', {})
    940  call term_sendkeys(buf, "\<Esc>")
    941 
    942  call StopVimInTerminal(buf)
    943 endfunc
    944 
    945 func Test_hlsearch_dump()
    946  CheckOption hlsearch
    947  CheckScreendump
    948 
    949  call writefile([
    950 \ 'set hlsearch cursorline',
    951        \ 'call setline(1, ["xxx", "xxx", "xxx"])',
    952 \ '/.*',
    953 \ '2',
    954 \ ], 'Xhlsearch_script', 'D')
    955  let buf = RunVimInTerminal('-S Xhlsearch_script', {'rows': 6, 'cols': 50})
    956  call VerifyScreenDump(buf, 'Test_hlsearch_1', {})
    957 
    958  call term_sendkeys(buf, "/\\_.*\<CR>")
    959  call VerifyScreenDump(buf, 'Test_hlsearch_2', {})
    960 
    961  call StopVimInTerminal(buf)
    962 endfunc
    963 
    964 func Test_hlsearch_and_visual()
    965  CheckOption hlsearch
    966  CheckScreendump
    967 
    968  call writefile([
    969 \ 'set hlsearch',
    970        \ 'call setline(1, repeat(["xxx yyy zzz"], 3))',
    971        \ 'hi Search cterm=bold',
    972 \ '/yyy',
    973 \ 'call cursor(1, 6)',
    974 \ ], 'Xhlvisual_script', 'D')
    975  let buf = RunVimInTerminal('-S Xhlvisual_script', {'rows': 6, 'cols': 40})
    976  call term_sendkeys(buf, "vjj")
    977  call VerifyScreenDump(buf, 'Test_hlsearch_visual_1', {})
    978  call term_sendkeys(buf, "\<Esc>")
    979 
    980  call StopVimInTerminal(buf)
    981 endfunc
    982 
    983 func Test_hlsearch_block_visual_match()
    984  CheckScreendump
    985 
    986  let lines =<< trim END
    987    set hlsearch
    988    call setline(1, ['aa', 'bbbb', 'cccccc'])
    989  END
    990  call writefile(lines, 'Xhlsearch_block', 'D')
    991  let buf = RunVimInTerminal('-S Xhlsearch_block', {'rows': 9, 'cols': 60})
    992 
    993  call term_sendkeys(buf, "G\<C-V>$kk\<Esc>")
    994  sleep 100m
    995  call term_sendkeys(buf, "/\\%V\<CR>")
    996  sleep 100m
    997  call VerifyScreenDump(buf, 'Test_hlsearch_block_visual_match', {})
    998 
    999  call StopVimInTerminal(buf)
   1000 endfunc
   1001 
   1002 func Test_incsearch_substitute()
   1003  CheckOption incsearch
   1004 
   1005  call Ntest_override("char_avail", 1)
   1006  new
   1007  set incsearch
   1008  for n in range(1, 10)
   1009    call setline(n, 'foo ' . n)
   1010  endfor
   1011  4
   1012  call feedkeys(":.,.+2s/foo\<BS>o\<BS>o/xxx\<cr>", 'tx')
   1013  call assert_equal('foo 3', getline(3))
   1014  call assert_equal('xxx 4', getline(4))
   1015  call assert_equal('xxx 5', getline(5))
   1016  call assert_equal('xxx 6', getline(6))
   1017  call assert_equal('foo 7', getline(7))
   1018 
   1019  call Incsearch_cleanup()
   1020 endfunc
   1021 
   1022 func Test_incsearch_substitute_long_line()
   1023  new
   1024  call Ntest_override("char_avail", 1)
   1025  set incsearch
   1026 
   1027  call repeat('x', 100000)->setline(1)
   1028  call feedkeys(':s/\%c', 'xt')
   1029  redraw
   1030  call feedkeys("\<Esc>", 'xt')
   1031 
   1032  call Incsearch_cleanup()
   1033  bwipe!
   1034 endfunc
   1035 
   1036 func Test_hlsearch_cursearch()
   1037  CheckScreendump
   1038 
   1039  let lines =<< trim END
   1040    set hlsearch scrolloff=0
   1041    call setline(1, ['one', 'foo', 'bar', 'baz', 'foo the foo and foo', 'bar'])
   1042    hi Search ctermbg=yellow
   1043    hi CurSearch ctermbg=blue
   1044  END
   1045  call writefile(lines, 'Xhlsearch_cursearch', 'D')
   1046  let buf = RunVimInTerminal('-S Xhlsearch_cursearch', {'rows': 9, 'cols': 60})
   1047 
   1048  call term_sendkeys(buf, "gg/foo\<CR>")
   1049  call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_1', {})
   1050 
   1051  call term_sendkeys(buf, "n")
   1052  call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2', {})
   1053 
   1054  call term_sendkeys(buf, "n")
   1055  call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2a', {})
   1056 
   1057  call term_sendkeys(buf, "n")
   1058  call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2b', {})
   1059 
   1060  call term_sendkeys(buf, ":call setline(5, 'foo')\<CR>")
   1061  call term_sendkeys(buf, "0?\<CR>")
   1062  call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_3', {})
   1063 
   1064  call term_sendkeys(buf, "gg/foo\\nbar\<CR>")
   1065  call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_1', {})
   1066 
   1067  call term_sendkeys(buf, ":call setline(1, ['---', 'abcdefg', 'hijkl', '---', 'abcdefg', 'hijkl'])\<CR>")
   1068  call term_sendkeys(buf, "gg/efg\\nhij\<CR>")
   1069  call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_2', {})
   1070  call term_sendkeys(buf, "h\<C-L>")
   1071  call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_3', {})
   1072  call term_sendkeys(buf, "j\<C-L>")
   1073  call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_4', {})
   1074  call term_sendkeys(buf, "h\<C-L>")
   1075  call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_5', {})
   1076 
   1077  " check clearing CurSearch when using it for another match
   1078  call term_sendkeys(buf, "G?^abcd\<CR>Y")
   1079  call term_sendkeys(buf, "kkP")
   1080  call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_changed_1', {})
   1081 
   1082  call StopVimInTerminal(buf)
   1083 endfunc
   1084 
   1085 " Similar to Test_incsearch_substitute() but with a screendump halfway.
   1086 func Test_incsearch_substitute_dump()
   1087  CheckOption incsearch
   1088  CheckScreendump
   1089 
   1090  call writefile([
   1091 \ 'set incsearch hlsearch scrolloff=0',
   1092 \ 'for n in range(1, 10)',
   1093 \ '  call setline(n, "foo " . n)',
   1094 \ 'endfor',
   1095 \ 'call setline(11, "bar 11")',
   1096 \ '3',
   1097 \ ], 'Xis_subst_script', 'D')
   1098  let buf = RunVimInTerminal('-S Xis_subst_script', {'rows': 9, 'cols': 70})
   1099  " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
   1100  " the 'ambiwidth' check.
   1101  sleep 100m
   1102 
   1103  " Need to send one key at a time to force a redraw.
   1104  " Select three lines at the cursor with typed pattern.
   1105  call term_sendkeys(buf, ':.,.+2s/')
   1106  sleep 100m
   1107  call term_sendkeys(buf, 'f')
   1108  sleep 100m
   1109  call term_sendkeys(buf, 'o')
   1110  sleep 100m
   1111  call term_sendkeys(buf, 'o')
   1112  call VerifyScreenDump(buf, 'Test_incsearch_substitute_01', {})
   1113  call term_sendkeys(buf, "\<Esc>")
   1114 
   1115  " Select three lines at the cursor using previous pattern.
   1116  call term_sendkeys(buf, "/foo\<CR>")
   1117  sleep 100m
   1118  call term_sendkeys(buf, ':.,.+2s//')
   1119  call VerifyScreenDump(buf, 'Test_incsearch_substitute_02', {})
   1120 
   1121  " Deleting last slash should remove the match.
   1122  call term_sendkeys(buf, "\<BS>")
   1123  call VerifyScreenDump(buf, 'Test_incsearch_substitute_03', {})
   1124  call term_sendkeys(buf, "\<Esc>")
   1125 
   1126  " Reverse range is accepted
   1127  call term_sendkeys(buf, ':5,2s/foo')
   1128  call VerifyScreenDump(buf, 'Test_incsearch_substitute_04', {})
   1129  call term_sendkeys(buf, "\<Esc>")
   1130 
   1131  " White space after the command is skipped
   1132  call term_sendkeys(buf, ':2,3sub  /fo')
   1133  call VerifyScreenDump(buf, 'Test_incsearch_substitute_05', {})
   1134  call term_sendkeys(buf, "\<Esc>")
   1135 
   1136  " Command modifiers are skipped
   1137  call term_sendkeys(buf, ':above below browse botr confirm keepmar keepalt keeppat keepjum filter xxx hide lockm leftabove noau noswap rightbel sandbox silent silent! $tab top unsil vert verbose 4,5s/fo.')
   1138  call VerifyScreenDump(buf, 'Test_incsearch_substitute_06', {})
   1139  call term_sendkeys(buf, "\<Esc>")
   1140 
   1141  " Cursorline highlighting at match
   1142  call term_sendkeys(buf, ":set cursorline\<CR>")
   1143  call term_sendkeys(buf, 'G9G')
   1144  call term_sendkeys(buf, ':9,11s/bar')
   1145  call VerifyScreenDump(buf, 'Test_incsearch_substitute_07', {})
   1146  call term_sendkeys(buf, "\<Esc>")
   1147 
   1148  " Cursorline highlighting at cursor when no match
   1149  call term_sendkeys(buf, ':9,10s/bar')
   1150  call VerifyScreenDump(buf, 'Test_incsearch_substitute_08', {})
   1151  call term_sendkeys(buf, "\<Esc>")
   1152 
   1153  " Only \v handled as empty pattern, does not move cursor
   1154  call term_sendkeys(buf, '3G4G')
   1155  call term_sendkeys(buf, ":nohlsearch\<CR>")
   1156  call term_sendkeys(buf, ':6,7s/\v')
   1157  call VerifyScreenDump(buf, 'Test_incsearch_substitute_09', {})
   1158  call term_sendkeys(buf, "\<Esc>")
   1159 
   1160  call term_sendkeys(buf, ":set nocursorline\<CR>")
   1161 
   1162  " All matches are highlighted for 'hlsearch' after the incsearch canceled
   1163  call term_sendkeys(buf, "1G*")
   1164  call term_sendkeys(buf, ":2,5s/foo")
   1165  sleep 100m
   1166  call term_sendkeys(buf, "\<Esc>")
   1167  call VerifyScreenDump(buf, 'Test_incsearch_substitute_10', {})
   1168 
   1169  call term_sendkeys(buf, ":split\<CR>")
   1170  call term_sendkeys(buf, ":let @/ = 'xyz'\<CR>")
   1171  call term_sendkeys(buf, ":%s/.")
   1172  call VerifyScreenDump(buf, 'Test_incsearch_substitute_11', {})
   1173  call term_sendkeys(buf, "\<BS>")
   1174  call VerifyScreenDump(buf, 'Test_incsearch_substitute_12', {})
   1175  call term_sendkeys(buf, "\<Esc>")
   1176  call VerifyScreenDump(buf, 'Test_incsearch_substitute_13', {})
   1177  call term_sendkeys(buf, ":%bwipe!\<CR>")
   1178  call term_sendkeys(buf, ":only!\<CR>")
   1179 
   1180  "  get :'<,'>s command in history
   1181  call term_sendkeys(buf, ":set cmdheight=2\<CR>")
   1182  call term_sendkeys(buf, "aasdfasdf\<Esc>")
   1183  call term_sendkeys(buf, "V:s/a/b/g\<CR>")
   1184  " Using '<,'> does not give E20
   1185  call term_sendkeys(buf, ":new\<CR>")
   1186  call term_sendkeys(buf, "aasdfasdf\<Esc>")
   1187  call term_sendkeys(buf, ":\<Up>\<Up>")
   1188  call VerifyScreenDump(buf, 'Test_incsearch_substitute_14', {})
   1189  call term_sendkeys(buf, "<Esc>")
   1190 
   1191  call StopVimInTerminal(buf)
   1192 endfunc
   1193 
   1194 func Test_incsearch_highlighting()
   1195  CheckOption incsearch
   1196  CheckScreendump
   1197 
   1198  call writefile([
   1199 \ 'set incsearch hlsearch',
   1200 \ 'call setline(1, "hello/there")',
   1201 \ ], 'Xis_subst_hl_script', 'D')
   1202  let buf = RunVimInTerminal('-S Xis_subst_hl_script', {'rows': 4, 'cols': 20})
   1203  " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
   1204  " the 'ambiwidth' check.
   1205  sleep 300m
   1206 
   1207  " Using a different search delimiter should still highlight matches
   1208  " that contain a '/'.
   1209  call term_sendkeys(buf, ":%s;ello/the")
   1210  call VerifyScreenDump(buf, 'Test_incsearch_substitute_15', {})
   1211  call term_sendkeys(buf, "<Esc>")
   1212 
   1213  call StopVimInTerminal(buf)
   1214 endfunc
   1215 
   1216 func Test_incsearch_with_change()
   1217  CheckFeature timers
   1218  CheckOption incsearch
   1219  CheckScreendump
   1220 
   1221  call writefile([
   1222 \ 'set incsearch hlsearch scrolloff=0',
   1223 \ 'call setline(1, ["one", "two ------ X", "three"])',
   1224 \ 'call timer_start(200, { _ -> setline(2, "x")})',
   1225 \ ], 'Xis_change_script', 'D')
   1226  let buf = RunVimInTerminal('-S Xis_change_script', {'rows': 9, 'cols': 70})
   1227  " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
   1228  " the 'ambiwidth' check.
   1229  sleep 300m
   1230 
   1231  " Highlight X, it will be deleted by the timer callback.
   1232  call term_sendkeys(buf, ':%s/X')
   1233  call VerifyScreenDump(buf, 'Test_incsearch_change_01', {})
   1234  call term_sendkeys(buf, "\<Esc>")
   1235 
   1236  call StopVimInTerminal(buf)
   1237 endfunc
   1238 
   1239 " Similar to Test_incsearch_substitute_dump() for :sort
   1240 func Test_incsearch_sort_dump()
   1241  CheckOption incsearch
   1242  CheckScreendump
   1243 
   1244  call writefile([
   1245 \ 'set incsearch hlsearch scrolloff=0',
   1246 \ 'call setline(1, ["another one 2", "that one 3", "the one 1"])',
   1247 \ ], 'Xis_sort_script', 'D')
   1248  let buf = RunVimInTerminal('-S Xis_sort_script', {'rows': 9, 'cols': 70})
   1249  " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
   1250  " the 'ambiwidth' check.
   1251  sleep 100m
   1252 
   1253  call term_sendkeys(buf, ':sort ni u /on')
   1254  call VerifyScreenDump(buf, 'Test_incsearch_sort_01', {})
   1255  call term_sendkeys(buf, "\<Esc>")
   1256 
   1257  call term_sendkeys(buf, ':sort! /on')
   1258  call VerifyScreenDump(buf, 'Test_incsearch_sort_02', {})
   1259  call term_sendkeys(buf, "\<Esc>")
   1260 
   1261  call StopVimInTerminal(buf)
   1262 endfunc
   1263 
   1264 " Similar to Test_incsearch_substitute_dump() for :vimgrep famiry
   1265 func Test_incsearch_vimgrep_dump()
   1266  CheckOption incsearch
   1267  CheckScreendump
   1268 
   1269  call writefile([
   1270 \ 'set incsearch hlsearch scrolloff=0',
   1271 \ 'call setline(1, ["another one 2", "that one 3", "the one 1"])',
   1272 \ ], 'Xis_vimgrep_script', 'D')
   1273  let buf = RunVimInTerminal('-S Xis_vimgrep_script', {'rows': 9, 'cols': 70})
   1274  " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
   1275  " the 'ambiwidth' check.
   1276  sleep 100m
   1277 
   1278  " Need to send one key at a time to force a redraw.
   1279  call term_sendkeys(buf, ':vimgrep on')
   1280  call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_01', {})
   1281  call term_sendkeys(buf, "\<Esc>")
   1282 
   1283  call term_sendkeys(buf, ':vimg /on/ *.txt')
   1284  call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_02', {})
   1285  call term_sendkeys(buf, "\<Esc>")
   1286 
   1287  call term_sendkeys(buf, ':vimgrepadd "\<on')
   1288  call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_03', {})
   1289  call term_sendkeys(buf, "\<Esc>")
   1290 
   1291  call term_sendkeys(buf, ':lv "tha')
   1292  call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_04', {})
   1293  call term_sendkeys(buf, "\<Esc>")
   1294 
   1295  call term_sendkeys(buf, ':lvimgrepa "the" **/*.txt')
   1296  call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_05', {})
   1297  call term_sendkeys(buf, "\<Esc>")
   1298 
   1299  call StopVimInTerminal(buf)
   1300 endfunc
   1301 
   1302 func Test_keep_last_search_pattern()
   1303  CheckOption incsearch
   1304 
   1305  new
   1306  call setline(1, ['foo', 'foo', 'foo'])
   1307  set incsearch
   1308  call Ntest_override("char_avail", 1)
   1309  let @/ = 'bar'
   1310  call feedkeys(":/foo/s//\<Esc>", 'ntx')
   1311  call assert_equal('bar', @/)
   1312 
   1313  " no error message if pattern not found
   1314  call feedkeys(":/xyz/s//\<Esc>", 'ntx')
   1315  call assert_equal('bar', @/)
   1316 
   1317  bwipe!
   1318  call Ntest_override("ALL", 0)
   1319  set noincsearch
   1320 endfunc
   1321 
   1322 func Test_word_under_cursor_after_match()
   1323  CheckOption incsearch
   1324 
   1325  new
   1326  call setline(1, 'foo bar')
   1327  set incsearch
   1328  call Ntest_override("char_avail", 1)
   1329  try
   1330    call feedkeys("/foo\<C-R>\<C-W>\<CR>", 'ntx')
   1331  catch /E486:/
   1332  endtry
   1333  call assert_equal('foobar', @/)
   1334 
   1335  bwipe!
   1336  call Ntest_override("ALL", 0)
   1337  set noincsearch
   1338 endfunc
   1339 
   1340 func Test_subst_word_under_cursor()
   1341  CheckOption incsearch
   1342 
   1343  new
   1344  call setline(1, ['int SomeLongName;', 'for (xxx = 1; xxx < len; ++xxx)'])
   1345  set incsearch
   1346  call Ntest_override("char_avail", 1)
   1347  call feedkeys("/LongName\<CR>", 'ntx')
   1348  call feedkeys(":%s/xxx/\<C-R>\<C-W>/g\<CR>", 'ntx')
   1349  call assert_equal('for (SomeLongName = 1; SomeLongName < len; ++SomeLongName)', getline(2))
   1350 
   1351  bwipe!
   1352  call Ntest_override("ALL", 0)
   1353  set noincsearch
   1354 endfunc
   1355 
   1356 func Test_search_skip_all_matches()
   1357  enew
   1358  call setline(1, ['no match here',
   1359        \ 'match this line',
   1360        \ 'nope',
   1361        \ 'match in this line',
   1362        \ 'last line',
   1363        \ ])
   1364  call cursor(1, 1)
   1365  let lnum = search('this', '', 0, 0, 'getline(".") =~ "this line"')
   1366  " Only check that no match is found.  Previously it searched forever.
   1367  call assert_equal(0, lnum)
   1368 
   1369  bwipe!
   1370 endfunc
   1371 
   1372 func Test_search_undefined_behaviour()
   1373  CheckFeature terminal
   1374 
   1375  let h = winheight(0)
   1376  if h < 3
   1377    return
   1378  endif
   1379  " did cause an undefined left shift
   1380  let g:buf = term_start([GetVimProg(), '--clean', '-e', '-s', '-c', 'call search(getline("."))', 'samples/test000'], {'term_rows': 3})
   1381  call assert_equal([''], getline(1, '$'))
   1382  call term_sendkeys(g:buf, ":qa!\<cr>")
   1383  bwipe!
   1384 endfunc
   1385 
   1386 func Test_search_undefined_behaviour2()
   1387  call search("\%UC0000000")
   1388 endfunc
   1389 
   1390 " Test for search('multi-byte char', 'bce')
   1391 func Test_search_multibyte()
   1392  let save_enc = &encoding
   1393  set encoding=utf8
   1394  enew!
   1395  call append('$', 'A')
   1396  call cursor(2, 1)
   1397  call assert_equal(2, search('A', 'bce', line('.')))
   1398  enew!
   1399  let &encoding = save_enc
   1400 endfunc
   1401 
   1402 " This was causing E874.  Also causes an invalid read?
   1403 func Test_look_behind()
   1404  new
   1405  call setline(1, '0\|\&\n\@<=')
   1406  call search(getline("."))
   1407  bwipe!
   1408 endfunc
   1409 
   1410 func Test_search_visual_area_linewise()
   1411  new
   1412  call setline(1, ['aa', 'bb', 'cc'])
   1413  exe "normal 2GV\<Esc>"
   1414  for engine in [1, 2]
   1415    exe 'set regexpengine=' .. engine
   1416    exe "normal gg/\\%'<\<CR>>"
   1417    call assert_equal([0, 2, 1, 0, 1], getcurpos(), 'engine ' .. engine)
   1418    exe "normal gg/\\%'>\<CR>"
   1419    call assert_equal([0, 2, 2, 0, 2], getcurpos(), 'engine ' .. engine)
   1420  endfor
   1421 
   1422  bwipe!
   1423  set regexpengine&
   1424 endfunc
   1425 
   1426 func Test_search_sentence()
   1427  new
   1428  " this used to cause a crash
   1429  /\%'(
   1430  /
   1431  bwipe
   1432 endfunc
   1433 
   1434 " Test that there is no crash when there is a last search pattern but no last
   1435 " substitute pattern.
   1436 func Test_no_last_substitute_pat()
   1437  throw 'Skipped: TODO: '
   1438  " Use viminfo to set the last search pattern to a string and make the last
   1439  " substitute pattern the most recent used and make it empty (NULL).
   1440  call writefile(['~MSle0/bar', '~MSle0~&'], 'Xviminfo', 'D')
   1441  rviminfo! Xviminfo
   1442  call assert_fails('normal n', 'E35:')
   1443 endfunc
   1444 
   1445 func Test_search_Ctrl_L_combining()
   1446  " Make sure, that Ctrl-L works correctly with combining characters.
   1447  " It uses an artificial example of an 'a' with 4 combining chars:
   1448    " 'a' U+0061 Dec:97 LATIN SMALL LETTER A &#x61; /\%u61\Z "\u0061"
   1449    " ' ̀' U+0300 Dec:768 COMBINING GRAVE ACCENT &#x300; /\%u300\Z "\u0300"
   1450    " ' ́' U+0301 Dec:769 COMBINING ACUTE ACCENT &#x301; /\%u301\Z "\u0301"
   1451    " ' ̇' U+0307 Dec:775 COMBINING DOT ABOVE &#x307; /\%u307\Z "\u0307"
   1452    " ' ̣' U+0323 Dec:803 COMBINING DOT BELOW &#x323; /\%u323 "\u0323"
   1453  " Those should also appear on the commandline
   1454  CheckOption incsearch
   1455 
   1456  call Cmdline3_prep()
   1457  1
   1458  let bufcontent = ['', 'Miạ̀́̇m']
   1459  call append('$', bufcontent)
   1460  call feedkeys("/Mi\<c-l>\<c-l>\<cr>", 'tx')
   1461  call assert_equal(5, line('.'))
   1462  call assert_equal(bufcontent[1], @/)
   1463  call Incsearch_cleanup()
   1464 endfunc
   1465 
   1466 func Test_large_hex_chars1()
   1467  " This used to cause a crash, the character becomes an NFA state.
   1468  try
   1469    /\%Ufffffc23
   1470  catch
   1471    call assert_match('E678:', v:exception)
   1472  endtry
   1473  try
   1474    set re=1
   1475    /\%Ufffffc23
   1476  catch
   1477    call assert_match('E678:', v:exception)
   1478  endtry
   1479  set re&
   1480 endfunc
   1481 
   1482 func Test_large_hex_chars2()
   1483  " This used to cause a crash, the character becomes an NFA state.
   1484  try
   1485    /[\Ufffffc1f]
   1486  catch
   1487    call assert_match('E1541:', v:exception)
   1488  endtry
   1489  try
   1490    set re=1
   1491    /[\Ufffffc1f]
   1492  catch
   1493    call assert_match('E1541:', v:exception)
   1494  endtry
   1495  set re&
   1496 endfunc
   1497 
   1498 func Test_large_hex_chars3()
   1499  " Validate max number of Unicode char
   1500  try
   1501    /[\UFFFFFFFF]
   1502  catch
   1503    call assert_match('E1541:', v:exception)
   1504  endtry
   1505  try
   1506    /[\UFFFFFFF]
   1507  catch
   1508    call assert_match('E486:', v:exception)
   1509  endtry
   1510  try
   1511    /\%#=2[\d32-\UFFFFFFFF]
   1512  catch
   1513    call assert_match('E1541:', v:exception)
   1514  endtry
   1515  try
   1516    /\%#=1[\UFFFFFFFF]
   1517  catch
   1518    call assert_match('E1541:', v:exception)
   1519  endtry
   1520  try
   1521    /\%#=1[\d32-\UFFFFFFFF]
   1522  catch
   1523    call assert_match('E945:', v:exception)
   1524  endtry
   1525 endfunc
   1526 
   1527 func Test_one_error_msg()
   1528  " This was also giving an internal error
   1529  call assert_fails('call search(" \\((\\v[[=P=]]){185}+             ")', 'E871:')
   1530 endfunc
   1531 
   1532 func Test_incsearch_add_char_under_cursor()
   1533  CheckOption incsearch
   1534 
   1535  set incsearch
   1536  new
   1537  call setline(1, ['find match', 'anything'])
   1538  1
   1539  call Ntest_override('char_avail', 1)
   1540  call feedkeys("fc/m\<C-L>\<C-L>\<C-L>\<C-L>\<C-L>\<CR>", 'tx')
   1541  call assert_equal('match', @/)
   1542  call Ntest_override('char_avail', 0)
   1543 
   1544  set incsearch&
   1545  bwipe!
   1546 endfunc
   1547 
   1548 " Test for the search() function with match at the cursor position
   1549 func Test_search_match_at_curpos()
   1550  new
   1551  call append(0, ['foobar', '', 'one two', ''])
   1552 
   1553  normal gg
   1554 
   1555  eval 'foobar'->search('c')
   1556  call assert_equal([1, 1], [line('.'), col('.')])
   1557 
   1558  normal j
   1559  call search('^$', 'c')
   1560  call assert_equal([2, 1], [line('.'), col('.')])
   1561 
   1562  call search('^$', 'bc')
   1563  call assert_equal([2, 1], [line('.'), col('.')])
   1564 
   1565  exe "normal /two\<CR>"
   1566  call search('.', 'c')
   1567  call assert_equal([3, 5], [line('.'), col('.')])
   1568 
   1569  bw!
   1570 endfunc
   1571 
   1572 " Test for error cases with the search() function
   1573 func Test_search_errors()
   1574  call assert_fails("call search('pat', [])", 'E730:')
   1575  call assert_fails("call search('pat', 'b', {})", 'E728:')
   1576  call assert_fails("call search('pat', 'b', 1, [])", 'E745:')
   1577  call assert_fails("call search('pat', 'ns')", 'E475:')
   1578  call assert_fails("call search('pat', 'mr')", 'E475:')
   1579 
   1580  new
   1581  call setline(1, ['foo', 'bar'])
   1582  call assert_fails('call feedkeys("/foo/;/bar/;\<CR>", "tx")', 'E386:')
   1583  bwipe!
   1584 endfunc
   1585 
   1586 func Test_search_display_pattern()
   1587  new
   1588  call setline(1, ['foo', 'bar', 'foobar'])
   1589 
   1590  call cursor(1, 1)
   1591  let @/ = 'foo'
   1592  let pat = @/->escape('()*?'. '\s\+')
   1593  let g:a = execute(':unsilent :norm! n')
   1594  call assert_match(pat, g:a)
   1595 
   1596  " right-left
   1597  if exists("+rightleft")
   1598    set rl
   1599    call cursor(1, 1)
   1600    let @/ = 'foo'
   1601    let pat = 'oof/\s\+'
   1602    let g:a = execute(':unsilent :norm! n')
   1603    call assert_match(pat, g:a)
   1604    set norl
   1605  endif
   1606 endfunc
   1607 
   1608 func Test_searchdecl()
   1609  let lines =<< trim END
   1610     int global;
   1611 
   1612     func()
   1613     {
   1614       int global;
   1615       if (cond) {
   1616  int local;
   1617       }
   1618       int local;
   1619       // comment
   1620     }
   1621  END
   1622  new
   1623  call setline(1, lines)
   1624  10
   1625  call assert_equal(0, searchdecl('local', 0, 0))
   1626  call assert_equal(7, getcurpos()[1])
   1627 
   1628  10
   1629  call assert_equal(0, 'local'->searchdecl(0, 1))
   1630  call assert_equal(9, getcurpos()[1])
   1631 
   1632  10
   1633  call assert_equal(0, searchdecl('global'))
   1634  call assert_equal(5, getcurpos()[1])
   1635 
   1636  10
   1637  call assert_equal(0, searchdecl('global', 1))
   1638  call assert_equal(1, getcurpos()[1])
   1639 
   1640  bwipe!
   1641 endfunc
   1642 
   1643 func Test_search_special()
   1644  " this was causing illegal memory access and an endless loop
   1645  set t_PE=
   1646  exe "norm /\x80PS"
   1647 endfunc
   1648 
   1649 " Test for command failures when the last search pattern is not set.
   1650 " Need to run this in a new vim instance where last search pattern is not set.
   1651 func Test_search_with_no_last_pat()
   1652  let lines =<< trim [SCRIPT]
   1653    call assert_fails("normal i\<C-R>/\e", 'E35:')
   1654    call assert_fails("exe '/'", 'E35:')
   1655    call assert_fails("exe '?'", 'E35:')
   1656    call assert_fails("/", 'E35:')
   1657    call assert_fails("?", 'E35:')
   1658    call assert_fails("normal n", 'E35:')
   1659    call assert_fails("normal N", 'E35:')
   1660    call assert_fails("normal gn", 'E35:')
   1661    call assert_fails("normal gN", 'E35:')
   1662    call assert_fails("normal cgn", 'E35:')
   1663    call assert_fails("normal cgN", 'E35:')
   1664    let p = []
   1665    let p = @/
   1666    call assert_equal('', p)
   1667    call assert_fails("normal :\<C-R>/", 'E35:')
   1668    call assert_fails("//p", 'E35:')
   1669    call assert_fails(";//p", 'E35:')
   1670    call assert_fails("??p", 'E35:')
   1671    call assert_fails(";??p", 'E35:')
   1672    call assert_fails('g//p', ['E35:', 'E476:'])
   1673    call assert_fails('v//p', ['E35:', 'E476:'])
   1674    call writefile(v:errors, 'Xresult')
   1675    qall!
   1676  [SCRIPT]
   1677  call writefile(lines, 'Xscript', 'D')
   1678 
   1679  if RunVim([], [], '--clean -S Xscript')
   1680    call assert_equal([], readfile('Xresult'))
   1681  endif
   1682  call delete('Xresult')
   1683 endfunc
   1684 
   1685 " Test for using the last substitute pattern without last search pattern.
   1686 func Test_search_with_last_substitute_pat()
   1687  let lines =<< trim [SCRIPT]
   1688    new
   1689    set shortmess+=S
   1690    call setline(1, repeat(['foofoo'], 3))
   1691    %s/foo/bar/
   1692    call assert_equal(repeat(['barfoo'], 3), getline(1, '$'))
   1693 
   1694    call cursor(1, 1)
   1695    call assert_equal("/foo", execute('call feedkeys("/\r", "tx")', '')->trim())
   1696    call assert_equal([0, 1, 4, 0], getpos('.'))
   1697 
   1698    if has('rightleft')
   1699      set rightleft rightleftcmd=search
   1700      call cursor(1, 1)
   1701      call assert_equal("oof/", execute('call feedkeys("/\r", "tx")', '')->trim())
   1702      call assert_equal([0, 1, 4, 0], getpos('.'))
   1703    endif
   1704 
   1705    call writefile(v:errors, 'Xresult')
   1706    qall!
   1707  [SCRIPT]
   1708  call writefile(lines, 'Xscript', 'D')
   1709 
   1710  if RunVim([], [], '--clean -S Xscript')
   1711    call assert_equal([], readfile('Xresult'))
   1712  endif
   1713  call delete('Xresult')
   1714 endfunc
   1715 
   1716 " Test for using tilde (~) atom in search. This should use the last used
   1717 " substitute pattern
   1718 func Test_search_tilde_pat()
   1719  let lines =<< trim [SCRIPT]
   1720    set regexpengine=1
   1721    call assert_fails('exe "normal /~\<CR>"', 'E33:')
   1722    call assert_fails('exe "normal ?~\<CR>"', 'E33:')
   1723    set regexpengine=2
   1724    call assert_fails('exe "normal /~\<CR>"', ['E33:', 'E383:'])
   1725    call assert_fails('exe "normal ?~\<CR>"', ['E33:', 'E383:'])
   1726    set regexpengine&
   1727    call writefile(v:errors, 'Xresult')
   1728    qall!
   1729  [SCRIPT]
   1730  call writefile(lines, 'Xscript', 'D')
   1731  if RunVim([], [], '--clean -S Xscript')
   1732    call assert_equal([], readfile('Xresult'))
   1733  endif
   1734  call delete('Xresult')
   1735 endfunc
   1736 
   1737 " Test for searching a pattern that is not present with 'nowrapscan'
   1738 func Test_search_pat_not_found()
   1739  new
   1740  set nowrapscan
   1741  let @/ = '1abcxyz2'
   1742  call assert_fails('normal n', 'E385:')
   1743  call assert_fails('normal N', 'E384:')
   1744  set wrapscan&
   1745  bw
   1746 endfunc
   1747 
   1748 " Test for v:searchforward variable
   1749 func Test_searchforward_var()
   1750  new
   1751  call setline(1, ['foo', '', 'foo'])
   1752  call cursor(2, 1)
   1753  let @/ = 'foo'
   1754  let v:searchforward = 0
   1755  normal N
   1756  call assert_equal(3, line('.'))
   1757  call cursor(2, 1)
   1758  let v:searchforward = 1
   1759  normal N
   1760  call assert_equal(1, line('.'))
   1761  bw!
   1762 endfunc
   1763 
   1764 " Test for invalid regular expressions
   1765 func Test_invalid_regexp()
   1766  set regexpengine=1
   1767  call assert_fails("call search(repeat('\\(.\\)', 10))", 'E51:')
   1768  call assert_fails("call search('\\%(')", 'E53:')
   1769  call assert_fails("call search('\\(')", 'E54:')
   1770  call assert_fails("call search('\\)')", 'E55:')
   1771  call assert_fails("call search('x\\@#')", 'E59:')
   1772  call assert_fails('call search(''\v%(%(%(%(%(%(%(%(%(%(%(a){1}){1}){1}){1}){1}){1}){1}){1}){1}){1}){1}'')', 'E60:')
   1773  call assert_fails("call search('a\\+*')", 'E61:')
   1774  call assert_fails("call search('\\_m')", 'E63:')
   1775  call assert_fails("call search('\\+')", 'E64:')
   1776  call assert_fails("call search('\\1')", 'E65:')
   1777  call assert_fails("call search('\\z\\(\\)')", 'E66:')
   1778  call assert_fails("call search('\\z2')", 'E67:')
   1779  call assert_fails("call search('\\zx')", 'E68:')
   1780  call assert_fails("call search('\\%[ab')", 'E69:')
   1781  call assert_fails("call search('\\%[]')", 'E70:')
   1782  call assert_fails("call search('\\%a')", 'E71:')
   1783  call assert_fails("call search('ab\\%[\\(cd\\)]')", 'E369:')
   1784  call assert_fails("call search('ab\\%[\\%(cd\\)]')", 'E369:')
   1785  set regexpengine=2
   1786  call assert_fails("call search('\\_')", 'E865:')
   1787  call assert_fails("call search('\\+')", 'E866:')
   1788  call assert_fails("call search('\\zx')", 'E867:')
   1789  call assert_fails("call search('\\%a')", 'E867:')
   1790  call assert_fails("call search('x\\@#')", 'E869:')
   1791  call assert_fails("call search(repeat('\\(.\\)', 10))", 'E872:')
   1792  call assert_fails("call search('\\_m')", 'E877:')
   1793  call assert_fails("call search('\\%(')", 'E53:')
   1794  call assert_fails("call search('\\(')", 'E54:')
   1795  call assert_fails("call search('\\)')", 'E55:')
   1796  call assert_fails("call search('\\z\\(\\)')", 'E66:')
   1797  call assert_fails("call search('\\z2')", 'E67:')
   1798  call assert_fails("call search('\\zx')", 'E867:')
   1799  call assert_fails("call search('\\%[ab')", 'E69:')
   1800  call assert_fails("call search('\\%[]')", 'E70:')
   1801  call assert_fails("call search('\\%9999999999999999999999999999v')", 'E951:')
   1802  set regexpengine&
   1803  call assert_fails("call search('\\%#=3ab')", 'E864:')
   1804 endfunc
   1805 
   1806 " Test for searching a very complex pattern in a string. Should switch the
   1807 " regexp engine from NFA to the old engine.
   1808 func Test_regexp_switch_engine()
   1809  let l = readfile('samples/re.freeze.txt')
   1810  let v = substitute(l[4], '..\@<!', '', '')
   1811  call assert_equal(l[4], v)
   1812 endfunc
   1813 
   1814 " Test for the \%V atom to search within visually selected text
   1815 func Test_search_in_visual_area()
   1816  new
   1817  call setline(1, ['foo bar1', 'foo bar2', 'foo bar3', 'foo bar4'])
   1818  exe "normal 2GVjo/\\%Vbar\<CR>\<Esc>"
   1819  call assert_equal([2, 5], [line('.'), col('.')])
   1820  exe "normal 2GVj$?\\%Vbar\<CR>\<Esc>"
   1821  call assert_equal([3, 5], [line('.'), col('.')])
   1822  bw!
   1823 endfunc
   1824 
   1825 " Test for searching with 'smartcase' and 'ignorecase'
   1826 func Test_search_smartcase()
   1827  new
   1828  call setline(1, ['', 'Hello'])
   1829  set noignorecase nosmartcase
   1830  call assert_fails('exe "normal /\\a\\_.\\(.*\\)O\<CR>"', 'E486:')
   1831 
   1832  set ignorecase nosmartcase
   1833  exe "normal /\\a\\_.\\(.*\\)O\<CR>"
   1834  call assert_equal([2, 1], [line('.'), col('.')])
   1835 
   1836  call cursor(1, 1)
   1837  set ignorecase smartcase
   1838  call assert_fails('exe "normal /\\a\\_.\\(.*\\)O\<CR>"', 'E486:')
   1839 
   1840  exe "normal /\\a\\_.\\(.*\\)o\<CR>"
   1841  call assert_equal([2, 1], [line('.'), col('.')])
   1842 
   1843  " Test for using special atoms with 'smartcase'
   1844  call setline(1, ['', '    Hello\ '])
   1845  call cursor(1, 1)
   1846  call feedkeys('/\_.\%(\uello\)\' .. "\<CR>", 'xt')
   1847  call assert_equal([2, 4], [line('.'), col('.')])
   1848 
   1849  set ignorecase& smartcase&
   1850  bw!
   1851 endfun
   1852 
   1853 " Test 'smartcase' with utf-8.
   1854 func Test_search_smartcase_utf8()
   1855  new
   1856  let save_enc = &encoding
   1857  set encoding=utf8 ignorecase smartcase
   1858 
   1859  call setline(1, 'Café cafÉ')
   1860  1s/café/x/g
   1861  call assert_equal('x x', getline(1))
   1862 
   1863  call setline(1, 'Café cafÉ')
   1864  1s/cafÉ/x/g
   1865  call assert_equal('Café x', getline(1))
   1866 
   1867  set ignorecase& smartcase&
   1868  let &encoding = save_enc
   1869  bwipe!
   1870 endfunc
   1871 
   1872 " Test searching past the end of a file
   1873 func Test_search_past_eof()
   1874  new
   1875  call setline(1, ['Line'])
   1876  exe "normal /\\n\\zs\<CR>"
   1877  call assert_equal([1, 4], [line('.'), col('.')])
   1878  bwipe!
   1879 endfunc
   1880 
   1881 " Test setting the start of the match and still finding a next match in the
   1882 " same line.
   1883 func Test_search_set_start_same_line()
   1884  new
   1885  set cpo-=c
   1886 
   1887  call setline(1, ['1', '2', '3 .', '4', '5'])
   1888  exe "normal /\\_s\\zs\\S\<CR>"
   1889  call assert_equal([2, 1], [line('.'), col('.')])
   1890  exe 'normal n'
   1891  call assert_equal([3, 1], [line('.'), col('.')])
   1892  exe 'normal n'
   1893  call assert_equal([3, 3], [line('.'), col('.')])
   1894  exe 'normal n'
   1895  call assert_equal([4, 1], [line('.'), col('.')])
   1896  exe 'normal n'
   1897  call assert_equal([5, 1], [line('.'), col('.')])
   1898 
   1899  set cpo+=c
   1900  bwipe!
   1901 endfunc
   1902 
   1903 " Test for various search offsets
   1904 func Test_search_offset()
   1905  " With /e, for a match in the first column of a line, the cursor should be
   1906  " placed at the end of the previous line.
   1907  new
   1908  call setline(1, ['one two', 'three four'])
   1909  call search('two\_.', 'e')
   1910  call assert_equal([1, 7], [line('.'), col('.')])
   1911 
   1912  " with cursor at the beginning of the file, use /s+1
   1913  " '+' without a digit is the same as +1, and 'b' is an alias for 's'
   1914  for searchcmd in ['/two/s+1', '/two/s+', '/two/b+1', '/two/b+', '/']
   1915    call cursor(1, 1)
   1916    exe $"normal {searchcmd}\<CR>"
   1917    call assert_equal([1, 6], [line('.'), col('.')], searchcmd)
   1918    call assert_equal('/two/s+1', Screenline(&lines)->trim(), searchcmd)
   1919  endfor
   1920 
   1921  " repeat the same search pattern with different offsets
   1922  for [offset, col] in [['s', 5], ['e-1', 6], ['s+2', 7], ['s-2', 3], ['', 5]]
   1923    let searchcmd = $'//{offset}'
   1924    call cursor(1, 1)
   1925    exe $"normal {searchcmd}\<CR>"
   1926    call assert_equal([1, col], [line('.'), col('.')], searchcmd)
   1927    call assert_equal(col == 5 ? '/two' : $'/two/{offset}',
   1928                      \ Screenline(&lines)->trim(), searchcmd)
   1929  endfor
   1930 
   1931  " with cursor at the end of the file, use /e-1
   1932  " '-' without a digit is the same as -1
   1933  for searchcmd in ['?three?e-1', '?three?e-', '?']
   1934    call cursor(2, 10)
   1935    exe $"normal {searchcmd}\<CR>"
   1936    call assert_equal([2, 4], [line('.'), col('.')], searchcmd)
   1937    call assert_equal('?three?e-1', Screenline(&lines)->trim(), searchcmd)
   1938  endfor
   1939 
   1940  " repeat the same search pattern with different offsets
   1941  for [offset, col] in [['e', 5], ['s+1', 2], ['e-2', 3], ['e+2', 7], ['', 1]]
   1942    let searchcmd = $'??{offset}'
   1943    call cursor(2, 10)
   1944    exe $"normal {searchcmd}\<CR>"
   1945    call assert_equal([2, col], [line('.'), col('.')], searchcmd)
   1946    call assert_equal(col == 1 ? '?three' : $'?three?{offset}',
   1947                      \ Screenline(&lines)->trim(), searchcmd)
   1948  endfor
   1949 
   1950  " line offset - after the last line
   1951  " '+' without a digit and '1' without a sign are the same as +1
   1952  for searchcmd in ['/three/+1', '/three/+', '/three/1', '/']
   1953    call cursor(1, 1)
   1954    exe $"normal {searchcmd}\<CR>"
   1955    call assert_equal([2, 1], [line('.'), col('.')], searchcmd)
   1956    call assert_equal('/three/+1', Screenline(&lines)->trim(), searchcmd)
   1957  endfor
   1958 
   1959  " repeat the same search pattern with different line offsets
   1960  for [offset, lnum] in [['+0', 2], ['-1', 1], ['+2', 2], ['-2', 1]]
   1961    let searchcmd = $'//{offset}'
   1962    call cursor(1, 1)
   1963    exe $"normal {searchcmd}\<CR>"
   1964    call assert_equal([lnum, 1], [line('.'), col('.')], searchcmd)
   1965    call assert_equal($'/three/{offset}',
   1966                      \ Screenline(&lines)->trim(), searchcmd)
   1967  endfor
   1968 
   1969  " line offset - before the first line
   1970  " '-' without a digit is the same as -1
   1971  for searchcmd in ['?one?-1', '?one?-', '?']
   1972    call cursor(2, 1)
   1973    exe $"normal {searchcmd}\<CR>"
   1974    call assert_equal([1, 1], [line('.'), col('.')], searchcmd)
   1975    call assert_equal('?one?-1', Screenline(&lines)->trim(), searchcmd)
   1976  endfor
   1977 
   1978  " repeat the same search pattern with different line offsets
   1979  for [offset, lnum] in [['+0', 1], ['+1', 2], ['-2', 1], ['+2', 2]]
   1980    let searchcmd = $'??{offset}'
   1981    call cursor(2, 1)
   1982    exe $"normal {searchcmd}\<CR>"
   1983    call assert_equal([lnum, 1], [line('.'), col('.')], searchcmd)
   1984    call assert_equal($'?one?{offset}',
   1985                      \ Screenline(&lines)->trim(), searchcmd)
   1986  endfor
   1987 
   1988  " character offset - before the first character in the file
   1989  call cursor(2, 1)
   1990  exe "normal ?one?s-1\<CR>"
   1991  call assert_equal([1, 1], [line('.'), col('.')])
   1992  call assert_equal('?one?s-1', Screenline(&lines)->trim())
   1993  call cursor(2, 1)
   1994  exe "normal ?one?e-3\<CR>"
   1995  call assert_equal([1, 1], [line('.'), col('.')])
   1996  call assert_equal('?one?e-3', Screenline(&lines)->trim())
   1997 
   1998  " character offset - after the last character in the file
   1999  call cursor(1, 1)
   2000  exe "normal /four/s+4\<CR>"
   2001  call assert_equal([2, 10], [line('.'), col('.')])
   2002  call assert_equal('/four/s+4', Screenline(&lines)->trim())
   2003  call cursor(1, 1)
   2004  exe "normal /four/e+1\<CR>"
   2005  call assert_equal([2, 10], [line('.'), col('.')])
   2006  call assert_equal('/four/e+1', Screenline(&lines)->trim())
   2007 
   2008  bw!
   2009 endfunc
   2010 
   2011 " Test for searching for matching parenthesis using %
   2012 func Test_search_match_paren()
   2013  new
   2014  call setline(1, "abc(def')'ghi'('jk'\\t'lm)no")
   2015  " searching for a matching parenthesis should skip single quoted characters
   2016  call cursor(1, 4)
   2017  normal %
   2018  call assert_equal([1, 25], [line('.'), col('.')])
   2019  normal %
   2020  call assert_equal([1, 4], [line('.'), col('.')])
   2021  call cursor(1, 5)
   2022  normal ])
   2023  call assert_equal([1, 25], [line('.'), col('.')])
   2024  call cursor(1, 24)
   2025  normal [(
   2026  call assert_equal([1, 4], [line('.'), col('.')])
   2027 
   2028  " matching parenthesis in 'virtualedit' mode with cursor after the eol
   2029  call setline(1, 'abc(defgh)')
   2030  set virtualedit=all
   2031  normal 20|%
   2032  call assert_equal(4, col('.'))
   2033  set virtualedit&
   2034  bw!
   2035 endfunc
   2036 
   2037 " Test for searching a pattern and stopping before a specified line
   2038 func Test_search_stopline()
   2039  new
   2040  call setline(1, ['', '', '', 'vim'])
   2041  call assert_equal(0, search('vim', 'n', 3))
   2042  call assert_equal(4, search('vim', 'n', 4))
   2043  call setline(1, ['vim', '', '', ''])
   2044  call cursor(4, 1)
   2045  call assert_equal(0, search('vim', 'bn', 2))
   2046  call assert_equal(1, search('vim', 'bn', 1))
   2047  bw!
   2048 endfunc
   2049 
   2050 func Test_incsearch_highlighting_newline()
   2051  CheckRunVimInTerminal
   2052  CheckOption incsearch
   2053  CheckScreendump
   2054  new
   2055  call test_override("char_avail", 1)
   2056 
   2057  let commands =<< trim [CODE]
   2058    set incsearch nohls
   2059    call setline(1, ['test', 'xxx'])
   2060  [CODE]
   2061  call writefile(commands, 'Xincsearch_nl', 'D')
   2062  let buf = RunVimInTerminal('-S Xincsearch_nl', {'rows': 5, 'cols': 10})
   2063  call term_sendkeys(buf, '/test')
   2064  call VerifyScreenDump(buf, 'Test_incsearch_newline1', {})
   2065  " Need to send one key at a time to force a redraw
   2066  call term_sendkeys(buf, '\n')
   2067  call VerifyScreenDump(buf, 'Test_incsearch_newline2', {})
   2068  call term_sendkeys(buf, 'x')
   2069  call VerifyScreenDump(buf, 'Test_incsearch_newline3', {})
   2070  call term_sendkeys(buf, 'x')
   2071  call VerifyScreenDump(buf, 'Test_incsearch_newline4', {})
   2072  call term_sendkeys(buf, "\<CR>")
   2073  call VerifyScreenDump(buf, 'Test_incsearch_newline5', {})
   2074  call StopVimInTerminal(buf)
   2075 
   2076  " clean up
   2077  call test_override("char_avail", 0)
   2078  bw
   2079 endfunc
   2080 
   2081 func Test_incsearch_substitute_dump2()
   2082  CheckOption incsearch
   2083  CheckScreendump
   2084 
   2085  call writefile([
   2086 \ 'set incsearch hlsearch scrolloff=0',
   2087 \ 'for n in range(1, 4)',
   2088 \ '  call setline(n, "foo " . n)',
   2089 \ 'endfor',
   2090 \ 'call setline(5, "abc|def")',
   2091 \ '3',
   2092 \ ], 'Xis_subst_script2', 'D')
   2093  let buf = RunVimInTerminal('-S Xis_subst_script2', {'rows': 9, 'cols': 70})
   2094 
   2095  call term_sendkeys(buf, ':%s/\vabc|')
   2096  sleep 100m
   2097  call VerifyScreenDump(buf, 'Test_incsearch_sub_01', {})
   2098  call term_sendkeys(buf, "\<Esc>")
   2099 
   2100  " The following should not be highlighted
   2101  call term_sendkeys(buf, ':1,5s/\v|')
   2102  sleep 100m
   2103  call VerifyScreenDump(buf, 'Test_incsearch_sub_02', {})
   2104 
   2105 
   2106  call StopVimInTerminal(buf)
   2107 endfunc
   2108 
   2109 func Test_incsearch_restore_view()
   2110  CheckOption incsearch
   2111  CheckScreendump
   2112 
   2113  let lines =<< trim [CODE]
   2114    set incsearch nohlsearch
   2115    setlocal scrolloff=0 smoothscroll
   2116    call setline(1, [join(range(25), ' '), '', '', '', '', 'xxx'])
   2117    call feedkeys("2\<C-E>", 't')
   2118  [CODE]
   2119  call writefile(lines, 'Xincsearch_restore_view', 'D')
   2120  let buf = RunVimInTerminal('-S Xincsearch_restore_view', {'rows': 6, 'cols': 20})
   2121 
   2122  call VerifyScreenDump(buf, 'Test_incsearch_restore_view_01', {})
   2123  call term_sendkeys(buf, '/xx')
   2124  call VerifyScreenDump(buf, 'Test_incsearch_restore_view_02', {})
   2125  call term_sendkeys(buf, 'x')
   2126  call VerifyScreenDump(buf, 'Test_incsearch_restore_view_03', {})
   2127  call term_sendkeys(buf, "\<Esc>")
   2128  call VerifyScreenDump(buf, 'Test_incsearch_restore_view_01', {})
   2129 
   2130  call StopVimInTerminal(buf)
   2131 endfunc
   2132 
   2133 func Test_pattern_is_uppercase_smartcase()
   2134  new
   2135  let input=['abc', 'ABC', 'Abc', 'abC']
   2136  call setline(1, input)
   2137  call cursor(1,1)
   2138  " default, matches firstline
   2139  %s/abc//g
   2140  call assert_equal(['', 'ABC', 'Abc', 'abC'],
   2141        \ getline(1, '$'))
   2142 
   2143  set smartcase ignorecase
   2144  sil %d
   2145  call setline(1, input)
   2146  call cursor(1,1)
   2147  " with smartcase and incsearch set, matches everything
   2148  %s/abc//g
   2149  call assert_equal(['', '', '', ''], getline(1, '$'))
   2150 
   2151  sil %d
   2152  call setline(1, input)
   2153  call cursor(1,1)
   2154  " with smartcase and incsearch set and found an uppercase letter,
   2155  " match only that.
   2156  %s/abC//g
   2157  call assert_equal(['abc', 'ABC', 'Abc', ''],
   2158        \ getline(1, '$'))
   2159 
   2160  sil %d
   2161  call setline(1, input)
   2162  call cursor(1,1)
   2163  exe "norm! vG$\<esc>"
   2164  " \%V should not be detected as uppercase letter
   2165  %s/\%Vabc//g
   2166  call assert_equal(['', '', '', ''], getline(1, '$'))
   2167 
   2168  call setline(1, input)
   2169  call cursor(1,1)
   2170  exe "norm! vG$\<esc>"
   2171  " \v%V should not be detected as uppercase letter
   2172  %s/\v%Vabc//g
   2173  call assert_equal(['', '', '', ''], getline(1, '$'))
   2174 
   2175  call setline(1, input)
   2176  call cursor(1,1)
   2177  exe "norm! vG$\<esc>"
   2178  " \v%VabC should be detected as uppercase letter
   2179  %s/\v%VabC//g
   2180  call assert_equal(['abc', 'ABC', 'Abc', ''],
   2181        \ getline(1, '$'))
   2182 
   2183  call setline(1, input)
   2184  call cursor(1,1)
   2185  " \Vabc should match everything
   2186  %s/\Vabc//g
   2187  call assert_equal(['', '', '', ''], getline(1, '$'))
   2188 
   2189  call setline(1, input + ['_abc'])
   2190  " _ matches normally
   2191  %s/\v_.*//g
   2192  call assert_equal(['abc', 'ABC', 'Abc', 'abC', ''], getline(1, '$'))
   2193 
   2194  set smartcase& ignorecase&
   2195  bw!
   2196 endfunc
   2197 
   2198 func Test_no_last_search_pattern()
   2199  CheckOption incsearch
   2200 
   2201  let @/ = ""
   2202  set incsearch
   2203  " these were causing a crash
   2204  call feedkeys("//\<C-G>", 'xt')
   2205  call feedkeys("//\<C-T>", 'xt')
   2206  call feedkeys("??\<C-G>", 'xt')
   2207  call feedkeys("??\<C-T>", 'xt')
   2208 endfunc
   2209 
   2210 func Test_search_with_invalid_range()
   2211  new
   2212  let lines =<< trim END
   2213    /\%.v
   2214    5/
   2215    c
   2216  END
   2217  call writefile(lines, 'Xrangesearch', 'D')
   2218  source Xrangesearch
   2219 
   2220  bwipe!
   2221 endfunc
   2222 
   2223 func Test_incsearch_delimiter_ctrlg()
   2224  CheckOption incsearch
   2225  CheckScreendump
   2226  CheckRunVimInTerminal
   2227  call assert_equal(0, &scrolloff)
   2228  call writefile([
   2229 \ 'set incsearch hls',
   2230  \ 'call setline(1, ["1 vim inc", "2 vim /", "3 vim /", "4 vim ?", "5 vim ?"])',
   2231 \ 'normal gg',
   2232 \ 'redraw',
   2233 \ ], 'Xscript_incsearch_delim', 'D')
   2234  let buf = RunVimInTerminal('-S Xscript_incsearch_delim', {'rows': 6})
   2235 
   2236  call term_sendkeys(buf, '/')
   2237  sleep 100m
   2238  call term_sendkeys(buf, 'v')
   2239  sleep 100m
   2240  call term_sendkeys(buf, 'i')
   2241  sleep 100m
   2242  call term_sendkeys(buf, 'm')
   2243  sleep 100m
   2244  call term_sendkeys(buf, ' ')
   2245  sleep 100m
   2246  call term_sendkeys(buf, '/')
   2247  sleep 100m
   2248  call term_sendkeys(buf, "\<C-G>")
   2249  call VerifyScreenDump(buf, 'Test_incsearch_delim_01', {})
   2250  call term_sendkeys(buf, "\<Esc>")
   2251 
   2252  call term_sendkeys(buf, ":5\<cr>")
   2253  call term_sendkeys(buf, '?')
   2254  sleep 100m
   2255  call term_sendkeys(buf, 'v')
   2256  sleep 100m
   2257  call term_sendkeys(buf, 'i')
   2258  sleep 100m
   2259  call term_sendkeys(buf, 'm')
   2260  sleep 100m
   2261  call term_sendkeys(buf, ' ')
   2262  sleep 100m
   2263  call term_sendkeys(buf, '?')
   2264  sleep 100m
   2265  call term_sendkeys(buf, "\<C-T>")
   2266  call VerifyScreenDump(buf, 'Test_incsearch_delim_02', {})
   2267  call term_sendkeys(buf, "\<Esc>")
   2268 
   2269  call term_sendkeys(buf, '/')
   2270  sleep 100m
   2271  call term_sendkeys(buf, 'v')
   2272  sleep 100m
   2273  call term_sendkeys(buf, 'i')
   2274  sleep 100m
   2275  call term_sendkeys(buf, 'm')
   2276  sleep 100m
   2277  call term_sendkeys(buf, ' ')
   2278  sleep 100m
   2279  call term_sendkeys(buf, '\/')
   2280  sleep 100m
   2281  call term_sendkeys(buf, "\<C-G>")
   2282  call VerifyScreenDump(buf, 'Test_incsearch_delim_03', {})
   2283  call term_sendkeys(buf, "\<Esc>")
   2284 
   2285  call term_sendkeys(buf, ":5\<cr>")
   2286  call term_sendkeys(buf, '?')
   2287  sleep 100m
   2288  call term_sendkeys(buf, 'v')
   2289  sleep 100m
   2290  call term_sendkeys(buf, 'i')
   2291  sleep 100m
   2292  call term_sendkeys(buf, 'm')
   2293  sleep 100m
   2294  call term_sendkeys(buf, ' ')
   2295  sleep 100m
   2296  call term_sendkeys(buf, '\?')
   2297  sleep 100m
   2298  call term_sendkeys(buf, "\<C-T>")
   2299  call VerifyScreenDump(buf, 'Test_incsearch_delim_04', {})
   2300  call term_sendkeys(buf, "\<Esc>")
   2301 
   2302  call StopVimInTerminal(buf)
   2303 endfunc
   2304 
   2305 " vim: shiftwidth=2 sts=2 expandtab