xref: /vim-8.2.3635/src/testdir/test_popup.vim (revision ba3ff539)
1" Test for completion menu
2
3source shared.vim
4source screendump.vim
5
6let g:months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
7let g:setting = ''
8
9func ListMonths()
10  if g:setting != ''
11    exe ":set" g:setting
12  endif
13  let mth = copy(g:months)
14  let entered = strcharpart(getline('.'),0,col('.'))
15  if !empty(entered)
16    let mth = filter(mth, 'v:val=~"^".entered')
17  endif
18  call complete(1, mth)
19  return ''
20endfunc
21
22func Test_popup_complete2()
23  " Although the popupmenu is not visible, this does not mean completion mode
24  " has ended. After pressing <f5> to complete the currently typed char, Vim
25  " still stays in the first state of the completion (:h ins-completion-menu),
26  " although the popupmenu wasn't shown <c-e> will remove the inserted
27  " completed text (:h complete_CTRL-E), while the following <c-e> will behave
28  " like expected (:h i_CTRL-E)
29  new
30  inoremap <f5> <c-r>=ListMonths()<cr>
31  call append(1, ["December2015"])
32  :1
33  call feedkeys("aD\<f5>\<C-E>\<C-E>\<C-E>\<C-E>\<enter>\<esc>", 'tx')
34  call assert_equal(["Dece", "", "December2015"], getline(1,3))
35  %d
36  bw!
37endfunc
38
39func Test_popup_complete()
40  new
41  inoremap <f5> <c-r>=ListMonths()<cr>
42
43  " <C-E> - select original typed text before the completion started
44  call feedkeys("aJu\<f5>\<down>\<c-e>\<esc>", 'tx')
45  call assert_equal(["Ju"], getline(1,2))
46  %d
47
48  " <C-Y> - accept current match
49  call feedkeys("a\<f5>". repeat("\<down>",7). "\<c-y>\<esc>", 'tx')
50  call assert_equal(["August"], getline(1,2))
51  %d
52
53  " <BS> - Delete one character from the inserted text (state: 1)
54  " TODO: This should not end the completion, but it does.
55  " This should according to the documentation:
56  " January
57  " but instead, this does
58  " Januar
59  " (idea is, C-L inserts the match from the popup menu
60  " but if the menu is closed, it will insert the character <c-l>
61  call feedkeys("aJ\<f5>\<bs>\<c-l>\<esc>", 'tx')
62  call assert_equal(["Januar"], getline(1,2))
63  %d
64
65  " any-non special character: Stop completion without changing the match
66  " and insert the typed character
67  call feedkeys("a\<f5>20", 'tx')
68  call assert_equal(["January20"], getline(1,2))
69  %d
70
71  " any-non printable, non-white character: Add this character and
72  " reduce number of matches
73  call feedkeys("aJu\<f5>\<c-p>l\<c-y>", 'tx')
74  call assert_equal(["Jul"], getline(1,2))
75  %d
76
77  " any-non printable, non-white character: Add this character and
78  " reduce number of matches
79  call feedkeys("aJu\<f5>\<c-p>l\<c-n>\<c-y>", 'tx')
80  call assert_equal(["July"], getline(1,2))
81  %d
82
83  " any-non printable, non-white character: Add this character and
84  " reduce number of matches
85  call feedkeys("aJu\<f5>\<c-p>l\<c-e>", 'tx')
86  call assert_equal(["Jul"], getline(1,2))
87  %d
88
89  " <BS> - Delete one character from the inserted text (state: 2)
90  call feedkeys("a\<f5>\<c-n>\<bs>", 'tx')
91  call assert_equal(["Februar"], getline(1,2))
92  %d
93
94  " <c-l> - Insert one character from the current match
95  call feedkeys("aJ\<f5>".repeat("\<c-n>",3)."\<c-l>\<esc>", 'tx')
96  call assert_equal(["J"], getline(1,2))
97  %d
98
99  " <c-l> - Insert one character from the current match
100  call feedkeys("aJ\<f5>".repeat("\<c-n>",4)."\<c-l>\<esc>", 'tx')
101  call assert_equal(["January"], getline(1,2))
102  %d
103
104  " <c-y> - Accept current selected match
105  call feedkeys("aJ\<f5>\<c-y>\<esc>", 'tx')
106  call assert_equal(["January"], getline(1,2))
107  %d
108
109  " <c-e> - End completion, go back to what was there before selecting a match
110  call feedkeys("aJu\<f5>\<c-e>\<esc>", 'tx')
111  call assert_equal(["Ju"], getline(1,2))
112  %d
113
114  " <PageUp> - Select a match several entries back
115  call feedkeys("a\<f5>\<PageUp>\<c-y>\<esc>", 'tx')
116  call assert_equal([""], getline(1,2))
117  %d
118
119  " <PageUp><PageUp> - Select a match several entries back
120  call feedkeys("a\<f5>\<PageUp>\<PageUp>\<c-y>\<esc>", 'tx')
121  call assert_equal(["December"], getline(1,2))
122  %d
123
124  " <PageUp><PageUp><PageUp> - Select a match several entries back
125  call feedkeys("a\<f5>\<PageUp>\<PageUp>\<PageUp>\<c-y>\<esc>", 'tx')
126  call assert_equal(["February"], getline(1,2))
127  %d
128
129  " <PageDown> - Select a match several entries further
130  call feedkeys("a\<f5>\<PageDown>\<c-y>\<esc>", 'tx')
131  call assert_equal(["November"], getline(1,2))
132  %d
133
134  " <PageDown><PageDown> - Select a match several entries further
135  call feedkeys("a\<f5>\<PageDown>\<PageDown>\<c-y>\<esc>", 'tx')
136  call assert_equal(["December"], getline(1,2))
137  %d
138
139  " <PageDown><PageDown><PageDown> - Select a match several entries further
140  call feedkeys("a\<f5>\<PageDown>\<PageDown>\<PageDown>\<c-y>\<esc>", 'tx')
141  call assert_equal([""], getline(1,2))
142  %d
143
144  " <PageDown><PageDown><PageDown><PageDown> - Select a match several entries further
145  call feedkeys("a\<f5>".repeat("\<PageDown>",4)."\<c-y>\<esc>", 'tx')
146  call assert_equal(["October"], getline(1,2))
147  %d
148
149  " <Up> - Select a match don't insert yet
150  call feedkeys("a\<f5>\<Up>\<c-y>\<esc>", 'tx')
151  call assert_equal([""], getline(1,2))
152  %d
153
154  " <Up><Up> - Select a match don't insert yet
155  call feedkeys("a\<f5>\<Up>\<Up>\<c-y>\<esc>", 'tx')
156  call assert_equal(["December"], getline(1,2))
157  %d
158
159  " <Up><Up><Up> - Select a match don't insert yet
160  call feedkeys("a\<f5>\<Up>\<Up>\<Up>\<c-y>\<esc>", 'tx')
161  call assert_equal(["November"], getline(1,2))
162  %d
163
164  " <Tab> - Stop completion and insert the match
165  call feedkeys("a\<f5>\<Tab>\<c-y>\<esc>", 'tx')
166  call assert_equal(["January	"], getline(1,2))
167  %d
168
169  " <Space> - Stop completion and insert the match
170  call feedkeys("a\<f5>".repeat("\<c-p>",5)." \<esc>", 'tx')
171  call assert_equal(["September "], getline(1,2))
172  %d
173
174  " <Enter> - Use the text and insert line break (state: 1)
175  call feedkeys("a\<f5>\<enter>\<esc>", 'tx')
176  call assert_equal(["January", ''], getline(1,2))
177  %d
178
179  " <Enter> - Insert the current selected text (state: 2)
180  call feedkeys("a\<f5>".repeat("\<Up>",5)."\<enter>\<esc>", 'tx')
181  call assert_equal(["September"], getline(1,2))
182  %d
183
184  " Insert match immediately, if there is only one match
185  " <c-y> selects a character from the line above
186  call append(0, ["December2015"])
187  call feedkeys("aD\<f5>\<C-Y>\<C-Y>\<C-Y>\<C-Y>\<enter>\<esc>", 'tx')
188  call assert_equal(["December2015", "December2015", ""], getline(1,3))
189  %d
190
191  " use menuone for 'completeopt'
192  " Since for the first <c-y> the menu is still shown, will only select
193  " three letters from the line above
194  set completeopt&vim
195  set completeopt+=menuone
196  call append(0, ["December2015"])
197  call feedkeys("aD\<f5>\<C-Y>\<C-Y>\<C-Y>\<C-Y>\<enter>\<esc>", 'tx')
198  call assert_equal(["December2015", "December201", ""], getline(1,3))
199  %d
200
201  " use longest for 'completeopt'
202  set completeopt&vim
203  call feedkeys("aM\<f5>\<C-N>\<C-P>\<c-e>\<enter>\<esc>", 'tx')
204  set completeopt+=longest
205  call feedkeys("aM\<f5>\<C-N>\<C-P>\<c-e>\<enter>\<esc>", 'tx')
206  call assert_equal(["M", "Ma", ""], getline(1,3))
207  %d
208
209  " use noselect/noinsert for 'completeopt'
210  set completeopt&vim
211  call feedkeys("aM\<f5>\<enter>\<esc>", 'tx')
212  set completeopt+=noselect
213  call feedkeys("aM\<f5>\<enter>\<esc>", 'tx')
214  set completeopt-=noselect completeopt+=noinsert
215  call feedkeys("aM\<f5>\<enter>\<esc>", 'tx')
216  call assert_equal(["March", "M", "March"], getline(1,4))
217  %d
218endfunc
219
220
221func Test_popup_completion_insertmode()
222  new
223  inoremap <F5> <C-R>=ListMonths()<CR>
224
225  call feedkeys("a\<f5>\<down>\<enter>\<esc>", 'tx')
226  call assert_equal('February', getline(1))
227  %d
228  " Set noinsertmode
229  let g:setting = 'noinsertmode'
230  call feedkeys("a\<f5>\<down>\<enter>\<esc>", 'tx')
231  call assert_equal('February', getline(1))
232  call assert_false(pumvisible())
233  %d
234  " Go through all matches, until none is selected
235  let g:setting = ''
236  call feedkeys("a\<f5>". repeat("\<c-n>",12)."\<enter>\<esc>", 'tx')
237  call assert_equal('', getline(1))
238  %d
239  " select previous entry
240  call feedkeys("a\<f5>\<c-p>\<enter>\<esc>", 'tx')
241  call assert_equal('', getline(1))
242  %d
243  " select last entry
244  call feedkeys("a\<f5>\<c-p>\<c-p>\<enter>\<esc>", 'tx')
245  call assert_equal('December', getline(1))
246
247  iunmap <F5>
248endfunc
249
250func Test_noinsert_complete()
251  func! s:complTest1() abort
252    call complete(1, ['source', 'soundfold'])
253    return ''
254  endfunc
255
256  func! s:complTest2() abort
257    call complete(1, ['source', 'soundfold'])
258    return ''
259  endfunc
260
261  new
262  set completeopt+=noinsert
263  inoremap <F5>  <C-R>=s:complTest1()<CR>
264  call feedkeys("i\<F5>soun\<CR>\<CR>\<ESC>.", 'tx')
265  call assert_equal('soundfold', getline(1))
266  call assert_equal('soundfold', getline(2))
267  bwipe!
268
269  new
270  inoremap <F5>  <C-R>=s:complTest2()<CR>
271  call feedkeys("i\<F5>\<CR>\<ESC>", 'tx')
272  call assert_equal('source', getline(1))
273  bwipe!
274
275  set completeopt-=noinsert
276  iunmap <F5>
277endfunc
278
279func Test_compl_vim_cmds_after_register_expr()
280  func! s:test_func()
281    return 'autocmd '
282  endfunc
283  augroup AAAAA_Group
284    au!
285  augroup END
286
287  new
288  call feedkeys("i\<c-r>=s:test_func()\<CR>\<C-x>\<C-v>\<Esc>", 'tx')
289  call assert_equal('autocmd AAAAA_Group', getline(1))
290  autocmd! AAAAA_Group
291  augroup! AAAAA_Group
292  bwipe!
293endfunc
294
295func DummyCompleteOne(findstart, base)
296  if a:findstart
297    return 0
298  else
299    wincmd n
300    return ['onedef', 'oneDEF']
301  endif
302endfunc
303
304" Test that nothing happens if the 'completefunc' opens
305" a new window (no completion, no crash)
306func Test_completefunc_opens_new_window_one()
307  new
308  let winid = win_getid()
309  setlocal completefunc=DummyCompleteOne
310  call setline(1, 'one')
311  /^one
312  call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E839:')
313  call assert_notequal(winid, win_getid())
314  q!
315  call assert_equal(winid, win_getid())
316  call assert_equal('', getline(1))
317  q!
318endfunc
319
320" Test that nothing happens if the 'completefunc' opens
321" a new window (no completion, no crash)
322func DummyCompleteTwo(findstart, base)
323  if a:findstart
324    wincmd n
325    return 0
326  else
327    return ['twodef', 'twoDEF']
328  endif
329endfunc
330
331" Test that nothing happens if the 'completefunc' opens
332" a new window (no completion, no crash)
333func Test_completefunc_opens_new_window_two()
334  new
335  let winid = win_getid()
336  setlocal completefunc=DummyCompleteTwo
337  call setline(1, 'two')
338  /^two
339  call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E764:')
340  call assert_notequal(winid, win_getid())
341  q!
342  call assert_equal(winid, win_getid())
343  call assert_equal('two', getline(1))
344  q!
345endfunc
346
347func DummyCompleteThree(findstart, base)
348  if a:findstart
349    return 0
350  else
351    return ['threedef', 'threeDEF']
352  endif
353endfunc
354
355:"Test that 'completefunc' works when it's OK.
356func Test_completefunc_works()
357  new
358  let winid = win_getid()
359  setlocal completefunc=DummyCompleteThree
360  call setline(1, 'three')
361  /^three
362  call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")
363  call assert_equal(winid, win_getid())
364  call assert_equal('threeDEF', getline(1))
365  q!
366endfunc
367
368func DummyCompleteFour(findstart, base)
369  if a:findstart
370    return 0
371  else
372    call complete_add('four1')
373    call complete_add('four2')
374    call complete_check()
375    call complete_add('four3')
376    call complete_add('four4')
377    call complete_check()
378    call complete_add('four5')
379    call complete_add('four6')
380    return []
381  endif
382endfunc
383
384" Test that 'omnifunc' works when it's OK.
385func Test_omnifunc_with_check()
386  new
387  setlocal omnifunc=DummyCompleteFour
388  call setline(1, 'four')
389  /^four
390  call feedkeys("A\<C-X>\<C-O>\<C-N>\<Esc>", "x")
391  call assert_equal('four2', getline(1))
392
393  call setline(1, 'four')
394  /^four
395  call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<Esc>", "x")
396  call assert_equal('four3', getline(1))
397
398  call setline(1, 'four')
399  /^four
400  call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<C-N>\<C-N>\<Esc>", "x")
401  call assert_equal('four5', getline(1))
402
403  q!
404endfunc
405
406func UndoComplete()
407  call complete(1, ['January', 'February', 'March',
408        \ 'April', 'May', 'June', 'July', 'August', 'September',
409        \ 'October', 'November', 'December'])
410  return ''
411endfunc
412
413" Test that no undo item is created when no completion is inserted
414func Test_complete_no_undo()
415  set completeopt=menu,preview,noinsert,noselect
416  inoremap <Right> <C-R>=UndoComplete()<CR>
417  new
418  call feedkeys("ixxx\<CR>\<CR>yyy\<Esc>k", 'xt')
419  call feedkeys("iaaa\<Esc>0", 'xt')
420  call assert_equal('aaa', getline(2))
421  call feedkeys("i\<Right>\<Esc>", 'xt')
422  call assert_equal('aaa', getline(2))
423  call feedkeys("u", 'xt')
424  call assert_equal('', getline(2))
425
426  call feedkeys("ibbb\<Esc>0", 'xt')
427  call assert_equal('bbb', getline(2))
428  call feedkeys("A\<Right>\<Down>\<CR>\<Esc>", 'xt')
429  call assert_equal('January', getline(2))
430  call feedkeys("u", 'xt')
431  call assert_equal('bbb', getline(2))
432
433  call feedkeys("A\<Right>\<C-N>\<Esc>", 'xt')
434  call assert_equal('January', getline(2))
435  call feedkeys("u", 'xt')
436  call assert_equal('bbb', getline(2))
437
438  iunmap <Right>
439  set completeopt&
440  q!
441endfunc
442
443func DummyCompleteFive(findstart, base)
444  if a:findstart
445    return 0
446  else
447    return [
448          \   { 'word': 'January', 'info': "info1-1\n1-2\n1-3" },
449          \   { 'word': 'February', 'info': "info2-1\n2-2\n2-3" },
450          \   { 'word': 'March', 'info': "info3-1\n3-2\n3-3" },
451          \   { 'word': 'April', 'info': "info4-1\n4-2\n4-3" },
452          \   { 'word': 'May', 'info': "info5-1\n5-2\n5-3" },
453          \ ]
454  endif
455endfunc
456
457" Test that 'completefunc' on Scratch buffer with preview window works when
458" it's OK.
459func Test_completefunc_with_scratch_buffer()
460  new +setlocal\ buftype=nofile\ bufhidden=wipe\ noswapfile
461  set completeopt+=preview
462  setlocal completefunc=DummyCompleteFive
463  call feedkeys("A\<C-X>\<C-U>\<C-N>\<C-N>\<C-N>\<Esc>", "x")
464  call assert_equal(['April'], getline(1, '$'))
465  pclose
466  q!
467  set completeopt&
468endfunc
469
470" <C-E> - select original typed text before the completion started without
471" auto-wrap text.
472func Test_completion_ctrl_e_without_autowrap()
473  new
474  let tw_save = &tw
475  set tw=78
476  let li = [
477        \ '"                                                        zzz',
478        \ '" zzzyyyyyyyyyyyyyyyyyyy']
479  call setline(1, li)
480  0
481  call feedkeys("A\<C-X>\<C-N>\<C-E>\<Esc>", "tx")
482  call assert_equal(li, getline(1, '$'))
483
484  let &tw = tw_save
485  q!
486endfunc
487
488func DummyCompleteSix()
489  call complete(1, ['Hello', 'World'])
490  return ''
491endfunction
492
493" complete() correctly clears the list of autocomplete candidates
494" See #1411
495func Test_completion_clear_candidate_list()
496  new
497  %d
498  " select first entry from the completion popup
499  call feedkeys("a    xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>", "tx")
500  call assert_equal('Hello', getline(1))
501  %d
502  " select second entry from the completion popup
503  call feedkeys("a    xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>", "tx")
504  call assert_equal('World', getline(1))
505  %d
506  " select original text
507  call feedkeys("a    xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>\<C-N>", "tx")
508  call assert_equal('    xxx', getline(1))
509  %d
510  " back at first entry from completion list
511  call feedkeys("a    xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>\<C-N>\<C-N>", "tx")
512  call assert_equal('Hello', getline(1))
513
514  bw!
515endfunc
516
517func Test_completion_respect_bs_option()
518  new
519  let li = ["aaa", "aaa12345", "aaaabcdef", "aaaABC"]
520
521  set bs=indent,eol
522  call setline(1, li)
523  1
524  call feedkeys("A\<C-X>\<C-N>\<C-P>\<BS>\<BS>\<BS>\<Esc>", "tx")
525  call assert_equal('aaa', getline(1))
526
527  %d
528  set bs=indent,eol,start
529  call setline(1, li)
530  1
531  call feedkeys("A\<C-X>\<C-N>\<C-P>\<BS>\<BS>\<BS>\<Esc>", "tx")
532  call assert_equal('', getline(1))
533
534  bw!
535endfunc
536
537func CompleteUndo() abort
538  call complete(1, g:months)
539  return ''
540endfunc
541
542func Test_completion_can_undo()
543  inoremap <Right> <c-r>=CompleteUndo()<cr>
544  set completeopt+=noinsert,noselect
545
546  new
547  call feedkeys("a\<Right>a\<Esc>", 'xt')
548  call assert_equal('a', getline(1))
549  undo
550  call assert_equal('', getline(1))
551
552  bwipe!
553  set completeopt&
554  iunmap <Right>
555endfunc
556
557func Test_completion_comment_formatting()
558  new
559  setl formatoptions=tcqro
560  call feedkeys("o/*\<cr>\<cr>/\<esc>", 'tx')
561  call assert_equal(['', '/*', ' *', ' */'], getline(1,4))
562  %d
563  call feedkeys("o/*\<cr>foobar\<cr>/\<esc>", 'tx')
564  call assert_equal(['', '/*', ' * foobar', ' */'], getline(1,4))
565  %d
566  try
567    call feedkeys("o/*\<cr>\<cr>\<c-x>\<c-u>/\<esc>", 'tx')
568    call assert_report('completefunc not set, should have failed')
569  catch
570    call assert_exception('E764:')
571  endtry
572  call assert_equal(['', '/*', ' *', ' */'], getline(1,4))
573  bwipe!
574endfunc
575
576func MessCompleteMonths()
577  for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep")
578    call complete_add(m)
579    if complete_check()
580      break
581    endif
582  endfor
583  return []
584endfunc
585
586func MessCompleteMore()
587  call complete(1, split("Oct Nov Dec"))
588  return []
589endfunc
590
591func MessComplete(findstart, base)
592  if a:findstart
593    let line = getline('.')
594    let start = col('.') - 1
595    while start > 0 && line[start - 1] =~ '\a'
596      let start -= 1
597    endwhile
598    return start
599  else
600    call MessCompleteMonths()
601    call MessCompleteMore()
602    return []
603  endif
604endfunc
605
606func Test_complete_func_mess()
607  " Calling complete() after complete_add() in 'completefunc' is wrong, but it
608  " should not crash.
609  set completefunc=MessComplete
610  new
611  call setline(1, 'Ju')
612  call feedkeys("A\<c-x>\<c-u>/\<esc>", 'tx')
613  call assert_equal('Oct/Oct', getline(1))
614  bwipe!
615  set completefunc=
616endfunc
617
618func Test_complete_CTRLN_startofbuffer()
619  new
620  call setline(1, [ 'organize(cupboard, 3, 2);',
621        \ 'prioritize(bureau, 8, 7);',
622        \ 'realize(bannister, 4, 4);',
623        \ 'moralize(railing, 3,9);'])
624  let expected=['cupboard.organize(3, 2);',
625        \ 'bureau.prioritize(8, 7);',
626        \ 'bannister.realize(4, 4);',
627        \ 'railing.moralize(3,9);']
628  call feedkeys("qai\<c-n>\<c-n>.\<esc>3wdW\<cr>q3@a", 'tx')
629  call assert_equal(expected, getline(1,'$'))
630  bwipe!
631endfunc
632
633func Test_popup_and_window_resize()
634  if !has('terminal') || has('gui_running')
635    return
636  endif
637  let h = winheight(0)
638  if h < 15
639    return
640  endif
641  let rows = h / 3
642  let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': rows})
643  call term_sendkeys(buf, (h / 3 - 1) . "o\<esc>")
644  " Wait for the nested Vim to exit insert mode, where it will show the ruler.
645  " Need to trigger a redraw.
646  call WaitFor({-> execute("redraw") == "" && term_getline(buf, rows) =~ '\<' . rows . ',.*Bot'})
647
648  call term_sendkeys(buf, "Gi\<c-x>")
649  call term_sendkeys(buf, "\<c-v>")
650  call term_wait(buf, 100)
651  " popup first entry "!" must be at the top
652  call WaitForAssert({-> assert_match('^!\s*$', term_getline(buf, 1))})
653  exe 'resize +' . (h - 1)
654  call term_wait(buf, 100)
655  redraw!
656  " popup shifted down, first line is now empty
657  call WaitForAssert({-> assert_equal('', term_getline(buf, 1))})
658  sleep 100m
659  " popup is below cursor line and shows first match "!"
660  call WaitForAssert({-> assert_match('^!\s*$', term_getline(buf, term_getcursor(buf)[0] + 1))})
661  " cursor line also shows !
662  call assert_match('^!\s*$', term_getline(buf, term_getcursor(buf)[0]))
663  bwipe!
664endfunc
665
666func Test_popup_and_preview_autocommand()
667  " This used to crash Vim
668  if !has('python')
669    return
670  endif
671  let h = winheight(0)
672  if h < 15
673    return
674  endif
675  new
676  augroup MyBufAdd
677    au!
678    au BufAdd * nested tab sball
679  augroup END
680  set omnifunc=pythoncomplete#Complete
681  call setline(1, 'import os')
682  " make the line long
683  call setline(2, '                                 os.')
684  $
685  call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<C-N>\<enter>\<esc>", 'tx')
686  call assert_equal("import os", getline(1))
687  call assert_match('                                 os.\(EX_IOERR\|O_CREAT\)$', getline(2))
688  call assert_equal(1, winnr('$'))
689  " previewwindow option is not set
690  call assert_equal(0, &previewwindow)
691  norm! gt
692  call assert_equal(0, &previewwindow)
693  norm! gT
694  call assert_equal(10, tabpagenr('$'))
695  tabonly
696  pclose
697  augroup MyBufAdd
698    au!
699  augroup END
700  augroup! MyBufAdd
701  bw!
702endfunc
703
704func Test_balloon_split()
705  if !exists('*balloon_split')
706    return
707  endif
708  call assert_equal([
709        \ 'tempname: 0x555555e380a0 "/home/mool/.viminfz.tmp"',
710        \ ], balloon_split(
711        \ 'tempname: 0x555555e380a0 "/home/mool/.viminfz.tmp"'))
712  call assert_equal([
713        \ 'one two three four one two three four one two thre',
714        \ 'e four',
715        \ ], balloon_split(
716        \ 'one two three four one two three four one two three four'))
717
718  call assert_equal([
719        \ 'struct = {',
720        \ '  one = 1,',
721        \ '  two = 2,',
722        \ '  three = 3}',
723        \ ], balloon_split(
724        \ 'struct = {one = 1, two = 2, three = 3}'))
725
726  call assert_equal([
727        \ 'struct = {',
728        \ '  one = 1,',
729        \ '  nested = {',
730        \ '    n1 = "yes",',
731        \ '    n2 = "no"}',
732        \ '  two = 2}',
733        \ ], balloon_split(
734        \ 'struct = {one = 1, nested = {n1 = "yes", n2 = "no"} two = 2}'))
735  call assert_equal([
736        \ 'struct = 0x234 {',
737        \ '  long = 2343 "\\"some long string that will be wr',
738        \ 'apped in two\\"",',
739        \ '  next = 123}',
740        \ ], balloon_split(
741        \ 'struct = 0x234 {long = 2343 "\\"some long string that will be wrapped in two\\"", next = 123}'))
742endfunc
743
744func Test_popup_position()
745  if !CanRunVimInTerminal()
746    return
747  endif
748  call writefile([
749	\ '123456789_123456789_123456789_a',
750	\ '123456789_123456789_123456789_b',
751	\ '            123',
752	\ ], 'Xtest')
753  let buf = RunVimInTerminal('Xtest', {})
754  call term_sendkeys(buf, ":vsplit\<CR>")
755
756  " default pumwidth in left window: overlap in right window
757  call term_sendkeys(buf, "GA\<C-N>")
758  call VerifyScreenDump(buf, 'Test_popup_position_01', {'rows': 8})
759  call term_sendkeys(buf, "\<Esc>u")
760
761  " default pumwidth: fill until right of window
762  call term_sendkeys(buf, "\<C-W>l")
763  call term_sendkeys(buf, "GA\<C-N>")
764  call VerifyScreenDump(buf, 'Test_popup_position_02', {'rows': 8})
765
766  " larger pumwidth: used as minimum width
767  call term_sendkeys(buf, "\<Esc>u")
768  call term_sendkeys(buf, ":set pumwidth=30\<CR>")
769  call term_sendkeys(buf, "GA\<C-N>")
770  call VerifyScreenDump(buf, 'Test_popup_position_03', {'rows': 8})
771
772  " completed text wider than the window and 'pumwidth' smaller than available
773  " space
774  call term_sendkeys(buf, "\<Esc>u")
775  call term_sendkeys(buf, ":set pumwidth=20\<CR>")
776  call term_sendkeys(buf, "ggI123456789_\<Esc>")
777  call term_sendkeys(buf, "jI123456789_\<Esc>")
778  call term_sendkeys(buf, "GA\<C-N>")
779  call VerifyScreenDump(buf, 'Test_popup_position_04', {'rows': 10})
780
781  call term_sendkeys(buf, "\<Esc>u")
782  call StopVimInTerminal(buf)
783  call delete('Xtest')
784endfunc
785
786func Test_popup_command()
787  if !CanRunVimInTerminal() || !has('menu')
788    return
789  endif
790
791  call writefile([
792	\ 'one two three four five',
793	\ 'and one two Xthree four five',
794	\ 'one more two three four five',
795	\ ], 'Xtest')
796  let buf = RunVimInTerminal('Xtest', {})
797  call term_sendkeys(buf, ":source $VIMRUNTIME/menu.vim\<CR>")
798  call term_sendkeys(buf, "/X\<CR>:popup PopUp\<CR>")
799  call VerifyScreenDump(buf, 'Test_popup_command_01', {})
800
801  " Select a word
802  call term_sendkeys(buf, "jj")
803  call VerifyScreenDump(buf, 'Test_popup_command_02', {})
804
805  " Select a word
806  call term_sendkeys(buf, "j\<CR>")
807  call VerifyScreenDump(buf, 'Test_popup_command_03', {})
808
809  call term_sendkeys(buf, "\<Esc>")
810  call StopVimInTerminal(buf)
811  call delete('Xtest')
812endfunc
813
814func Test_popup_complete_backwards()
815  new
816  call setline(1, ['Post', 'Port', 'Po'])
817  let expected=['Post', 'Port', 'Port']
818  call cursor(3,2)
819  call feedkeys("A\<C-X>". repeat("\<C-P>", 3). "rt\<cr>", 'tx')
820  call assert_equal(expected, getline(1,'$'))
821  bwipe!
822endfunc
823
824func Test_popup_complete_backwards_ctrl_p()
825  new
826  call setline(1, ['Post', 'Port', 'Po'])
827  let expected=['Post', 'Port', 'Port']
828  call cursor(3,2)
829  call feedkeys("A\<C-P>\<C-N>rt\<cr>", 'tx')
830  call assert_equal(expected, getline(1,'$'))
831  bwipe!
832endfunc
833
834func Test_complete_o_tab()
835  let s:o_char_pressed = 0
836
837  fun! s:act_on_text_changed()
838    if s:o_char_pressed
839      let s:o_char_pressed = 0
840      call feedkeys("\<c-x>\<c-n>", 'i')
841    endif
842  endfunc
843
844  set completeopt=menu,noselect
845  new
846  imap <expr> <buffer> <tab> pumvisible() ? "\<c-p>" : "X"
847  autocmd! InsertCharPre <buffer> let s:o_char_pressed = (v:char ==# 'o')
848  autocmd! TextChangedI <buffer> call <sid>act_on_text_changed()
849  call setline(1,  ['hoard', 'hoax', 'hoarse', ''])
850  let l:expected = ['hoard', 'hoax', 'hoarse', 'hoax', 'hoax']
851  call cursor(4,1)
852  call test_override("char_avail", 1)
853  call feedkeys("Ahoa\<tab>\<tab>\<c-y>\<esc>", 'tx')
854  call feedkeys("oho\<tab>\<tab>\<c-y>\<esc>", 'tx')
855  call assert_equal(l:expected, getline(1,'$'))
856
857  call test_override("char_avail", 0)
858  bwipe!
859  set completeopt&
860  delfunc s:act_on_text_changed
861endfunc
862
863
864" vim: shiftwidth=2 sts=2 expandtab
865