xref: /vim-8.2.3635/src/testdir/test_search.vim (revision 3d1d6475)
1" Test for the search command
2
3source shared.vim
4source screendump.vim
5
6func Test_search_cmdline()
7  if !exists('+incsearch')
8    return
9  endif
10  " need to disable char_avail,
11  " so that expansion of commandline works
12  call test_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  " eigth 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  " eigth 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 test_override("char_avail", 0)
200  bw!
201endfunc
202
203func Test_search_cmdline2()
204  if !exists('+incsearch')
205    return
206  endif
207  " need to disable char_avail,
208  " so that expansion of commandline works
209  call test_override("char_avail", 1)
210  new
211  call setline(1, ['  1', '  2 these', '  3 the theother'])
212  " Test 1
213  " Ctrl-T goes correctly back and forth
214  set incsearch
215  1
216  " first match
217  call feedkeys("/the\<cr>", 'tx')
218  call assert_equal('  2 these', getline('.'))
219  1
220  " go to next match (on next line)
221  call feedkeys("/the\<C-G>\<cr>", 'tx')
222  call assert_equal('  3 the theother', getline('.'))
223  1
224  " go to next match (still on line 3)
225  call feedkeys("/the\<C-G>\<C-G>\<cr>", 'tx')
226  call assert_equal('  3 the theother', getline('.'))
227  1
228  " go to next match (still on line 3)
229  call feedkeys("/the\<C-G>\<C-G>\<C-G>\<cr>", 'tx')
230  call assert_equal('  3 the theother', getline('.'))
231  1
232  " go to previous match (on line 3)
233  call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<cr>", 'tx')
234  call assert_equal('  3 the theother', getline('.'))
235  1
236  " go to previous match (on line 3)
237  call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<cr>", 'tx')
238  call assert_equal('  3 the theother', getline('.'))
239  1
240  " go to previous match (on line 2)
241  call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<C-T>\<cr>", 'tx')
242  call assert_equal('  2 these', getline('.'))
243
244  " Test 2: keep the view,
245  " after deleting a character from the search cmd
246  call setline(1, ['  1', '  2 these', '  3 the', '  4 their', '  5 there', '  6 their', '  7 the', '  8 them', '  9 these', ' 10 foobar'])
247  resize 5
248  1
249  call feedkeys("/foo\<bs>\<cr>", 'tx')
250  redraw
251  call assert_equal({'lnum': 10, 'leftcol': 0, 'col': 4, 'topfill': 0, 'topline': 6, 'coladd': 0, 'skipcol': 0, 'curswant': 4}, winsaveview())
252
253  " remove all history entries
254  for i in range(10)
255      call histdel('/')
256  endfor
257
258  " Test 3: reset the view,
259  " after deleting all characters from the search cmd
260  norm! 1gg0
261  " unfortunately, neither "/foo\<c-w>\<cr>", nor "/foo\<bs>\<bs>\<bs>\<cr>",
262  " nor "/foo\<c-u>\<cr>" works to delete the commandline.
263  " In that case Vim should return "E35 no previous regular expression",
264  " but it looks like Vim still sees /foo and therefore the test fails.
265  " Therefore, disableing this test
266  "call assert_fails(feedkeys("/foo\<c-w>\<cr>", 'tx'), 'E35')
267  "call assert_equal({'lnum': 1, 'leftcol': 0, 'col': 0, 'topfill': 0, 'topline': 1, 'coladd': 0, 'skipcol': 0, 'curswant': 0}, winsaveview())
268
269  " clean up
270  set noincsearch
271  call test_override("char_avail", 0)
272  bw!
273endfunc
274
275func Test_use_sub_pat()
276  split
277  let @/ = ''
278  func X()
279    s/^/a/
280    /
281  endfunc
282  call X()
283  bwipe!
284endfunc
285
286func Test_searchpair()
287  new
288  call setline(1, ['other code here', '', '[', '" cursor here', ']'])
289  4
290  let a = searchpair('\[','',']','bW')
291  call assert_equal(3, a)
292  set nomagic
293  4
294  let a = searchpair('\[','',']','bW')
295  call assert_equal(3, a)
296  set magic
297  q!
298endfunc
299
300func Test_searchpair_errors()
301  call assert_fails("call searchpair([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: using List as a String')
302  call assert_fails("call searchpair('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: using Funcref as a String')
303  call assert_fails("call searchpair('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: using Dictionary as a String')
304  call assert_fails("call searchpair('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags')
305  call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 0, 99, 100)", 'E475: Invalid argument: 0')
306  call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99')
307  call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100')
308endfunc
309
310func Test_searchpair_skip()
311    func Zero()
312	return 0
313    endfunc
314    func Partial(x)
315	return a:x
316    endfunc
317    new
318    call setline(1, ['{', 'foo', 'foo', 'foo', '}'])
319    3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', ''))
320    3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', '0'))
321    3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', {-> 0}))
322    3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Zero')))
323    3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Partial', [0])))
324    bw!
325endfunc
326
327func Test_searchc()
328  " These commands used to cause memory overflow in searchc().
329  new
330  norm ixx
331  exe "norm 0t\u93cf"
332  bw!
333endfunc
334
335func Test_search_cmdline3()
336  if !exists('+incsearch')
337    return
338  endif
339  " need to disable char_avail,
340  " so that expansion of commandline works
341  call test_override("char_avail", 1)
342  new
343  call setline(1, ['  1', '  2 the~e', '  3 the theother'])
344  set incsearch
345  1
346  " first match
347  call feedkeys("/the\<c-l>\<cr>", 'tx')
348  call assert_equal('  2 the~e', getline('.'))
349  " clean up
350  set noincsearch
351  call test_override("char_avail", 0)
352  bw!
353endfunc
354
355func Test_search_cmdline4()
356  if !exists('+incsearch')
357    return
358  endif
359  " need to disable char_avail,
360  " so that expansion of commandline works
361  call test_override("char_avail", 1)
362  new
363  call setline(1, ['  1 the first', '  2 the second', '  3 the third'])
364  set incsearch
365  $
366  call feedkeys("?the\<c-g>\<cr>", 'tx')
367  call assert_equal('  3 the third', getline('.'))
368  $
369  call feedkeys("?the\<c-g>\<c-g>\<cr>", 'tx')
370  call assert_equal('  1 the first', getline('.'))
371  $
372  call feedkeys("?the\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
373  call assert_equal('  2 the second', getline('.'))
374  $
375  call feedkeys("?the\<c-t>\<cr>", 'tx')
376  call assert_equal('  1 the first', getline('.'))
377  $
378  call feedkeys("?the\<c-t>\<c-t>\<cr>", 'tx')
379  call assert_equal('  3 the third', getline('.'))
380  $
381  call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
382  call assert_equal('  2 the second', getline('.'))
383  " clean up
384  set noincsearch
385  call test_override("char_avail", 0)
386  bw!
387endfunc
388
389func Test_search_cmdline5()
390  if !exists('+incsearch')
391    return
392  endif
393  " Do not call test_override("char_avail", 1) so that <C-g> and <C-t> work
394  " regardless char_avail.
395  new
396  call setline(1, ['  1 the first', '  2 the second', '  3 the third'])
397  set incsearch
398  1
399  call feedkeys("/the\<c-g>\<c-g>\<cr>", 'tx')
400  call assert_equal('  3 the third', getline('.'))
401  $
402  call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
403  call assert_equal('  2 the second', getline('.'))
404  " clean up
405  set noincsearch
406  bw!
407endfunc
408
409func Test_search_cmdline6()
410  " Test that consecutive matches
411  " are caught by <c-g>/<c-t>
412  if !exists('+incsearch')
413    return
414  endif
415  " need to disable char_avail,
416  " so that expansion of commandline works
417  call test_override("char_avail", 1)
418  new
419  call setline(1, [' bbvimb', ''])
420  set incsearch
421  " first match
422  norm! gg0
423  call feedkeys("/b\<cr>", 'tx')
424  call assert_equal([0,1,2,0], getpos('.'))
425  " second match
426  norm! gg0
427  call feedkeys("/b\<c-g>\<cr>", 'tx')
428  call assert_equal([0,1,3,0], getpos('.'))
429  " third match
430  norm! gg0
431  call feedkeys("/b\<c-g>\<c-g>\<cr>", 'tx')
432  call assert_equal([0,1,7,0], getpos('.'))
433  " first match again
434  norm! gg0
435  call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
436  call assert_equal([0,1,2,0], getpos('.'))
437  set nowrapscan
438  " last match
439  norm! gg0
440  call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
441  call assert_equal([0,1,7,0], getpos('.'))
442  " clean up
443  set wrapscan&vim
444  set noincsearch
445  call test_override("char_avail", 0)
446  bw!
447endfunc
448
449func Test_search_cmdline7()
450  " Test that an pressing <c-g> in an empty command line
451  " does not move the cursor
452  if !exists('+incsearch')
453    return
454  endif
455  " need to disable char_avail,
456  " so that expansion of commandline works
457  call test_override("char_avail", 1)
458  new
459  let @/='b'
460  call setline(1, [' bbvimb', ''])
461  set incsearch
462  " first match
463  norm! gg0
464  " moves to next match of previous search pattern, just like /<cr>
465  call feedkeys("/\<c-g>\<cr>", 'tx')
466  call assert_equal([0,1,2,0], getpos('.'))
467  " moves to next match of previous search pattern, just like /<cr>
468  call feedkeys("/\<cr>", 'tx')
469  call assert_equal([0,1,3,0], getpos('.'))
470  " moves to next match of previous search pattern, just like /<cr>
471  call feedkeys("/\<c-t>\<cr>", 'tx')
472  call assert_equal([0,1,7,0], getpos('.'))
473
474  " using an offset uses the last search pattern
475  call cursor(1, 1)
476  call setline(1, ['1 bbvimb', ' 2 bbvimb'])
477  let @/ = 'b'
478  call feedkeys("//e\<c-g>\<cr>", 'tx')
479  call assert_equal('1 bbvimb', getline('.'))
480  call assert_equal(4, col('.'))
481
482  set noincsearch
483  call test_override("char_avail", 0)
484  bw!
485endfunc
486
487func Test_search_cmdline8()
488  " Highlighting is cleared in all windows
489  " since hls applies to all windows
490  if !exists('+incsearch') || !has('terminal') || has('gui_running') || winwidth(0) < 30
491    return
492  endif
493  if has("win32")
494    throw "Skipped: Bug with sending <ESC> to terminal window not fixed yet"
495  endif
496  let h = winheight(0)
497  if h < 3
498    return
499  endif
500  " Prepare buffer text
501  let lines = ['abb vim vim vi', 'vimvivim']
502  call writefile(lines, 'Xsearch.txt')
503  let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
504
505  call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])})
506
507  call term_sendkeys(buf, ":set incsearch hlsearch\<cr>")
508  call term_sendkeys(buf, ":14vsp\<cr>")
509  call term_sendkeys(buf, "/vim\<cr>")
510  call term_sendkeys(buf, "/b\<esc>")
511  call term_sendkeys(buf, "gg0")
512  call term_wait(buf, 500)
513  let screen_line = term_scrape(buf, 1)
514  let [a0,a1,a2,a3] = [screen_line[3].attr, screen_line[4].attr,
515        \ screen_line[18].attr, screen_line[19].attr]
516  call assert_notequal(a0, a1)
517  call assert_notequal(a0, a3)
518  call assert_notequal(a1, a2)
519  call assert_equal(a0, a2)
520  call assert_equal(a1, a3)
521  " clean up
522  call delete('Xsearch.txt')
523
524  bwipe!
525endfunc
526
527" Tests for regexp with various magic settings
528func Test_search_regexp()
529  enew!
530
531  put ='1 a aa abb abbccc'
532  exe 'normal! /a*b\{2}c\+/e' . "\<CR>"
533  call assert_equal([0, 2, 17, 0], getpos('.'))
534
535  put ='2 d dd dee deefff'
536  exe 'normal! /\Md\*e\{2}f\+/e' . "\<CR>"
537  call assert_equal([0, 3, 17, 0], getpos('.'))
538
539  set nomagic
540  put ='3 g gg ghh ghhiii'
541  exe 'normal! /g\*h\{2}i\+/e' . "\<CR>"
542  call assert_equal([0, 4, 17, 0], getpos('.'))
543
544  put ='4 j jj jkk jkklll'
545  exe 'normal! /\mj*k\{2}l\+/e' . "\<CR>"
546  call assert_equal([0, 5, 17, 0], getpos('.'))
547
548  put ='5 m mm mnn mnnooo'
549  exe 'normal! /\vm*n{2}o+/e' . "\<CR>"
550  call assert_equal([0, 6, 17, 0], getpos('.'))
551
552  put ='6 x ^aa$ x'
553  exe 'normal! /\V^aa$' . "\<CR>"
554  call assert_equal([0, 7, 5, 0], getpos('.'))
555
556  set magic
557  put ='7 (a)(b) abbaa'
558  exe 'normal! /\v(a)(b)\2\1\1/e' . "\<CR>"
559  call assert_equal([0, 8, 14, 0], getpos('.'))
560
561  put ='8 axx [ab]xx'
562  exe 'normal! /\V[ab]\(\[xy]\)\1' . "\<CR>"
563  call assert_equal([0, 9, 7, 0], getpos('.'))
564
565  set undolevels=100
566  put ='9 foobar'
567  put =''
568  exe "normal! a\<C-G>u\<Esc>"
569  normal G
570  exe 'normal! dv?bar?' . "\<CR>"
571  call assert_equal('9 foo', getline('.'))
572  call assert_equal([0, 10, 5, 0], getpos('.'))
573  call assert_equal(10, line('$'))
574  normal u
575  call assert_equal('9 foobar', getline('.'))
576  call assert_equal([0, 10, 6, 0], getpos('.'))
577  call assert_equal(11, line('$'))
578
579  set undolevels&
580  enew!
581endfunc
582
583func Test_search_cmdline_incsearch_highlight()
584  if !exists('+incsearch')
585    return
586  endif
587  set incsearch hlsearch
588  " need to disable char_avail,
589  " so that expansion of commandline works
590  call test_override("char_avail", 1)
591  new
592  call setline(1, ['aaa  1 the first', '  2 the second', '  3 the third'])
593
594  1
595  call feedkeys("/second\<cr>", 'tx')
596  call assert_equal('second', @/)
597  call assert_equal('  2 the second', getline('.'))
598
599  " Canceling search won't change @/
600  1
601  let @/ = 'last pattern'
602  call feedkeys("/third\<C-c>", 'tx')
603  call assert_equal('last pattern', @/)
604  call feedkeys("/third\<Esc>", 'tx')
605  call assert_equal('last pattern', @/)
606  call feedkeys("/3\<bs>\<bs>", 'tx')
607  call assert_equal('last pattern', @/)
608  call feedkeys("/third\<c-g>\<c-t>\<Esc>", 'tx')
609  call assert_equal('last pattern', @/)
610
611  " clean up
612  set noincsearch nohlsearch
613  bw!
614endfunc
615
616func Test_search_cmdline_incsearch_highlight_attr()
617  if !exists('+incsearch') || !has('terminal') || has('gui_running')
618    return
619  endif
620  let h = winheight(0)
621  if h < 3
622    return
623  endif
624
625  " Prepare buffer text
626  let lines = ['abb vim vim vi', 'vimvivim']
627  call writefile(lines, 'Xsearch.txt')
628  let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
629
630  call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])})
631  " wait for vim to complete initialization
632  call term_wait(buf)
633
634  " Get attr of normal(a0), incsearch(a1), hlsearch(a2) highlight
635  call term_sendkeys(buf, ":set incsearch hlsearch\<cr>")
636  call term_sendkeys(buf, '/b')
637  call term_wait(buf, 200)
638  let screen_line1 = term_scrape(buf, 1)
639  call assert_true(len(screen_line1) > 2)
640  " a0: attr_normal
641  let a0 = screen_line1[0].attr
642  " a1: attr_incsearch
643  let a1 = screen_line1[1].attr
644  " a2: attr_hlsearch
645  let a2 = screen_line1[2].attr
646  call assert_notequal(a0, a1)
647  call assert_notequal(a0, a2)
648  call assert_notequal(a1, a2)
649  call term_sendkeys(buf, "\<cr>gg0")
650
651  " Test incremental highlight search
652  call term_sendkeys(buf, "/vim")
653  call term_wait(buf, 200)
654  " Buffer:
655  " abb vim vim vi
656  " vimvivim
657  " Search: /vim
658  let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a2,a2,a2,a0,a0,a0]
659  let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
660  call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
661  call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
662
663  " Test <C-g>
664  call term_sendkeys(buf, "\<C-g>\<C-g>")
665  call term_wait(buf, 200)
666  let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
667  let attr_line2 = [a1,a1,a1,a0,a0,a2,a2,a2]
668  call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
669  call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
670
671  " Test <C-t>
672  call term_sendkeys(buf, "\<C-t>")
673  call term_wait(buf, 200)
674  let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a1,a1,a1,a0,a0,a0]
675  let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
676  call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
677  call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
678
679  " Type Enter and a1(incsearch highlight) should become a2(hlsearch highlight)
680  call term_sendkeys(buf, "\<cr>")
681  call term_wait(buf, 200)
682  let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
683  let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
684  call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
685  call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
686
687  " Test nohlsearch. a2(hlsearch highlight) should become a0(normal highlight)
688  call term_sendkeys(buf, ":1\<cr>")
689  call term_sendkeys(buf, ":set nohlsearch\<cr>")
690  call term_sendkeys(buf, "/vim")
691  call term_wait(buf, 200)
692  let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a0,a0,a0,a0,a0,a0]
693  let attr_line2 = [a0,a0,a0,a0,a0,a0,a0,a0]
694  call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
695  call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
696  call delete('Xsearch.txt')
697
698  call delete('Xsearch.txt')
699  bwipe!
700endfunc
701
702func Test_incsearch_scrolling()
703  if !CanRunVimInTerminal()
704    return
705  endif
706  call assert_equal(0, &scrolloff)
707  call writefile([
708	\ 'let dots = repeat(".", 120)',
709	\ 'set incsearch cmdheight=2 scrolloff=0',
710	\ 'call setline(1, [dots, dots, dots, "", "target", dots, dots])',
711	\ 'normal gg',
712	\ 'redraw',
713	\ ], 'Xscript')
714  let buf = RunVimInTerminal('-S Xscript', {'rows': 9, 'cols': 70})
715  " Need to send one key at a time to force a redraw
716  call term_sendkeys(buf, '/')
717  sleep 100m
718  call term_sendkeys(buf, 't')
719  sleep 100m
720  call term_sendkeys(buf, 'a')
721  sleep 100m
722  call term_sendkeys(buf, 'r')
723  sleep 100m
724  call term_sendkeys(buf, 'g')
725  call VerifyScreenDump(buf, 'Test_incsearch_scrolling_01', {})
726
727  call term_sendkeys(buf, "\<Esc>")
728  call StopVimInTerminal(buf)
729  call delete('Xscript')
730endfunc
731
732func Test_search_undefined_behaviour()
733  if !has("terminal")
734    return
735  endif
736  let h = winheight(0)
737  if h < 3
738    return
739  endif
740  " did cause an undefined left shift
741  let g:buf = term_start([GetVimProg(), '--clean', '-e', '-s', '-c', 'call search(getline("."))', 'samples/test000'], {'term_rows': 3})
742  call assert_equal([''], getline(1, '$'))
743  call term_sendkeys(g:buf, ":qa!\<cr>")
744  bwipe!
745endfunc
746
747func Test_search_undefined_behaviour2()
748  call search("\%UC0000000")
749endfunc
750
751" Test for search('multi-byte char', 'bce')
752func Test_search_multibyte()
753  if !has('multi_byte')
754    return
755  endif
756  let save_enc = &encoding
757  set encoding=utf8
758  enew!
759  call append('$', 'A')
760  call cursor(2, 1)
761  call assert_equal(2, search('A', 'bce', line('.')))
762  enew!
763  let &encoding = save_enc
764endfunc
765
766" This was causing E874.  Also causes an invalid read?
767func Test_look_behind()
768  new
769  call setline(1, '0\|\&\n\@<=')
770  call search(getline("."))
771  bwipe!
772endfunc
773
774func Test_search_sentence()
775  new
776  " this used to cause a crash
777  call assert_fails("/\\%')", 'E486')
778  call assert_fails("/", 'E486')
779  /\%'(
780  /
781endfunc
782