1" Test for insert completion
2
3source screendump.vim
4source check.vim
5
6" Test for insert expansion
7func Test_ins_complete()
8  edit test_ins_complete.vim
9  " The files in the current directory interferes with the files
10  " used by this test. So use a separate directory for the test.
11  call mkdir('Xdir')
12  cd Xdir
13
14  set ff=unix
15  call writefile(["test11\t36Gepeto\t/Tag/",
16	      \ "asd\ttest11file\t36G",
17	      \ "Makefile\tto\trun"], 'Xtestfile')
18  call writefile(['', 'start of testfile',
19	      \ 'ru',
20	      \ 'run1',
21	      \ 'run2',
22	      \ 'STARTTEST',
23	      \ 'ENDTEST',
24	      \ 'end of testfile'], 'Xtestdata')
25  set ff&
26
27  enew!
28  edit Xtestdata
29  new
30  call append(0, ['#include "Xtestfile"', ''])
31  call cursor(2, 1)
32
33  set cot=
34  set cpt=.,w
35  " add-expands (word from next line) from other window
36  exe "normal iru\<C-N>\<C-N>\<C-X>\<C-N>\<Esc>\<C-A>"
37  call assert_equal('run1 run3', getline('.'))
38  " add-expands (current buffer first)
39  exe "normal o\<C-P>\<C-X>\<C-N>"
40  call assert_equal('run3 run3', getline('.'))
41  " Local expansion, ends in an empty line (unless it becomes a global
42  " expansion)
43  exe "normal o\<C-X>\<C-P>\<C-P>\<C-P>\<C-P>\<C-P>"
44  call assert_equal('', getline('.'))
45  " starts Local and switches to global add-expansion
46  exe "normal o\<C-X>\<C-P>\<C-P>\<C-X>\<C-X>\<C-N>\<C-X>\<C-N>\<C-N>"
47  call assert_equal('run1 run2', getline('.'))
48
49  set cpt=.,w,i
50  " i-add-expands and switches to local
51  exe "normal OM\<C-N>\<C-X>\<C-N>\<C-X>\<C-N>\<C-X>\<C-X>\<C-X>\<C-P>"
52  call assert_equal("Makefile\tto\trun3", getline('.'))
53  " add-expands lines (it would end in an empty line if it didn't ignored
54  " itself)
55  exe "normal o\<C-X>\<C-L>\<C-X>\<C-L>\<C-P>\<C-P>"
56  call assert_equal("Makefile\tto\trun3", getline('.'))
57  call assert_equal("Makefile\tto\trun3", getline(line('.') - 1))
58
59  set cpt=kXtestfile
60  " checks k-expansion, and file expansion (use Xtest11 instead of test11,
61  " because TEST11.OUT may match first on DOS)
62  write Xtest11.one
63  write Xtest11.two
64  exe "normal o\<C-N>\<Esc>IX\<Esc>A\<C-X>\<C-F>\<C-N>"
65  call assert_equal('Xtest11.two', getline('.'))
66
67  " use CTRL-X CTRL-F to complete Xtest11.one, remove it and then use CTRL-X
68  " CTRL-F again to verify this doesn't cause trouble.
69  exe "normal oXt\<C-X>\<C-F>\<BS>\<BS>\<BS>\<BS>\<BS>\<BS>\<BS>\<BS>\<C-X>\<C-F>"
70  call assert_equal('Xtest11.one', getline('.'))
71  normal ddk
72
73  set cpt=w
74  " checks make_cyclic in other window
75  exe "normal oST\<C-N>\<C-P>\<C-P>\<C-P>\<C-P>"
76  call assert_equal('STARTTEST', getline('.'))
77
78  set cpt=u nohid
79  " checks unloaded buffer expansion
80  only
81  exe "normal oEN\<C-N>"
82  call assert_equal('ENDTEST', getline('.'))
83  " checks adding mode abortion
84  exe "normal ounl\<C-N>\<C-X>\<C-X>\<C-P>"
85  call assert_equal('unless', getline('.'))
86
87  set cpt=t,d def=^\\k* tags=Xtestfile notagbsearch
88  " tag expansion, define add-expansion interrupted
89  exe "normal o\<C-X>\<C-]>\<C-X>\<C-D>\<C-X>\<C-D>\<C-X>\<C-X>\<C-D>\<C-X>\<C-D>\<C-X>\<C-D>\<C-X>\<C-D>"
90  call assert_equal('test11file	36Gepeto	/Tag/ asd', getline('.'))
91  " t-expansion
92  exe "normal oa\<C-N>\<Esc>"
93  call assert_equal('asd', getline('.'))
94
95  %bw!
96  call delete('Xtestfile')
97  call delete('Xtest11.one')
98  call delete('Xtest11.two')
99  call delete('Xtestdata')
100  set cpt& cot& def& tags& tagbsearch& hidden&
101  cd ..
102  call delete('Xdir', 'rf')
103endfunc
104
105func Test_omni_dash()
106  func Omni(findstart, base)
107    if a:findstart
108        return 5
109    else
110        echom a:base
111	return ['-help', '-v']
112    endif
113  endfunc
114  set omnifunc=Omni
115  new
116  exe "normal Gofind -\<C-x>\<C-o>"
117  call assert_equal("find -help", getline('$'))
118
119  bwipe!
120  delfunc Omni
121  set omnifunc=
122endfunc
123
124func Test_omni_autoload()
125  let save_rtp = &rtp
126  set rtp=Xruntime/some
127  let dir = 'Xruntime/some/autoload'
128  call mkdir(dir, 'p')
129
130  let lines =<< trim END
131      vim9script
132      def omni#func(findstart: bool, base: string): any
133          if findstart
134              return 1
135          else
136              return ['match']
137          endif
138      enddef
139      {
140          eval 1 + 2
141      }
142  END
143  call writefile(lines, dir .. '/omni.vim')
144
145  new
146  setlocal omnifunc=omni#func
147  call feedkeys("i\<C-X>\<C-O>\<Esc>", 'xt')
148
149  bwipe!
150  call delete('Xruntime', 'rf')
151  set omnifunc=
152  let &rtp = save_rtp
153endfunc
154
155func Test_completefunc_args()
156  let s:args = []
157  func! CompleteFunc(findstart, base)
158    let s:args += [[a:findstart, empty(a:base)]]
159  endfunc
160  new
161
162  set completefunc=CompleteFunc
163  call feedkeys("i\<C-X>\<C-U>\<Esc>", 'x')
164  call assert_equal([1, 1], s:args[0])
165  call assert_equal(0, s:args[1][0])
166  set completefunc=
167
168  let s:args = []
169  set omnifunc=CompleteFunc
170  call feedkeys("i\<C-X>\<C-O>\<Esc>", 'x')
171  call assert_equal([1, 1], s:args[0])
172  call assert_equal(0, s:args[1][0])
173  set omnifunc=
174
175  bwipe!
176  unlet s:args
177  delfunc CompleteFunc
178endfunc
179
180func s:CompleteDone_CompleteFuncNone( findstart, base )
181  if a:findstart
182    return 0
183  endif
184
185  return v:none
186endfunc
187
188func s:CompleteDone_CompleteFuncDict( findstart, base )
189  if a:findstart
190    return 0
191  endif
192
193  return {
194	  \ 'words': [
195	    \ {
196	      \ 'word': 'aword',
197	      \ 'abbr': 'wrd',
198	      \ 'menu': 'extra text',
199	      \ 'info': 'words are cool',
200	      \ 'kind': 'W',
201	      \ 'user_data': 'test'
202	    \ }
203	  \ ]
204	\ }
205endfunc
206
207func s:CompleteDone_CheckCompletedItemNone()
208  let s:called_completedone = 1
209endfunc
210
211func s:CompleteDone_CheckCompletedItemDict(pre)
212  call assert_equal( 'aword',          v:completed_item[ 'word' ] )
213  call assert_equal( 'wrd',            v:completed_item[ 'abbr' ] )
214  call assert_equal( 'extra text',     v:completed_item[ 'menu' ] )
215  call assert_equal( 'words are cool', v:completed_item[ 'info' ] )
216  call assert_equal( 'W',              v:completed_item[ 'kind' ] )
217  call assert_equal( 'test',           v:completed_item[ 'user_data' ] )
218
219  if a:pre
220    call assert_equal('function', complete_info().mode)
221  endif
222
223  let s:called_completedone = 1
224endfunc
225
226func Test_CompleteDoneNone()
227  au CompleteDone * :call <SID>CompleteDone_CheckCompletedItemNone()
228  let oldline = join(map(range(&columns), 'nr2char(screenchar(&lines-1, v:val+1))'), '')
229
230  set completefunc=<SID>CompleteDone_CompleteFuncNone
231  execute "normal a\<C-X>\<C-U>\<C-Y>"
232  set completefunc&
233  let newline = join(map(range(&columns), 'nr2char(screenchar(&lines-1, v:val+1))'), '')
234
235  call assert_true(s:called_completedone)
236  call assert_equal(oldline, newline)
237
238  let s:called_completedone = 0
239  au! CompleteDone
240endfunc
241
242func Test_CompleteDoneDict()
243  au CompleteDonePre * :call <SID>CompleteDone_CheckCompletedItemDict(1)
244  au CompleteDone * :call <SID>CompleteDone_CheckCompletedItemDict(0)
245
246  set completefunc=<SID>CompleteDone_CompleteFuncDict
247  execute "normal a\<C-X>\<C-U>\<C-Y>"
248  set completefunc&
249
250  call assert_equal('test', v:completed_item[ 'user_data' ])
251  call assert_true(s:called_completedone)
252
253  let s:called_completedone = 0
254  au! CompleteDone
255endfunc
256
257func s:CompleteDone_CompleteFuncDictNoUserData(findstart, base)
258  if a:findstart
259    return 0
260  endif
261
262  return {
263	  \ 'words': [
264	    \ {
265	      \ 'word': 'aword',
266	      \ 'abbr': 'wrd',
267	      \ 'menu': 'extra text',
268	      \ 'info': 'words are cool',
269	      \ 'kind': 'W',
270	      \ 'user_data': ['one', 'two'],
271	    \ }
272	  \ ]
273	\ }
274endfunc
275
276func s:CompleteDone_CheckCompletedItemDictNoUserData()
277  call assert_equal( 'aword',          v:completed_item[ 'word' ] )
278  call assert_equal( 'wrd',            v:completed_item[ 'abbr' ] )
279  call assert_equal( 'extra text',     v:completed_item[ 'menu' ] )
280  call assert_equal( 'words are cool', v:completed_item[ 'info' ] )
281  call assert_equal( 'W',              v:completed_item[ 'kind' ] )
282  call assert_equal( ['one', 'two'],   v:completed_item[ 'user_data' ] )
283
284  let s:called_completedone = 1
285endfunc
286
287func Test_CompleteDoneDictNoUserData()
288  au CompleteDone * :call <SID>CompleteDone_CheckCompletedItemDictNoUserData()
289
290  set completefunc=<SID>CompleteDone_CompleteFuncDictNoUserData
291  execute "normal a\<C-X>\<C-U>\<C-Y>"
292  set completefunc&
293
294  call assert_equal(['one', 'two'], v:completed_item[ 'user_data' ])
295  call assert_true(s:called_completedone)
296
297  let s:called_completedone = 0
298  au! CompleteDone
299endfunc
300
301func s:CompleteDone_CompleteFuncList(findstart, base)
302  if a:findstart
303    return 0
304  endif
305
306  return [ 'aword' ]
307endfunc
308
309func s:CompleteDone_CheckCompletedItemList()
310  call assert_equal( 'aword', v:completed_item[ 'word' ] )
311  call assert_equal( '',      v:completed_item[ 'abbr' ] )
312  call assert_equal( '',      v:completed_item[ 'menu' ] )
313  call assert_equal( '',      v:completed_item[ 'info' ] )
314  call assert_equal( '',      v:completed_item[ 'kind' ] )
315  call assert_equal( '',      v:completed_item[ 'user_data' ] )
316
317  let s:called_completedone = 1
318endfunc
319
320func Test_CompleteDoneList()
321  au CompleteDone * :call <SID>CompleteDone_CheckCompletedItemList()
322
323  set completefunc=<SID>CompleteDone_CompleteFuncList
324  execute "normal a\<C-X>\<C-U>\<C-Y>"
325  set completefunc&
326
327  call assert_equal('', v:completed_item[ 'user_data' ])
328  call assert_true(s:called_completedone)
329
330  let s:called_completedone = 0
331  au! CompleteDone
332endfunc
333
334func Test_CompleteDone_undo()
335  au CompleteDone * call append(0, "prepend1")
336  new
337  call setline(1, ["line1", "line2"])
338  call feedkeys("Go\<C-X>\<C-N>\<CR>\<ESC>", "tx")
339  call assert_equal(["prepend1", "line1", "line2", "line1", ""],
340              \     getline(1, '$'))
341  undo
342  call assert_equal(["line1", "line2"], getline(1, '$'))
343  bwipe!
344  au! CompleteDone
345endfunc
346
347func CompleteTest(findstart, query)
348  if a:findstart
349    return col('.')
350  endif
351  return ['matched']
352endfunc
353
354func Test_completefunc_info()
355  new
356  set completeopt=menuone
357  set completefunc=CompleteTest
358  call feedkeys("i\<C-X>\<C-U>\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx")
359  call assert_equal("matched{'pum_visible': 1, 'mode': 'function', 'selected': 0, 'items': [{'word': 'matched', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}]}", getline(1))
360  bwipe!
361  set completeopt&
362  set completefunc&
363endfunc
364
365" Check that when using feedkeys() typeahead does not interrupt searching for
366" completions.
367func Test_compl_feedkeys()
368  new
369  set completeopt=menuone,noselect
370  call feedkeys("ajump ju\<C-X>\<C-N>\<C-P>\<ESC>", "tx")
371  call assert_equal("jump jump", getline(1))
372  bwipe!
373  set completeopt&
374endfunc
375
376func s:ComplInCmdwin_GlobalCompletion(a, l, p)
377  return 'global'
378endfunc
379
380func s:ComplInCmdwin_LocalCompletion(a, l, p)
381  return 'local'
382endfunc
383
384func Test_compl_in_cmdwin()
385  CheckFeature cmdwin
386
387  set wildmenu wildchar=<Tab>
388  com! -nargs=1 -complete=command GetInput let input = <q-args>
389  com! -buffer TestCommand echo 'TestCommand'
390  let w:test_winvar = 'winvar'
391  let b:test_bufvar = 'bufvar'
392
393  " User-defined commands
394  let input = ''
395  call feedkeys("q:iGetInput T\<C-x>\<C-v>\<CR>", 'tx!')
396  call assert_equal('TestCommand', input)
397
398  let input = ''
399  call feedkeys("q::GetInput T\<Tab>\<CR>:q\<CR>", 'tx!')
400  call assert_equal('T', input)
401
402
403  com! -nargs=1 -complete=var GetInput let input = <q-args>
404  " Window-local variables
405  let input = ''
406  call feedkeys("q:iGetInput w:test_\<C-x>\<C-v>\<CR>", 'tx!')
407  call assert_equal('w:test_winvar', input)
408
409  let input = ''
410  call feedkeys("q::GetInput w:test_\<Tab>\<CR>:q\<CR>", 'tx!')
411  call assert_equal('w:test_', input)
412
413  " Buffer-local variables
414  let input = ''
415  call feedkeys("q:iGetInput b:test_\<C-x>\<C-v>\<CR>", 'tx!')
416  call assert_equal('b:test_bufvar', input)
417
418  let input = ''
419  call feedkeys("q::GetInput b:test_\<Tab>\<CR>:q\<CR>", 'tx!')
420  call assert_equal('b:test_', input)
421
422
423  " Argument completion of buffer-local command
424  func s:ComplInCmdwin_GlobalCompletionList(a, l, p)
425    return ['global']
426  endfunc
427
428  func s:ComplInCmdwin_LocalCompletionList(a, l, p)
429    return ['local']
430  endfunc
431
432  func s:ComplInCmdwin_CheckCompletion(arg)
433    call assert_equal('local', a:arg)
434  endfunc
435
436  com! -nargs=1 -complete=custom,<SID>ComplInCmdwin_GlobalCompletion
437       \ TestCommand call s:ComplInCmdwin_CheckCompletion(<q-args>)
438  com! -buffer -nargs=1 -complete=custom,<SID>ComplInCmdwin_LocalCompletion
439       \ TestCommand call s:ComplInCmdwin_CheckCompletion(<q-args>)
440  call feedkeys("q:iTestCommand \<Tab>\<CR>", 'tx!')
441
442  com! -nargs=1 -complete=customlist,<SID>ComplInCmdwin_GlobalCompletionList
443       \ TestCommand call s:ComplInCmdwin_CheckCompletion(<q-args>)
444  com! -buffer -nargs=1 -complete=customlist,<SID>ComplInCmdwin_LocalCompletionList
445       \ TestCommand call s:ComplInCmdwin_CheckCompletion(<q-args>)
446
447  call feedkeys("q:iTestCommand \<Tab>\<CR>", 'tx!')
448
449  func! s:ComplInCmdwin_CheckCompletion(arg)
450    call assert_equal('global', a:arg)
451  endfunc
452  new
453  call feedkeys("q:iTestCommand \<Tab>\<CR>", 'tx!')
454  quit
455
456  delfunc s:ComplInCmdwin_GlobalCompletion
457  delfunc s:ComplInCmdwin_LocalCompletion
458  delfunc s:ComplInCmdwin_GlobalCompletionList
459  delfunc s:ComplInCmdwin_LocalCompletionList
460  delfunc s:ComplInCmdwin_CheckCompletion
461
462  delcom -buffer TestCommand
463  delcom TestCommand
464  delcom GetInput
465  unlet w:test_winvar
466  unlet b:test_bufvar
467  set wildmenu& wildchar&
468endfunc
469
470" Test for insert path completion with completeslash option
471func Test_ins_completeslash()
472  CheckMSWindows
473
474  call mkdir('Xdir')
475  let orig_shellslash = &shellslash
476  set cpt&
477  new
478
479  set noshellslash
480
481  set completeslash=
482  exe "normal oXd\<C-X>\<C-F>"
483  call assert_equal('Xdir\', getline('.'))
484
485  set completeslash=backslash
486  exe "normal oXd\<C-X>\<C-F>"
487  call assert_equal('Xdir\', getline('.'))
488
489  set completeslash=slash
490  exe "normal oXd\<C-X>\<C-F>"
491  call assert_equal('Xdir/', getline('.'))
492
493  set shellslash
494
495  set completeslash=
496  exe "normal oXd\<C-X>\<C-F>"
497  call assert_equal('Xdir/', getline('.'))
498
499  set completeslash=backslash
500  exe "normal oXd\<C-X>\<C-F>"
501  call assert_equal('Xdir\', getline('.'))
502
503  set completeslash=slash
504  exe "normal oXd\<C-X>\<C-F>"
505  call assert_equal('Xdir/', getline('.'))
506  %bw!
507  call delete('Xdir', 'rf')
508
509  set noshellslash
510  set completeslash=slash
511  call assert_true(stridx(globpath(&rtp, 'syntax/*.vim', 1, 1)[0], '\') != -1)
512
513  let &shellslash = orig_shellslash
514  set completeslash=
515endfunc
516
517func Test_pum_stopped_by_timer()
518  CheckScreendump
519
520  let lines =<< trim END
521    call setline(1, ['hello', 'hullo', 'heeee', ''])
522    func StartCompl()
523      call timer_start(100, { -> execute('stopinsert') })
524      call feedkeys("Gah\<C-N>")
525    endfunc
526  END
527
528  call writefile(lines, 'Xpumscript')
529  let buf = RunVimInTerminal('-S Xpumscript', #{rows: 12})
530  call term_sendkeys(buf, ":call StartCompl()\<CR>")
531  call TermWait(buf, 200)
532  call term_sendkeys(buf, "k")
533  call VerifyScreenDump(buf, 'Test_pum_stopped_by_timer', {})
534
535  call StopVimInTerminal(buf)
536  call delete('Xpumscript')
537endfunc
538
539func Test_pum_with_folds_two_tabs()
540  CheckScreendump
541
542  let lines =<< trim END
543    set fdm=marker
544    call setline(1, ['" x {{{1', '" a some text'])
545    call setline(3, range(&lines)->map({_, val -> '" a' .. val}))
546    norm! zm
547    tab sp
548    call feedkeys('2Gzv', 'xt')
549    call feedkeys("0fa", 'xt')
550  END
551
552  call writefile(lines, 'Xpumscript')
553  let buf = RunVimInTerminal('-S Xpumscript', #{rows: 10})
554  call TermWait(buf, 50)
555  call term_sendkeys(buf, "a\<C-N>")
556  call VerifyScreenDump(buf, 'Test_pum_with_folds_two_tabs', {})
557
558  call term_sendkeys(buf, "\<Esc>")
559  call StopVimInTerminal(buf)
560  call delete('Xpumscript')
561endfunc
562
563func Test_pum_with_preview_win()
564  CheckScreendump
565
566  let lines =<< trim END
567      funct Omni_test(findstart, base)
568	if a:findstart
569	  return col(".") - 1
570	endif
571	return [#{word: "one", info: "1info"}, #{word: "two", info: "2info"}, #{word: "three", info: "3info"}]
572      endfunc
573      set omnifunc=Omni_test
574      set completeopt+=longest
575  END
576
577  call writefile(lines, 'Xpreviewscript')
578  let buf = RunVimInTerminal('-S Xpreviewscript', #{rows: 12})
579  call TermWait(buf, 50)
580  call term_sendkeys(buf, "Gi\<C-X>\<C-O>")
581  call TermWait(buf, 100)
582  call term_sendkeys(buf, "\<C-N>")
583  call VerifyScreenDump(buf, 'Test_pum_with_preview_win', {})
584
585  call term_sendkeys(buf, "\<Esc>")
586  call StopVimInTerminal(buf)
587  call delete('Xpreviewscript')
588endfunc
589
590" Test for inserting the tag search pattern in insert mode
591func Test_ins_compl_tag_sft()
592  call writefile([
593        \ "!_TAG_FILE_ENCODING\tutf-8\t//",
594        \ "first\tXfoo\t/^int first() {}$/",
595        \ "second\tXfoo\t/^int second() {}$/",
596        \ "third\tXfoo\t/^int third() {}$/"],
597        \ 'Xtags')
598  set tags=Xtags
599  let code =<< trim [CODE]
600    int first() {}
601    int second() {}
602    int third() {}
603  [CODE]
604  call writefile(code, 'Xfoo')
605
606  enew
607  set showfulltag
608  exe "normal isec\<C-X>\<C-]>\<C-N>\<CR>"
609  call assert_equal('int second() {}', getline(1))
610  set noshowfulltag
611
612  call delete('Xtags')
613  call delete('Xfoo')
614  set tags&
615  %bwipe!
616endfunc
617
618" Test for 'completefunc' deleting text
619func Test_completefunc_error()
620  new
621  " delete text when called for the first time
622  func CompleteFunc(findstart, base)
623    if a:findstart == 1
624      normal dd
625      return col('.') - 1
626    endif
627    return ['a', 'b']
628  endfunc
629  set completefunc=CompleteFunc
630  call setline(1, ['', 'abcd', ''])
631  call assert_fails('exe "normal 2G$a\<C-X>\<C-U>"', 'E578:')
632
633  " delete text when called for the second time
634  func CompleteFunc2(findstart, base)
635    if a:findstart == 1
636      return col('.') - 1
637    endif
638    normal dd
639    return ['a', 'b']
640  endfunc
641  set completefunc=CompleteFunc2
642  call setline(1, ['', 'abcd', ''])
643  call assert_fails('exe "normal 2G$a\<C-X>\<C-U>"', 'E578:')
644
645  " Jump to a different window from the complete function
646  func CompleteFunc3(findstart, base)
647    if a:findstart == 1
648      return col('.') - 1
649    endif
650    wincmd p
651    return ['a', 'b']
652  endfunc
653  set completefunc=CompleteFunc3
654  new
655  call assert_fails('exe "normal a\<C-X>\<C-U>"', 'E565:')
656  close!
657
658  set completefunc&
659  delfunc CompleteFunc
660  delfunc CompleteFunc2
661  delfunc CompleteFunc3
662  close!
663endfunc
664
665" Test for returning non-string values from 'completefunc'
666func Test_completefunc_invalid_data()
667  new
668  func! CompleteFunc(findstart, base)
669    if a:findstart == 1
670      return col('.') - 1
671    endif
672    return [{}, '', 'moon']
673  endfunc
674  set completefunc=CompleteFunc
675  exe "normal i\<C-X>\<C-U>"
676  call assert_equal('moon', getline(1))
677  set completefunc&
678  close!
679endfunc
680
681" Test for errors in using complete() function
682func Test_complete_func_error()
683  call assert_fails('call complete(1, ["a"])', 'E785:')
684  func ListColors()
685    call complete(col('.'), "blue")
686  endfunc
687  call assert_fails('exe "normal i\<C-R>=ListColors()\<CR>"', 'E474:')
688  func ListMonths()
689    call complete(col('.'), test_null_list())
690  endfunc
691  call assert_fails('exe "normal i\<C-R>=ListMonths()\<CR>"', 'E474:')
692  delfunc ListColors
693  delfunc ListMonths
694  call assert_fails('call complete_info({})', 'E714:')
695  call assert_equal([], complete_info(['items']).items)
696endfunc
697
698" Test for completing words following a completed word in a line
699func Test_complete_wrapscan()
700  " complete words from another buffer
701  new
702  call setline(1, ['one two', 'three four'])
703  new
704  setlocal complete=w
705  call feedkeys("itw\<C-N>\<C-X>\<C-N>\<C-X>\<C-N>\<C-X>\<C-N>", 'xt')
706  call assert_equal('two three four', getline(1))
707  close!
708  " complete words from the current buffer
709  setlocal complete=.
710  %d
711  call setline(1, ['one two', ''])
712  call cursor(2, 1)
713  call feedkeys("ion\<C-N>\<C-X>\<C-N>\<C-X>\<C-N>\<C-X>\<C-N>", 'xt')
714  call assert_equal('one two one two', getline(2))
715  close!
716endfunc
717
718" Test for completing special characters
719func Test_complete_special_chars()
720  new
721  call setline(1, 'int .*[-\^$ func float')
722  call feedkeys("oin\<C-X>\<C-P>\<C-X>\<C-P>\<C-X>\<C-P>", 'xt')
723  call assert_equal('int .*[-\^$ func float', getline(2))
724  close!
725endfunc
726
727" Test for completion when text is wrapped across lines.
728func Test_complete_across_line()
729  new
730  call setline(1, ['red green blue', 'one two three'])
731  setlocal textwidth=20
732  exe "normal 2G$a re\<C-X>\<C-P>\<C-X>\<C-P>\<C-X>\<C-P>\<C-X>\<C-P>"
733  call assert_equal(['one two three red', 'green blue one'], getline(2, '$'))
734  close!
735endfunc
736
737" Test for using CTRL-L to add one character when completing matching
738func Test_complete_add_onechar()
739  new
740  call setline(1, ['wool', 'woodwork'])
741  call feedkeys("Gowoo\<C-P>\<C-P>\<C-P>\<C-L>f", 'xt')
742  call assert_equal('woof', getline(3))
743
744  " use 'ignorecase' and backspace to erase characters from the prefix string
745  " and then add letters using CTRL-L
746  %d
747  set ignorecase backspace=2
748  setlocal complete=.
749  call setline(1, ['workhorse', 'workload'])
750  normal Go
751  exe "normal aWOR\<C-P>\<bs>\<bs>\<bs>\<bs>\<bs>\<bs>\<C-L>r\<C-L>\<C-L>"
752  call assert_equal('workh', getline(3))
753  set ignorecase& backspace&
754  close!
755endfunc
756
757" Test insert completion with 'cindent' (adjust the indent)
758func Test_complete_with_cindent()
759  new
760  setlocal cindent
761  call setline(1, ['if (i == 1)', "    j = 2;"])
762  exe "normal Go{\<CR>i\<C-X>\<C-L>\<C-X>\<C-L>\<CR>}"
763  call assert_equal(['{', "\tif (i == 1)", "\t\tj = 2;", '}'], getline(3, '$'))
764
765  %d
766  call setline(1, ['when while', '{', ''])
767  setlocal cinkeys+==while
768  exe "normal Giwh\<C-P> "
769  call assert_equal("\twhile ", getline('$'))
770  close!
771endfunc
772
773" Test for <CTRL-X> <CTRL-V> completion. Complete commands and functions
774func Test_complete_cmdline()
775  new
776  exe "normal icaddb\<C-X>\<C-V>"
777  call assert_equal('caddbuffer', getline(1))
778  exe "normal ocall getqf\<C-X>\<C-V>"
779  call assert_equal('call getqflist(', getline(2))
780  exe "normal oabcxyz(\<C-X>\<C-V>"
781  call assert_equal('abcxyz(', getline(3))
782  com! -buffer TestCommand1 echo 'TestCommand1'
783  com! -buffer TestCommand2 echo 'TestCommand2'
784  write TestCommand1Test
785  write TestCommand2Test
786  " Test repeating <CTRL-X> <CTRL-V> and switching to another CTRL-X mode
787  exe "normal oT\<C-X>\<C-V>\<C-X>\<C-V>\<C-X>\<C-F>\<Esc>"
788  call assert_equal('TestCommand2Test', getline(4))
789  call delete('TestCommand1Test')
790  call delete('TestCommand2Test')
791  delcom TestCommand1
792  delcom TestCommand2
793  close!
794endfunc
795
796" Test for <CTRL-X> <CTRL-Z> stopping completion without changing the match
797func Test_complete_stop()
798  new
799  func Save_mode1()
800    let g:mode1 = mode(1)
801    return ''
802  endfunc
803  func Save_mode2()
804    let g:mode2 = mode(1)
805    return ''
806  endfunc
807  inoremap <F1> <C-R>=Save_mode1()<CR>
808  inoremap <F2> <C-R>=Save_mode2()<CR>
809  call setline(1, ['aaa bbb ccc '])
810  exe "normal A\<C-N>\<C-P>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>"
811  call assert_equal('ic', g:mode1)
812  call assert_equal('i', g:mode2)
813  call assert_equal('aaa bbb ccc ', getline(1))
814  exe "normal A\<C-N>\<Down>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>"
815  call assert_equal('ic', g:mode1)
816  call assert_equal('i', g:mode2)
817  call assert_equal('aaa bbb ccc aaa', getline(1))
818  set completeopt+=noselect
819  exe "normal A \<C-N>\<Down>\<Down>\<C-L>\<C-L>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>"
820  call assert_equal('ic', g:mode1)
821  call assert_equal('i', g:mode2)
822  call assert_equal('aaa bbb ccc aaa bb', getline(1))
823  set completeopt&
824  exe "normal A d\<C-N>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>"
825  call assert_equal('ic', g:mode1)
826  call assert_equal('i', g:mode2)
827  call assert_equal('aaa bbb ccc aaa bb d', getline(1))
828  com! -buffer TestCommand1 echo 'TestCommand1'
829  com! -buffer TestCommand2 echo 'TestCommand2'
830  exe "normal oT\<C-X>\<C-V>\<C-X>\<C-V>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>"
831  call assert_equal('ic', g:mode1)
832  call assert_equal('i', g:mode2)
833  call assert_equal('TestCommand2', getline(2))
834  delcom TestCommand1
835  delcom TestCommand2
836  unlet g:mode1
837  unlet g:mode2
838  iunmap <F1>
839  iunmap <F2>
840  delfunc Save_mode1
841  delfunc Save_mode2
842  close!
843endfunc
844
845func Test_issue_7021()
846  CheckMSWindows
847
848  let orig_shellslash = &shellslash
849  set noshellslash
850
851  set completeslash=slash
852  call assert_false(expand('~') =~ '/')
853
854  let &shellslash = orig_shellslash
855  set completeslash=
856endfunc
857
858" Test to ensure 'Scanning...' messages are not recorded in messages history
859func Test_z1_complete_no_history()
860  new
861  messages clear
862  let currmess = execute('messages')
863  setlocal dictionary=README.txt
864  exe "normal owh\<C-X>\<C-K>"
865  exe "normal owh\<C-N>"
866  call assert_equal(currmess, execute('messages'))
867  close!
868endfunc
869
870" vim: shiftwidth=2 sts=2 expandtab
871