xref: /vim-8.2.3635/src/testdir/test_search.vim (revision fcfe1a9b)
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  1
244  " go to previous match (on line 2)
245  call feedkeys("/the\<C-G>\<C-R>\<C-W>\<cr>", 'tx')
246  call assert_equal('theother', @/)
247
248  " Test 2: keep the view,
249  " after deleting a character from the search cmd
250  call setline(1, ['  1', '  2 these', '  3 the', '  4 their', '  5 there', '  6 their', '  7 the', '  8 them', '  9 these', ' 10 foobar'])
251  resize 5
252  1
253  call feedkeys("/foo\<bs>\<cr>", 'tx')
254  redraw
255  call assert_equal({'lnum': 10, 'leftcol': 0, 'col': 4, 'topfill': 0, 'topline': 6, 'coladd': 0, 'skipcol': 0, 'curswant': 4}, winsaveview())
256
257  " remove all history entries
258  for i in range(11)
259      call histdel('/')
260  endfor
261
262  " Test 3: reset the view,
263  " after deleting all characters from the search cmd
264  norm! 1gg0
265  " unfortunately, neither "/foo\<c-w>\<cr>", nor "/foo\<bs>\<bs>\<bs>\<cr>",
266  " nor "/foo\<c-u>\<cr>" works to delete the commandline.
267  " In that case Vim should return "E35 no previous regular expression",
268  " but it looks like Vim still sees /foo and therefore the test fails.
269  " Therefore, disableing this test
270  "call assert_fails(feedkeys("/foo\<c-w>\<cr>", 'tx'), 'E35')
271  "call assert_equal({'lnum': 1, 'leftcol': 0, 'col': 0, 'topfill': 0, 'topline': 1, 'coladd': 0, 'skipcol': 0, 'curswant': 0}, winsaveview())
272
273  " clean up
274  set noincsearch
275  call test_override("char_avail", 0)
276  bw!
277endfunc
278
279func Test_use_sub_pat()
280  split
281  let @/ = ''
282  func X()
283    s/^/a/
284    /
285  endfunc
286  call X()
287  bwipe!
288endfunc
289
290func Test_searchpair()
291  new
292  call setline(1, ['other code here', '', '[', '" cursor here', ']'])
293  4
294  let a = searchpair('\[','',']','bW')
295  call assert_equal(3, a)
296  set nomagic
297  4
298  let a = searchpair('\[','',']','bW')
299  call assert_equal(3, a)
300  set magic
301  q!
302endfunc
303
304func Test_searchpair_errors()
305  call assert_fails("call searchpair([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: using List as a String')
306  call assert_fails("call searchpair('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: using Funcref as a String')
307  call assert_fails("call searchpair('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: using Dictionary as a String')
308  call assert_fails("call searchpair('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags')
309  call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 0, 99, 100)", 'E475: Invalid argument: 0')
310  call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99')
311  call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100')
312endfunc
313
314func Test_searchpair_skip()
315    func Zero()
316	return 0
317    endfunc
318    func Partial(x)
319	return a:x
320    endfunc
321    new
322    call setline(1, ['{', 'foo', 'foo', 'foo', '}'])
323    3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', ''))
324    3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', '0'))
325    3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', {-> 0}))
326    3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Zero')))
327    3 | call assert_equal(1, searchpair('{', '', '}', 'bWn', function('Partial', [0])))
328    bw!
329endfunc
330
331func Test_searchpair_leak()
332  new
333  call setline(1, 'if one else another endif')
334
335  " The error in the skip expression caused memory to leak.
336  call assert_fails("call searchpair('\\<if\\>', '\\<else\\>', '\\<endif\\>', '', '\"foo\" 2')", 'E15:')
337
338  bwipe!
339endfunc
340
341func Test_searchc()
342  " These commands used to cause memory overflow in searchc().
343  new
344  norm ixx
345  exe "norm 0t\u93cf"
346  bw!
347endfunc
348
349func Cmdline3_prep()
350  " need to disable char_avail,
351  " so that expansion of commandline works
352  call test_override("char_avail", 1)
353  new
354  call setline(1, ['  1', '  2 the~e', '  3 the theother'])
355  set incsearch
356endfunc
357
358func Incsearch_cleanup()
359  set noincsearch
360  call test_override("char_avail", 0)
361  bw!
362endfunc
363
364func Test_search_cmdline3()
365  if !exists('+incsearch')
366    return
367  endif
368  call Cmdline3_prep()
369  1
370  " first match
371  call feedkeys("/the\<c-l>\<cr>", 'tx')
372  call assert_equal('  2 the~e', getline('.'))
373
374  call Incsearch_cleanup()
375endfunc
376
377func Test_search_cmdline3s()
378  if !exists('+incsearch')
379    return
380  endif
381  call Cmdline3_prep()
382  1
383  call feedkeys(":%s/the\<c-l>/xxx\<cr>", 'tx')
384  call assert_equal('  2 xxxe', getline('.'))
385  undo
386  call feedkeys(":%subs/the\<c-l>/xxx\<cr>", 'tx')
387  call assert_equal('  2 xxxe', getline('.'))
388  undo
389  call feedkeys(":%substitute/the\<c-l>/xxx\<cr>", 'tx')
390  call assert_equal('  2 xxxe', getline('.'))
391  undo
392  call feedkeys(":%smagic/the.e/xxx\<cr>", 'tx')
393  call assert_equal('  2 xxx', getline('.'))
394  undo
395  call assert_fails(":%snomagic/the.e/xxx\<cr>", 'E486')
396  "
397  call feedkeys(":%snomagic/the\\.e/xxx\<cr>", 'tx')
398  call assert_equal('  2 xxx', getline('.'))
399
400  call Incsearch_cleanup()
401endfunc
402
403func Test_search_cmdline3g()
404  if !exists('+incsearch')
405    return
406  endif
407  call Cmdline3_prep()
408  1
409  call feedkeys(":g/the\<c-l>/d\<cr>", 'tx')
410  call assert_equal('  3 the theother', getline(2))
411  undo
412  call feedkeys(":global/the\<c-l>/d\<cr>", 'tx')
413  call assert_equal('  3 the theother', getline(2))
414  undo
415  call feedkeys(":g!/the\<c-l>/d\<cr>", 'tx')
416  call assert_equal(1, line('$'))
417  call assert_equal('  2 the~e', getline(1))
418  undo
419  call feedkeys(":global!/the\<c-l>/d\<cr>", 'tx')
420  call assert_equal(1, line('$'))
421  call assert_equal('  2 the~e', getline(1))
422
423  call Incsearch_cleanup()
424endfunc
425
426func Test_search_cmdline3v()
427  if !exists('+incsearch')
428    return
429  endif
430  call Cmdline3_prep()
431  1
432  call feedkeys(":v/the\<c-l>/d\<cr>", 'tx')
433  call assert_equal(1, line('$'))
434  call assert_equal('  2 the~e', getline(1))
435  undo
436  call feedkeys(":vglobal/the\<c-l>/d\<cr>", 'tx')
437  call assert_equal(1, line('$'))
438  call assert_equal('  2 the~e', getline(1))
439
440  call Incsearch_cleanup()
441endfunc
442
443func Test_search_cmdline4()
444  if !exists('+incsearch')
445    return
446  endif
447  " need to disable char_avail,
448  " so that expansion of commandline works
449  call test_override("char_avail", 1)
450  new
451  call setline(1, ['  1 the first', '  2 the second', '  3 the third'])
452  set incsearch
453  $
454  call feedkeys("?the\<c-g>\<cr>", 'tx')
455  call assert_equal('  3 the third', getline('.'))
456  $
457  call feedkeys("?the\<c-g>\<c-g>\<cr>", 'tx')
458  call assert_equal('  1 the first', getline('.'))
459  $
460  call feedkeys("?the\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
461  call assert_equal('  2 the second', getline('.'))
462  $
463  call feedkeys("?the\<c-t>\<cr>", 'tx')
464  call assert_equal('  1 the first', getline('.'))
465  $
466  call feedkeys("?the\<c-t>\<c-t>\<cr>", 'tx')
467  call assert_equal('  3 the third', getline('.'))
468  $
469  call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
470  call assert_equal('  2 the second', getline('.'))
471  " clean up
472  set noincsearch
473  call test_override("char_avail", 0)
474  bw!
475endfunc
476
477func Test_search_cmdline5()
478  if !exists('+incsearch')
479    return
480  endif
481  " Do not call test_override("char_avail", 1) so that <C-g> and <C-t> work
482  " regardless char_avail.
483  new
484  call setline(1, ['  1 the first', '  2 the second', '  3 the third', ''])
485  set incsearch
486  1
487  call feedkeys("/the\<c-g>\<c-g>\<cr>", 'tx')
488  call assert_equal('  3 the third', getline('.'))
489  $
490  call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
491  call assert_equal('  1 the first', getline('.'))
492  " clean up
493  set noincsearch
494  bw!
495endfunc
496
497func Test_search_cmdline6()
498  " Test that consecutive matches
499  " are caught by <c-g>/<c-t>
500  if !exists('+incsearch')
501    return
502  endif
503  " need to disable char_avail,
504  " so that expansion of commandline works
505  call test_override("char_avail", 1)
506  new
507  call setline(1, [' bbvimb', ''])
508  set incsearch
509  " first match
510  norm! gg0
511  call feedkeys("/b\<cr>", 'tx')
512  call assert_equal([0,1,2,0], getpos('.'))
513  " second match
514  norm! gg0
515  call feedkeys("/b\<c-g>\<cr>", 'tx')
516  call assert_equal([0,1,3,0], getpos('.'))
517  " third match
518  norm! gg0
519  call feedkeys("/b\<c-g>\<c-g>\<cr>", 'tx')
520  call assert_equal([0,1,7,0], getpos('.'))
521  " first match again
522  norm! gg0
523  call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
524  call assert_equal([0,1,2,0], getpos('.'))
525  set nowrapscan
526  " last match
527  norm! gg0
528  call feedkeys("/b\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
529  call assert_equal([0,1,7,0], getpos('.'))
530  " clean up
531  set wrapscan&vim
532  set noincsearch
533  call test_override("char_avail", 0)
534  bw!
535endfunc
536
537func Test_search_cmdline7()
538  " Test that an pressing <c-g> in an empty command line
539  " does not move the cursor
540  if !exists('+incsearch')
541    return
542  endif
543  " need to disable char_avail,
544  " so that expansion of commandline works
545  call test_override("char_avail", 1)
546  new
547  let @/ = 'b'
548  call setline(1, [' bbvimb', ''])
549  set incsearch
550  " first match
551  norm! gg0
552  " moves to next match of previous search pattern, just like /<cr>
553  call feedkeys("/\<c-g>\<cr>", 'tx')
554  call assert_equal([0,1,2,0], getpos('.'))
555  " moves to next match of previous search pattern, just like /<cr>
556  call feedkeys("/\<cr>", 'tx')
557  call assert_equal([0,1,3,0], getpos('.'))
558  " moves to next match of previous search pattern, just like /<cr>
559  call feedkeys("/\<c-t>\<cr>", 'tx')
560  call assert_equal([0,1,7,0], getpos('.'))
561
562  " using an offset uses the last search pattern
563  call cursor(1, 1)
564  call setline(1, ['1 bbvimb', ' 2 bbvimb'])
565  let @/ = 'b'
566  call feedkeys("//e\<c-g>\<cr>", 'tx')
567  call assert_equal('1 bbvimb', getline('.'))
568  call assert_equal(4, col('.'))
569
570  set noincsearch
571  call test_override("char_avail", 0)
572  bw!
573endfunc
574
575func Test_search_cmdline8()
576  " Highlighting is cleared in all windows
577  " since hls applies to all windows
578  if !exists('+incsearch') || !has('terminal') || has('gui_running') || winwidth(0) < 30
579    return
580  endif
581  if has("win32")
582    throw "Skipped: Bug with sending <ESC> to terminal window not fixed yet"
583  endif
584  let h = winheight(0)
585  if h < 3
586    return
587  endif
588  " Prepare buffer text
589  let lines = ['abb vim vim vi', 'vimvivim']
590  call writefile(lines, 'Xsearch.txt')
591  let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
592
593  call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])})
594
595  call term_sendkeys(buf, ":set incsearch hlsearch\<cr>")
596  call term_sendkeys(buf, ":14vsp\<cr>")
597  call term_sendkeys(buf, "/vim\<cr>")
598  call term_sendkeys(buf, "/b\<esc>")
599  call term_sendkeys(buf, "gg0")
600  call term_wait(buf, 500)
601  let screen_line = term_scrape(buf, 1)
602  let [a0,a1,a2,a3] = [screen_line[3].attr, screen_line[4].attr,
603        \ screen_line[18].attr, screen_line[19].attr]
604  call assert_notequal(a0, a1)
605  call assert_notequal(a0, a3)
606  call assert_notequal(a1, a2)
607  call assert_equal(a0, a2)
608  call assert_equal(a1, a3)
609  " clean up
610  call delete('Xsearch.txt')
611
612  bwipe!
613endfunc
614
615" Tests for regexp with various magic settings
616func Test_search_regexp()
617  enew!
618
619  put ='1 a aa abb abbccc'
620  exe 'normal! /a*b\{2}c\+/e' . "\<CR>"
621  call assert_equal([0, 2, 17, 0], getpos('.'))
622
623  put ='2 d dd dee deefff'
624  exe 'normal! /\Md\*e\{2}f\+/e' . "\<CR>"
625  call assert_equal([0, 3, 17, 0], getpos('.'))
626
627  set nomagic
628  put ='3 g gg ghh ghhiii'
629  exe 'normal! /g\*h\{2}i\+/e' . "\<CR>"
630  call assert_equal([0, 4, 17, 0], getpos('.'))
631
632  put ='4 j jj jkk jkklll'
633  exe 'normal! /\mj*k\{2}l\+/e' . "\<CR>"
634  call assert_equal([0, 5, 17, 0], getpos('.'))
635
636  put ='5 m mm mnn mnnooo'
637  exe 'normal! /\vm*n{2}o+/e' . "\<CR>"
638  call assert_equal([0, 6, 17, 0], getpos('.'))
639
640  put ='6 x ^aa$ x'
641  exe 'normal! /\V^aa$' . "\<CR>"
642  call assert_equal([0, 7, 5, 0], getpos('.'))
643
644  set magic
645  put ='7 (a)(b) abbaa'
646  exe 'normal! /\v(a)(b)\2\1\1/e' . "\<CR>"
647  call assert_equal([0, 8, 14, 0], getpos('.'))
648
649  put ='8 axx [ab]xx'
650  exe 'normal! /\V[ab]\(\[xy]\)\1' . "\<CR>"
651  call assert_equal([0, 9, 7, 0], getpos('.'))
652
653  set undolevels=100
654  put ='9 foobar'
655  put =''
656  exe "normal! a\<C-G>u\<Esc>"
657  normal G
658  exe 'normal! dv?bar?' . "\<CR>"
659  call assert_equal('9 foo', getline('.'))
660  call assert_equal([0, 10, 5, 0], getpos('.'))
661  call assert_equal(10, line('$'))
662  normal u
663  call assert_equal('9 foobar', getline('.'))
664  call assert_equal([0, 10, 6, 0], getpos('.'))
665  call assert_equal(11, line('$'))
666
667  set undolevels&
668  enew!
669endfunc
670
671func Test_search_cmdline_incsearch_highlight()
672  if !exists('+incsearch')
673    return
674  endif
675  set incsearch hlsearch
676  " need to disable char_avail,
677  " so that expansion of commandline works
678  call test_override("char_avail", 1)
679  new
680  call setline(1, ['aaa  1 the first', '  2 the second', '  3 the third'])
681
682  1
683  call feedkeys("/second\<cr>", 'tx')
684  call assert_equal('second', @/)
685  call assert_equal('  2 the second', getline('.'))
686
687  " Canceling search won't change @/
688  1
689  let @/ = 'last pattern'
690  call feedkeys("/third\<C-c>", 'tx')
691  call assert_equal('last pattern', @/)
692  call feedkeys("/third\<Esc>", 'tx')
693  call assert_equal('last pattern', @/)
694  call feedkeys("/3\<bs>\<bs>", 'tx')
695  call assert_equal('last pattern', @/)
696  call feedkeys("/third\<c-g>\<c-t>\<Esc>", 'tx')
697  call assert_equal('last pattern', @/)
698
699  " clean up
700  set noincsearch nohlsearch
701  bw!
702endfunc
703
704func Test_search_cmdline_incsearch_highlight_attr()
705  if !exists('+incsearch') || !has('terminal') || has('gui_running')
706    return
707  endif
708  let h = winheight(0)
709  if h < 3
710    return
711  endif
712
713  " Prepare buffer text
714  let lines = ['abb vim vim vi', 'vimvivim']
715  call writefile(lines, 'Xsearch.txt')
716  let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile', 'Xsearch.txt'], {'term_rows': 3})
717
718  call WaitForAssert({-> assert_equal(lines, [term_getline(buf, 1), term_getline(buf, 2)])})
719  " wait for vim to complete initialization
720  call term_wait(buf)
721
722  " Get attr of normal(a0), incsearch(a1), hlsearch(a2) highlight
723  call term_sendkeys(buf, ":set incsearch hlsearch\<cr>")
724  call term_sendkeys(buf, '/b')
725  call term_wait(buf, 200)
726  let screen_line1 = term_scrape(buf, 1)
727  call assert_true(len(screen_line1) > 2)
728  " a0: attr_normal
729  let a0 = screen_line1[0].attr
730  " a1: attr_incsearch
731  let a1 = screen_line1[1].attr
732  " a2: attr_hlsearch
733  let a2 = screen_line1[2].attr
734  call assert_notequal(a0, a1)
735  call assert_notequal(a0, a2)
736  call assert_notequal(a1, a2)
737  call term_sendkeys(buf, "\<cr>gg0")
738
739  " Test incremental highlight search
740  call term_sendkeys(buf, "/vim")
741  call term_wait(buf, 200)
742  " Buffer:
743  " abb vim vim vi
744  " vimvivim
745  " Search: /vim
746  let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a2,a2,a2,a0,a0,a0]
747  let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
748  call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
749  call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
750
751  " Test <C-g>
752  call term_sendkeys(buf, "\<C-g>\<C-g>")
753  call term_wait(buf, 200)
754  let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
755  let attr_line2 = [a1,a1,a1,a0,a0,a2,a2,a2]
756  call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
757  call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
758
759  " Test <C-t>
760  call term_sendkeys(buf, "\<C-t>")
761  call term_wait(buf, 200)
762  let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a1,a1,a1,a0,a0,a0]
763  let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
764  call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
765  call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
766
767  " Type Enter and a1(incsearch highlight) should become a2(hlsearch highlight)
768  call term_sendkeys(buf, "\<cr>")
769  call term_wait(buf, 200)
770  let attr_line1 = [a0,a0,a0,a0,a2,a2,a2,a0,a2,a2,a2,a0,a0,a0]
771  let attr_line2 = [a2,a2,a2,a0,a0,a2,a2,a2]
772  call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
773  call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
774
775  " Test nohlsearch. a2(hlsearch highlight) should become a0(normal highlight)
776  call term_sendkeys(buf, ":1\<cr>")
777  call term_sendkeys(buf, ":set nohlsearch\<cr>")
778  call term_sendkeys(buf, "/vim")
779  call term_wait(buf, 200)
780  let attr_line1 = [a0,a0,a0,a0,a1,a1,a1,a0,a0,a0,a0,a0,a0,a0]
781  let attr_line2 = [a0,a0,a0,a0,a0,a0,a0,a0]
782  call assert_equal(attr_line1, map(term_scrape(buf, 1)[:len(attr_line1)-1], 'v:val.attr'))
783  call assert_equal(attr_line2, map(term_scrape(buf, 2)[:len(attr_line2)-1], 'v:val.attr'))
784  call delete('Xsearch.txt')
785
786  call delete('Xsearch.txt')
787  bwipe!
788endfunc
789
790func Test_incsearch_cmdline_modifier()
791  if !exists('+incsearch')
792    return
793  endif
794  call test_override("char_avail", 1)
795  new
796  call setline(1, ['foo'])
797  set incsearch
798  " Test that error E14 does not occur in parsing command modifier.
799  call feedkeys("V:tab", 'tx')
800
801  call Incsearch_cleanup()
802endfunc
803
804func Test_incsearch_scrolling()
805  if !CanRunVimInTerminal()
806    throw 'Skipped: cannot make screendumps'
807  endif
808  call assert_equal(0, &scrolloff)
809  call writefile([
810	\ 'let dots = repeat(".", 120)',
811	\ 'set incsearch cmdheight=2 scrolloff=0',
812	\ 'call setline(1, [dots, dots, dots, "", "target", dots, dots])',
813	\ 'normal gg',
814	\ 'redraw',
815	\ ], 'Xscript')
816  let buf = RunVimInTerminal('-S Xscript', {'rows': 9, 'cols': 70})
817  " Need to send one key at a time to force a redraw
818  call term_sendkeys(buf, '/')
819  sleep 100m
820  call term_sendkeys(buf, 't')
821  sleep 100m
822  call term_sendkeys(buf, 'a')
823  sleep 100m
824  call term_sendkeys(buf, 'r')
825  sleep 100m
826  call term_sendkeys(buf, 'g')
827  call VerifyScreenDump(buf, 'Test_incsearch_scrolling_01', {})
828
829  call term_sendkeys(buf, "\<Esc>")
830  call StopVimInTerminal(buf)
831  call delete('Xscript')
832endfunc
833
834func Test_incsearch_search_dump()
835  if !exists('+incsearch')
836    return
837  endif
838  if !CanRunVimInTerminal()
839    throw 'Skipped: cannot make screendumps'
840  endif
841  call writefile([
842	\ 'set incsearch hlsearch scrolloff=0',
843	\ 'for n in range(1, 8)',
844	\ '  call setline(n, "foo " . n)',
845	\ 'endfor',
846	\ '3',
847	\ ], 'Xis_search_script')
848  let buf = RunVimInTerminal('-S Xis_search_script', {'rows': 9, 'cols': 70})
849  " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
850  " the 'ambiwidth' check.
851  sleep 100m
852
853  " Need to send one key at a time to force a redraw.
854  call term_sendkeys(buf, '/fo')
855  call VerifyScreenDump(buf, 'Test_incsearch_search_01', {})
856  call term_sendkeys(buf, "\<Esc>")
857  sleep 100m
858
859  call term_sendkeys(buf, '/\v')
860  call VerifyScreenDump(buf, 'Test_incsearch_search_02', {})
861  call term_sendkeys(buf, "\<Esc>")
862
863  call StopVimInTerminal(buf)
864  call delete('Xis_search_script')
865endfunc
866
867func Test_incsearch_substitute()
868  if !exists('+incsearch')
869    return
870  endif
871  call test_override("char_avail", 1)
872  new
873  set incsearch
874  for n in range(1, 10)
875    call setline(n, 'foo ' . n)
876  endfor
877  4
878  call feedkeys(":.,.+2s/foo\<BS>o\<BS>o/xxx\<cr>", 'tx')
879  call assert_equal('foo 3', getline(3))
880  call assert_equal('xxx 4', getline(4))
881  call assert_equal('xxx 5', getline(5))
882  call assert_equal('xxx 6', getline(6))
883  call assert_equal('foo 7', getline(7))
884
885  call Incsearch_cleanup()
886endfunc
887
888" Similar to Test_incsearch_substitute() but with a screendump halfway.
889func Test_incsearch_substitute_dump()
890  if !exists('+incsearch')
891    return
892  endif
893  if !CanRunVimInTerminal()
894    throw 'Skipped: cannot make screendumps'
895  endif
896  call writefile([
897	\ 'set incsearch hlsearch scrolloff=0',
898	\ 'for n in range(1, 10)',
899	\ '  call setline(n, "foo " . n)',
900	\ 'endfor',
901	\ 'call setline(11, "bar 11")',
902	\ '3',
903	\ ], 'Xis_subst_script')
904  let buf = RunVimInTerminal('-S Xis_subst_script', {'rows': 9, 'cols': 70})
905  " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
906  " the 'ambiwidth' check.
907  sleep 100m
908
909  " Need to send one key at a time to force a redraw.
910  " Select three lines at the cursor with typed pattern.
911  call term_sendkeys(buf, ':.,.+2s/')
912  sleep 100m
913  call term_sendkeys(buf, 'f')
914  sleep 100m
915  call term_sendkeys(buf, 'o')
916  sleep 100m
917  call term_sendkeys(buf, 'o')
918  call VerifyScreenDump(buf, 'Test_incsearch_substitute_01', {})
919  call term_sendkeys(buf, "\<Esc>")
920
921  " Select three lines at the cursor using previous pattern.
922  call term_sendkeys(buf, "/foo\<CR>")
923  sleep 100m
924  call term_sendkeys(buf, ':.,.+2s//')
925  call VerifyScreenDump(buf, 'Test_incsearch_substitute_02', {})
926
927  " Deleting last slash should remove the match.
928  call term_sendkeys(buf, "\<BS>")
929  call VerifyScreenDump(buf, 'Test_incsearch_substitute_03', {})
930  call term_sendkeys(buf, "\<Esc>")
931
932  " Reverse range is accepted
933  call term_sendkeys(buf, ':5,2s/foo')
934  call VerifyScreenDump(buf, 'Test_incsearch_substitute_04', {})
935  call term_sendkeys(buf, "\<Esc>")
936
937  " White space after the command is skipped
938  call term_sendkeys(buf, ':2,3sub  /fo')
939  call VerifyScreenDump(buf, 'Test_incsearch_substitute_05', {})
940  call term_sendkeys(buf, "\<Esc>")
941
942  " Command modifiers are skipped
943  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.')
944  call VerifyScreenDump(buf, 'Test_incsearch_substitute_06', {})
945  call term_sendkeys(buf, "\<Esc>")
946
947  " Cursorline highlighting at match
948  call term_sendkeys(buf, ":set cursorline\<CR>")
949  call term_sendkeys(buf, 'G9G')
950  call term_sendkeys(buf, ':9,11s/bar')
951  call VerifyScreenDump(buf, 'Test_incsearch_substitute_07', {})
952  call term_sendkeys(buf, "\<Esc>")
953
954  " Cursorline highlighting at cursor when no match
955  call term_sendkeys(buf, ':9,10s/bar')
956  call VerifyScreenDump(buf, 'Test_incsearch_substitute_08', {})
957  call term_sendkeys(buf, "\<Esc>")
958
959  " Only \v handled as empty pattern, does not move cursor
960  call term_sendkeys(buf, '3G4G')
961  call term_sendkeys(buf, ":nohlsearch\<CR>")
962  call term_sendkeys(buf, ':6,7s/\v')
963  call VerifyScreenDump(buf, 'Test_incsearch_substitute_09', {})
964  call term_sendkeys(buf, "\<Esc>")
965
966  call term_sendkeys(buf, ":set nocursorline\<CR>")
967
968  " All matches are highlighted for 'hlsearch' after the incsearch canceled
969  call term_sendkeys(buf, "1G*")
970  call term_sendkeys(buf, ":2,5s/foo")
971  sleep 100m
972  call term_sendkeys(buf, "\<Esc>")
973  call VerifyScreenDump(buf, 'Test_incsearch_substitute_10', {})
974
975  call term_sendkeys(buf, ":split\<CR>")
976  call term_sendkeys(buf, ":let @/ = 'xyz'\<CR>")
977  call term_sendkeys(buf, ":%s/.")
978  call VerifyScreenDump(buf, 'Test_incsearch_substitute_11', {})
979  call term_sendkeys(buf, "\<BS>")
980  call VerifyScreenDump(buf, 'Test_incsearch_substitute_12', {})
981  call term_sendkeys(buf, "\<Esc>")
982  call VerifyScreenDump(buf, 'Test_incsearch_substitute_13', {})
983
984  call StopVimInTerminal(buf)
985  call delete('Xis_subst_script')
986endfunc
987
988func Test_incsearch_with_change()
989  if !has('timers') || !exists('+incsearch') || !CanRunVimInTerminal()
990    throw 'Skipped: cannot make screendumps and/or timers feature and/or incsearch option missing'
991  endif
992
993  call writefile([
994	\ 'set incsearch hlsearch scrolloff=0',
995	\ 'call setline(1, ["one", "two ------ X", "three"])',
996	\ 'call timer_start(200, { _ -> setline(2, "x")})',
997	\ ], 'Xis_change_script')
998  let buf = RunVimInTerminal('-S Xis_change_script', {'rows': 9, 'cols': 70})
999  " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1000  " the 'ambiwidth' check.
1001  sleep 300m
1002
1003  " Highlight X, it will be deleted by the timer callback.
1004  call term_sendkeys(buf, ':%s/X')
1005  call VerifyScreenDump(buf, 'Test_incsearch_change_01', {})
1006  call term_sendkeys(buf, "\<Esc>")
1007
1008  call StopVimInTerminal(buf)
1009  call delete('Xis_change_script')
1010endfunc
1011
1012" Similar to Test_incsearch_substitute_dump() for :sort
1013func Test_incsearch_sort_dump()
1014  if !exists('+incsearch')
1015    return
1016  endif
1017  if !CanRunVimInTerminal()
1018    throw 'Skipped: cannot make screendumps'
1019  endif
1020  call writefile([
1021	\ 'set incsearch hlsearch scrolloff=0',
1022	\ 'call setline(1, ["another one 2", "that one 3", "the one 1"])',
1023	\ ], 'Xis_sort_script')
1024  let buf = RunVimInTerminal('-S Xis_sort_script', {'rows': 9, 'cols': 70})
1025  " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1026  " the 'ambiwidth' check.
1027  sleep 100m
1028
1029  " Need to send one key at a time to force a redraw.
1030  call term_sendkeys(buf, ':sort ni u /on')
1031  call VerifyScreenDump(buf, 'Test_incsearch_sort_01', {})
1032  call term_sendkeys(buf, "\<Esc>")
1033
1034  call StopVimInTerminal(buf)
1035  call delete('Xis_sort_script')
1036endfunc
1037
1038" Similar to Test_incsearch_substitute_dump() for :vimgrep famiry
1039func Test_incsearch_vimgrep_dump()
1040  if !exists('+incsearch')
1041    return
1042  endif
1043  if !CanRunVimInTerminal()
1044    throw 'Skipped: cannot make screendumps'
1045  endif
1046  call writefile([
1047	\ 'set incsearch hlsearch scrolloff=0',
1048	\ 'call setline(1, ["another one 2", "that one 3", "the one 1"])',
1049	\ ], 'Xis_vimgrep_script')
1050  let buf = RunVimInTerminal('-S Xis_vimgrep_script', {'rows': 9, 'cols': 70})
1051  " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
1052  " the 'ambiwidth' check.
1053  sleep 100m
1054
1055  " Need to send one key at a time to force a redraw.
1056  call term_sendkeys(buf, ':vimgrep on')
1057  call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_01', {})
1058  call term_sendkeys(buf, "\<Esc>")
1059
1060  call term_sendkeys(buf, ':vimg /on/ *.txt')
1061  call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_02', {})
1062  call term_sendkeys(buf, "\<Esc>")
1063
1064  call term_sendkeys(buf, ':vimgrepadd "\<on')
1065  call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_03', {})
1066  call term_sendkeys(buf, "\<Esc>")
1067
1068  call term_sendkeys(buf, ':lv "tha')
1069  call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_04', {})
1070  call term_sendkeys(buf, "\<Esc>")
1071
1072  call term_sendkeys(buf, ':lvimgrepa "the" **/*.txt')
1073  call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_05', {})
1074  call term_sendkeys(buf, "\<Esc>")
1075
1076  call StopVimInTerminal(buf)
1077  call delete('Xis_vimgrep_script')
1078endfunc
1079
1080func Test_keep_last_search_pattern()
1081  if !exists('+incsearch')
1082    return
1083  endif
1084  new
1085  call setline(1, ['foo', 'foo', 'foo'])
1086  set incsearch
1087  call test_override("char_avail", 1)
1088  let @/ = 'bar'
1089  call feedkeys(":/foo/s//\<Esc>", 'ntx')
1090  call assert_equal('bar', @/)
1091
1092  " no error message if pattern not found
1093  call feedkeys(":/xyz/s//\<Esc>", 'ntx')
1094  call assert_equal('bar', @/)
1095
1096  bwipe!
1097  call test_override("ALL", 0)
1098  set noincsearch
1099endfunc
1100
1101func Test_word_under_cursor_after_match()
1102  if !exists('+incsearch')
1103    return
1104  endif
1105  new
1106  call setline(1, 'foo bar')
1107  set incsearch
1108  call test_override("char_avail", 1)
1109  try
1110    call feedkeys("/foo\<C-R>\<C-W>\<CR>", 'ntx')
1111  catch /E486:/
1112  endtry
1113  call assert_equal('foobar', @/)
1114
1115  bwipe!
1116  call test_override("ALL", 0)
1117  set noincsearch
1118endfunc
1119
1120func Test_subst_word_under_cursor()
1121  if !exists('+incsearch')
1122    return
1123  endif
1124  new
1125  call setline(1, ['int SomeLongName;', 'for (xxx = 1; xxx < len; ++xxx)'])
1126  set incsearch
1127  call test_override("char_avail", 1)
1128  call feedkeys("/LongName\<CR>", 'ntx')
1129  call feedkeys(":%s/xxx/\<C-R>\<C-W>/g\<CR>", 'ntx')
1130  call assert_equal('for (SomeLongName = 1; SomeLongName < len; ++SomeLongName)', getline(2))
1131
1132  bwipe!
1133  call test_override("ALL", 0)
1134  set noincsearch
1135endfunc
1136
1137func Test_search_undefined_behaviour()
1138  if !has("terminal")
1139    return
1140  endif
1141  let h = winheight(0)
1142  if h < 3
1143    return
1144  endif
1145  " did cause an undefined left shift
1146  let g:buf = term_start([GetVimProg(), '--clean', '-e', '-s', '-c', 'call search(getline("."))', 'samples/test000'], {'term_rows': 3})
1147  call assert_equal([''], getline(1, '$'))
1148  call term_sendkeys(g:buf, ":qa!\<cr>")
1149  bwipe!
1150endfunc
1151
1152func Test_search_undefined_behaviour2()
1153  call search("\%UC0000000")
1154endfunc
1155
1156" Test for search('multi-byte char', 'bce')
1157func Test_search_multibyte()
1158  let save_enc = &encoding
1159  set encoding=utf8
1160  enew!
1161  call append('$', 'A')
1162  call cursor(2, 1)
1163  call assert_equal(2, search('A', 'bce', line('.')))
1164  enew!
1165  let &encoding = save_enc
1166endfunc
1167
1168" This was causing E874.  Also causes an invalid read?
1169func Test_look_behind()
1170  new
1171  call setline(1, '0\|\&\n\@<=')
1172  call search(getline("."))
1173  bwipe!
1174endfunc
1175
1176func Test_search_sentence()
1177  new
1178  " this used to cause a crash
1179  call assert_fails("/\\%')", 'E486')
1180  call assert_fails("/", 'E486')
1181  /\%'(
1182  /
1183endfunc
1184
1185" Test that there is no crash when there is a last search pattern but no last
1186" substitute pattern.
1187func Test_no_last_substitute_pat()
1188  " Use viminfo to set the last search pattern to a string and make the last
1189  " substitute pattern the most recent used and make it empty (NULL).
1190  call writefile(['~MSle0/bar', '~MSle0~&'], 'Xviminfo')
1191  rviminfo! Xviminfo
1192  call assert_fails('normal n', 'E35:')
1193
1194  call delete('Xviminfo')
1195endfunc
1196
1197func Test_search_Ctrl_L_combining()
1198  " Make sure, that Ctrl-L works correctly with combining characters.
1199  " It uses an artificial example of an 'a' with 4 combining chars:
1200    " 'a' U+0061 Dec:97 LATIN SMALL LETTER A &#x61; /\%u61\Z "\u0061"
1201    " ' ̀' U+0300 Dec:768 COMBINING GRAVE ACCENT &#x300; /\%u300\Z "\u0300"
1202    " ' ́' U+0301 Dec:769 COMBINING ACUTE ACCENT &#x301; /\%u301\Z "\u0301"
1203    " ' ̇' U+0307 Dec:775 COMBINING DOT ABOVE &#x307; /\%u307\Z "\u0307"
1204    " ' ̣' U+0323 Dec:803 COMBINING DOT BELOW &#x323; /\%u323 "\u0323"
1205  " Those should also appear on the commandline
1206  if !exists('+incsearch')
1207    return
1208  endif
1209  call Cmdline3_prep()
1210  1
1211  let bufcontent = ['', 'Miạ̀́̇m']
1212  call append('$', bufcontent)
1213  call feedkeys("/Mi\<c-l>\<c-l>\<cr>", 'tx')
1214  call assert_equal(5, line('.'))
1215  call assert_equal(bufcontent[1], @/)
1216  call Incsearch_cleanup()
1217endfunc
1218
1219func Test_large_hex_chars1()
1220  " This used to cause a crash, the character becomes an NFA state.
1221  try
1222    /\%Ufffffc23
1223  catch
1224    call assert_match('E678:', v:exception)
1225  endtry
1226  try
1227    set re=1
1228    /\%Ufffffc23
1229  catch
1230    call assert_match('E678:', v:exception)
1231  endtry
1232  set re&
1233endfunc
1234
1235func Test_large_hex_chars2()
1236  " This used to cause a crash, the character becomes an NFA state.
1237  try
1238    /[\Ufffffc1f]
1239  catch
1240    call assert_match('E486:', v:exception)
1241  endtry
1242  try
1243    set re=1
1244    /[\Ufffffc1f]
1245  catch
1246    call assert_match('E486:', v:exception)
1247  endtry
1248  set re&
1249endfunc
1250
1251func Test_one_error_msg()
1252  " This  was also giving an internal error
1253  call assert_fails('call search(" \\((\\v[[=P=]]){185}+             ")', 'E871:')
1254endfunc
1255
1256func Test_incsearch_add_char_under_cursor()
1257  if !exists('+incsearch')
1258    return
1259  endif
1260  set incsearch
1261  new
1262  call setline(1, ['find match', 'anything'])
1263  1
1264  call test_override('char_avail', 1)
1265  call feedkeys("fc/m\<C-L>\<C-L>\<C-L>\<C-L>\<C-L>\<CR>", 'tx')
1266  call assert_equal('match', @/)
1267  call test_override('char_avail', 0)
1268
1269  set incsearch&
1270  bwipe!
1271endfunc
1272
1273" Test for the search() function with match at the cursor position
1274func Test_search_match_at_curpos()
1275  new
1276  call append(0, ['foobar', '', 'one two', ''])
1277
1278  normal gg
1279
1280  call search('foobar', 'c')
1281  call assert_equal([1, 1], [line('.'), col('.')])
1282
1283  normal j
1284  call search('^$', 'c')
1285  call assert_equal([2, 1], [line('.'), col('.')])
1286
1287  call search('^$', 'bc')
1288  call assert_equal([2, 1], [line('.'), col('.')])
1289
1290  exe "normal /two\<CR>"
1291  call search('.', 'c')
1292  call assert_equal([3, 5], [line('.'), col('.')])
1293
1294  close!
1295endfunc
1296
1297func Test_search_display_pattern()
1298  new
1299  call setline(1, ['foo', 'bar', 'foobar'])
1300
1301  call cursor(1, 1)
1302  let @/ = 'foo'
1303  let pat = escape(@/, '()*?'. '\s\+')
1304  let g:a = execute(':unsilent :norm! n')
1305  call assert_match(pat, g:a)
1306
1307  " right-left
1308  if exists("+rightleft")
1309    set rl
1310    call cursor(1, 1)
1311    let @/ = 'foo'
1312    let pat = 'oof/\s\+'
1313    let g:a = execute(':unsilent :norm! n')
1314    call assert_match(pat, g:a)
1315    set norl
1316  endif
1317endfunc
1318