blob: 35cacf23bac29583efcff68172c3c3620522724c [file] [log] [blame]
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001" Test for insert completion
2
Bram Moolenaar09dd2bb2019-12-14 18:42:15 +01003source screendump.vim
Bram Moolenaar50f91d22019-08-02 19:52:15 +02004source check.vim
Bram Moolenaar62aec932022-01-29 21:45:34 +00005import './vim9.vim' as v9
Bram Moolenaar15993ce2017-10-26 20:21:44 +02006
7" Test for insert expansion
8func Test_ins_complete()
Bram Moolenaarcf1ba352017-10-27 00:55:04 +02009 edit test_ins_complete.vim
Bram Moolenaarfb094e12017-11-05 20:59:28 +010010 " The files in the current directory interferes with the files
11 " used by this test. So use a separate directory for the test.
12 call mkdir('Xdir')
13 cd Xdir
14
Bram Moolenaar15993ce2017-10-26 20:21:44 +020015 set ff=unix
16 call writefile(["test11\t36Gepeto\t/Tag/",
17 \ "asd\ttest11file\t36G",
18 \ "Makefile\tto\trun"], 'Xtestfile')
19 call writefile(['', 'start of testfile',
20 \ 'ru',
21 \ 'run1',
22 \ 'run2',
23 \ 'STARTTEST',
24 \ 'ENDTEST',
25 \ 'end of testfile'], 'Xtestdata')
26 set ff&
27
28 enew!
29 edit Xtestdata
30 new
31 call append(0, ['#include "Xtestfile"', ''])
32 call cursor(2, 1)
33
34 set cot=
35 set cpt=.,w
36 " add-expands (word from next line) from other window
37 exe "normal iru\<C-N>\<C-N>\<C-X>\<C-N>\<Esc>\<C-A>"
38 call assert_equal('run1 run3', getline('.'))
39 " add-expands (current buffer first)
40 exe "normal o\<C-P>\<C-X>\<C-N>"
41 call assert_equal('run3 run3', getline('.'))
42 " Local expansion, ends in an empty line (unless it becomes a global
43 " expansion)
44 exe "normal o\<C-X>\<C-P>\<C-P>\<C-P>\<C-P>\<C-P>"
45 call assert_equal('', getline('.'))
46 " starts Local and switches to global add-expansion
47 exe "normal o\<C-X>\<C-P>\<C-P>\<C-X>\<C-X>\<C-N>\<C-X>\<C-N>\<C-N>"
48 call assert_equal('run1 run2', getline('.'))
49
Yegappan Lakshmananedc6f102021-12-29 17:38:46 +000050 set cpt=.,\ ,w,i
Bram Moolenaar15993ce2017-10-26 20:21:44 +020051 " i-add-expands and switches to local
52 exe "normal OM\<C-N>\<C-X>\<C-N>\<C-X>\<C-N>\<C-X>\<C-X>\<C-X>\<C-P>"
53 call assert_equal("Makefile\tto\trun3", getline('.'))
Dominique Pelle923dce22021-11-21 11:36:04 +000054 " add-expands lines (it would end in an empty line if it didn't ignore
Bram Moolenaar15993ce2017-10-26 20:21:44 +020055 " itself)
56 exe "normal o\<C-X>\<C-L>\<C-X>\<C-L>\<C-P>\<C-P>"
57 call assert_equal("Makefile\tto\trun3", getline('.'))
58 call assert_equal("Makefile\tto\trun3", getline(line('.') - 1))
59
60 set cpt=kXtestfile
61 " checks k-expansion, and file expansion (use Xtest11 instead of test11,
62 " because TEST11.OUT may match first on DOS)
63 write Xtest11.one
64 write Xtest11.two
65 exe "normal o\<C-N>\<Esc>IX\<Esc>A\<C-X>\<C-F>\<C-N>"
66 call assert_equal('Xtest11.two', getline('.'))
67
68 " use CTRL-X CTRL-F to complete Xtest11.one, remove it and then use CTRL-X
69 " CTRL-F again to verify this doesn't cause trouble.
70 exe "normal oXt\<C-X>\<C-F>\<BS>\<BS>\<BS>\<BS>\<BS>\<BS>\<BS>\<BS>\<C-X>\<C-F>"
71 call assert_equal('Xtest11.one', getline('.'))
72 normal ddk
73
Yegappan Lakshmanan37079142022-01-08 10:38:48 +000074 " Test for expanding a non-existing filename
75 exe "normal oa1b2X3Y4\<C-X>\<C-F>"
76 call assert_equal('a1b2X3Y4', getline('.'))
77 normal ddk
78
Bram Moolenaar15993ce2017-10-26 20:21:44 +020079 set cpt=w
80 " checks make_cyclic in other window
81 exe "normal oST\<C-N>\<C-P>\<C-P>\<C-P>\<C-P>"
82 call assert_equal('STARTTEST', getline('.'))
83
84 set cpt=u nohid
85 " checks unloaded buffer expansion
86 only
87 exe "normal oEN\<C-N>"
88 call assert_equal('ENDTEST', getline('.'))
89 " checks adding mode abortion
90 exe "normal ounl\<C-N>\<C-X>\<C-X>\<C-P>"
91 call assert_equal('unless', getline('.'))
92
93 set cpt=t,d def=^\\k* tags=Xtestfile notagbsearch
94 " tag expansion, define add-expansion interrupted
95 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>"
96 call assert_equal('test11file 36Gepeto /Tag/ asd', getline('.'))
97 " t-expansion
98 exe "normal oa\<C-N>\<Esc>"
99 call assert_equal('asd', getline('.'))
100
101 %bw!
102 call delete('Xtestfile')
103 call delete('Xtest11.one')
104 call delete('Xtest11.two')
105 call delete('Xtestdata')
106 set cpt& cot& def& tags& tagbsearch& hidden&
Bram Moolenaarfb094e12017-11-05 20:59:28 +0100107 cd ..
108 call delete('Xdir', 'rf')
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200109endfunc
Bram Moolenaarffd99f72017-11-02 15:44:14 +0100110
Bram Moolenaar4b28ba32021-12-27 19:28:37 +0000111func Test_ins_complete_invalid_byte()
112 if has('unix') && executable('base64')
113 " this weird command was causing an illegal memory access
114 call writefile(['bm9ybTlvMDCAMM4Dbw4OGA4ODg=='], 'Xinvalid64')
115 call system('base64 -d Xinvalid64 > Xinvalid')
116 call writefile(['qa!'], 'Xexit')
117 call RunVim([], [], " -i NONE -n -X -Z -e -m -s -S Xinvalid -S Xexit")
118 call delete('Xinvalid64')
119 call delete('Xinvalid')
120 call delete('Xexit')
121 endif
122endfunc
123
Bram Moolenaarffd99f72017-11-02 15:44:14 +0100124func Test_omni_dash()
125 func Omni(findstart, base)
126 if a:findstart
127 return 5
128 else
129 echom a:base
130 return ['-help', '-v']
131 endif
132 endfunc
133 set omnifunc=Omni
134 new
135 exe "normal Gofind -\<C-x>\<C-o>"
Bram Moolenaarcc233582020-12-12 13:32:07 +0100136 call assert_equal("find -help", getline('$'))
Bram Moolenaarffd99f72017-11-02 15:44:14 +0100137
138 bwipe!
139 delfunc Omni
140 set omnifunc=
141endfunc
Bram Moolenaar02ae9b42018-02-09 15:06:02 +0100142
Bram Moolenaarff34bee2021-07-25 20:27:06 +0200143func Test_omni_autoload()
144 let save_rtp = &rtp
145 set rtp=Xruntime/some
146 let dir = 'Xruntime/some/autoload'
147 call mkdir(dir, 'p')
148
149 let lines =<< trim END
150 vim9script
151 def omni#func(findstart: bool, base: string): any
152 if findstart
153 return 1
154 else
155 return ['match']
156 endif
157 enddef
158 {
159 eval 1 + 2
160 }
161 END
162 call writefile(lines, dir .. '/omni.vim')
163
164 new
165 setlocal omnifunc=omni#func
166 call feedkeys("i\<C-X>\<C-O>\<Esc>", 'xt')
167
168 bwipe!
169 call delete('Xruntime', 'rf')
170 set omnifunc=
171 let &rtp = save_rtp
172endfunc
173
Bram Moolenaarffa96842018-06-12 22:05:14 +0200174func Test_completefunc_args()
175 let s:args = []
176 func! CompleteFunc(findstart, base)
177 let s:args += [[a:findstart, empty(a:base)]]
178 endfunc
179 new
180
181 set completefunc=CompleteFunc
182 call feedkeys("i\<C-X>\<C-U>\<Esc>", 'x')
Bram Moolenaar52d3aae2018-06-13 21:27:24 +0200183 call assert_equal([1, 1], s:args[0])
184 call assert_equal(0, s:args[1][0])
Bram Moolenaarffa96842018-06-12 22:05:14 +0200185 set completefunc=
186
187 let s:args = []
188 set omnifunc=CompleteFunc
189 call feedkeys("i\<C-X>\<C-O>\<Esc>", 'x')
Bram Moolenaar52d3aae2018-06-13 21:27:24 +0200190 call assert_equal([1, 1], s:args[0])
191 call assert_equal(0, s:args[1][0])
Bram Moolenaarffa96842018-06-12 22:05:14 +0200192 set omnifunc=
193
194 bwipe!
195 unlet s:args
196 delfunc CompleteFunc
197endfunc
198
Bram Moolenaarcee9bc22019-01-11 13:02:23 +0100199func s:CompleteDone_CompleteFuncNone( findstart, base )
200 if a:findstart
201 return 0
202 endif
203
204 return v:none
205endfunc
206
Bram Moolenaar1e115362019-01-09 23:01:02 +0100207func s:CompleteDone_CompleteFuncDict( findstart, base )
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100208 if a:findstart
209 return 0
210 endif
211
212 return {
Bram Moolenaar08928322020-01-04 14:32:48 +0100213 \ 'words': [
214 \ {
215 \ 'word': 'aword',
216 \ 'abbr': 'wrd',
217 \ 'menu': 'extra text',
218 \ 'info': 'words are cool',
219 \ 'kind': 'W',
220 \ 'user_data': 'test'
221 \ }
222 \ ]
223 \ }
Bram Moolenaar1e115362019-01-09 23:01:02 +0100224endfunc
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100225
Bram Moolenaarcee9bc22019-01-11 13:02:23 +0100226func s:CompleteDone_CheckCompletedItemNone()
227 let s:called_completedone = 1
228endfunc
229
Bram Moolenaar3f169ce2020-01-26 22:43:31 +0100230func s:CompleteDone_CheckCompletedItemDict(pre)
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100231 call assert_equal( 'aword', v:completed_item[ 'word' ] )
232 call assert_equal( 'wrd', v:completed_item[ 'abbr' ] )
233 call assert_equal( 'extra text', v:completed_item[ 'menu' ] )
234 call assert_equal( 'words are cool', v:completed_item[ 'info' ] )
235 call assert_equal( 'W', v:completed_item[ 'kind' ] )
236 call assert_equal( 'test', v:completed_item[ 'user_data' ] )
237
Bram Moolenaar3f169ce2020-01-26 22:43:31 +0100238 if a:pre
239 call assert_equal('function', complete_info().mode)
240 endif
Bram Moolenaar17e04782020-01-17 18:58:59 +0100241
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100242 let s:called_completedone = 1
Bram Moolenaar1e115362019-01-09 23:01:02 +0100243endfunc
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100244
Bram Moolenaarcee9bc22019-01-11 13:02:23 +0100245func Test_CompleteDoneNone()
246 au CompleteDone * :call <SID>CompleteDone_CheckCompletedItemNone()
Bram Moolenaar9845f362019-04-08 18:59:54 +0200247 let oldline = join(map(range(&columns), 'nr2char(screenchar(&lines-1, v:val+1))'), '')
Bram Moolenaarcee9bc22019-01-11 13:02:23 +0100248
249 set completefunc=<SID>CompleteDone_CompleteFuncNone
250 execute "normal a\<C-X>\<C-U>\<C-Y>"
251 set completefunc&
Bram Moolenaar9845f362019-04-08 18:59:54 +0200252 let newline = join(map(range(&columns), 'nr2char(screenchar(&lines-1, v:val+1))'), '')
Bram Moolenaarcee9bc22019-01-11 13:02:23 +0100253
254 call assert_true(s:called_completedone)
Bram Moolenaar9845f362019-04-08 18:59:54 +0200255 call assert_equal(oldline, newline)
Bram Moolenaarcee9bc22019-01-11 13:02:23 +0100256
257 let s:called_completedone = 0
258 au! CompleteDone
259endfunc
260
261func Test_CompleteDoneDict()
Bram Moolenaar3f169ce2020-01-26 22:43:31 +0100262 au CompleteDonePre * :call <SID>CompleteDone_CheckCompletedItemDict(1)
263 au CompleteDone * :call <SID>CompleteDone_CheckCompletedItemDict(0)
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100264
265 set completefunc=<SID>CompleteDone_CompleteFuncDict
266 execute "normal a\<C-X>\<C-U>\<C-Y>"
267 set completefunc&
268
Bram Moolenaarcee9bc22019-01-11 13:02:23 +0100269 call assert_equal('test', v:completed_item[ 'user_data' ])
270 call assert_true(s:called_completedone)
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100271
272 let s:called_completedone = 0
273 au! CompleteDone
274endfunc
275
Bram Moolenaarcee9bc22019-01-11 13:02:23 +0100276func s:CompleteDone_CompleteFuncDictNoUserData(findstart, base)
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100277 if a:findstart
278 return 0
279 endif
280
281 return {
Bram Moolenaar08928322020-01-04 14:32:48 +0100282 \ 'words': [
283 \ {
284 \ 'word': 'aword',
285 \ 'abbr': 'wrd',
286 \ 'menu': 'extra text',
287 \ 'info': 'words are cool',
288 \ 'kind': 'W',
289 \ 'user_data': ['one', 'two'],
290 \ }
291 \ ]
292 \ }
Bram Moolenaar1e115362019-01-09 23:01:02 +0100293endfunc
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100294
Bram Moolenaar1e115362019-01-09 23:01:02 +0100295func s:CompleteDone_CheckCompletedItemDictNoUserData()
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100296 call assert_equal( 'aword', v:completed_item[ 'word' ] )
297 call assert_equal( 'wrd', v:completed_item[ 'abbr' ] )
298 call assert_equal( 'extra text', v:completed_item[ 'menu' ] )
299 call assert_equal( 'words are cool', v:completed_item[ 'info' ] )
300 call assert_equal( 'W', v:completed_item[ 'kind' ] )
Bram Moolenaar08928322020-01-04 14:32:48 +0100301 call assert_equal( ['one', 'two'], v:completed_item[ 'user_data' ] )
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100302
303 let s:called_completedone = 1
Bram Moolenaar1e115362019-01-09 23:01:02 +0100304endfunc
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100305
Bram Moolenaarcee9bc22019-01-11 13:02:23 +0100306func Test_CompleteDoneDictNoUserData()
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100307 au CompleteDone * :call <SID>CompleteDone_CheckCompletedItemDictNoUserData()
308
309 set completefunc=<SID>CompleteDone_CompleteFuncDictNoUserData
310 execute "normal a\<C-X>\<C-U>\<C-Y>"
311 set completefunc&
312
Bram Moolenaar08928322020-01-04 14:32:48 +0100313 call assert_equal(['one', 'two'], v:completed_item[ 'user_data' ])
Bram Moolenaarcee9bc22019-01-11 13:02:23 +0100314 call assert_true(s:called_completedone)
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100315
316 let s:called_completedone = 0
317 au! CompleteDone
318endfunc
319
Bram Moolenaarcee9bc22019-01-11 13:02:23 +0100320func s:CompleteDone_CompleteFuncList(findstart, base)
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100321 if a:findstart
322 return 0
323 endif
324
325 return [ 'aword' ]
Bram Moolenaar1e115362019-01-09 23:01:02 +0100326endfunc
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100327
Bram Moolenaar1e115362019-01-09 23:01:02 +0100328func s:CompleteDone_CheckCompletedItemList()
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100329 call assert_equal( 'aword', v:completed_item[ 'word' ] )
330 call assert_equal( '', v:completed_item[ 'abbr' ] )
331 call assert_equal( '', v:completed_item[ 'menu' ] )
332 call assert_equal( '', v:completed_item[ 'info' ] )
333 call assert_equal( '', v:completed_item[ 'kind' ] )
334 call assert_equal( '', v:completed_item[ 'user_data' ] )
335
336 let s:called_completedone = 1
Bram Moolenaar1e115362019-01-09 23:01:02 +0100337endfunc
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100338
Bram Moolenaarcee9bc22019-01-11 13:02:23 +0100339func Test_CompleteDoneList()
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100340 au CompleteDone * :call <SID>CompleteDone_CheckCompletedItemList()
341
342 set completefunc=<SID>CompleteDone_CompleteFuncList
343 execute "normal a\<C-X>\<C-U>\<C-Y>"
344 set completefunc&
345
Bram Moolenaarcee9bc22019-01-11 13:02:23 +0100346 call assert_equal('', v:completed_item[ 'user_data' ])
347 call assert_true(s:called_completedone)
Bram Moolenaar9b56a572018-02-10 16:19:32 +0100348
349 let s:called_completedone = 0
350 au! CompleteDone
351endfunc
352
Bram Moolenaaraf559d22018-08-08 22:55:41 +0200353func Test_CompleteDone_undo()
354 au CompleteDone * call append(0, "prepend1")
355 new
356 call setline(1, ["line1", "line2"])
357 call feedkeys("Go\<C-X>\<C-N>\<CR>\<ESC>", "tx")
358 call assert_equal(["prepend1", "line1", "line2", "line1", ""],
359 \ getline(1, '$'))
360 undo
361 call assert_equal(["line1", "line2"], getline(1, '$'))
362 bwipe!
363 au! CompleteDone
364endfunc
365
Bram Moolenaarb806aa52020-09-12 22:52:57 +0200366func CompleteTest(findstart, query)
367 if a:findstart
368 return col('.')
369 endif
370 return ['matched']
371endfunc
372
373func Test_completefunc_info()
374 new
375 set completeopt=menuone
376 set completefunc=CompleteTest
377 call feedkeys("i\<C-X>\<C-U>\<C-R>\<C-R>=string(complete_info())\<CR>\<ESC>", "tx")
Bram Moolenaarf9d51352020-10-26 19:22:42 +0100378 call assert_equal("matched{'pum_visible': 1, 'mode': 'function', 'selected': 0, 'items': [{'word': 'matched', 'menu': '', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}]}", getline(1))
Bram Moolenaarb806aa52020-09-12 22:52:57 +0200379 bwipe!
380 set completeopt&
381 set completefunc&
382endfunc
383
Bram Moolenaar02ae9b42018-02-09 15:06:02 +0100384" Check that when using feedkeys() typeahead does not interrupt searching for
385" completions.
386func Test_compl_feedkeys()
387 new
388 set completeopt=menuone,noselect
389 call feedkeys("ajump ju\<C-X>\<C-N>\<C-P>\<ESC>", "tx")
390 call assert_equal("jump jump", getline(1))
391 bwipe!
392 set completeopt&
393endfunc
Bram Moolenaarf03e3282019-07-22 21:55:18 +0200394
mityua1198122021-11-20 19:13:39 +0000395func s:ComplInCmdwin_GlobalCompletion(a, l, p)
396 return 'global'
397endfunc
398
399func s:ComplInCmdwin_LocalCompletion(a, l, p)
400 return 'local'
401endfunc
402
Bram Moolenaarf03e3282019-07-22 21:55:18 +0200403func Test_compl_in_cmdwin()
Bram Moolenaar21829c52021-01-26 22:42:21 +0100404 CheckFeature cmdwin
405
Bram Moolenaarf03e3282019-07-22 21:55:18 +0200406 set wildmenu wildchar=<Tab>
407 com! -nargs=1 -complete=command GetInput let input = <q-args>
408 com! -buffer TestCommand echo 'TestCommand'
Bram Moolenaar4ff2f2f2020-10-25 13:22:42 +0100409 let w:test_winvar = 'winvar'
410 let b:test_bufvar = 'bufvar'
Bram Moolenaarf03e3282019-07-22 21:55:18 +0200411
Bram Moolenaar4ff2f2f2020-10-25 13:22:42 +0100412 " User-defined commands
Bram Moolenaarf03e3282019-07-22 21:55:18 +0200413 let input = ''
414 call feedkeys("q:iGetInput T\<C-x>\<C-v>\<CR>", 'tx!')
415 call assert_equal('TestCommand', input)
416
417 let input = ''
418 call feedkeys("q::GetInput T\<Tab>\<CR>:q\<CR>", 'tx!')
419 call assert_equal('T', input)
420
Bram Moolenaar4ff2f2f2020-10-25 13:22:42 +0100421
422 com! -nargs=1 -complete=var GetInput let input = <q-args>
423 " Window-local variables
424 let input = ''
425 call feedkeys("q:iGetInput w:test_\<C-x>\<C-v>\<CR>", 'tx!')
426 call assert_equal('w:test_winvar', input)
427
428 let input = ''
429 call feedkeys("q::GetInput w:test_\<Tab>\<CR>:q\<CR>", 'tx!')
430 call assert_equal('w:test_', input)
431
432 " Buffer-local variables
433 let input = ''
434 call feedkeys("q:iGetInput b:test_\<C-x>\<C-v>\<CR>", 'tx!')
435 call assert_equal('b:test_bufvar', input)
436
437 let input = ''
438 call feedkeys("q::GetInput b:test_\<Tab>\<CR>:q\<CR>", 'tx!')
439 call assert_equal('b:test_', input)
440
mityua1198122021-11-20 19:13:39 +0000441
442 " Argument completion of buffer-local command
443 func s:ComplInCmdwin_GlobalCompletionList(a, l, p)
444 return ['global']
445 endfunc
446
447 func s:ComplInCmdwin_LocalCompletionList(a, l, p)
448 return ['local']
449 endfunc
450
451 func s:ComplInCmdwin_CheckCompletion(arg)
452 call assert_equal('local', a:arg)
453 endfunc
454
455 com! -nargs=1 -complete=custom,<SID>ComplInCmdwin_GlobalCompletion
456 \ TestCommand call s:ComplInCmdwin_CheckCompletion(<q-args>)
457 com! -buffer -nargs=1 -complete=custom,<SID>ComplInCmdwin_LocalCompletion
458 \ TestCommand call s:ComplInCmdwin_CheckCompletion(<q-args>)
459 call feedkeys("q:iTestCommand \<Tab>\<CR>", 'tx!')
460
461 com! -nargs=1 -complete=customlist,<SID>ComplInCmdwin_GlobalCompletionList
462 \ TestCommand call s:ComplInCmdwin_CheckCompletion(<q-args>)
463 com! -buffer -nargs=1 -complete=customlist,<SID>ComplInCmdwin_LocalCompletionList
464 \ TestCommand call s:ComplInCmdwin_CheckCompletion(<q-args>)
465
466 call feedkeys("q:iTestCommand \<Tab>\<CR>", 'tx!')
467
468 func! s:ComplInCmdwin_CheckCompletion(arg)
469 call assert_equal('global', a:arg)
470 endfunc
471 new
472 call feedkeys("q:iTestCommand \<Tab>\<CR>", 'tx!')
473 quit
474
475 delfunc s:ComplInCmdwin_GlobalCompletion
476 delfunc s:ComplInCmdwin_LocalCompletion
477 delfunc s:ComplInCmdwin_GlobalCompletionList
478 delfunc s:ComplInCmdwin_LocalCompletionList
479 delfunc s:ComplInCmdwin_CheckCompletion
480
481 delcom -buffer TestCommand
Bram Moolenaarf03e3282019-07-22 21:55:18 +0200482 delcom TestCommand
483 delcom GetInput
Bram Moolenaar4ff2f2f2020-10-25 13:22:42 +0100484 unlet w:test_winvar
485 unlet b:test_bufvar
Bram Moolenaarf03e3282019-07-22 21:55:18 +0200486 set wildmenu& wildchar&
487endfunc
Bram Moolenaarac3150d2019-07-28 16:36:39 +0200488
489" Test for insert path completion with completeslash option
490func Test_ins_completeslash()
Bram Moolenaar50f91d22019-08-02 19:52:15 +0200491 CheckMSWindows
Bram Moolenaar8f187fc2020-09-26 18:47:11 +0200492
Bram Moolenaarac3150d2019-07-28 16:36:39 +0200493 call mkdir('Xdir')
Bram Moolenaarac3150d2019-07-28 16:36:39 +0200494 let orig_shellslash = &shellslash
495 set cpt&
Bram Moolenaarac3150d2019-07-28 16:36:39 +0200496 new
Bram Moolenaar8f187fc2020-09-26 18:47:11 +0200497
Bram Moolenaarac3150d2019-07-28 16:36:39 +0200498 set noshellslash
499
500 set completeslash=
501 exe "normal oXd\<C-X>\<C-F>"
502 call assert_equal('Xdir\', getline('.'))
503
504 set completeslash=backslash
505 exe "normal oXd\<C-X>\<C-F>"
506 call assert_equal('Xdir\', getline('.'))
507
508 set completeslash=slash
509 exe "normal oXd\<C-X>\<C-F>"
510 call assert_equal('Xdir/', getline('.'))
511
512 set shellslash
513
514 set completeslash=
515 exe "normal oXd\<C-X>\<C-F>"
516 call assert_equal('Xdir/', getline('.'))
517
518 set completeslash=backslash
519 exe "normal oXd\<C-X>\<C-F>"
520 call assert_equal('Xdir\', getline('.'))
521
522 set completeslash=slash
523 exe "normal oXd\<C-X>\<C-F>"
524 call assert_equal('Xdir/', getline('.'))
525 %bw!
526 call delete('Xdir', 'rf')
527
Bram Moolenaar50f91d22019-08-02 19:52:15 +0200528 set noshellslash
529 set completeslash=slash
530 call assert_true(stridx(globpath(&rtp, 'syntax/*.vim', 1, 1)[0], '\') != -1)
531
Bram Moolenaarac3150d2019-07-28 16:36:39 +0200532 let &shellslash = orig_shellslash
Bram Moolenaar50f91d22019-08-02 19:52:15 +0200533 set completeslash=
Bram Moolenaarac3150d2019-07-28 16:36:39 +0200534endfunc
535
Bram Moolenaard0e1b712020-09-27 20:13:03 +0200536func Test_pum_stopped_by_timer()
537 CheckScreendump
538
539 let lines =<< trim END
540 call setline(1, ['hello', 'hullo', 'heeee', ''])
541 func StartCompl()
542 call timer_start(100, { -> execute('stopinsert') })
543 call feedkeys("Gah\<C-N>")
544 endfunc
545 END
546
547 call writefile(lines, 'Xpumscript')
548 let buf = RunVimInTerminal('-S Xpumscript', #{rows: 12})
549 call term_sendkeys(buf, ":call StartCompl()\<CR>")
550 call TermWait(buf, 200)
551 call term_sendkeys(buf, "k")
552 call VerifyScreenDump(buf, 'Test_pum_stopped_by_timer', {})
553
554 call StopVimInTerminal(buf)
555 call delete('Xpumscript')
556endfunc
557
Bram Moolenaar09dd2bb2019-12-14 18:42:15 +0100558func Test_pum_with_folds_two_tabs()
559 CheckScreendump
560
561 let lines =<< trim END
562 set fdm=marker
563 call setline(1, ['" x {{{1', '" a some text'])
564 call setline(3, range(&lines)->map({_, val -> '" a' .. val}))
565 norm! zm
566 tab sp
567 call feedkeys('2Gzv', 'xt')
568 call feedkeys("0fa", 'xt')
569 END
570
571 call writefile(lines, 'Xpumscript')
572 let buf = RunVimInTerminal('-S Xpumscript', #{rows: 10})
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200573 call TermWait(buf, 50)
Bram Moolenaar09dd2bb2019-12-14 18:42:15 +0100574 call term_sendkeys(buf, "a\<C-N>")
575 call VerifyScreenDump(buf, 'Test_pum_with_folds_two_tabs', {})
576
577 call term_sendkeys(buf, "\<Esc>")
578 call StopVimInTerminal(buf)
579 call delete('Xpumscript')
580endfunc
Bram Moolenaar5e5a98d2019-12-15 14:55:33 +0100581
582func Test_pum_with_preview_win()
583 CheckScreendump
584
585 let lines =<< trim END
586 funct Omni_test(findstart, base)
587 if a:findstart
588 return col(".") - 1
589 endif
590 return [#{word: "one", info: "1info"}, #{word: "two", info: "2info"}, #{word: "three", info: "3info"}]
591 endfunc
592 set omnifunc=Omni_test
593 set completeopt+=longest
594 END
595
596 call writefile(lines, 'Xpreviewscript')
597 let buf = RunVimInTerminal('-S Xpreviewscript', #{rows: 12})
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200598 call TermWait(buf, 50)
Bram Moolenaar5e5a98d2019-12-15 14:55:33 +0100599 call term_sendkeys(buf, "Gi\<C-X>\<C-O>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200600 call TermWait(buf, 100)
Bram Moolenaar5e5a98d2019-12-15 14:55:33 +0100601 call term_sendkeys(buf, "\<C-N>")
602 call VerifyScreenDump(buf, 'Test_pum_with_preview_win', {})
603
604 call term_sendkeys(buf, "\<Esc>")
605 call StopVimInTerminal(buf)
606 call delete('Xpreviewscript')
607endfunc
Bram Moolenaar830c1af2020-01-05 20:35:44 +0100608
609" Test for inserting the tag search pattern in insert mode
610func Test_ins_compl_tag_sft()
611 call writefile([
612 \ "!_TAG_FILE_ENCODING\tutf-8\t//",
613 \ "first\tXfoo\t/^int first() {}$/",
614 \ "second\tXfoo\t/^int second() {}$/",
615 \ "third\tXfoo\t/^int third() {}$/"],
616 \ 'Xtags')
617 set tags=Xtags
618 let code =<< trim [CODE]
619 int first() {}
620 int second() {}
621 int third() {}
622 [CODE]
623 call writefile(code, 'Xfoo')
624
625 enew
626 set showfulltag
627 exe "normal isec\<C-X>\<C-]>\<C-N>\<CR>"
628 call assert_equal('int second() {}', getline(1))
629 set noshowfulltag
630
631 call delete('Xtags')
632 call delete('Xfoo')
633 set tags&
634 %bwipe!
635endfunc
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200636
637" Test for 'completefunc' deleting text
638func Test_completefunc_error()
639 new
Bram Moolenaarad48e6c2020-04-21 22:19:45 +0200640 " delete text when called for the first time
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200641 func CompleteFunc(findstart, base)
642 if a:findstart == 1
643 normal dd
644 return col('.') - 1
645 endif
646 return ['a', 'b']
647 endfunc
648 set completefunc=CompleteFunc
649 call setline(1, ['', 'abcd', ''])
Bram Moolenaar3eb6bd92021-01-29 21:47:24 +0100650 call assert_fails('exe "normal 2G$a\<C-X>\<C-U>"', 'E578:')
Bram Moolenaarad48e6c2020-04-21 22:19:45 +0200651
652 " delete text when called for the second time
653 func CompleteFunc2(findstart, base)
654 if a:findstart == 1
655 return col('.') - 1
656 endif
657 normal dd
658 return ['a', 'b']
659 endfunc
660 set completefunc=CompleteFunc2
661 call setline(1, ['', 'abcd', ''])
Bram Moolenaar6adb9ea2020-04-30 22:31:18 +0200662 call assert_fails('exe "normal 2G$a\<C-X>\<C-U>"', 'E578:')
Bram Moolenaarad48e6c2020-04-21 22:19:45 +0200663
Bram Moolenaar97202d92021-01-28 18:34:35 +0100664 " Jump to a different window from the complete function
Bram Moolenaar28976e22021-01-29 21:07:07 +0100665 func CompleteFunc3(findstart, base)
Bram Moolenaar97202d92021-01-28 18:34:35 +0100666 if a:findstart == 1
667 return col('.') - 1
668 endif
669 wincmd p
670 return ['a', 'b']
671 endfunc
Bram Moolenaar28976e22021-01-29 21:07:07 +0100672 set completefunc=CompleteFunc3
Bram Moolenaar97202d92021-01-28 18:34:35 +0100673 new
Bram Moolenaar28976e22021-01-29 21:07:07 +0100674 call assert_fails('exe "normal a\<C-X>\<C-U>"', 'E565:')
Bram Moolenaar97202d92021-01-28 18:34:35 +0100675 close!
676
677 set completefunc&
678 delfunc CompleteFunc
Bram Moolenaar28976e22021-01-29 21:07:07 +0100679 delfunc CompleteFunc2
680 delfunc CompleteFunc3
681 close!
Bram Moolenaar97202d92021-01-28 18:34:35 +0100682endfunc
683
Bram Moolenaarf9ab52e2020-05-05 19:57:18 +0200684" Test for returning non-string values from 'completefunc'
685func Test_completefunc_invalid_data()
686 new
687 func! CompleteFunc(findstart, base)
688 if a:findstart == 1
689 return col('.') - 1
690 endif
691 return [{}, '', 'moon']
692 endfunc
693 set completefunc=CompleteFunc
694 exe "normal i\<C-X>\<C-U>"
695 call assert_equal('moon', getline(1))
696 set completefunc&
697 close!
698endfunc
699
Bram Moolenaarad48e6c2020-04-21 22:19:45 +0200700" Test for errors in using complete() function
701func Test_complete_func_error()
702 call assert_fails('call complete(1, ["a"])', 'E785:')
703 func ListColors()
704 call complete(col('.'), "blue")
705 endfunc
706 call assert_fails('exe "normal i\<C-R>=ListColors()\<CR>"', 'E474:')
707 func ListMonths()
708 call complete(col('.'), test_null_list())
709 endfunc
710 call assert_fails('exe "normal i\<C-R>=ListMonths()\<CR>"', 'E474:')
711 delfunc ListColors
712 delfunc ListMonths
713 call assert_fails('call complete_info({})', 'E714:')
Bram Moolenaarf9ab52e2020-05-05 19:57:18 +0200714 call assert_equal([], complete_info(['items']).items)
Bram Moolenaarad48e6c2020-04-21 22:19:45 +0200715endfunc
716
Yegappan Lakshmanane9825862022-01-03 11:03:48 +0000717" Test for recursively starting completion mode using complete()
718func Test_recursive_complete_func()
719 func ListColors()
720 call complete(5, ["red", "blue"])
721 return ''
722 endfunc
723 new
724 call setline(1, ['a1', 'a2'])
725 set complete=.
726 exe "normal Goa\<C-X>\<C-L>\<C-R>=ListColors()\<CR>\<C-N>"
727 call assert_equal('a2blue', getline(3))
728 delfunc ListColors
729 bw!
730endfunc
731
Bram Moolenaar224a5f12020-04-28 20:29:07 +0200732" Test for completing words following a completed word in a line
733func Test_complete_wrapscan()
734 " complete words from another buffer
735 new
736 call setline(1, ['one two', 'three four'])
737 new
738 setlocal complete=w
739 call feedkeys("itw\<C-N>\<C-X>\<C-N>\<C-X>\<C-N>\<C-X>\<C-N>", 'xt')
740 call assert_equal('two three four', getline(1))
741 close!
742 " complete words from the current buffer
743 setlocal complete=.
744 %d
745 call setline(1, ['one two', ''])
746 call cursor(2, 1)
747 call feedkeys("ion\<C-N>\<C-X>\<C-N>\<C-X>\<C-N>\<C-X>\<C-N>", 'xt')
748 call assert_equal('one two one two', getline(2))
749 close!
750endfunc
751
Bram Moolenaarf9ab52e2020-05-05 19:57:18 +0200752" Test for completing special characters
753func Test_complete_special_chars()
754 new
755 call setline(1, 'int .*[-\^$ func float')
756 call feedkeys("oin\<C-X>\<C-P>\<C-X>\<C-P>\<C-X>\<C-P>", 'xt')
757 call assert_equal('int .*[-\^$ func float', getline(2))
758 close!
759endfunc
760
761" Test for completion when text is wrapped across lines.
762func Test_complete_across_line()
763 new
764 call setline(1, ['red green blue', 'one two three'])
765 setlocal textwidth=20
766 exe "normal 2G$a re\<C-X>\<C-P>\<C-X>\<C-P>\<C-X>\<C-P>\<C-X>\<C-P>"
767 call assert_equal(['one two three red', 'green blue one'], getline(2, '$'))
768 close!
769endfunc
770
Yegappan Lakshmananedc6f102021-12-29 17:38:46 +0000771" Test for completing words with a '.' at the end of a word.
772func Test_complete_joinspaces()
773 new
774 call setline(1, ['one two.', 'three. four'])
775 set joinspaces
776 exe "normal Goon\<C-P>\<C-X>\<C-P>\<C-X>\<C-P>\<C-X>\<C-P>\<C-X>\<C-P>"
777 call assert_equal("one two. three. four", getline(3))
778 set joinspaces&
779 bw!
780endfunc
781
Bram Moolenaarf9ab52e2020-05-05 19:57:18 +0200782" Test for using CTRL-L to add one character when completing matching
783func Test_complete_add_onechar()
784 new
785 call setline(1, ['wool', 'woodwork'])
786 call feedkeys("Gowoo\<C-P>\<C-P>\<C-P>\<C-L>f", 'xt')
787 call assert_equal('woof', getline(3))
788
789 " use 'ignorecase' and backspace to erase characters from the prefix string
790 " and then add letters using CTRL-L
791 %d
792 set ignorecase backspace=2
793 setlocal complete=.
794 call setline(1, ['workhorse', 'workload'])
795 normal Go
796 exe "normal aWOR\<C-P>\<bs>\<bs>\<bs>\<bs>\<bs>\<bs>\<C-L>r\<C-L>\<C-L>"
797 call assert_equal('workh', getline(3))
798 set ignorecase& backspace&
799 close!
800endfunc
801
Yegappan Lakshmananedc6f102021-12-29 17:38:46 +0000802" Test for using CTRL-X CTRL-L to complete whole lines lines
803func Test_complete_wholeline()
804 new
805 " complete one-line
806 call setline(1, ['a1', 'a2'])
807 exe "normal ggoa\<C-X>\<C-L>"
808 call assert_equal(['a1', 'a1', 'a2'], getline(1, '$'))
809 " go to the next match (wrapping around the buffer)
810 exe "normal 2GCa\<C-X>\<C-L>\<C-N>"
811 call assert_equal(['a1', 'a', 'a2'], getline(1, '$'))
812 " go to the next match
813 exe "normal 2GCa\<C-X>\<C-L>\<C-N>\<C-N>"
814 call assert_equal(['a1', 'a2', 'a2'], getline(1, '$'))
815 exe "normal 2GCa\<C-X>\<C-L>\<C-N>\<C-N>\<C-N>"
816 call assert_equal(['a1', 'a1', 'a2'], getline(1, '$'))
817 " repeat the test using CTRL-L
818 " go to the next match (wrapping around the buffer)
819 exe "normal 2GCa\<C-X>\<C-L>\<C-L>"
820 call assert_equal(['a1', 'a2', 'a2'], getline(1, '$'))
821 " go to the next match
822 exe "normal 2GCa\<C-X>\<C-L>\<C-L>\<C-L>"
823 call assert_equal(['a1', 'a', 'a2'], getline(1, '$'))
824 exe "normal 2GCa\<C-X>\<C-L>\<C-L>\<C-L>\<C-L>"
825 call assert_equal(['a1', 'a1', 'a2'], getline(1, '$'))
826 %d
827 " use CTRL-X CTRL-L to add one more line
828 call setline(1, ['a1', 'b1'])
829 setlocal complete=.
830 exe "normal ggOa\<C-X>\<C-L>\<C-X>\<C-L>\<C-X>\<C-L>"
831 call assert_equal(['a1', 'b1', '', 'a1', 'b1'], getline(1, '$'))
832 bw!
833endfunc
834
Bram Moolenaarf9ab52e2020-05-05 19:57:18 +0200835" Test insert completion with 'cindent' (adjust the indent)
836func Test_complete_with_cindent()
837 new
838 setlocal cindent
839 call setline(1, ['if (i == 1)', " j = 2;"])
840 exe "normal Go{\<CR>i\<C-X>\<C-L>\<C-X>\<C-L>\<CR>}"
841 call assert_equal(['{', "\tif (i == 1)", "\t\tj = 2;", '}'], getline(3, '$'))
842
843 %d
844 call setline(1, ['when while', '{', ''])
845 setlocal cinkeys+==while
846 exe "normal Giwh\<C-P> "
847 call assert_equal("\twhile ", getline('$'))
848 close!
849endfunc
850
851" Test for <CTRL-X> <CTRL-V> completion. Complete commands and functions
852func Test_complete_cmdline()
853 new
854 exe "normal icaddb\<C-X>\<C-V>"
855 call assert_equal('caddbuffer', getline(1))
856 exe "normal ocall getqf\<C-X>\<C-V>"
857 call assert_equal('call getqflist(', getline(2))
858 exe "normal oabcxyz(\<C-X>\<C-V>"
859 call assert_equal('abcxyz(', getline(3))
zeertzjqdca29d92021-08-31 19:12:51 +0200860 com! -buffer TestCommand1 echo 'TestCommand1'
861 com! -buffer TestCommand2 echo 'TestCommand2'
862 write TestCommand1Test
863 write TestCommand2Test
864 " Test repeating <CTRL-X> <CTRL-V> and switching to another CTRL-X mode
865 exe "normal oT\<C-X>\<C-V>\<C-X>\<C-V>\<C-X>\<C-F>\<Esc>"
866 call assert_equal('TestCommand2Test', getline(4))
867 call delete('TestCommand1Test')
868 call delete('TestCommand2Test')
869 delcom TestCommand1
870 delcom TestCommand2
871 close!
872endfunc
873
874" Test for <CTRL-X> <CTRL-Z> stopping completion without changing the match
875func Test_complete_stop()
876 new
877 func Save_mode1()
878 let g:mode1 = mode(1)
879 return ''
880 endfunc
881 func Save_mode2()
882 let g:mode2 = mode(1)
883 return ''
884 endfunc
885 inoremap <F1> <C-R>=Save_mode1()<CR>
886 inoremap <F2> <C-R>=Save_mode2()<CR>
887 call setline(1, ['aaa bbb ccc '])
888 exe "normal A\<C-N>\<C-P>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>"
889 call assert_equal('ic', g:mode1)
890 call assert_equal('i', g:mode2)
891 call assert_equal('aaa bbb ccc ', getline(1))
892 exe "normal A\<C-N>\<Down>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>"
893 call assert_equal('ic', g:mode1)
894 call assert_equal('i', g:mode2)
895 call assert_equal('aaa bbb ccc aaa', getline(1))
896 set completeopt+=noselect
897 exe "normal A \<C-N>\<Down>\<Down>\<C-L>\<C-L>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>"
898 call assert_equal('ic', g:mode1)
899 call assert_equal('i', g:mode2)
900 call assert_equal('aaa bbb ccc aaa bb', getline(1))
901 set completeopt&
902 exe "normal A d\<C-N>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>"
903 call assert_equal('ic', g:mode1)
904 call assert_equal('i', g:mode2)
905 call assert_equal('aaa bbb ccc aaa bb d', getline(1))
906 com! -buffer TestCommand1 echo 'TestCommand1'
907 com! -buffer TestCommand2 echo 'TestCommand2'
908 exe "normal oT\<C-X>\<C-V>\<C-X>\<C-V>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>"
909 call assert_equal('ic', g:mode1)
910 call assert_equal('i', g:mode2)
911 call assert_equal('TestCommand2', getline(2))
912 delcom TestCommand1
913 delcom TestCommand2
914 unlet g:mode1
915 unlet g:mode2
916 iunmap <F1>
917 iunmap <F2>
918 delfunc Save_mode1
919 delfunc Save_mode2
Bram Moolenaarf9ab52e2020-05-05 19:57:18 +0200920 close!
921endfunc
922
Yegappan Lakshmanan5d2e0072021-12-30 11:40:53 +0000923" Test for typing CTRL-R in insert completion mode to insert a register
924" content.
925func Test_complete_reginsert()
926 new
927 call setline(1, ['a1', 'a12', 'a123', 'a1234'])
928
929 " if a valid CTRL-X mode key is returned from <C-R>=, then it should be
930 " processed. Otherwise, CTRL-X mode should be stopped and the key should be
931 " inserted.
932 exe "normal Goa\<C-P>\<C-R>=\"\\<C-P>\"\<CR>"
933 call assert_equal('a123', getline(5))
934 let @r = "\<C-P>\<C-P>"
935 exe "normal GCa\<C-P>\<C-R>r"
936 call assert_equal('a12', getline(5))
937 exe "normal GCa\<C-P>\<C-R>=\"x\"\<CR>"
938 call assert_equal('a1234x', getline(5))
939 bw!
940endfunc
941
Bram Moolenaar8f187fc2020-09-26 18:47:11 +0200942func Test_issue_7021()
943 CheckMSWindows
944
945 let orig_shellslash = &shellslash
946 set noshellslash
947
948 set completeslash=slash
949 call assert_false(expand('~') =~ '/')
950
951 let &shellslash = orig_shellslash
952 set completeslash=
953endfunc
954
Yegappan Lakshmanane9825862022-01-03 11:03:48 +0000955" Test for 'longest' setting in 'completeopt' with latin1 and utf-8 encodings
956func Test_complete_longest_match()
957 for e in ['latin1', 'utf-8']
958 exe 'set encoding=' .. e
959 new
960 set complete=.
961 set completeopt=menu,longest
962 call setline(1, ['pfx_a1', 'pfx_a12', 'pfx_a123', 'pfx_b1'])
963 exe "normal Gopfx\<C-P>"
964 call assert_equal('pfx_', getline(5))
965 bw!
966 endfor
967
968 " Test for completing additional words with longest match set
969 new
970 call setline(1, ['abc1', 'abd2'])
971 exe "normal Goab\<C-P>\<C-X>\<C-P>"
972 call assert_equal('ab', getline(3))
973 bw!
974 set complete& completeopt&
975endfunc
976
977" Test for removing the first displayed completion match and selecting the
978" match just before that.
979func Test_complete_erase_firstmatch()
980 new
981 call setline(1, ['a12', 'a34', 'a56'])
982 set complete=.
983 exe "normal Goa\<C-P>\<BS>\<BS>3\<CR>"
984 call assert_equal('a34', getline('$'))
985 set complete&
986 bw!
987endfunc
988
Yegappan Lakshmanan37079142022-01-08 10:38:48 +0000989" Test for completing words from unloaded buffers
990func Test_complete_from_unloadedbuf()
991 call writefile(['abc'], "Xfile1")
992 call writefile(['def'], "Xfile2")
993 edit Xfile1
994 edit Xfile2
995 new | close
996 enew
997 bunload Xfile1 Xfile2
998 set complete=u
999 " complete from an unloaded buffer
1000 exe "normal! ia\<C-P>"
1001 call assert_equal('abc', getline(1))
1002 exe "normal! od\<C-P>"
1003 call assert_equal('def', getline(2))
1004 set complete&
1005 %bw!
1006 call delete("Xfile1")
1007 call delete("Xfile2")
1008endfunc
1009
Yegappan Lakshmanane9825862022-01-03 11:03:48 +00001010" Test for completing whole lines from unloaded buffers
1011func Test_complete_wholeline_unloadedbuf()
1012 call writefile(['a line1', 'a line2', 'a line3'], "Xfile1")
1013 edit Xfile1
1014 enew
1015 set complete=u
1016 exe "normal! ia\<C-X>\<C-L>\<C-P>"
1017 call assert_equal('a line2', getline(1))
1018 %d
1019 " completing from an unlisted buffer should fail
1020 bdel Xfile1
1021 exe "normal! ia\<C-X>\<C-L>\<C-P>"
1022 call assert_equal('a', getline(1))
1023 set complete&
1024 %bw!
1025 call delete("Xfile1")
1026endfunc
1027
Yegappan Lakshmanan37079142022-01-08 10:38:48 +00001028" Test for completing words from unlisted buffers
1029func Test_complete_from_unlistedbuf()
1030 call writefile(['abc'], "Xfile1")
1031 call writefile(['def'], "Xfile2")
1032 edit Xfile1
1033 edit Xfile2
1034 new | close
1035 bdel Xfile1 Xfile2
1036 set complete=U
1037 " complete from an unlisted buffer
1038 exe "normal! ia\<C-P>"
1039 call assert_equal('abc', getline(1))
1040 exe "normal! od\<C-P>"
1041 call assert_equal('def', getline(2))
1042 set complete&
1043 %bw!
1044 call delete("Xfile1")
1045 call delete("Xfile2")
1046endfunc
1047
Yegappan Lakshmanane9825862022-01-03 11:03:48 +00001048" Test for completing whole lines from unlisted buffers
1049func Test_complete_wholeline_unlistedbuf()
1050 call writefile(['a line1', 'a line2', 'a line3'], "Xfile1")
1051 edit Xfile1
1052 enew
1053 set complete=U
1054 " completing from a unloaded buffer should fail
1055 exe "normal! ia\<C-X>\<C-L>\<C-P>"
1056 call assert_equal('a', getline(1))
1057 %d
1058 bdel Xfile1
1059 exe "normal! ia\<C-X>\<C-L>\<C-P>"
1060 call assert_equal('a line2', getline(1))
1061 set complete&
1062 %bw!
1063 call delete("Xfile1")
1064endfunc
1065
1066" Test for adding a multibyte character using CTRL-L in completion mode
1067func Test_complete_mbyte_char_add()
1068 new
1069 set complete=.
1070 call setline(1, 'abÄ—')
1071 exe "normal! oa\<C-P>\<BS>\<BS>\<C-L>\<C-L>"
1072 call assert_equal('abÄ—', getline(2))
1073 " Test for a leader with multibyte character
1074 %d
1075 call setline(1, 'abÄ—Ä•')
1076 exe "normal! oabÄ—\<C-P>"
1077 call assert_equal('abÄ—Ä•', getline(2))
1078 bw!
1079endfunc
1080
Yegappan Lakshmanan37079142022-01-08 10:38:48 +00001081" Test for using <C-X><C-P> for local expansion even if 'complete' is set to
1082" not to complete matches from the local buffer. Also test using multiple
1083" <C-X> to cancel the current completion mode.
1084func Test_complete_local_expansion()
1085 new
1086 set complete=t
1087 call setline(1, ['abc', 'def'])
1088 exe "normal! Go\<C-X>\<C-P>"
1089 call assert_equal("def", getline(3))
1090 exe "normal! Go\<C-P>"
1091 call assert_equal("", getline(4))
1092 exe "normal! Go\<C-X>\<C-N>"
1093 call assert_equal("abc", getline(5))
1094 exe "normal! Go\<C-N>"
1095 call assert_equal("", getline(6))
1096
1097 " use multiple <C-X> to cancel the previous completion mode
1098 exe "normal! Go\<C-P>\<C-X>\<C-P>"
1099 call assert_equal("", getline(7))
1100 exe "normal! Go\<C-P>\<C-X>\<C-X>\<C-P>"
1101 call assert_equal("", getline(8))
1102 exe "normal! Go\<C-P>\<C-X>\<C-X>\<C-X>\<C-P>"
1103 call assert_equal("abc", getline(9))
1104
1105 " interrupt the current completion mode
1106 set completeopt=menu,noinsert
1107 exe "normal! Go\<C-X>\<C-F>\<C-X>\<C-X>\<C-P>\<C-Y>"
1108 call assert_equal("abc", getline(10))
1109
1110 " when only one <C-X> is used to interrupt, do normal expansion
1111 exe "normal! Go\<C-X>\<C-F>\<C-X>\<C-P>"
1112 call assert_equal("", getline(11))
1113 set completeopt&
1114
1115 " using two <C-X> in non-completion mode and restarting the same mode
1116 exe "normal! God\<C-X>\<C-X>\<C-P>\<C-X>\<C-X>\<C-P>\<C-Y>"
1117 call assert_equal("def", getline(12))
1118
1119 " test for adding a match from the original empty text
1120 %d
1121 call setline(1, 'abc def g')
1122 exe "normal! o\<C-X>\<C-P>\<C-N>\<C-X>\<C-P>"
1123 call assert_equal('def', getline(2))
1124 exe "normal! 0C\<C-X>\<C-N>\<C-P>\<C-X>\<C-N>"
1125 call assert_equal('abc', getline(2))
1126
1127 bw!
1128endfunc
1129
1130" Test for undoing changes after a insert-mode completion
1131func Test_complete_undo()
1132 new
1133 set complete=.
1134 " undo with 'ignorecase'
1135 call setline(1, ['ABOVE', 'BELOW'])
1136 set ignorecase
1137 exe "normal! Goab\<C-G>u\<C-P>"
1138 call assert_equal("ABOVE", getline(3))
1139 undo
1140 call assert_equal("ab", getline(3))
1141 set ignorecase&
1142 %d
1143 " undo with longest match
1144 set completeopt=menu,longest
1145 call setline(1, ['above', 'about'])
1146 exe "normal! Goa\<C-G>u\<C-P>"
1147 call assert_equal("abo", getline(3))
1148 undo
1149 call assert_equal("a", getline(3))
1150 set completeopt&
1151 %d
1152 " undo for line completion
1153 call setline(1, ['above that change', 'below that change'])
1154 exe "normal! Goabove\<C-G>u\<C-X>\<C-L>"
1155 call assert_equal("above that change", getline(3))
1156 undo
1157 call assert_equal("above", getline(3))
1158
1159 bw!
1160endfunc
1161
1162" Test for completing a very long word
1163func Test_complete_long_word()
1164 set complete&
1165 new
1166 call setline(1, repeat('x', 950) .. ' one two three')
1167 exe "normal! Gox\<C-X>\<C-P>\<C-X>\<C-P>\<C-X>\<C-P>\<C-X>\<C-P>"
1168 call assert_equal(repeat('x', 950) .. ' one two three', getline(2))
1169 %d
1170 " should fail when more than 950 characters are in a word
1171 call setline(1, repeat('x', 951) .. ' one two three')
1172 exe "normal! Gox\<C-X>\<C-P>\<C-X>\<C-P>\<C-X>\<C-P>\<C-X>\<C-P>"
1173 call assert_equal(repeat('x', 951), getline(2))
1174
1175 " Test for adding a very long word to an existing completion
1176 %d
1177 call setline(1, ['abc', repeat('x', 1016) .. '012345'])
1178 exe "normal! Goab\<C-P>\<C-X>\<C-P>"
1179 call assert_equal('abc ' .. repeat('x', 1016) .. '0123', getline(3))
1180 bw!
1181endfunc
1182
1183" Test for some fields in the complete items used by complete()
1184func Test_complete_items()
1185 func CompleteItems(idx)
1186 let items = [[#{word: "one", dup: 1, user_data: 'u1'}, #{word: "one", dup: 1, user_data: 'u2'}],
1187 \ [#{word: "one", dup: 0, user_data: 'u3'}, #{word: "one", dup: 0, user_data: 'u4'}],
1188 \ [#{word: "one", icase: 1, user_data: 'u7'}, #{word: "oNE", icase: 1, user_data: 'u8'}],
1189 \ [#{user_data: 'u9'}],
1190 \ [#{word: "", user_data: 'u10'}],
1191 \ [#{word: "", empty: 1, user_data: 'u11'}]]
1192 call complete(col('.'), items[a:idx])
1193 return ''
1194 endfunc
1195 new
1196 exe "normal! i\<C-R>=CompleteItems(0)\<CR>\<C-N>\<C-Y>"
1197 call assert_equal('u2', v:completed_item.user_data)
1198 call assert_equal('one', getline(1))
1199 exe "normal! o\<C-R>=CompleteItems(1)\<CR>\<C-Y>"
1200 call assert_equal('u3', v:completed_item.user_data)
1201 call assert_equal('one', getline(2))
1202 exe "normal! o\<C-R>=CompleteItems(1)\<CR>\<C-N>"
1203 call assert_equal('', getline(3))
1204 set completeopt=menu,noinsert
1205 exe "normal! o\<C-R>=CompleteItems(2)\<CR>one\<C-N>\<C-Y>"
1206 call assert_equal('oNE', getline(4))
1207 call assert_equal('u8', v:completed_item.user_data)
1208 set completeopt&
1209 exe "normal! o\<C-R>=CompleteItems(3)\<CR>"
1210 call assert_equal('', getline(5))
1211 exe "normal! o\<C-R>=CompleteItems(4)\<CR>"
1212 call assert_equal('', getline(6))
1213 exe "normal! o\<C-R>=CompleteItems(5)\<CR>"
1214 call assert_equal('', getline(7))
1215 call assert_equal('u11', v:completed_item.user_data)
1216 " pass invalid argument to complete()
1217 let cmd = "normal! o\<C-R>=complete(1, [[]])\<CR>"
1218 call assert_fails('exe cmd', 'E730:')
1219 bw!
1220 delfunc CompleteItems
1221endfunc
1222
1223" Test for the "refresh" item in the dict returned by an insert completion
1224" function
1225func Test_complete_item_refresh_always()
1226 let g:CallCount = 0
1227 func! Tcomplete(findstart, base)
1228 if a:findstart
1229 " locate the start of the word
1230 let line = getline('.')
1231 let start = col('.') - 1
1232 while start > 0 && line[start - 1] =~ '\a'
1233 let start -= 1
1234 endwhile
1235 return start
1236 else
1237 let g:CallCount += 1
1238 let res = ["update1", "update12", "update123"]
1239 return #{words: res, refresh: 'always'}
1240 endif
1241 endfunc
1242 new
1243 set completeopt=menu,longest
1244 set completefunc=Tcomplete
1245 exe "normal! iup\<C-X>\<C-U>\<BS>\<BS>\<BS>\<BS>\<BS>"
1246 call assert_equal('up', getline(1))
1247 call assert_equal(2, g:CallCount)
1248 set completeopt&
1249 set completefunc&
1250 bw!
1251 delfunc Tcomplete
1252endfunc
1253
1254" Test for completing from a thesaurus file without read permission
1255func Test_complete_unreadable_thesaurus_file()
1256 CheckUnix
1257 CheckNotRoot
1258
1259 call writefile(['about', 'above'], 'Xfile')
1260 call setfperm('Xfile', '---r--r--')
1261 new
1262 set complete=sXfile
1263 exe "normal! ia\<C-P>"
1264 call assert_equal('a', getline(1))
1265 bw!
1266 call delete('Xfile')
1267 set complete&
1268endfunc
1269
Bram Moolenaarcc233582020-12-12 13:32:07 +01001270" Test to ensure 'Scanning...' messages are not recorded in messages history
1271func Test_z1_complete_no_history()
1272 new
1273 messages clear
1274 let currmess = execute('messages')
1275 setlocal dictionary=README.txt
1276 exe "normal owh\<C-X>\<C-K>"
1277 exe "normal owh\<C-N>"
1278 call assert_equal(currmess, execute('messages'))
1279 close!
1280endfunc
1281
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001282" Test for different ways of setting the 'completefunc' option
1283func Test_completefunc_callback()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001284 func CompleteFunc1(callnr, findstart, base)
1285 call add(g:CompleteFunc1Args, [a:callnr, a:findstart, a:base])
1286 return a:findstart ? 0 : []
1287 endfunc
1288 func CompleteFunc2(findstart, base)
1289 call add(g:CompleteFunc2Args, [a:findstart, a:base])
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001290 return a:findstart ? 0 : []
1291 endfunc
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00001292
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001293 let lines =<< trim END
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00001294 #" Test for using a global function name
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001295 LET &completefunc = 'g:CompleteFunc2'
1296 new
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00001297 call setline(1, 'global')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001298 LET g:CompleteFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001299 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00001300 call assert_equal([[1, ''], [0, 'global']], g:CompleteFunc2Args)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001301 bw!
1302
1303 #" Test for using a function()
1304 set completefunc=function('g:CompleteFunc1',\ [10])
1305 new
1306 call setline(1, 'one')
1307 LET g:CompleteFunc1Args = []
1308 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
1309 call assert_equal([[10, 1, ''], [10, 0, 'one']], g:CompleteFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001310 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001311
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001312 #" Using a funcref variable to set 'completefunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001313 VAR Fn = function('g:CompleteFunc1', [11])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001314 LET &completefunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001315 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001316 call setline(1, 'two')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001317 LET g:CompleteFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001318 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001319 call assert_equal([[11, 1, ''], [11, 0, 'two']], g:CompleteFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001320 bw!
Yegappan Lakshmanan64095532021-12-06 11:03:55 +00001321
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001322 #" Using string(funcref_variable) to set 'completefunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001323 LET Fn = function('g:CompleteFunc1', [12])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001324 LET &completefunc = string(Fn)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001325 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001326 call setline(1, 'two')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001327 LET g:CompleteFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001328 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001329 call assert_equal([[12, 1, ''], [12, 0, 'two']], g:CompleteFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001330 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001331
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001332 #" Test for using a funcref()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001333 set completefunc=funcref('g:CompleteFunc1',\ [13])
1334 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001335 call setline(1, 'three')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001336 LET g:CompleteFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001337 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001338 call assert_equal([[13, 1, ''], [13, 0, 'three']], g:CompleteFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001339 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001340
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001341 #" Using a funcref variable to set 'completefunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001342 LET Fn = funcref('g:CompleteFunc1', [14])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001343 LET &completefunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001344 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001345 call setline(1, 'four')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001346 LET g:CompleteFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001347 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001348 call assert_equal([[14, 1, ''], [14, 0, 'four']], g:CompleteFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001349 bw!
Yegappan Lakshmanan64095532021-12-06 11:03:55 +00001350
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001351 #" Using a string(funcref_variable) to set 'completefunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001352 LET Fn = funcref('g:CompleteFunc1', [15])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001353 LET &completefunc = string(Fn)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001354 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001355 call setline(1, 'four')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001356 LET g:CompleteFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001357 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001358 call assert_equal([[15, 1, ''], [15, 0, 'four']], g:CompleteFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001359 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001360
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001361 #" Test for using a lambda function with set
Bram Moolenaar62aec932022-01-29 21:45:34 +00001362 VAR optval = "LSTART a, b LMIDDLE g:CompleteFunc1(16, a, b) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001363 LET optval = substitute(optval, ' ', '\\ ', 'g')
1364 exe "set completefunc=" .. optval
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001365 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001366 call setline(1, 'five')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001367 LET g:CompleteFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001368 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001369 call assert_equal([[16, 1, ''], [16, 0, 'five']], g:CompleteFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001370 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001371
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001372 #" Set 'completefunc' to a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00001373 LET &completefunc = LSTART a, b LMIDDLE g:CompleteFunc1(17, a, b) LEND
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001374 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001375 call setline(1, 'six')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001376 LET g:CompleteFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001377 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001378 call assert_equal([[17, 1, ''], [17, 0, 'six']], g:CompleteFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001379 bw!
Yegappan Lakshmanan64095532021-12-06 11:03:55 +00001380
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001381 #" Set 'completefunc' to string(lambda_expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00001382 LET &completefunc = 'LSTART a, b LMIDDLE g:CompleteFunc1(18, a, b) LEND'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001383 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001384 call setline(1, 'six')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001385 LET g:CompleteFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001386 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001387 call assert_equal([[18, 1, ''], [18, 0, 'six']], g:CompleteFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001388 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001389
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001390 #" Set 'completefunc' to a variable with a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00001391 VAR Lambda = LSTART a, b LMIDDLE g:CompleteFunc1(19, a, b) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001392 LET &completefunc = Lambda
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001393 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001394 call setline(1, 'seven')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001395 LET g:CompleteFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001396 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001397 call assert_equal([[19, 1, ''], [19, 0, 'seven']], g:CompleteFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001398 bw!
Yegappan Lakshmanan64095532021-12-06 11:03:55 +00001399
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001400 #" Set 'completefunc' to a string(variable with a lambda expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00001401 LET Lambda = LSTART a, b LMIDDLE g:CompleteFunc1(20, a, b) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001402 LET &completefunc = string(Lambda)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001403 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001404 call setline(1, 'seven')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001405 LET g:CompleteFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001406 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001407 call assert_equal([[20, 1, ''], [20, 0, 'seven']], g:CompleteFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001408 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001409
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001410 #" Test for using a lambda function with incorrect return value
1411 LET Lambda = LSTART a, b LMIDDLE strlen(a) LEND
1412 LET &completefunc = Lambda
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001413 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001414 call setline(1, 'eight')
1415 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
1416 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001417
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001418 #" Test for clearing the 'completefunc' option
1419 set completefunc=''
1420 set completefunc&
1421 call assert_fails("set completefunc=function('abc')", "E700:")
1422 call assert_fails("set completefunc=funcref('abc')", "E700:")
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001423
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001424 #" set 'completefunc' to a non-existing function
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001425 set completefunc=g:CompleteFunc2
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001426 call setline(1, 'five')
1427 call assert_fails("set completefunc=function('NonExistingFunc')", 'E700:')
1428 call assert_fails("LET &completefunc = function('NonExistingFunc')", 'E700:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001429 LET g:CompleteFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001430 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001431 call assert_equal([[1, ''], [0, 'five']], g:CompleteFunc2Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001432 bw!
1433 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001434 call v9.CheckLegacyAndVim9Success(lines)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001435
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00001436 " Test for using a script-local function name
1437 func s:CompleteFunc3(findstart, base)
1438 call add(g:CompleteFunc3Args, [a:findstart, a:base])
1439 return a:findstart ? 0 : []
1440 endfunc
1441 set completefunc=s:CompleteFunc3
1442 new
1443 call setline(1, 'script1')
1444 let g:CompleteFunc3Args = []
1445 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
1446 call assert_equal([[1, ''], [0, 'script1']], g:CompleteFunc3Args)
1447 bw!
1448
1449 let &completefunc = 's:CompleteFunc3'
1450 new
1451 call setline(1, 'script2')
1452 let g:CompleteFunc3Args = []
1453 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
1454 call assert_equal([[1, ''], [0, 'script2']], g:CompleteFunc3Args)
1455 bw!
1456 delfunc s:CompleteFunc3
1457
1458 " invalid return value
Yegappan Lakshmanan64095532021-12-06 11:03:55 +00001459 let &completefunc = {a -> 'abc'}
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001460 call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
1461
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001462 " Using Vim9 lambda expression in legacy context should fail
Bram Moolenaar62aec932022-01-29 21:45:34 +00001463 set completefunc=(a,\ b)\ =>\ g:CompleteFunc1(21,\ a,\ b)
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001464 new | only
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001465 let g:CompleteFunc1Args = []
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001466 call assert_fails('call feedkeys("A\<C-X>\<C-U>\<Esc>", "x")', 'E117:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001467 call assert_equal([], g:CompleteFunc1Args)
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001468
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001469 " set 'completefunc' to a partial with dict. This used to cause a crash.
1470 func SetCompleteFunc()
1471 let params = {'complete': function('g:DictCompleteFunc')}
1472 let &completefunc = params.complete
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00001473 endfunc
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001474 func g:DictCompleteFunc(_) dict
1475 endfunc
1476 call SetCompleteFunc()
1477 new
1478 call SetCompleteFunc()
1479 bw
1480 call test_garbagecollect_now()
1481 new
1482 set completefunc=
1483 wincmd w
1484 set completefunc=
1485 %bw!
1486 delfunc g:DictCompleteFunc
1487 delfunc SetCompleteFunc
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00001488
1489 " Vim9 tests
1490 let lines =<< trim END
1491 vim9script
1492
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00001493 def Vim9CompleteFunc(callnr: number, findstart: number, base: string): any
1494 add(g:Vim9completeFuncArgs, [callnr, findstart, base])
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00001495 return findstart ? 0 : []
1496 enddef
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00001497
1498 # Test for using a def function with completefunc
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00001499 set completefunc=function('Vim9CompleteFunc',\ [60])
1500 new | only
1501 setline(1, 'one')
1502 g:Vim9completeFuncArgs = []
1503 feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
1504 assert_equal([[60, 1, ''], [60, 0, 'one']], g:Vim9completeFuncArgs)
1505 bw!
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00001506
1507 # Test for using a global function name
1508 &completefunc = g:CompleteFunc2
1509 new | only
1510 setline(1, 'two')
1511 g:CompleteFunc2Args = []
1512 feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
1513 assert_equal([[1, ''], [0, 'two']], g:CompleteFunc2Args)
1514 bw!
1515
1516 # Test for using a script-local function name
1517 def s:LocalCompleteFunc(findstart: number, base: string): any
1518 add(g:LocalCompleteFuncArgs, [findstart, base])
1519 return findstart ? 0 : []
1520 enddef
1521 &completefunc = s:LocalCompleteFunc
1522 new | only
1523 setline(1, 'three')
1524 g:LocalCompleteFuncArgs = []
1525 feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
1526 assert_equal([[1, ''], [0, 'three']], g:LocalCompleteFuncArgs)
1527 bw!
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00001528 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001529 call v9.CheckScriptSuccess(lines)
Yegappan Lakshmanan4dc24eb2021-12-07 12:23:57 +00001530
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001531 " cleanup
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001532 set completefunc&
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001533 delfunc CompleteFunc1
1534 delfunc CompleteFunc2
1535 unlet g:CompleteFunc1Args g:CompleteFunc2Args
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001536 %bw!
1537endfunc
1538
1539" Test for different ways of setting the 'omnifunc' option
1540func Test_omnifunc_callback()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001541 func OmniFunc1(callnr, findstart, base)
1542 call add(g:OmniFunc1Args, [a:callnr, a:findstart, a:base])
1543 return a:findstart ? 0 : []
1544 endfunc
1545 func OmniFunc2(findstart, base)
1546 call add(g:OmniFunc2Args, [a:findstart, a:base])
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001547 return a:findstart ? 0 : []
1548 endfunc
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00001549
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001550 let lines =<< trim END
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001551 #" Test for using a function name
1552 LET &omnifunc = 'g:OmniFunc2'
1553 new
1554 call setline(1, 'zero')
1555 LET g:OmniFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001556 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001557 call assert_equal([[1, ''], [0, 'zero']], g:OmniFunc2Args)
1558 bw!
1559
1560 #" Test for using a function()
1561 set omnifunc=function('g:OmniFunc1',\ [10])
1562 new
1563 call setline(1, 'one')
1564 LET g:OmniFunc1Args = []
1565 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
1566 call assert_equal([[10, 1, ''], [10, 0, 'one']], g:OmniFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001567 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001568
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001569 #" Using a funcref variable to set 'omnifunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001570 VAR Fn = function('g:OmniFunc1', [11])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001571 LET &omnifunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001572 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001573 call setline(1, 'two')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001574 LET g:OmniFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001575 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001576 call assert_equal([[11, 1, ''], [11, 0, 'two']], g:OmniFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001577 bw!
Yegappan Lakshmanan64095532021-12-06 11:03:55 +00001578
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001579 #" Using a string(funcref_variable) to set 'omnifunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001580 LET Fn = function('g:OmniFunc1', [12])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001581 LET &omnifunc = string(Fn)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001582 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001583 call setline(1, 'two')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001584 LET g:OmniFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001585 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001586 call assert_equal([[12, 1, ''], [12, 0, 'two']], g:OmniFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001587 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001588
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001589 #" Test for using a funcref()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001590 set omnifunc=funcref('g:OmniFunc1',\ [13])
1591 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001592 call setline(1, 'three')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001593 LET g:OmniFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001594 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001595 call assert_equal([[13, 1, ''], [13, 0, 'three']], g:OmniFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001596 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001597
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001598 #" Use let to set 'omnifunc' to a funcref
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001599 LET Fn = funcref('g:OmniFunc1', [14])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001600 LET &omnifunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001601 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001602 call setline(1, 'four')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001603 LET g:OmniFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001604 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001605 call assert_equal([[14, 1, ''], [14, 0, 'four']], g:OmniFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001606 bw!
Yegappan Lakshmanan64095532021-12-06 11:03:55 +00001607
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001608 #" Using a string(funcref) to set 'omnifunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001609 LET Fn = funcref("g:OmniFunc1", [15])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001610 LET &omnifunc = string(Fn)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001611 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001612 call setline(1, 'four')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001613 LET g:OmniFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001614 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001615 call assert_equal([[15, 1, ''], [15, 0, 'four']], g:OmniFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001616 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001617
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001618 #" Test for using a lambda function with set
Bram Moolenaar62aec932022-01-29 21:45:34 +00001619 VAR optval = "LSTART a, b LMIDDLE g:OmniFunc1(16, a, b) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001620 LET optval = substitute(optval, ' ', '\\ ', 'g')
1621 exe "set omnifunc=" .. optval
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001622 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001623 call setline(1, 'five')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001624 LET g:OmniFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001625 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001626 call assert_equal([[16, 1, ''], [16, 0, 'five']], g:OmniFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001627 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001628
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001629 #" Set 'omnifunc' to a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00001630 LET &omnifunc = LSTART a, b LMIDDLE g:OmniFunc1(17, a, b) LEND
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001631 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001632 call setline(1, 'six')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001633 LET g:OmniFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001634 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001635 call assert_equal([[17, 1, ''], [17, 0, 'six']], g:OmniFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001636 bw!
Yegappan Lakshmanan64095532021-12-06 11:03:55 +00001637
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001638 #" Set 'omnifunc' to a string(lambda_expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00001639 LET &omnifunc = 'LSTART a, b LMIDDLE g:OmniFunc1(18, a, b) LEND'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001640 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001641 call setline(1, 'six')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001642 LET g:OmniFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001643 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001644 call assert_equal([[18, 1, ''], [18, 0, 'six']], g:OmniFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001645 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001646
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001647 #" Set 'omnifunc' to a variable with a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00001648 VAR Lambda = LSTART a, b LMIDDLE g:OmniFunc1(19, a, b) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001649 LET &omnifunc = Lambda
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001650 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001651 call setline(1, 'seven')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001652 LET g:OmniFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001653 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001654 call assert_equal([[19, 1, ''], [19, 0, 'seven']], g:OmniFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001655 bw!
Yegappan Lakshmanan64095532021-12-06 11:03:55 +00001656
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001657 #" Set 'omnifunc' to a string(variable with a lambda expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00001658 LET Lambda = LSTART a, b LMIDDLE g:OmniFunc1(20, a, b) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001659 LET &omnifunc = string(Lambda)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001660 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001661 call setline(1, 'seven')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001662 LET g:OmniFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001663 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001664 call assert_equal([[20, 1, ''], [20, 0, 'seven']], g:OmniFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001665 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001666
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001667 #" Test for using a lambda function with incorrect return value
1668 LET Lambda = LSTART a, b LMIDDLE strlen(a) LEND
1669 LET &omnifunc = Lambda
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001670 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001671 call setline(1, 'eight')
1672 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
1673 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001674
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001675 #" Test for clearing the 'omnifunc' option
1676 set omnifunc=''
1677 set omnifunc&
1678 call assert_fails("set omnifunc=function('abc')", "E700:")
1679 call assert_fails("set omnifunc=funcref('abc')", "E700:")
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001680
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001681 #" set 'omnifunc' to a non-existing function
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001682 set omnifunc=g:OmniFunc2
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001683 call setline(1, 'nine')
1684 call assert_fails("set omnifunc=function('NonExistingFunc')", 'E700:')
1685 call assert_fails("LET &omnifunc = function('NonExistingFunc')", 'E700:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001686 LET g:OmniFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001687 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001688 call assert_equal([[1, ''], [0, 'nine']], g:OmniFunc2Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001689 bw!
1690 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001691 call v9.CheckLegacyAndVim9Success(lines)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001692
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00001693 " Test for using a script-local function name
1694 func s:OmniFunc3(findstart, base)
1695 call add(g:OmniFunc3Args, [a:findstart, a:base])
1696 return a:findstart ? 0 : []
1697 endfunc
1698 set omnifunc=s:OmniFunc3
1699 new
1700 call setline(1, 'script1')
1701 let g:OmniFunc3Args = []
1702 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
1703 call assert_equal([[1, ''], [0, 'script1']], g:OmniFunc3Args)
1704 bw!
1705
1706 let &omnifunc = 's:OmniFunc3'
1707 new
1708 call setline(1, 'script2')
1709 let g:OmniFunc3Args = []
1710 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
1711 call assert_equal([[1, ''], [0, 'script2']], g:OmniFunc3Args)
1712 bw!
1713 delfunc s:OmniFunc3
1714
1715 " invalid return value
Yegappan Lakshmanan64095532021-12-06 11:03:55 +00001716 let &omnifunc = {a -> 'abc'}
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001717 call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
1718
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001719 " Using Vim9 lambda expression in legacy context should fail
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001720 set omnifunc=(a,\ b)\ =>\ OmniFunc1(21,\ a,\ b)
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001721 new | only
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001722 let g:OmniFunc1Args = []
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001723 call assert_fails('call feedkeys("A\<C-X>\<C-O>\<Esc>", "x")', 'E117:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001724 call assert_equal([], g:OmniFunc1Args)
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001725
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001726 " set 'omnifunc' to a partial with dict. This used to cause a crash.
1727 func SetOmniFunc()
1728 let params = {'omni': function('g:DictOmniFunc')}
1729 let &omnifunc = params.omni
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00001730 endfunc
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001731 func g:DictOmniFunc(_) dict
1732 endfunc
1733 call SetOmniFunc()
1734 new
1735 call SetOmniFunc()
1736 bw
1737 call test_garbagecollect_now()
1738 new
1739 set omnifunc=
1740 wincmd w
1741 set omnifunc=
1742 %bw!
1743 delfunc g:DictOmniFunc
1744 delfunc SetOmniFunc
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00001745
1746 " Vim9 tests
1747 let lines =<< trim END
1748 vim9script
1749
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00001750 def Vim9omniFunc(callnr: number, findstart: number, base: string): any
1751 add(g:Vim9omniFunc_Args, [callnr, findstart, base])
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00001752 return findstart ? 0 : []
1753 enddef
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00001754
1755 # Test for using a def function with omnifunc
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00001756 set omnifunc=function('Vim9omniFunc',\ [60])
1757 new | only
1758 setline(1, 'one')
1759 g:Vim9omniFunc_Args = []
1760 feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
1761 assert_equal([[60, 1, ''], [60, 0, 'one']], g:Vim9omniFunc_Args)
1762 bw!
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00001763
1764 # Test for using a global function name
1765 &omnifunc = g:OmniFunc2
1766 new | only
1767 setline(1, 'two')
1768 g:OmniFunc2Args = []
1769 feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
1770 assert_equal([[1, ''], [0, 'two']], g:OmniFunc2Args)
1771 bw!
1772
1773 # Test for using a script-local function name
1774 def s:LocalOmniFunc(findstart: number, base: string): any
1775 add(g:LocalOmniFuncArgs, [findstart, base])
1776 return findstart ? 0 : []
1777 enddef
1778 &omnifunc = s:LocalOmniFunc
1779 new | only
1780 setline(1, 'three')
1781 g:LocalOmniFuncArgs = []
1782 feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
1783 assert_equal([[1, ''], [0, 'three']], g:LocalOmniFuncArgs)
1784 bw!
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00001785 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001786 call v9.CheckScriptSuccess(lines)
Yegappan Lakshmanan4dc24eb2021-12-07 12:23:57 +00001787
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001788 " cleanup
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001789 set omnifunc&
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001790 delfunc OmniFunc1
1791 delfunc OmniFunc2
1792 unlet g:OmniFunc1Args g:OmniFunc2Args
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001793 %bw!
1794endfunc
1795
1796" Test for different ways of setting the 'thesaurusfunc' option
1797func Test_thesaurusfunc_callback()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001798 func TsrFunc1(callnr, findstart, base)
1799 call add(g:TsrFunc1Args, [a:callnr, a:findstart, a:base])
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001800 return a:findstart ? 0 : []
1801 endfunc
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001802 func TsrFunc2(findstart, base)
1803 call add(g:TsrFunc2Args, [a:findstart, a:base])
1804 return a:findstart ? 0 : ['sunday']
1805 endfunc
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00001806
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001807 let lines =<< trim END
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001808 #" Test for using a function name
1809 LET &thesaurusfunc = 'g:TsrFunc2'
1810 new
1811 call setline(1, 'zero')
1812 LET g:TsrFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001813 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001814 call assert_equal([[1, ''], [0, 'zero']], g:TsrFunc2Args)
1815 bw!
1816
1817 #" Test for using a function()
1818 set thesaurusfunc=function('g:TsrFunc1',\ [10])
1819 new
1820 call setline(1, 'one')
1821 LET g:TsrFunc1Args = []
1822 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
1823 call assert_equal([[10, 1, ''], [10, 0, 'one']], g:TsrFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001824 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001825
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001826 #" Using a funcref variable to set 'thesaurusfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001827 VAR Fn = function('g:TsrFunc1', [11])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001828 LET &thesaurusfunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001829 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001830 call setline(1, 'two')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001831 LET g:TsrFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001832 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001833 call assert_equal([[11, 1, ''], [11, 0, 'two']], g:TsrFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001834 bw!
Yegappan Lakshmanan64095532021-12-06 11:03:55 +00001835
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001836 #" Using a string(funcref_variable) to set 'thesaurusfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001837 LET Fn = function('g:TsrFunc1', [12])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001838 LET &thesaurusfunc = string(Fn)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001839 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001840 call setline(1, 'two')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001841 LET g:TsrFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001842 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001843 call assert_equal([[12, 1, ''], [12, 0, 'two']], g:TsrFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001844 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001845
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001846 #" Test for using a funcref()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001847 set thesaurusfunc=funcref('g:TsrFunc1',\ [13])
1848 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001849 call setline(1, 'three')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001850 LET g:TsrFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001851 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001852 call assert_equal([[13, 1, ''], [13, 0, 'three']], g:TsrFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001853 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001854
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001855 #" Using a funcref variable to set 'thesaurusfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001856 LET Fn = funcref('g:TsrFunc1', [14])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001857 LET &thesaurusfunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001858 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001859 call setline(1, 'four')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001860 LET g:TsrFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001861 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001862 call assert_equal([[14, 1, ''], [14, 0, 'four']], g:TsrFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001863 bw!
Yegappan Lakshmanan64095532021-12-06 11:03:55 +00001864
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001865 #" Using a string(funcref_variable) to set 'thesaurusfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001866 LET Fn = funcref('g:TsrFunc1', [15])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001867 LET &thesaurusfunc = string(Fn)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001868 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001869 call setline(1, 'four')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001870 LET g:TsrFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001871 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001872 call assert_equal([[15, 1, ''], [15, 0, 'four']], g:TsrFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001873 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001874
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001875 #" Test for using a lambda function
Bram Moolenaar62aec932022-01-29 21:45:34 +00001876 VAR optval = "LSTART a, b LMIDDLE g:TsrFunc1(16, a, b) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001877 LET optval = substitute(optval, ' ', '\\ ', 'g')
1878 exe "set thesaurusfunc=" .. optval
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001879 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001880 call setline(1, 'five')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001881 LET g:TsrFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001882 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001883 call assert_equal([[16, 1, ''], [16, 0, 'five']], g:TsrFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001884 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001885
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001886 #" Test for using a lambda function with set
Bram Moolenaar62aec932022-01-29 21:45:34 +00001887 LET &thesaurusfunc = LSTART a, b LMIDDLE g:TsrFunc1(17, a, b) LEND
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001888 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001889 call setline(1, 'six')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001890 LET g:TsrFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001891 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001892 call assert_equal([[17, 1, ''], [17, 0, 'six']], g:TsrFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001893 bw!
Yegappan Lakshmanan64095532021-12-06 11:03:55 +00001894
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001895 #" Set 'thesaurusfunc' to a string(lambda expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00001896 LET &thesaurusfunc = 'LSTART a, b LMIDDLE g:TsrFunc1(18, a, b) LEND'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001897 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001898 call setline(1, 'six')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001899 LET g:TsrFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001900 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001901 call assert_equal([[18, 1, ''], [18, 0, 'six']], g:TsrFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001902 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001903
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001904 #" Set 'thesaurusfunc' to a variable with a lambda expression
Bram Moolenaar62aec932022-01-29 21:45:34 +00001905 VAR Lambda = LSTART a, b LMIDDLE g:TsrFunc1(19, a, b) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001906 LET &thesaurusfunc = Lambda
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001907 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001908 call setline(1, 'seven')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001909 LET g:TsrFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001910 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001911 call assert_equal([[19, 1, ''], [19, 0, 'seven']], g:TsrFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001912 bw!
Yegappan Lakshmanan64095532021-12-06 11:03:55 +00001913
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001914 #" Set 'thesaurusfunc' to a string(variable with a lambda expression)
Bram Moolenaar62aec932022-01-29 21:45:34 +00001915 LET Lambda = LSTART a, b LMIDDLE g:TsrFunc1(20, a, b) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001916 LET &thesaurusfunc = string(Lambda)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001917 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001918 call setline(1, 'seven')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001919 LET g:TsrFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001920 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001921 call assert_equal([[20, 1, ''], [20, 0, 'seven']], g:TsrFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001922 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001923
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001924 #" Test for using a lambda function with incorrect return value
1925 LET Lambda = LSTART a, b LMIDDLE strlen(a) LEND
1926 LET &thesaurusfunc = Lambda
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001927 new
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001928 call setline(1, 'eight')
1929 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
1930 bw!
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001931
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001932 #" Test for clearing the 'thesaurusfunc' option
1933 set thesaurusfunc=''
1934 set thesaurusfunc&
1935 call assert_fails("set thesaurusfunc=function('abc')", "E700:")
1936 call assert_fails("set thesaurusfunc=funcref('abc')", "E700:")
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001937
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001938 #" set 'thesaurusfunc' to a non-existing function
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001939 set thesaurusfunc=g:TsrFunc2
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001940 call setline(1, 'ten')
1941 call assert_fails("set thesaurusfunc=function('NonExistingFunc')", 'E700:')
1942 call assert_fails("LET &thesaurusfunc = function('NonExistingFunc')", 'E700:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001943 LET g:TsrFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001944 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001945 call assert_equal([[1, ''], [0, 'ten']], g:TsrFunc2Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001946 bw!
1947
1948 #" Use a buffer-local value and a global value
1949 set thesaurusfunc&
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001950 setlocal thesaurusfunc=function('g:TsrFunc1',\ [22])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001951 call setline(1, 'sun')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001952 LET g:TsrFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001953 call feedkeys("A\<C-X>\<C-T>\<Esc>", "x")
1954 call assert_equal('sun', getline(1))
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001955 call assert_equal([[22, 1, ''], [22, 0, 'sun']], g:TsrFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001956 new
1957 call setline(1, 'sun')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001958 LET g:TsrFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001959 call feedkeys("A\<C-X>\<C-T>\<Esc>", "x")
1960 call assert_equal('sun', getline(1))
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001961 call assert_equal([], g:TsrFunc1Args)
1962 set thesaurusfunc=function('g:TsrFunc1',\ [23])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001963 wincmd w
1964 call setline(1, 'sun')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001965 LET g:TsrFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001966 call feedkeys("A\<C-X>\<C-T>\<Esc>", "x")
1967 call assert_equal('sun', getline(1))
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00001968 call assert_equal([[22, 1, ''], [22, 0, 'sun']], g:TsrFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001969 :%bw!
1970 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001971 call v9.CheckLegacyAndVim9Success(lines)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00001972
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00001973 " Test for using a script-local function name
1974 func s:TsrFunc3(findstart, base)
1975 call add(g:TsrFunc3Args, [a:findstart, a:base])
1976 return a:findstart ? 0 : []
1977 endfunc
1978 set tsrfu=s:TsrFunc3
1979 new
1980 call setline(1, 'script1')
1981 let g:TsrFunc3Args = []
1982 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
1983 call assert_equal([[1, ''], [0, 'script1']], g:TsrFunc3Args)
1984 bw!
1985
1986 let &tsrfu = 's:TsrFunc3'
1987 new
1988 call setline(1, 'script2')
1989 let g:TsrFunc3Args = []
1990 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
1991 call assert_equal([[1, ''], [0, 'script2']], g:TsrFunc3Args)
1992 bw!
1993 delfunc s:TsrFunc3
1994
1995 " invalid return value
Yegappan Lakshmanan64095532021-12-06 11:03:55 +00001996 let &thesaurusfunc = {a -> 'abc'}
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001997 call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
1998
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00001999 " Using Vim9 lambda expression in legacy context should fail
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00002000 set thesaurusfunc=(a,\ b)\ =>\ TsrFunc1(21,\ a,\ b)
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00002001 new | only
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00002002 let g:TsrFunc1Args = []
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00002003 call assert_fails('call feedkeys("A\<C-X>\<C-T>\<Esc>", "x")', 'E117:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00002004 call assert_equal([], g:TsrFunc1Args)
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00002005 bw!
2006
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00002007 " set 'thesaurusfunc' to a partial with dict. This used to cause a crash.
2008 func SetTsrFunc()
2009 let params = {'thesaurus': function('g:DictTsrFunc')}
2010 let &thesaurusfunc = params.thesaurus
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00002011 endfunc
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00002012 func g:DictTsrFunc(_) dict
2013 endfunc
2014 call SetTsrFunc()
2015 new
2016 call SetTsrFunc()
2017 bw
2018 call test_garbagecollect_now()
2019 new
2020 set thesaurusfunc=
2021 wincmd w
2022 %bw!
2023 delfunc SetTsrFunc
2024
2025 " set buffer-local 'thesaurusfunc' to a partial with dict. This used to
2026 " cause a crash.
2027 func SetLocalTsrFunc()
2028 let params = {'thesaurus': function('g:DictTsrFunc')}
2029 let &l:thesaurusfunc = params.thesaurus
2030 endfunc
2031 call SetLocalTsrFunc()
2032 call test_garbagecollect_now()
2033 call SetLocalTsrFunc()
2034 set thesaurusfunc=
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00002035 bw!
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +00002036 delfunc g:DictTsrFunc
2037 delfunc SetLocalTsrFunc
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00002038
2039 " Vim9 tests
2040 let lines =<< trim END
2041 vim9script
2042
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00002043 def Vim9tsrFunc(callnr: number, findstart: number, base: string): any
2044 add(g:Vim9tsrFunc_Args, [callnr, findstart, base])
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00002045 return findstart ? 0 : []
2046 enddef
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00002047
2048 # Test for using a def function with thesaurusfunc
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00002049 set thesaurusfunc=function('Vim9tsrFunc',\ [60])
2050 new | only
2051 setline(1, 'one')
2052 g:Vim9tsrFunc_Args = []
2053 feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
2054 assert_equal([[60, 1, ''], [60, 0, 'one']], g:Vim9tsrFunc_Args)
2055 bw!
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +00002056
2057 # Test for using a global function name
2058 &thesaurusfunc = g:TsrFunc2
2059 new | only
2060 setline(1, 'two')
2061 g:TsrFunc2Args = []
2062 feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
2063 assert_equal([[1, ''], [0, 'two']], g:TsrFunc2Args)
2064 bw!
2065
2066 # Test for using a script-local function name
2067 def s:LocalTsrFunc(findstart: number, base: string): any
2068 add(g:LocalTsrFuncArgs, [findstart, base])
2069 return findstart ? 0 : []
2070 enddef
2071 &thesaurusfunc = s:LocalTsrFunc
2072 new | only
2073 setline(1, 'three')
2074 g:LocalTsrFuncArgs = []
2075 feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
2076 assert_equal([[1, ''], [0, 'three']], g:LocalTsrFuncArgs)
2077 bw!
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00002078 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002079 call v9.CheckScriptSuccess(lines)
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00002080
2081 " cleanup
2082 set thesaurusfunc&
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +00002083 delfunc TsrFunc1
2084 delfunc TsrFunc2
2085 unlet g:TsrFunc1Args g:TsrFunc2Args
Yegappan Lakshmanan8658c752021-12-03 11:09:29 +00002086 %bw!
2087endfunc
2088
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002089" vim: shiftwidth=2 sts=2 expandtab