1" Test for completion menu 2 3let g:months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] 4let g:setting = '' 5 6func! ListMonths() 7 if g:setting != '' 8 exe ":set" g:setting 9 endif 10 let mth = copy(g:months) 11 let entered = strcharpart(getline('.'),0,col('.')) 12 if !empty(entered) 13 let mth = filter(mth, 'v:val=~"^".entered') 14 endif 15 call complete(1, mth) 16 return '' 17endfunc 18 19func! Test_popup_complete2() 20 " Although the popupmenu is not visible, this does not mean completion mode 21 " has ended. After pressing <f5> to complete the currently typed char, Vim 22 " still stays in the first state of the completion (:h ins-completion-menu), 23 " although the popupmenu wasn't shown <c-e> will remove the inserted 24 " completed text (:h complete_CTRL-E), while the following <c-e> will behave 25 " like expected (:h i_CTRL-E) 26 new 27 inoremap <f5> <c-r>=ListMonths()<cr> 28 call append(1, ["December2015"]) 29 :1 30 call feedkeys("aD\<f5>\<C-E>\<C-E>\<C-E>\<C-E>\<enter>\<esc>", 'tx') 31 call assert_equal(["Dece", "", "December2015"], getline(1,3)) 32 %d 33 bw! 34endfu 35 36func! Test_popup_complete() 37 new 38 inoremap <f5> <c-r>=ListMonths()<cr> 39 40 " <C-E> - select original typed text before the completion started 41 call feedkeys("aJu\<f5>\<down>\<c-e>\<esc>", 'tx') 42 call assert_equal(["Ju"], getline(1,2)) 43 %d 44 45 " <C-Y> - accept current match 46 call feedkeys("a\<f5>". repeat("\<down>",7). "\<c-y>\<esc>", 'tx') 47 call assert_equal(["August"], getline(1,2)) 48 %d 49 50 " <BS> - Delete one character from the inserted text (state: 1) 51 " TODO: This should not end the completion, but it does. 52 " This should according to the documentation: 53 " January 54 " but instead, this does 55 " Januar 56 " (idea is, C-L inserts the match from the popup menu 57 " but if the menu is closed, it will insert the character <c-l> 58 call feedkeys("aJ\<f5>\<bs>\<c-l>\<esc>", 'tx') 59 call assert_equal(["Januar"], getline(1,2)) 60 %d 61 62 " any-non special character: Stop completion without changing the match 63 " and insert the typed character 64 call feedkeys("a\<f5>20", 'tx') 65 call assert_equal(["January20"], getline(1,2)) 66 %d 67 68 " any-non printable, non-white character: Add this character and 69 " reduce number of matches 70 call feedkeys("aJu\<f5>\<c-p>l\<c-y>", 'tx') 71 call assert_equal(["Jul"], getline(1,2)) 72 %d 73 74 " any-non printable, non-white character: Add this character and 75 " reduce number of matches 76 call feedkeys("aJu\<f5>\<c-p>l\<c-n>\<c-y>", 'tx') 77 call assert_equal(["July"], getline(1,2)) 78 %d 79 80 " any-non printable, non-white character: Add this character and 81 " reduce number of matches 82 call feedkeys("aJu\<f5>\<c-p>l\<c-e>", 'tx') 83 call assert_equal(["Jul"], getline(1,2)) 84 %d 85 86 " <BS> - Delete one character from the inserted text (state: 2) 87 call feedkeys("a\<f5>\<c-n>\<bs>", 'tx') 88 call assert_equal(["Februar"], getline(1,2)) 89 %d 90 91 " <c-l> - Insert one character from the current match 92 call feedkeys("aJ\<f5>".repeat("\<c-n>",3)."\<c-l>\<esc>", 'tx') 93 call assert_equal(["J"], getline(1,2)) 94 %d 95 96 " <c-l> - Insert one character from the current match 97 call feedkeys("aJ\<f5>".repeat("\<c-n>",4)."\<c-l>\<esc>", 'tx') 98 call assert_equal(["January"], getline(1,2)) 99 %d 100 101 " <c-y> - Accept current selected match 102 call feedkeys("aJ\<f5>\<c-y>\<esc>", 'tx') 103 call assert_equal(["January"], getline(1,2)) 104 %d 105 106 " <c-e> - End completion, go back to what was there before selecting a match 107 call feedkeys("aJu\<f5>\<c-e>\<esc>", 'tx') 108 call assert_equal(["Ju"], getline(1,2)) 109 %d 110 111 " <PageUp> - Select a match several entries back 112 call feedkeys("a\<f5>\<PageUp>\<c-y>\<esc>", 'tx') 113 call assert_equal([""], getline(1,2)) 114 %d 115 116 " <PageUp><PageUp> - Select a match several entries back 117 call feedkeys("a\<f5>\<PageUp>\<PageUp>\<c-y>\<esc>", 'tx') 118 call assert_equal(["December"], getline(1,2)) 119 %d 120 121 " <PageUp><PageUp><PageUp> - Select a match several entries back 122 call feedkeys("a\<f5>\<PageUp>\<PageUp>\<PageUp>\<c-y>\<esc>", 'tx') 123 call assert_equal(["February"], getline(1,2)) 124 %d 125 126 " <PageDown> - Select a match several entries further 127 call feedkeys("a\<f5>\<PageDown>\<c-y>\<esc>", 'tx') 128 call assert_equal(["November"], getline(1,2)) 129 %d 130 131 " <PageDown><PageDown> - Select a match several entries further 132 call feedkeys("a\<f5>\<PageDown>\<PageDown>\<c-y>\<esc>", 'tx') 133 call assert_equal(["December"], getline(1,2)) 134 %d 135 136 " <PageDown><PageDown><PageDown> - Select a match several entries further 137 call feedkeys("a\<f5>\<PageDown>\<PageDown>\<PageDown>\<c-y>\<esc>", 'tx') 138 call assert_equal([""], getline(1,2)) 139 %d 140 141 " <PageDown><PageDown><PageDown><PageDown> - Select a match several entries further 142 call feedkeys("a\<f5>".repeat("\<PageDown>",4)."\<c-y>\<esc>", 'tx') 143 call assert_equal(["October"], getline(1,2)) 144 %d 145 146 " <Up> - Select a match don't insert yet 147 call feedkeys("a\<f5>\<Up>\<c-y>\<esc>", 'tx') 148 call assert_equal([""], getline(1,2)) 149 %d 150 151 " <Up><Up> - Select a match don't insert yet 152 call feedkeys("a\<f5>\<Up>\<Up>\<c-y>\<esc>", 'tx') 153 call assert_equal(["December"], getline(1,2)) 154 %d 155 156 " <Up><Up><Up> - Select a match don't insert yet 157 call feedkeys("a\<f5>\<Up>\<Up>\<Up>\<c-y>\<esc>", 'tx') 158 call assert_equal(["November"], getline(1,2)) 159 %d 160 161 " <Tab> - Stop completion and insert the match 162 call feedkeys("a\<f5>\<Tab>\<c-y>\<esc>", 'tx') 163 call assert_equal(["January "], getline(1,2)) 164 %d 165 166 " <Space> - Stop completion and insert the match 167 call feedkeys("a\<f5>".repeat("\<c-p>",5)." \<esc>", 'tx') 168 call assert_equal(["September "], getline(1,2)) 169 %d 170 171 " <Enter> - Use the text and insert line break (state: 1) 172 call feedkeys("a\<f5>\<enter>\<esc>", 'tx') 173 call assert_equal(["January", ''], getline(1,2)) 174 %d 175 176 " <Enter> - Insert the current selected text (state: 2) 177 call feedkeys("a\<f5>".repeat("\<Up>",5)."\<enter>\<esc>", 'tx') 178 call assert_equal(["September"], getline(1,2)) 179 %d 180 181 " Insert match immediately, if there is only one match 182 " <c-y> selects a character from the line above 183 call append(0, ["December2015"]) 184 call feedkeys("aD\<f5>\<C-Y>\<C-Y>\<C-Y>\<C-Y>\<enter>\<esc>", 'tx') 185 call assert_equal(["December2015", "December2015", ""], getline(1,3)) 186 %d 187 188 " use menuone for 'completeopt' 189 " Since for the first <c-y> the menu is still shown, will only select 190 " three letters from the line above 191 set completeopt&vim 192 set completeopt+=menuone 193 call append(0, ["December2015"]) 194 call feedkeys("aD\<f5>\<C-Y>\<C-Y>\<C-Y>\<C-Y>\<enter>\<esc>", 'tx') 195 call assert_equal(["December2015", "December201", ""], getline(1,3)) 196 %d 197 198 " use longest for 'completeopt' 199 set completeopt&vim 200 call feedkeys("aM\<f5>\<C-N>\<C-P>\<c-e>\<enter>\<esc>", 'tx') 201 set completeopt+=longest 202 call feedkeys("aM\<f5>\<C-N>\<C-P>\<c-e>\<enter>\<esc>", 'tx') 203 call assert_equal(["M", "Ma", ""], getline(1,3)) 204 %d 205 206 " use noselect/noinsert for 'completeopt' 207 set completeopt&vim 208 call feedkeys("aM\<f5>\<enter>\<esc>", 'tx') 209 set completeopt+=noselect 210 call feedkeys("aM\<f5>\<enter>\<esc>", 'tx') 211 set completeopt-=noselect completeopt+=noinsert 212 call feedkeys("aM\<f5>\<enter>\<esc>", 'tx') 213 call assert_equal(["March", "M", "March"], getline(1,4)) 214 %d 215endfu 216 217 218func! Test_popup_completion_insertmode() 219 new 220 inoremap <F5> <C-R>=ListMonths()<CR> 221 222 call feedkeys("a\<f5>\<down>\<enter>\<esc>", 'tx') 223 call assert_equal('February', getline(1)) 224 %d 225 " Set noinsertmode 226 let g:setting = 'noinsertmode' 227 call feedkeys("a\<f5>\<down>\<enter>\<esc>", 'tx') 228 call assert_equal('February', getline(1)) 229 call assert_false(pumvisible()) 230 %d 231 " Go through all matches, until none is selected 232 let g:setting = '' 233 call feedkeys("a\<f5>". repeat("\<c-n>",12)."\<enter>\<esc>", 'tx') 234 call assert_equal('', getline(1)) 235 %d 236 " select previous entry 237 call feedkeys("a\<f5>\<c-p>\<enter>\<esc>", 'tx') 238 call assert_equal('', getline(1)) 239 %d 240 " select last entry 241 call feedkeys("a\<f5>\<c-p>\<c-p>\<enter>\<esc>", 'tx') 242 call assert_equal('December', getline(1)) 243 244 iunmap <F5> 245endfunc 246 247func Test_noinsert_complete() 248 function! s:complTest1() abort 249 call complete(1, ['source', 'soundfold']) 250 return '' 251 endfunction 252 253 function! s:complTest2() abort 254 call complete(1, ['source', 'soundfold']) 255 return '' 256 endfunction 257 258 new 259 set completeopt+=noinsert 260 inoremap <F5> <C-R>=s:complTest1()<CR> 261 call feedkeys("i\<F5>soun\<CR>\<CR>\<ESC>.", 'tx') 262 call assert_equal('soundfold', getline(1)) 263 call assert_equal('soundfold', getline(2)) 264 bwipe! 265 266 new 267 inoremap <F5> <C-R>=s:complTest2()<CR> 268 call feedkeys("i\<F5>\<CR>\<ESC>", 'tx') 269 call assert_equal('source', getline(1)) 270 bwipe! 271 272 set completeopt-=noinsert 273 iunmap <F5> 274endfunc 275 276func Test_compl_vim_cmds_after_register_expr() 277 function! s:test_func() 278 return 'autocmd ' 279 endfunction 280 augroup AAAAA_Group 281 au! 282 augroup END 283 284 new 285 call feedkeys("i\<c-r>=s:test_func()\<CR>\<C-x>\<C-v>\<Esc>", 'tx') 286 call assert_equal('autocmd AAAAA_Group', getline(1)) 287 autocmd! AAAAA_Group 288 augroup! AAAAA_Group 289 bwipe! 290endfunc 291 292func DummyCompleteOne(findstart, base) 293 if a:findstart 294 return 0 295 else 296 wincmd n 297 return ['onedef', 'oneDEF'] 298 endif 299endfunc 300 301" Test that nothing happens if the 'completefunc' opens 302" a new window (no completion, no crash) 303func Test_completefunc_opens_new_window_one() 304 new 305 let winid = win_getid() 306 setlocal completefunc=DummyCompleteOne 307 call setline(1, 'one') 308 /^one 309 call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E839:') 310 call assert_notequal(winid, win_getid()) 311 q! 312 call assert_equal(winid, win_getid()) 313 call assert_equal('', getline(1)) 314 q! 315endfunc 316 317" Test that nothing happens if the 'completefunc' opens 318" a new window (no completion, no crash) 319func DummyCompleteTwo(findstart, base) 320 if a:findstart 321 wincmd n 322 return 0 323 else 324 return ['twodef', 'twoDEF'] 325 endif 326endfunction 327 328" Test that nothing happens if the 'completefunc' opens 329" a new window (no completion, no crash) 330func Test_completefunc_opens_new_window_two() 331 new 332 let winid = win_getid() 333 setlocal completefunc=DummyCompleteTwo 334 call setline(1, 'two') 335 /^two 336 call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E764:') 337 call assert_notequal(winid, win_getid()) 338 q! 339 call assert_equal(winid, win_getid()) 340 call assert_equal('two', getline(1)) 341 q! 342endfunc 343 344func DummyCompleteThree(findstart, base) 345 if a:findstart 346 return 0 347 else 348 return ['threedef', 'threeDEF'] 349 endif 350endfunc 351 352:"Test that 'completefunc' works when it's OK. 353func Test_completefunc_works() 354 new 355 let winid = win_getid() 356 setlocal completefunc=DummyCompleteThree 357 call setline(1, 'three') 358 /^three 359 call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x") 360 call assert_equal(winid, win_getid()) 361 call assert_equal('threeDEF', getline(1)) 362 q! 363endfunc 364 365func DummyCompleteFour(findstart, base) 366 if a:findstart 367 return 0 368 else 369 call complete_add('four1') 370 call complete_add('four2') 371 call complete_check() 372 call complete_add('four3') 373 call complete_add('four4') 374 call complete_check() 375 call complete_add('four5') 376 call complete_add('four6') 377 return [] 378 endif 379endfunc 380 381" Test that 'omnifunc' works when it's OK. 382func Test_omnifunc_with_check() 383 new 384 setlocal omnifunc=DummyCompleteFour 385 call setline(1, 'four') 386 /^four 387 call feedkeys("A\<C-X>\<C-O>\<C-N>\<Esc>", "x") 388 call assert_equal('four2', getline(1)) 389 390 call setline(1, 'four') 391 /^four 392 call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<Esc>", "x") 393 call assert_equal('four3', getline(1)) 394 395 call setline(1, 'four') 396 /^four 397 call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<C-N>\<C-N>\<Esc>", "x") 398 call assert_equal('four5', getline(1)) 399 400 q! 401endfunc 402 403function UndoComplete() 404 call complete(1, ['January', 'February', 'March', 405 \ 'April', 'May', 'June', 'July', 'August', 'September', 406 \ 'October', 'November', 'December']) 407 return '' 408endfunc 409 410" Test that no undo item is created when no completion is inserted 411func Test_complete_no_undo() 412 set completeopt=menu,preview,noinsert,noselect 413 inoremap <Right> <C-R>=UndoComplete()<CR> 414 new 415 call feedkeys("ixxx\<CR>\<CR>yyy\<Esc>k", 'xt') 416 call feedkeys("iaaa\<Esc>0", 'xt') 417 call assert_equal('aaa', getline(2)) 418 call feedkeys("i\<Right>\<Esc>", 'xt') 419 call assert_equal('aaa', getline(2)) 420 call feedkeys("u", 'xt') 421 call assert_equal('', getline(2)) 422 423 call feedkeys("ibbb\<Esc>0", 'xt') 424 call assert_equal('bbb', getline(2)) 425 call feedkeys("A\<Right>\<Down>\<CR>\<Esc>", 'xt') 426 call assert_equal('January', getline(2)) 427 call feedkeys("u", 'xt') 428 call assert_equal('bbb', getline(2)) 429 430 call feedkeys("A\<Right>\<C-N>\<Esc>", 'xt') 431 call assert_equal('January', getline(2)) 432 call feedkeys("u", 'xt') 433 call assert_equal('bbb', getline(2)) 434 435 iunmap <Right> 436 set completeopt& 437 q! 438endfunc 439 440function! DummyCompleteFive(findstart, base) 441 if a:findstart 442 return 0 443 else 444 return [ 445 \ { 'word': 'January', 'info': "info1-1\n1-2\n1-3" }, 446 \ { 'word': 'February', 'info': "info2-1\n2-2\n2-3" }, 447 \ { 'word': 'March', 'info': "info3-1\n3-2\n3-3" }, 448 \ { 'word': 'April', 'info': "info4-1\n4-2\n4-3" }, 449 \ { 'word': 'May', 'info': "info5-1\n5-2\n5-3" }, 450 \ ] 451 endif 452endfunc 453 454" Test that 'completefunc' on Scratch buffer with preview window works when 455" it's OK. 456func Test_completefunc_with_scratch_buffer() 457 new +setlocal\ buftype=nofile\ bufhidden=wipe\ noswapfile 458 set completeopt+=preview 459 setlocal completefunc=DummyCompleteFive 460 call feedkeys("A\<C-X>\<C-U>\<C-N>\<C-N>\<C-N>\<Esc>", "x") 461 call assert_equal(['April'], getline(1, '$')) 462 pclose 463 q! 464 set completeopt& 465endfunc 466 467" <C-E> - select original typed text before the completion started without 468" auto-wrap text. 469func Test_completion_ctrl_e_without_autowrap() 470 new 471 let tw_save = &tw 472 set tw=78 473 let li = [ 474 \ '" zzz', 475 \ '" zzzyyyyyyyyyyyyyyyyyyy'] 476 call setline(1, li) 477 0 478 call feedkeys("A\<C-X>\<C-N>\<C-E>\<Esc>", "tx") 479 call assert_equal(li, getline(1, '$')) 480 481 let &tw = tw_save 482 q! 483endfunc 484 485function! DummyCompleteSix() 486 call complete(1, ['Hello', 'World']) 487 return '' 488endfunction 489 490" complete() correctly clears the list of autocomplete candidates 491" See #1411 492func Test_completion_clear_candidate_list() 493 new 494 %d 495 " select first entry from the completion popup 496 call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>", "tx") 497 call assert_equal('Hello', getline(1)) 498 %d 499 " select second entry from the completion popup 500 call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>", "tx") 501 call assert_equal('World', getline(1)) 502 %d 503 " select original text 504 call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>\<C-N>", "tx") 505 call assert_equal(' xxx', getline(1)) 506 %d 507 " back at first entry from completion list 508 call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>\<C-N>\<C-N>", "tx") 509 call assert_equal('Hello', getline(1)) 510 511 bw! 512endfunc 513 514func Test_completion_respect_bs_option() 515 new 516 let li = ["aaa", "aaa12345", "aaaabcdef", "aaaABC"] 517 518 set bs=indent,eol 519 call setline(1, li) 520 1 521 call feedkeys("A\<C-X>\<C-N>\<C-P>\<BS>\<BS>\<BS>\<Esc>", "tx") 522 call assert_equal('aaa', getline(1)) 523 524 %d 525 set bs=indent,eol,start 526 call setline(1, li) 527 1 528 call feedkeys("A\<C-X>\<C-N>\<C-P>\<BS>\<BS>\<BS>\<Esc>", "tx") 529 call assert_equal('', getline(1)) 530 531 bw! 532endfunc 533 534func CompleteUndo() abort 535 call complete(1, g:months) 536 return '' 537endfunc 538 539func Test_completion_can_undo() 540 inoremap <Right> <c-r>=CompleteUndo()<cr> 541 set completeopt+=noinsert,noselect 542 543 new 544 call feedkeys("a\<Right>a\<Esc>", 'xt') 545 call assert_equal('a', getline(1)) 546 undo 547 call assert_equal('', getline(1)) 548 549 bwipe! 550 set completeopt& 551 iunmap <Right> 552endfunc 553 554func Test_completion_comment_formatting() 555 new 556 setl formatoptions=tcqro 557 call feedkeys("o/*\<cr>\<cr>/\<esc>", 'tx') 558 call assert_equal(['', '/*', ' *', ' */'], getline(1,4)) 559 %d 560 call feedkeys("o/*\<cr>foobar\<cr>/\<esc>", 'tx') 561 call assert_equal(['', '/*', ' * foobar', ' */'], getline(1,4)) 562 %d 563 try 564 call feedkeys("o/*\<cr>\<cr>\<c-x>\<c-u>/\<esc>", 'tx') 565 call assert_report('completefunc not set, should have failed') 566 catch 567 call assert_exception('E764:') 568 endtry 569 call assert_equal(['', '/*', ' *', ' */'], getline(1,4)) 570 bwipe! 571endfunc 572 573fun MessCompleteMonths() 574 for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep") 575 call complete_add(m) 576 if complete_check() 577 break 578 endif 579 endfor 580 return [] 581endfun 582 583fun MessCompleteMore() 584 call complete(1, split("Oct Nov Dec")) 585 return [] 586endfun 587 588fun MessComplete(findstart, base) 589 if a:findstart 590 let line = getline('.') 591 let start = col('.') - 1 592 while start > 0 && line[start - 1] =~ '\a' 593 let start -= 1 594 endwhile 595 return start 596 else 597 call MessCompleteMonths() 598 call MessCompleteMore() 599 return [] 600 endif 601endf 602 603func Test_complete_func_mess() 604 " Calling complete() after complete_add() in 'completefunc' is wrong, but it 605 " should not crash. 606 set completefunc=MessComplete 607 new 608 call setline(1, 'Ju') 609 call feedkeys("A\<c-x>\<c-u>/\<esc>", 'tx') 610 call assert_equal('Oct/Oct', getline(1)) 611 bwipe! 612 set completefunc= 613endfunc 614 615func Test_complete_CTRLN_startofbuffer() 616 new 617 call setline(1, [ 'organize(cupboard, 3, 2);', 618 \ 'prioritize(bureau, 8, 7);', 619 \ 'realize(bannister, 4, 4);', 620 \ 'moralize(railing, 3,9);']) 621 let expected=['cupboard.organize(3, 2);', 622 \ 'bureau.prioritize(8, 7);', 623 \ 'bannister.realize(4, 4);', 624 \ 'railing.moralize(3,9);'] 625 call feedkeys("qai\<c-n>\<c-n>.\<esc>3wdW\<cr>q3@a", 'tx') 626 call assert_equal(expected, getline(1,'$')) 627 bwipe! 628endfunc 629 630" vim: shiftwidth=2 sts=2 expandtab 631