blob: 5d04583717e89541aae8097ab6c288f5c31a94bb [file] [log] [blame]
Bram Moolenaar00672e12016-06-26 18:38:13 +02001" Test for completion menu
2
Bram Moolenaara5e66212017-09-29 22:42:33 +02003source shared.vim
Bram Moolenaar6bb2cdf2018-02-24 19:53:53 +01004source screendump.vim
Bram Moolenaar8c5a2782019-08-07 23:07:07 +02005source check.vim
Bram Moolenaara5e66212017-09-29 22:42:33 +02006
Bram Moolenaar00672e12016-06-26 18:38:13 +02007let g:months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
8let g:setting = ''
9
Bram Moolenaarae0f30b2018-06-12 15:22:43 +020010func ListMonths()
Bram Moolenaar47247282016-08-02 22:36:02 +020011 if g:setting != ''
12 exe ":set" g:setting
13 endif
Bram Moolenaaraed6d0b2017-01-27 21:48:54 +010014 let mth = copy(g:months)
Bram Moolenaar47247282016-08-02 22:36:02 +020015 let entered = strcharpart(getline('.'),0,col('.'))
16 if !empty(entered)
Bram Moolenaaraed6d0b2017-01-27 21:48:54 +010017 let mth = filter(mth, 'v:val=~"^".entered')
Bram Moolenaar47247282016-08-02 22:36:02 +020018 endif
19 call complete(1, mth)
20 return ''
Bram Moolenaar00672e12016-06-26 18:38:13 +020021endfunc
22
Bram Moolenaarae0f30b2018-06-12 15:22:43 +020023func Test_popup_complete2()
Bram Moolenaar9e02cfa2016-09-22 21:27:11 +020024 " Although the popupmenu is not visible, this does not mean completion mode
25 " has ended. After pressing <f5> to complete the currently typed char, Vim
26 " still stays in the first state of the completion (:h ins-completion-menu),
27 " although the popupmenu wasn't shown <c-e> will remove the inserted
28 " completed text (:h complete_CTRL-E), while the following <c-e> will behave
29 " like expected (:h i_CTRL-E)
Bram Moolenaardac19472016-09-03 22:35:40 +020030 new
31 inoremap <f5> <c-r>=ListMonths()<cr>
32 call append(1, ["December2015"])
33 :1
34 call feedkeys("aD\<f5>\<C-E>\<C-E>\<C-E>\<C-E>\<enter>\<esc>", 'tx')
Bram Moolenaar9e02cfa2016-09-22 21:27:11 +020035 call assert_equal(["Dece", "", "December2015"], getline(1,3))
Bram Moolenaardac19472016-09-03 22:35:40 +020036 %d
37 bw!
Bram Moolenaarae0f30b2018-06-12 15:22:43 +020038endfunc
Bram Moolenaardac19472016-09-03 22:35:40 +020039
Bram Moolenaarae0f30b2018-06-12 15:22:43 +020040func Test_popup_complete()
Bram Moolenaar47247282016-08-02 22:36:02 +020041 new
42 inoremap <f5> <c-r>=ListMonths()<cr>
43
44 " <C-E> - select original typed text before the completion started
45 call feedkeys("aJu\<f5>\<down>\<c-e>\<esc>", 'tx')
46 call assert_equal(["Ju"], getline(1,2))
47 %d
48
49 " <C-Y> - accept current match
50 call feedkeys("a\<f5>". repeat("\<down>",7). "\<c-y>\<esc>", 'tx')
51 call assert_equal(["August"], getline(1,2))
52 %d
53
54 " <BS> - Delete one character from the inserted text (state: 1)
55 " TODO: This should not end the completion, but it does.
56 " This should according to the documentation:
57 " January
58 " but instead, this does
59 " Januar
60 " (idea is, C-L inserts the match from the popup menu
61 " but if the menu is closed, it will insert the character <c-l>
62 call feedkeys("aJ\<f5>\<bs>\<c-l>\<esc>", 'tx')
63 call assert_equal(["Januar "], getline(1,2))
64 %d
65
66 " any-non special character: Stop completion without changing the match
67 " and insert the typed character
68 call feedkeys("a\<f5>20", 'tx')
69 call assert_equal(["January20"], getline(1,2))
70 %d
71
72 " any-non printable, non-white character: Add this character and
73 " reduce number of matches
74 call feedkeys("aJu\<f5>\<c-p>l\<c-y>", 'tx')
75 call assert_equal(["Jul"], getline(1,2))
76 %d
77
78 " any-non printable, non-white character: Add this character and
79 " reduce number of matches
80 call feedkeys("aJu\<f5>\<c-p>l\<c-n>\<c-y>", 'tx')
81 call assert_equal(["July"], getline(1,2))
82 %d
83
84 " any-non printable, non-white character: Add this character and
85 " reduce number of matches
86 call feedkeys("aJu\<f5>\<c-p>l\<c-e>", 'tx')
87 call assert_equal(["Jul"], getline(1,2))
88 %d
89
90 " <BS> - Delete one character from the inserted text (state: 2)
91 call feedkeys("a\<f5>\<c-n>\<bs>", 'tx')
92 call assert_equal(["Februar"], getline(1,2))
93 %d
94
95 " <c-l> - Insert one character from the current match
96 call feedkeys("aJ\<f5>".repeat("\<c-n>",3)."\<c-l>\<esc>", 'tx')
97 call assert_equal(["J "], getline(1,2))
98 %d
99
100 " <c-l> - Insert one character from the current match
101 call feedkeys("aJ\<f5>".repeat("\<c-n>",4)."\<c-l>\<esc>", 'tx')
102 call assert_equal(["January "], getline(1,2))
103 %d
104
105 " <c-y> - Accept current selected match
106 call feedkeys("aJ\<f5>\<c-y>\<esc>", 'tx')
107 call assert_equal(["January"], getline(1,2))
108 %d
109
110 " <c-e> - End completion, go back to what was there before selecting a match
111 call feedkeys("aJu\<f5>\<c-e>\<esc>", 'tx')
112 call assert_equal(["Ju"], getline(1,2))
113 %d
114
115 " <PageUp> - Select a match several entries back
116 call feedkeys("a\<f5>\<PageUp>\<c-y>\<esc>", 'tx')
117 call assert_equal([""], getline(1,2))
118 %d
119
120 " <PageUp><PageUp> - Select a match several entries back
121 call feedkeys("a\<f5>\<PageUp>\<PageUp>\<c-y>\<esc>", 'tx')
122 call assert_equal(["December"], getline(1,2))
123 %d
124
125 " <PageUp><PageUp><PageUp> - Select a match several entries back
126 call feedkeys("a\<f5>\<PageUp>\<PageUp>\<PageUp>\<c-y>\<esc>", 'tx')
127 call assert_equal(["February"], getline(1,2))
128 %d
129
130 " <PageDown> - Select a match several entries further
131 call feedkeys("a\<f5>\<PageDown>\<c-y>\<esc>", 'tx')
132 call assert_equal(["November"], getline(1,2))
133 %d
134
135 " <PageDown><PageDown> - Select a match several entries further
136 call feedkeys("a\<f5>\<PageDown>\<PageDown>\<c-y>\<esc>", 'tx')
137 call assert_equal(["December"], getline(1,2))
138 %d
139
140 " <PageDown><PageDown><PageDown> - Select a match several entries further
141 call feedkeys("a\<f5>\<PageDown>\<PageDown>\<PageDown>\<c-y>\<esc>", 'tx')
142 call assert_equal([""], getline(1,2))
143 %d
144
145 " <PageDown><PageDown><PageDown><PageDown> - Select a match several entries further
146 call feedkeys("a\<f5>".repeat("\<PageDown>",4)."\<c-y>\<esc>", 'tx')
147 call assert_equal(["October"], getline(1,2))
148 %d
149
150 " <Up> - Select a match don't insert yet
151 call feedkeys("a\<f5>\<Up>\<c-y>\<esc>", 'tx')
152 call assert_equal([""], getline(1,2))
153 %d
154
155 " <Up><Up> - Select a match don't insert yet
156 call feedkeys("a\<f5>\<Up>\<Up>\<c-y>\<esc>", 'tx')
157 call assert_equal(["December"], getline(1,2))
158 %d
159
160 " <Up><Up><Up> - Select a match don't insert yet
161 call feedkeys("a\<f5>\<Up>\<Up>\<Up>\<c-y>\<esc>", 'tx')
162 call assert_equal(["November"], getline(1,2))
163 %d
164
165 " <Tab> - Stop completion and insert the match
166 call feedkeys("a\<f5>\<Tab>\<c-y>\<esc>", 'tx')
167 call assert_equal(["January "], getline(1,2))
168 %d
169
170 " <Space> - Stop completion and insert the match
171 call feedkeys("a\<f5>".repeat("\<c-p>",5)." \<esc>", 'tx')
172 call assert_equal(["September "], getline(1,2))
173 %d
174
175 " <Enter> - Use the text and insert line break (state: 1)
176 call feedkeys("a\<f5>\<enter>\<esc>", 'tx')
177 call assert_equal(["January", ''], getline(1,2))
178 %d
179
180 " <Enter> - Insert the current selected text (state: 2)
181 call feedkeys("a\<f5>".repeat("\<Up>",5)."\<enter>\<esc>", 'tx')
182 call assert_equal(["September"], getline(1,2))
183 %d
184
185 " Insert match immediately, if there is only one match
186 " <c-y> selects a character from the line above
187 call append(0, ["December2015"])
188 call feedkeys("aD\<f5>\<C-Y>\<C-Y>\<C-Y>\<C-Y>\<enter>\<esc>", 'tx')
189 call assert_equal(["December2015", "December2015", ""], getline(1,3))
190 %d
191
Bram Moolenaar47247282016-08-02 22:36:02 +0200192 " use menuone for 'completeopt'
193 " Since for the first <c-y> the menu is still shown, will only select
194 " three letters from the line above
195 set completeopt&vim
196 set completeopt+=menuone
197 call append(0, ["December2015"])
198 call feedkeys("aD\<f5>\<C-Y>\<C-Y>\<C-Y>\<C-Y>\<enter>\<esc>", 'tx')
199 call assert_equal(["December2015", "December201", ""], getline(1,3))
200 %d
201
202 " use longest for 'completeopt'
203 set completeopt&vim
204 call feedkeys("aM\<f5>\<C-N>\<C-P>\<c-e>\<enter>\<esc>", 'tx')
205 set completeopt+=longest
206 call feedkeys("aM\<f5>\<C-N>\<C-P>\<c-e>\<enter>\<esc>", 'tx')
207 call assert_equal(["M", "Ma", ""], getline(1,3))
208 %d
209
210 " use noselect/noinsert for 'completeopt'
211 set completeopt&vim
212 call feedkeys("aM\<f5>\<enter>\<esc>", 'tx')
213 set completeopt+=noselect
214 call feedkeys("aM\<f5>\<enter>\<esc>", 'tx')
215 set completeopt-=noselect completeopt+=noinsert
216 call feedkeys("aM\<f5>\<enter>\<esc>", 'tx')
217 call assert_equal(["March", "M", "March"], getline(1,4))
218 %d
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200219endfunc
Bram Moolenaar47247282016-08-02 22:36:02 +0200220
221
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200222func Test_popup_completion_insertmode()
Bram Moolenaar67081e52016-07-09 21:49:03 +0200223 new
224 inoremap <F5> <C-R>=ListMonths()<CR>
225
226 call feedkeys("a\<f5>\<down>\<enter>\<esc>", 'tx')
227 call assert_equal('February', getline(1))
228 %d
Bram Moolenaar47247282016-08-02 22:36:02 +0200229 " Set noinsertmode
Bram Moolenaar67081e52016-07-09 21:49:03 +0200230 let g:setting = 'noinsertmode'
231 call feedkeys("a\<f5>\<down>\<enter>\<esc>", 'tx')
232 call assert_equal('February', getline(1))
233 call assert_false(pumvisible())
234 %d
Bram Moolenaar47247282016-08-02 22:36:02 +0200235 " Go through all matches, until none is selected
Bram Moolenaar67081e52016-07-09 21:49:03 +0200236 let g:setting = ''
237 call feedkeys("a\<f5>". repeat("\<c-n>",12)."\<enter>\<esc>", 'tx')
238 call assert_equal('', getline(1))
239 %d
Bram Moolenaar47247282016-08-02 22:36:02 +0200240 " select previous entry
Bram Moolenaar67081e52016-07-09 21:49:03 +0200241 call feedkeys("a\<f5>\<c-p>\<enter>\<esc>", 'tx')
242 call assert_equal('', getline(1))
243 %d
Bram Moolenaar47247282016-08-02 22:36:02 +0200244 " select last entry
Bram Moolenaar67081e52016-07-09 21:49:03 +0200245 call feedkeys("a\<f5>\<c-p>\<c-p>\<enter>\<esc>", 'tx')
246 call assert_equal('December', getline(1))
247
Bram Moolenaar67081e52016-07-09 21:49:03 +0200248 iunmap <F5>
249endfunc
250
Bram Moolenaar67081e52016-07-09 21:49:03 +0200251func Test_noinsert_complete()
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200252 func! s:complTest1() abort
Bram Moolenaar1a3a8912019-08-23 22:31:37 +0200253 eval ['source', 'soundfold']->complete(1)
Bram Moolenaar33a80ee2016-09-05 21:51:14 +0200254 return ''
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200255 endfunc
Bram Moolenaar33a80ee2016-09-05 21:51:14 +0200256
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200257 func! s:complTest2() abort
Bram Moolenaar33a80ee2016-09-05 21:51:14 +0200258 call complete(1, ['source', 'soundfold'])
259 return ''
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200260 endfunc
Bram Moolenaar33a80ee2016-09-05 21:51:14 +0200261
Bram Moolenaar67081e52016-07-09 21:49:03 +0200262 new
263 set completeopt+=noinsert
Bram Moolenaar33a80ee2016-09-05 21:51:14 +0200264 inoremap <F5> <C-R>=s:complTest1()<CR>
Bram Moolenaar67081e52016-07-09 21:49:03 +0200265 call feedkeys("i\<F5>soun\<CR>\<CR>\<ESC>.", 'tx')
266 call assert_equal('soundfold', getline(1))
267 call assert_equal('soundfold', getline(2))
Bram Moolenaar67081e52016-07-09 21:49:03 +0200268 bwipe!
Bram Moolenaar32b808a2016-07-09 21:57:20 +0200269
270 new
Bram Moolenaar33a80ee2016-09-05 21:51:14 +0200271 inoremap <F5> <C-R>=s:complTest2()<CR>
Bram Moolenaar32b808a2016-07-09 21:57:20 +0200272 call feedkeys("i\<F5>\<CR>\<ESC>", 'tx')
273 call assert_equal('source', getline(1))
274 bwipe!
275
Bram Moolenaar67081e52016-07-09 21:49:03 +0200276 set completeopt-=noinsert
277 iunmap <F5>
Bram Moolenaar00672e12016-06-26 18:38:13 +0200278endfunc
Bram Moolenaar32b808a2016-07-09 21:57:20 +0200279
Bram Moolenaar73655cf2019-04-06 13:45:55 +0200280func Test_complete_no_filter()
281 func! s:complTest1() abort
282 call complete(1, [{'word': 'foobar'}])
283 return ''
284 endfunc
285 func! s:complTest2() abort
286 call complete(1, [{'word': 'foobar', 'equal': 1}])
287 return ''
288 endfunc
289
290 let completeopt = &completeopt
291
292 " without equal=1
293 new
294 set completeopt=menuone,noinsert,menu
295 inoremap <F5> <C-R>=s:complTest1()<CR>
296 call feedkeys("i\<F5>z\<CR>\<CR>\<ESC>.", 'tx')
297 call assert_equal('z', getline(1))
298 bwipe!
299
300 " with equal=1
301 new
302 set completeopt=menuone,noinsert,menu
303 inoremap <F5> <C-R>=s:complTest2()<CR>
304 call feedkeys("i\<F5>z\<CR>\<CR>\<ESC>.", 'tx')
305 call assert_equal('foobar', getline(1))
306 bwipe!
307
308 let &completeopt = completeopt
309 iunmap <F5>
310endfunc
311
Bram Moolenaar33a80ee2016-09-05 21:51:14 +0200312func Test_compl_vim_cmds_after_register_expr()
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200313 func! s:test_func()
Bram Moolenaar33a80ee2016-09-05 21:51:14 +0200314 return 'autocmd '
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200315 endfunc
Bram Moolenaar33a80ee2016-09-05 21:51:14 +0200316 augroup AAAAA_Group
317 au!
318 augroup END
Bram Moolenaar32b808a2016-07-09 21:57:20 +0200319
Bram Moolenaar33a80ee2016-09-05 21:51:14 +0200320 new
321 call feedkeys("i\<c-r>=s:test_func()\<CR>\<C-x>\<C-v>\<Esc>", 'tx')
322 call assert_equal('autocmd AAAAA_Group', getline(1))
323 autocmd! AAAAA_Group
324 augroup! AAAAA_Group
325 bwipe!
326endfunc
Bram Moolenaar47247282016-08-02 22:36:02 +0200327
Bram Moolenaar472e8592016-10-15 17:06:47 +0200328func DummyCompleteOne(findstart, base)
329 if a:findstart
330 return 0
331 else
332 wincmd n
333 return ['onedef', 'oneDEF']
334 endif
335endfunc
336
Bram Moolenaarff06f282020-04-21 22:01:14 +0200337" Test that nothing happens if the 'completefunc' tries to open
338" a new window (fails to open window, continues)
Bram Moolenaar472e8592016-10-15 17:06:47 +0200339func Test_completefunc_opens_new_window_one()
340 new
341 let winid = win_getid()
342 setlocal completefunc=DummyCompleteOne
343 call setline(1, 'one')
344 /^one
Bram Moolenaar28976e22021-01-29 21:07:07 +0100345 call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E565:')
Bram Moolenaar472e8592016-10-15 17:06:47 +0200346 call assert_equal(winid, win_getid())
Bram Moolenaar28ee8922020-10-28 20:20:00 +0100347 call assert_equal('onedef', getline(1))
Bram Moolenaar472e8592016-10-15 17:06:47 +0200348 q!
349endfunc
350
351" Test that nothing happens if the 'completefunc' opens
352" a new window (no completion, no crash)
353func DummyCompleteTwo(findstart, base)
354 if a:findstart
355 wincmd n
356 return 0
357 else
358 return ['twodef', 'twoDEF']
359 endif
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200360endfunc
Bram Moolenaar472e8592016-10-15 17:06:47 +0200361
362" Test that nothing happens if the 'completefunc' opens
363" a new window (no completion, no crash)
364func Test_completefunc_opens_new_window_two()
365 new
366 let winid = win_getid()
367 setlocal completefunc=DummyCompleteTwo
368 call setline(1, 'two')
369 /^two
Bram Moolenaar3eb6bd92021-01-29 21:47:24 +0100370 call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E565:')
Bram Moolenaar472e8592016-10-15 17:06:47 +0200371 call assert_equal(winid, win_getid())
Bram Moolenaar3eb6bd92021-01-29 21:47:24 +0100372 call assert_equal('twodef', getline(1))
Bram Moolenaar472e8592016-10-15 17:06:47 +0200373 q!
374endfunc
375
376func DummyCompleteThree(findstart, base)
377 if a:findstart
378 return 0
379 else
380 return ['threedef', 'threeDEF']
381 endif
382endfunc
383
384:"Test that 'completefunc' works when it's OK.
385func Test_completefunc_works()
386 new
387 let winid = win_getid()
388 setlocal completefunc=DummyCompleteThree
389 call setline(1, 'three')
390 /^three
391 call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")
392 call assert_equal(winid, win_getid())
393 call assert_equal('threeDEF', getline(1))
394 q!
395endfunc
396
397func DummyCompleteFour(findstart, base)
398 if a:findstart
399 return 0
400 else
401 call complete_add('four1')
Bram Moolenaar1a3a8912019-08-23 22:31:37 +0200402 eval 'four2'->complete_add()
Bram Moolenaar472e8592016-10-15 17:06:47 +0200403 call complete_check()
404 call complete_add('four3')
405 call complete_add('four4')
406 call complete_check()
407 call complete_add('four5')
408 call complete_add('four6')
409 return []
410 endif
411endfunc
412
Bram Moolenaar60ef3e82016-10-29 14:37:56 +0200413" Test that 'omnifunc' works when it's OK.
Bram Moolenaar472e8592016-10-15 17:06:47 +0200414func Test_omnifunc_with_check()
415 new
416 setlocal omnifunc=DummyCompleteFour
417 call setline(1, 'four')
418 /^four
419 call feedkeys("A\<C-X>\<C-O>\<C-N>\<Esc>", "x")
420 call assert_equal('four2', getline(1))
421
422 call setline(1, 'four')
423 /^four
424 call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<Esc>", "x")
425 call assert_equal('four3', getline(1))
426
427 call setline(1, 'four')
428 /^four
429 call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<C-N>\<C-N>\<Esc>", "x")
430 call assert_equal('four5', getline(1))
431
432 q!
433endfunc
434
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200435func UndoComplete()
Bram Moolenaar869e3522016-10-16 15:35:47 +0200436 call complete(1, ['January', 'February', 'March',
437 \ 'April', 'May', 'June', 'July', 'August', 'September',
438 \ 'October', 'November', 'December'])
439 return ''
440endfunc
441
442" Test that no undo item is created when no completion is inserted
443func Test_complete_no_undo()
444 set completeopt=menu,preview,noinsert,noselect
445 inoremap <Right> <C-R>=UndoComplete()<CR>
446 new
447 call feedkeys("ixxx\<CR>\<CR>yyy\<Esc>k", 'xt')
448 call feedkeys("iaaa\<Esc>0", 'xt')
449 call assert_equal('aaa', getline(2))
450 call feedkeys("i\<Right>\<Esc>", 'xt')
451 call assert_equal('aaa', getline(2))
452 call feedkeys("u", 'xt')
453 call assert_equal('', getline(2))
454
Bram Moolenaarcbd3bd62016-10-17 20:47:02 +0200455 call feedkeys("ibbb\<Esc>0", 'xt')
456 call assert_equal('bbb', getline(2))
457 call feedkeys("A\<Right>\<Down>\<CR>\<Esc>", 'xt')
458 call assert_equal('January', getline(2))
459 call feedkeys("u", 'xt')
460 call assert_equal('bbb', getline(2))
461
Bram Moolenaar9ec7fa82016-10-18 13:06:41 +0200462 call feedkeys("A\<Right>\<C-N>\<Esc>", 'xt')
463 call assert_equal('January', getline(2))
464 call feedkeys("u", 'xt')
465 call assert_equal('bbb', getline(2))
466
Bram Moolenaar869e3522016-10-16 15:35:47 +0200467 iunmap <Right>
468 set completeopt&
469 q!
470endfunc
471
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200472func DummyCompleteFive(findstart, base)
Bram Moolenaar60ef3e82016-10-29 14:37:56 +0200473 if a:findstart
474 return 0
475 else
476 return [
477 \ { 'word': 'January', 'info': "info1-1\n1-2\n1-3" },
478 \ { 'word': 'February', 'info': "info2-1\n2-2\n2-3" },
479 \ { 'word': 'March', 'info': "info3-1\n3-2\n3-3" },
480 \ { 'word': 'April', 'info': "info4-1\n4-2\n4-3" },
481 \ { 'word': 'May', 'info': "info5-1\n5-2\n5-3" },
482 \ ]
483 endif
484endfunc
485
486" Test that 'completefunc' on Scratch buffer with preview window works when
487" it's OK.
488func Test_completefunc_with_scratch_buffer()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +0100489 CheckFeature quickfix
490
Bram Moolenaar60ef3e82016-10-29 14:37:56 +0200491 new +setlocal\ buftype=nofile\ bufhidden=wipe\ noswapfile
492 set completeopt+=preview
493 setlocal completefunc=DummyCompleteFive
494 call feedkeys("A\<C-X>\<C-U>\<C-N>\<C-N>\<C-N>\<Esc>", "x")
495 call assert_equal(['April'], getline(1, '$'))
496 pclose
497 q!
498 set completeopt&
499endfunc
Bram Moolenaar869e3522016-10-16 15:35:47 +0200500
Bram Moolenaar73fd4982016-12-09 19:36:56 +0100501" <C-E> - select original typed text before the completion started without
502" auto-wrap text.
503func Test_completion_ctrl_e_without_autowrap()
504 new
Bram Moolenaaraed6d0b2017-01-27 21:48:54 +0100505 let tw_save = &tw
Bram Moolenaar73fd4982016-12-09 19:36:56 +0100506 set tw=78
507 let li = [
508 \ '" zzz',
509 \ '" zzzyyyyyyyyyyyyyyyyyyy']
510 call setline(1, li)
511 0
512 call feedkeys("A\<C-X>\<C-N>\<C-E>\<Esc>", "tx")
513 call assert_equal(li, getline(1, '$'))
514
Bram Moolenaaraed6d0b2017-01-27 21:48:54 +0100515 let &tw = tw_save
Bram Moolenaar73fd4982016-12-09 19:36:56 +0100516 q!
517endfunc
518
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200519func DummyCompleteSix()
Bram Moolenaaraed6d0b2017-01-27 21:48:54 +0100520 call complete(1, ['Hello', 'World'])
521 return ''
522endfunction
523
524" complete() correctly clears the list of autocomplete candidates
525" See #1411
526func Test_completion_clear_candidate_list()
527 new
528 %d
529 " select first entry from the completion popup
530 call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>", "tx")
531 call assert_equal('Hello', getline(1))
532 %d
533 " select second entry from the completion popup
534 call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>", "tx")
535 call assert_equal('World', getline(1))
536 %d
537 " select original text
538 call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>\<C-N>", "tx")
539 call assert_equal(' xxx', getline(1))
540 %d
541 " back at first entry from completion list
542 call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>\<C-N>\<C-N>", "tx")
543 call assert_equal('Hello', getline(1))
544
545 bw!
546endfunc
547
Bram Moolenaar190b04c2017-02-09 17:37:03 +0100548func Test_completion_respect_bs_option()
549 new
550 let li = ["aaa", "aaa12345", "aaaabcdef", "aaaABC"]
551
552 set bs=indent,eol
553 call setline(1, li)
554 1
555 call feedkeys("A\<C-X>\<C-N>\<C-P>\<BS>\<BS>\<BS>\<Esc>", "tx")
556 call assert_equal('aaa', getline(1))
557
558 %d
559 set bs=indent,eol,start
560 call setline(1, li)
561 1
562 call feedkeys("A\<C-X>\<C-N>\<C-P>\<BS>\<BS>\<BS>\<Esc>", "tx")
563 call assert_equal('', getline(1))
564
565 bw!
566endfunc
567
Bram Moolenaard56a79d2017-02-19 15:26:18 +0100568func CompleteUndo() abort
569 call complete(1, g:months)
570 return ''
571endfunc
572
573func Test_completion_can_undo()
574 inoremap <Right> <c-r>=CompleteUndo()<cr>
575 set completeopt+=noinsert,noselect
576
577 new
578 call feedkeys("a\<Right>a\<Esc>", 'xt')
579 call assert_equal('a', getline(1))
580 undo
581 call assert_equal('', getline(1))
582
583 bwipe!
584 set completeopt&
585 iunmap <Right>
586endfunc
587
Bram Moolenaard099e032017-02-21 23:00:36 +0100588func Test_completion_comment_formatting()
589 new
590 setl formatoptions=tcqro
591 call feedkeys("o/*\<cr>\<cr>/\<esc>", 'tx')
592 call assert_equal(['', '/*', ' *', ' */'], getline(1,4))
593 %d
594 call feedkeys("o/*\<cr>foobar\<cr>/\<esc>", 'tx')
595 call assert_equal(['', '/*', ' * foobar', ' */'], getline(1,4))
596 %d
597 try
598 call feedkeys("o/*\<cr>\<cr>\<c-x>\<c-u>/\<esc>", 'tx')
Bram Moolenaar37175402017-03-18 20:18:45 +0100599 call assert_report('completefunc not set, should have failed')
Bram Moolenaard099e032017-02-21 23:00:36 +0100600 catch
601 call assert_exception('E764:')
602 endtry
603 call assert_equal(['', '/*', ' *', ' */'], getline(1,4))
604 bwipe!
605endfunc
606
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200607func MessCompleteMonths()
Bram Moolenaar4475b622017-05-01 20:46:52 +0200608 for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep")
609 call complete_add(m)
610 if complete_check()
611 break
612 endif
613 endfor
614 return []
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200615endfunc
Bram Moolenaar4475b622017-05-01 20:46:52 +0200616
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200617func MessCompleteMore()
Bram Moolenaar4475b622017-05-01 20:46:52 +0200618 call complete(1, split("Oct Nov Dec"))
619 return []
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200620endfunc
Bram Moolenaar4475b622017-05-01 20:46:52 +0200621
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200622func MessComplete(findstart, base)
Bram Moolenaar4475b622017-05-01 20:46:52 +0200623 if a:findstart
624 let line = getline('.')
625 let start = col('.') - 1
626 while start > 0 && line[start - 1] =~ '\a'
627 let start -= 1
628 endwhile
629 return start
630 else
631 call MessCompleteMonths()
632 call MessCompleteMore()
633 return []
634 endif
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200635endfunc
Bram Moolenaar4475b622017-05-01 20:46:52 +0200636
637func Test_complete_func_mess()
638 " Calling complete() after complete_add() in 'completefunc' is wrong, but it
639 " should not crash.
640 set completefunc=MessComplete
641 new
642 call setline(1, 'Ju')
Bram Moolenaar28976e22021-01-29 21:07:07 +0100643 call assert_fails('call feedkeys("A\<c-x>\<c-u>/\<esc>", "tx")', 'E578:')
644 call assert_equal('Jan/', getline(1))
Bram Moolenaar4475b622017-05-01 20:46:52 +0200645 bwipe!
646 set completefunc=
647endfunc
648
Bram Moolenaar24a9e342017-06-24 15:39:07 +0200649func Test_complete_CTRLN_startofbuffer()
650 new
651 call setline(1, [ 'organize(cupboard, 3, 2);',
652 \ 'prioritize(bureau, 8, 7);',
653 \ 'realize(bannister, 4, 4);',
654 \ 'moralize(railing, 3,9);'])
655 let expected=['cupboard.organize(3, 2);',
656 \ 'bureau.prioritize(8, 7);',
657 \ 'bannister.realize(4, 4);',
658 \ 'railing.moralize(3,9);']
659 call feedkeys("qai\<c-n>\<c-n>.\<esc>3wdW\<cr>q3@a", 'tx')
660 call assert_equal(expected, getline(1,'$'))
Bram Moolenaara5e66212017-09-29 22:42:33 +0200661 bwipe!
662endfunc
663
664func Test_popup_and_window_resize()
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200665 CheckFeature terminal
Bram Moolenaar5a4c3082019-12-01 15:23:11 +0100666 CheckFeature quickfix
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200667 CheckNotGui
Bram Moolenaarf08b0eb2021-10-16 13:00:14 +0100668 let g:test_is_flaky = 1
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200669
Bram Moolenaara5e66212017-09-29 22:42:33 +0200670 let h = winheight(0)
671 if h < 15
672 return
673 endif
Bram Moolenaarb3158762017-11-02 17:50:14 +0100674 let rows = h / 3
Bram Moolenaarab8b1c12017-11-04 19:24:31 +0100675 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': rows})
676 call term_sendkeys(buf, (h / 3 - 1) . "o\<esc>")
Bram Moolenaarb3158762017-11-02 17:50:14 +0100677 " Wait for the nested Vim to exit insert mode, where it will show the ruler.
678 " Need to trigger a redraw.
Bram Moolenaarab8b1c12017-11-04 19:24:31 +0100679 call WaitFor({-> execute("redraw") == "" && term_getline(buf, rows) =~ '\<' . rows . ',.*Bot'})
Bram Moolenaarb3158762017-11-02 17:50:14 +0100680
Bram Moolenaarab8b1c12017-11-04 19:24:31 +0100681 call term_sendkeys(buf, "Gi\<c-x>")
682 call term_sendkeys(buf, "\<c-v>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200683 call TermWait(buf, 50)
Bram Moolenaarf52c3832017-09-30 16:49:19 +0200684 " popup first entry "!" must be at the top
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200685 call WaitForAssert({-> assert_match('^!\s*$', term_getline(buf, 1))})
Bram Moolenaara5e66212017-09-29 22:42:33 +0200686 exe 'resize +' . (h - 1)
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200687 call TermWait(buf, 50)
Bram Moolenaara5e66212017-09-29 22:42:33 +0200688 redraw!
Bram Moolenaarf52c3832017-09-30 16:49:19 +0200689 " popup shifted down, first line is now empty
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200690 call WaitForAssert({-> assert_equal('', term_getline(buf, 1))})
Bram Moolenaara5e66212017-09-29 22:42:33 +0200691 sleep 100m
Bram Moolenaarf52c3832017-09-30 16:49:19 +0200692 " popup is below cursor line and shows first match "!"
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200693 call WaitForAssert({-> assert_match('^!\s*$', term_getline(buf, term_getcursor(buf)[0] + 1))})
Bram Moolenaarf52c3832017-09-30 16:49:19 +0200694 " cursor line also shows !
Bram Moolenaarab8b1c12017-11-04 19:24:31 +0100695 call assert_match('^!\s*$', term_getline(buf, term_getcursor(buf)[0]))
Bram Moolenaar24a9e342017-06-24 15:39:07 +0200696 bwipe!
697endfunc
Bram Moolenaar4475b622017-05-01 20:46:52 +0200698
Bram Moolenaar9ad89c62017-10-26 22:04:04 +0200699func Test_popup_and_preview_autocommand()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +0100700 CheckFeature python
701 CheckFeature quickfix
702 if winheight(0) < 15
703 throw 'Skipped: window height insufficient'
704 endif
705
Bram Moolenaar9ad89c62017-10-26 22:04:04 +0200706 " This used to crash Vim
Bram Moolenaar9ad89c62017-10-26 22:04:04 +0200707 new
708 augroup MyBufAdd
709 au!
710 au BufAdd * nested tab sball
711 augroup END
712 set omnifunc=pythoncomplete#Complete
713 call setline(1, 'import os')
714 " make the line long
715 call setline(2, ' os.')
716 $
717 call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<C-N>\<enter>\<esc>", 'tx')
Bram Moolenaar2a45d642017-10-27 01:35:00 +0200718 call assert_equal("import os", getline(1))
719 call assert_match(' os.\(EX_IOERR\|O_CREAT\)$', getline(2))
Bram Moolenaar9ad89c62017-10-26 22:04:04 +0200720 call assert_equal(1, winnr('$'))
721 " previewwindow option is not set
722 call assert_equal(0, &previewwindow)
723 norm! gt
724 call assert_equal(0, &previewwindow)
725 norm! gT
Bram Moolenaar02ae9b42018-02-09 15:06:02 +0100726 call assert_equal(10, tabpagenr('$'))
Bram Moolenaar9ad89c62017-10-26 22:04:04 +0200727 tabonly
728 pclose
729 augroup MyBufAdd
730 au!
731 augroup END
732 augroup! MyBufAdd
733 bw!
734endfunc
735
Bram Moolenaar614ab8a2018-12-01 11:59:00 +0100736func Test_popup_and_previewwindow_dump()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +0100737 CheckScreendump
738 CheckFeature quickfix
739
Bram Moolenaare7eb9272019-06-24 00:58:07 +0200740 let lines =<< trim END
741 set previewheight=9
742 silent! pedit
Bram Moolenaar37bb0302020-03-27 20:24:14 +0100743 call setline(1, map(repeat(["ab"], 10), "v:val .. v:key"))
Bram Moolenaare7eb9272019-06-24 00:58:07 +0200744 exec "norm! G\<C-E>\<C-E>"
745 END
746 call writefile(lines, 'Xscript')
Bram Moolenaar614ab8a2018-12-01 11:59:00 +0100747 let buf = RunVimInTerminal('-S Xscript', {})
748
Bram Moolenaar37bb0302020-03-27 20:24:14 +0100749 " wait for the script to finish
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200750 call TermWait(buf)
Bram Moolenaar37bb0302020-03-27 20:24:14 +0100751
Bram Moolenaar614ab8a2018-12-01 11:59:00 +0100752 " Test that popup and previewwindow do not overlap.
Bram Moolenaar37bb0302020-03-27 20:24:14 +0100753 call term_sendkeys(buf, "o")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200754 call TermWait(buf, 50)
Bram Moolenaar37bb0302020-03-27 20:24:14 +0100755 call term_sendkeys(buf, "\<C-X>\<C-N>")
Bram Moolenaar614ab8a2018-12-01 11:59:00 +0100756 call VerifyScreenDump(buf, 'Test_popup_and_previewwindow_01', {})
757
758 call term_sendkeys(buf, "\<Esc>u")
759 call StopVimInTerminal(buf)
760 call delete('Xscript')
761endfunc
762
Bram Moolenaar246fe032017-11-19 19:56:27 +0100763func Test_balloon_split()
Bram Moolenaar073e4b92019-08-18 23:01:56 +0200764 CheckFunction balloon_split
765
Bram Moolenaar246fe032017-11-19 19:56:27 +0100766 call assert_equal([
Bram Moolenaara3571eb2017-11-26 16:53:16 +0100767 \ 'tempname: 0x555555e380a0 "/home/mool/.viminfz.tmp"',
768 \ ], balloon_split(
769 \ 'tempname: 0x555555e380a0 "/home/mool/.viminfz.tmp"'))
770 call assert_equal([
Bram Moolenaar246fe032017-11-19 19:56:27 +0100771 \ 'one two three four one two three four one two thre',
772 \ 'e four',
773 \ ], balloon_split(
774 \ 'one two three four one two three four one two three four'))
775
Bram Moolenaar073e4b92019-08-18 23:01:56 +0200776 eval 'struct = {one = 1, two = 2, three = 3}'
777 \ ->balloon_split()
778 \ ->assert_equal([
779 \ 'struct = {',
780 \ ' one = 1,',
781 \ ' two = 2,',
782 \ ' three = 3}',
783 \ ])
Bram Moolenaar246fe032017-11-19 19:56:27 +0100784
785 call assert_equal([
786 \ 'struct = {',
787 \ ' one = 1,',
788 \ ' nested = {',
789 \ ' n1 = "yes",',
790 \ ' n2 = "no"}',
791 \ ' two = 2}',
792 \ ], balloon_split(
793 \ 'struct = {one = 1, nested = {n1 = "yes", n2 = "no"} two = 2}'))
794 call assert_equal([
795 \ 'struct = 0x234 {',
796 \ ' long = 2343 "\\"some long string that will be wr',
797 \ 'apped in two\\"",',
798 \ ' next = 123}',
799 \ ], balloon_split(
800 \ 'struct = 0x234 {long = 2343 "\\"some long string that will be wrapped in two\\"", next = 123}'))
Bram Moolenaar9ae862e2019-11-21 13:27:06 +0100801 call assert_equal([
802 \ 'Some comment',
803 \ '',
804 \ 'typedef this that;',
805 \ ], balloon_split(
806 \ "Some comment\n\ntypedef this that;"))
Bram Moolenaar246fe032017-11-19 19:56:27 +0100807endfunc
808
Bram Moolenaar6bb2cdf2018-02-24 19:53:53 +0100809func Test_popup_position()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +0100810 CheckScreendump
811
Bram Moolenaare7eb9272019-06-24 00:58:07 +0200812 let lines =<< trim END
813 123456789_123456789_123456789_a
814 123456789_123456789_123456789_b
815 123
816 END
817 call writefile(lines, 'Xtest')
Bram Moolenaar6bb2cdf2018-02-24 19:53:53 +0100818 let buf = RunVimInTerminal('Xtest', {})
819 call term_sendkeys(buf, ":vsplit\<CR>")
820
821 " default pumwidth in left window: overlap in right window
822 call term_sendkeys(buf, "GA\<C-N>")
823 call VerifyScreenDump(buf, 'Test_popup_position_01', {'rows': 8})
824 call term_sendkeys(buf, "\<Esc>u")
825
826 " default pumwidth: fill until right of window
827 call term_sendkeys(buf, "\<C-W>l")
828 call term_sendkeys(buf, "GA\<C-N>")
829 call VerifyScreenDump(buf, 'Test_popup_position_02', {'rows': 8})
830
831 " larger pumwidth: used as minimum width
832 call term_sendkeys(buf, "\<Esc>u")
833 call term_sendkeys(buf, ":set pumwidth=30\<CR>")
834 call term_sendkeys(buf, "GA\<C-N>")
835 call VerifyScreenDump(buf, 'Test_popup_position_03', {'rows': 8})
836
Bram Moolenaar2b10bcb2018-02-24 21:25:44 +0100837 " completed text wider than the window and 'pumwidth' smaller than available
838 " space
839 call term_sendkeys(buf, "\<Esc>u")
840 call term_sendkeys(buf, ":set pumwidth=20\<CR>")
841 call term_sendkeys(buf, "ggI123456789_\<Esc>")
842 call term_sendkeys(buf, "jI123456789_\<Esc>")
843 call term_sendkeys(buf, "GA\<C-N>")
844 call VerifyScreenDump(buf, 'Test_popup_position_04', {'rows': 10})
845
Bram Moolenaar6bb2cdf2018-02-24 19:53:53 +0100846 call term_sendkeys(buf, "\<Esc>u")
847 call StopVimInTerminal(buf)
848 call delete('Xtest')
849endfunc
850
Bram Moolenaar69f5a302018-03-06 13:23:08 +0100851func Test_popup_command()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +0100852 CheckScreendump
853 CheckFeature menu
Bram Moolenaar69f5a302018-03-06 13:23:08 +0100854
Bram Moolenaar0eabd4d2020-03-15 16:13:53 +0100855 menu Test.Foo Foo
856 call assert_fails('popup Test.Foo', 'E336:')
857 call assert_fails('popup Test.Foo.X', 'E327:')
858 call assert_fails('popup Foo', 'E337:')
859 unmenu Test.Foo
860
Bram Moolenaar38455a92020-12-24 18:39:02 +0100861 let script =<< trim END
862 func StartTimer()
863 call timer_start(100, {-> ChangeMenu()})
864 endfunc
865 func ChangeMenu()
866 nunmenu PopUp.&Paste
867 nnoremenu 1.40 PopUp.&Paste :echomsg "pasted"<CR>
868 echomsg 'changed'
869 endfunc
870 END
871 call writefile(script, 'XtimerScript')
872
Bram Moolenaare7eb9272019-06-24 00:58:07 +0200873 let lines =<< trim END
874 one two three four five
875 and one two Xthree four five
876 one more two three four five
877 END
878 call writefile(lines, 'Xtest')
Bram Moolenaar38455a92020-12-24 18:39:02 +0100879 let buf = RunVimInTerminal('-S XtimerScript Xtest', {})
Bram Moolenaar69f5a302018-03-06 13:23:08 +0100880 call term_sendkeys(buf, ":source $VIMRUNTIME/menu.vim\<CR>")
881 call term_sendkeys(buf, "/X\<CR>:popup PopUp\<CR>")
882 call VerifyScreenDump(buf, 'Test_popup_command_01', {})
883
Bram Moolenaar38455a92020-12-24 18:39:02 +0100884 " go to the Paste entry in the menu
Bram Moolenaar69f5a302018-03-06 13:23:08 +0100885 call term_sendkeys(buf, "jj")
886 call VerifyScreenDump(buf, 'Test_popup_command_02', {})
887
888 " Select a word
889 call term_sendkeys(buf, "j\<CR>")
890 call VerifyScreenDump(buf, 'Test_popup_command_03', {})
891
892 call term_sendkeys(buf, "\<Esc>")
Bram Moolenaar38455a92020-12-24 18:39:02 +0100893
894 " Set a timer to change a menu entry while it's displayed. The text should
895 " not change but the command does. Making the screendump also verifies that
896 " "changed" shows up, which means the timer triggered
897 call term_sendkeys(buf, "/X\<CR>:call StartTimer() | popup PopUp\<CR>")
898 call VerifyScreenDump(buf, 'Test_popup_command_04', {})
899
900 " Select the Paste entry, executes the changed menu item.
901 call term_sendkeys(buf, "jj\<CR>")
902 call VerifyScreenDump(buf, 'Test_popup_command_05', {})
903
Bram Moolenaar69f5a302018-03-06 13:23:08 +0100904 call StopVimInTerminal(buf)
905 call delete('Xtest')
Bram Moolenaar38455a92020-12-24 18:39:02 +0100906 call delete('XtimerScript')
Bram Moolenaar69f5a302018-03-06 13:23:08 +0100907endfunc
908
Bram Moolenaare87edf32018-04-17 22:14:32 +0200909func Test_popup_complete_backwards()
910 new
911 call setline(1, ['Post', 'Port', 'Po'])
912 let expected=['Post', 'Port', 'Port']
913 call cursor(3,2)
914 call feedkeys("A\<C-X>". repeat("\<C-P>", 3). "rt\<cr>", 'tx')
915 call assert_equal(expected, getline(1,'$'))
916 bwipe!
917endfunc
Bram Moolenaar69f5a302018-03-06 13:23:08 +0100918
Bram Moolenaarbad0ce72018-04-17 23:31:05 +0200919func Test_popup_complete_backwards_ctrl_p()
920 new
921 call setline(1, ['Post', 'Port', 'Po'])
922 let expected=['Post', 'Port', 'Port']
923 call cursor(3,2)
924 call feedkeys("A\<C-P>\<C-N>rt\<cr>", 'tx')
925 call assert_equal(expected, getline(1,'$'))
926 bwipe!
927endfunc
928
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200929func Test_complete_o_tab()
Bram Moolenaar39de9522018-05-08 22:48:00 +0200930 let s:o_char_pressed = 0
931
932 fun! s:act_on_text_changed()
933 if s:o_char_pressed
934 let s:o_char_pressed = 0
935 call feedkeys("\<c-x>\<c-n>", 'i')
936 endif
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200937 endfunc
Bram Moolenaar39de9522018-05-08 22:48:00 +0200938
939 set completeopt=menu,noselect
940 new
941 imap <expr> <buffer> <tab> pumvisible() ? "\<c-p>" : "X"
942 autocmd! InsertCharPre <buffer> let s:o_char_pressed = (v:char ==# 'o')
943 autocmd! TextChangedI <buffer> call <sid>act_on_text_changed()
944 call setline(1, ['hoard', 'hoax', 'hoarse', ''])
945 let l:expected = ['hoard', 'hoax', 'hoarse', 'hoax', 'hoax']
946 call cursor(4,1)
947 call test_override("char_avail", 1)
948 call feedkeys("Ahoa\<tab>\<tab>\<c-y>\<esc>", 'tx')
949 call feedkeys("oho\<tab>\<tab>\<c-y>\<esc>", 'tx')
950 call assert_equal(l:expected, getline(1,'$'))
951
952 call test_override("char_avail", 0)
953 bwipe!
954 set completeopt&
955 delfunc s:act_on_text_changed
Bram Moolenaarae0f30b2018-06-12 15:22:43 +0200956endfunc
Bram Moolenaar39de9522018-05-08 22:48:00 +0200957
Bram Moolenaarf42b45d2019-01-06 13:11:05 +0100958func Test_menu_only_exists_in_terminal()
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200959 CheckCommand tlmenu
960 CheckNotGui
961
Bram Moolenaarf42b45d2019-01-06 13:11:05 +0100962 tlnoremenu &Edit.&Paste<Tab>"+gP <C-W>"+
963 aunmenu *
964 try
965 popup Edit
966 call assert_false(1, 'command should have failed')
967 catch
968 call assert_exception('E328:')
969 endtry
970endfunc
Bram Moolenaar39de9522018-05-08 22:48:00 +0200971
Bram Moolenaarfd133322019-03-29 12:20:27 +0100972func Test_popup_complete_info_01()
973 new
974 inoremap <buffer><F5> <C-R>=complete_info().mode<CR>
975 func s:complTestEval() abort
976 call complete(1, ['aa', 'ab'])
977 return ''
978 endfunc
979 inoremap <buffer><F6> <C-R>=s:complTestEval()<CR>
980 call writefile([
981 \ 'dummy dummy.txt 1',
982 \], 'Xdummy.txt')
983 setlocal tags=Xdummy.txt
984 setlocal dictionary=Xdummy.txt
985 setlocal thesaurus=Xdummy.txt
986 setlocal omnifunc=syntaxcomplete#Complete
987 setlocal completefunc=syntaxcomplete#Complete
988 setlocal spell
989 for [keys, mode_name] in [
990 \ ["", ''],
991 \ ["\<C-X>", 'ctrl_x'],
992 \ ["\<C-X>\<C-N>", 'keyword'],
993 \ ["\<C-X>\<C-P>", 'keyword'],
zeertzjq27fef592021-10-03 12:01:27 +0100994 \ ["\<C-X>\<C-E>", 'scroll'],
995 \ ["\<C-X>\<C-Y>", 'scroll'],
996 \ ["\<C-X>\<C-E>\<C-E>\<C-Y>", 'scroll'],
997 \ ["\<C-X>\<C-Y>\<C-E>\<C-Y>", 'scroll'],
Bram Moolenaarfd133322019-03-29 12:20:27 +0100998 \ ["\<C-X>\<C-L>", 'whole_line'],
999 \ ["\<C-X>\<C-F>", 'files'],
1000 \ ["\<C-X>\<C-]>", 'tags'],
1001 \ ["\<C-X>\<C-D>", 'path_defines'],
1002 \ ["\<C-X>\<C-I>", 'path_patterns'],
1003 \ ["\<C-X>\<C-K>", 'dictionary'],
1004 \ ["\<C-X>\<C-T>", 'thesaurus'],
1005 \ ["\<C-X>\<C-V>", 'cmdline'],
1006 \ ["\<C-X>\<C-U>", 'function'],
1007 \ ["\<C-X>\<C-O>", 'omni'],
1008 \ ["\<C-X>s", 'spell'],
1009 \ ["\<F6>", 'eval'],
1010 \]
1011 call feedkeys("i" . keys . "\<F5>\<Esc>", 'tx')
1012 call assert_equal(mode_name, getline('.'))
1013 %d
1014 endfor
1015 call delete('Xdummy.txt')
1016 bwipe!
1017endfunc
1018
1019func UserDefinedComplete(findstart, base)
1020 if a:findstart
1021 return 0
1022 else
1023 return [
1024 \ { 'word': 'Jan', 'menu': 'January' },
1025 \ { 'word': 'Feb', 'menu': 'February' },
1026 \ { 'word': 'Mar', 'menu': 'March' },
1027 \ { 'word': 'Apr', 'menu': 'April' },
1028 \ { 'word': 'May', 'menu': 'May' },
1029 \ ]
1030 endif
1031endfunc
1032
1033func GetCompleteInfo()
1034 if empty(g:compl_what)
1035 let g:compl_info = complete_info()
1036 else
Bram Moolenaar1a3a8912019-08-23 22:31:37 +02001037 let g:compl_info = g:compl_what->complete_info()
Bram Moolenaarfd133322019-03-29 12:20:27 +01001038 endif
1039 return ''
1040endfunc
1041
1042func Test_popup_complete_info_02()
1043 new
1044 inoremap <buffer><F5> <C-R>=GetCompleteInfo()<CR>
1045 setlocal completefunc=UserDefinedComplete
1046
1047 let d = {
1048 \ 'mode': 'function',
1049 \ 'pum_visible': 1,
1050 \ 'items': [
1051 \ {'word': 'Jan', 'menu': 'January', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''},
1052 \ {'word': 'Feb', 'menu': 'February', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''},
1053 \ {'word': 'Mar', 'menu': 'March', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''},
1054 \ {'word': 'Apr', 'menu': 'April', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''},
1055 \ {'word': 'May', 'menu': 'May', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}
1056 \ ],
1057 \ 'selected': 0,
1058 \ }
1059
1060 let g:compl_what = []
1061 call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx')
1062 call assert_equal(d, g:compl_info)
1063
1064 let g:compl_what = ['mode', 'pum_visible', 'selected']
1065 call remove(d, 'items')
1066 call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx')
1067 call assert_equal(d, g:compl_info)
1068
1069 let g:compl_what = ['mode']
1070 call remove(d, 'selected')
1071 call remove(d, 'pum_visible')
1072 call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx')
1073 call assert_equal(d, g:compl_info)
1074 bwipe!
1075endfunc
1076
Bram Moolenaare9bd5722019-08-17 19:36:06 +02001077func Test_popup_complete_info_no_pum()
1078 new
1079 call assert_false( pumvisible() )
1080 let no_pum_info = complete_info()
1081 let d = {
1082 \ 'mode': '',
1083 \ 'pum_visible': 0,
1084 \ 'items': [],
1085 \ 'selected': -1,
1086 \ }
1087 call assert_equal( d, complete_info() )
1088 bwipe!
1089endfunc
1090
Bram Moolenaard7f246c2019-04-08 18:15:41 +02001091func Test_CompleteChanged()
1092 new
1093 call setline(1, ['foo', 'bar', 'foobar', ''])
1094 set complete=. completeopt=noinsert,noselect,menuone
1095 function! OnPumChange()
1096 let g:event = copy(v:event)
1097 let g:item = get(v:event, 'completed_item', {})
1098 let g:word = get(g:item, 'word', v:null)
1099 endfunction
1100 augroup AAAAA_Group
1101 au!
1102 autocmd CompleteChanged * :call OnPumChange()
1103 augroup END
1104 call cursor(4, 1)
1105
1106 call feedkeys("Sf\<C-N>", 'tx')
1107 call assert_equal({'completed_item': {}, 'width': 15,
1108 \ 'height': 2, 'size': 2,
1109 \ 'col': 0, 'row': 4, 'scrollbar': v:false}, g:event)
1110 call feedkeys("a\<C-N>\<C-N>\<C-E>", 'tx')
1111 call assert_equal('foo', g:word)
1112 call feedkeys("a\<C-N>\<C-N>\<C-N>\<C-E>", 'tx')
1113 call assert_equal('foobar', g:word)
1114 call feedkeys("a\<C-N>\<C-N>\<C-N>\<C-N>\<C-E>", 'tx')
1115 call assert_equal(v:null, g:word)
1116 call feedkeys("a\<C-N>\<C-N>\<C-N>\<C-N>\<C-P>", 'tx')
1117 call assert_equal('foobar', g:word)
1118
1119 autocmd! AAAAA_Group
1120 set complete& completeopt&
Bram Moolenaare9bd5722019-08-17 19:36:06 +02001121 delfunc! OnPumChange
Bram Moolenaard7f246c2019-04-08 18:15:41 +02001122 bw!
1123endfunc
1124
Bram Moolenaare9bd5722019-08-17 19:36:06 +02001125function! GetPumPosition()
1126 call assert_true( pumvisible() )
1127 let g:pum_pos = pum_getpos()
1128 return ''
1129endfunction
1130
1131func Test_pum_getpos()
1132 new
1133 inoremap <buffer><F5> <C-R>=GetPumPosition()<CR>
1134 setlocal completefunc=UserDefinedComplete
1135
1136 let d = {
1137 \ 'height': 5,
1138 \ 'width': 15,
1139 \ 'row': 1,
1140 \ 'col': 0,
1141 \ 'size': 5,
1142 \ 'scrollbar': v:false,
1143 \ }
1144 call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx')
1145 call assert_equal(d, g:pum_pos)
1146
1147 call assert_false( pumvisible() )
1148 call assert_equal( {}, pum_getpos() )
1149 bw!
1150 unlet g:pum_pos
1151endfunc
1152
Yegappan Lakshmanan1e615662021-05-22 17:12:46 +02001153" Test for the popup menu with the 'rightleft' option set
1154func Test_pum_rightleft()
Dominique Pelle56cddb32021-06-04 21:09:55 +02001155 CheckFeature rightleft
Yegappan Lakshmanan1e615662021-05-22 17:12:46 +02001156 CheckScreendump
Dominique Pelle56cddb32021-06-04 21:09:55 +02001157
Yegappan Lakshmanan1e615662021-05-22 17:12:46 +02001158 let lines =<< trim END
1159 abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
1160 vim
1161 victory
1162 END
1163 call writefile(lines, 'Xtest1')
1164 let buf = RunVimInTerminal('--cmd "set rightleft" Xtest1', {})
1165 call term_wait(buf)
1166 call term_sendkeys(buf, "Go\<C-P>")
Yegappan Lakshmanan1e615662021-05-22 17:12:46 +02001167 call VerifyScreenDump(buf, 'Test_pum_rightleft_01', {'rows': 8})
1168 call term_sendkeys(buf, "\<C-P>\<C-Y>")
1169 call term_wait(buf)
1170 redraw!
1171 call assert_match('\s*miv', Screenline(5))
1172
1173 " Test for expanding tabs to spaces in the popup menu
1174 let lines =<< trim END
1175 one two
1176 one three
1177 four
1178 END
1179 call writefile(lines, 'Xtest2')
1180 call term_sendkeys(buf, "\<Esc>:e! Xtest2\<CR>")
1181 call term_wait(buf)
1182 call term_sendkeys(buf, "Goone\<C-X>\<C-L>")
1183 call term_wait(buf)
1184 redraw!
1185 call VerifyScreenDump(buf, 'Test_pum_rightleft_02', {'rows': 7})
1186 call term_sendkeys(buf, "\<C-Y>")
1187 call term_wait(buf)
1188 redraw!
1189 call assert_match('\s*eerht eno', Screenline(4))
1190
1191 call StopVimInTerminal(buf)
1192 call delete('Xtest1')
1193 call delete('Xtest2')
1194endfunc
1195
1196" Test for a popup menu with a scrollbar
1197func Test_pum_scrollbar()
1198 CheckScreendump
1199 let lines =<< trim END
1200 one
1201 two
1202 three
1203 END
1204 call writefile(lines, 'Xtest1')
1205 let buf = RunVimInTerminal('--cmd "set pumheight=2" Xtest1', {})
1206 call term_wait(buf)
1207 call term_sendkeys(buf, "Go\<C-P>\<C-P>\<C-P>")
Yegappan Lakshmanan1e615662021-05-22 17:12:46 +02001208 call VerifyScreenDump(buf, 'Test_pum_scrollbar_01', {'rows': 7})
1209 call term_sendkeys(buf, "\<C-E>\<Esc>dd")
1210 call term_wait(buf)
1211
Dominique Pelle56cddb32021-06-04 21:09:55 +02001212 if has('rightleft')
1213 call term_sendkeys(buf, ":set rightleft\<CR>")
1214 call term_wait(buf)
1215 call term_sendkeys(buf, "Go\<C-P>\<C-P>\<C-P>")
Dominique Pelle56cddb32021-06-04 21:09:55 +02001216 call VerifyScreenDump(buf, 'Test_pum_scrollbar_02', {'rows': 7})
1217 endif
Yegappan Lakshmanan1e615662021-05-22 17:12:46 +02001218
1219 call StopVimInTerminal(buf)
1220 call delete('Xtest1')
1221endfunc
1222
Bram Moolenaar47247282016-08-02 22:36:02 +02001223" vim: shiftwidth=2 sts=2 expandtab