1" Test for completion menu 2 3source shared.vim 4source screendump.vim 5source check.vim 6 7let g:months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] 8let g:setting = '' 9 10func ListMonths() 11 if g:setting != '' 12 exe ":set" g:setting 13 endif 14 let mth = copy(g:months) 15 let entered = strcharpart(getline('.'),0,col('.')) 16 if !empty(entered) 17 let mth = filter(mth, 'v:val=~"^".entered') 18 endif 19 call complete(1, mth) 20 return '' 21endfunc 22 23func Test_popup_complete2() 24 " 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) 30 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') 35 call assert_equal(["Dece", "", "December2015"], getline(1,3)) 36 %d 37 bw! 38endfunc 39 40func Test_popup_complete() 41 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 192 " 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 219endfunc 220 221 222func Test_popup_completion_insertmode() 223 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 229 " Set noinsertmode 230 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 235 " Go through all matches, until none is selected 236 let g:setting = '' 237 call feedkeys("a\<f5>". repeat("\<c-n>",12)."\<enter>\<esc>", 'tx') 238 call assert_equal('', getline(1)) 239 %d 240 " select previous entry 241 call feedkeys("a\<f5>\<c-p>\<enter>\<esc>", 'tx') 242 call assert_equal('', getline(1)) 243 %d 244 " select last entry 245 call feedkeys("a\<f5>\<c-p>\<c-p>\<enter>\<esc>", 'tx') 246 call assert_equal('December', getline(1)) 247 248 iunmap <F5> 249endfunc 250 251func Test_noinsert_complete() 252 func! s:complTest1() abort 253 eval ['source', 'soundfold']->complete(1) 254 return '' 255 endfunc 256 257 func! s:complTest2() abort 258 call complete(1, ['source', 'soundfold']) 259 return '' 260 endfunc 261 262 new 263 set completeopt+=noinsert 264 inoremap <F5> <C-R>=s:complTest1()<CR> 265 call feedkeys("i\<F5>soun\<CR>\<CR>\<ESC>.", 'tx') 266 call assert_equal('soundfold', getline(1)) 267 call assert_equal('soundfold', getline(2)) 268 bwipe! 269 270 new 271 inoremap <F5> <C-R>=s:complTest2()<CR> 272 call feedkeys("i\<F5>\<CR>\<ESC>", 'tx') 273 call assert_equal('source', getline(1)) 274 bwipe! 275 276 set completeopt-=noinsert 277 iunmap <F5> 278endfunc 279 280func 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 312func Test_compl_vim_cmds_after_register_expr() 313 func! s:test_func() 314 return 'autocmd ' 315 endfunc 316 augroup AAAAA_Group 317 au! 318 augroup END 319 320 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 327 328func DummyCompleteOne(findstart, base) 329 if a:findstart 330 return 0 331 else 332 wincmd n 333 return ['onedef', 'oneDEF'] 334 endif 335endfunc 336 337" Test that nothing happens if the 'completefunc' tries to open 338" a new window (fails to open window, continues) 339func Test_completefunc_opens_new_window_one() 340 new 341 let winid = win_getid() 342 setlocal completefunc=DummyCompleteOne 343 call setline(1, 'one') 344 /^one 345 call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E565:') 346 call assert_equal(winid, win_getid()) 347 call assert_equal('onedef', getline(1)) 348 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 360endfunc 361 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 370 call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E565:') 371 call assert_equal(winid, win_getid()) 372 call assert_equal('twodef', getline(1)) 373 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') 402 eval 'four2'->complete_add() 403 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 413" Test that 'omnifunc' works when it's OK. 414func 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 435func UndoComplete() 436 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 455 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 462 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 467 iunmap <Right> 468 set completeopt& 469 q! 470endfunc 471 472func DummyCompleteFive(findstart, base) 473 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() 489 CheckFeature quickfix 490 491 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 500 501" <C-E> - select original typed text before the completion started without 502" auto-wrap text. 503func Test_completion_ctrl_e_without_autowrap() 504 new 505 let tw_save = &tw 506 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 515 let &tw = tw_save 516 q! 517endfunc 518 519func DummyCompleteSix() 520 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 548func 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 568func 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 588func 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') 599 call assert_report('completefunc not set, should have failed') 600 catch 601 call assert_exception('E764:') 602 endtry 603 call assert_equal(['', '/*', ' *', ' */'], getline(1,4)) 604 bwipe! 605endfunc 606 607func MessCompleteMonths() 608 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 [] 615endfunc 616 617func MessCompleteMore() 618 call complete(1, split("Oct Nov Dec")) 619 return [] 620endfunc 621 622func MessComplete(findstart, base) 623 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 635endfunc 636 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') 643 call assert_fails('call feedkeys("A\<c-x>\<c-u>/\<esc>", "tx")', 'E578:') 644 call assert_equal('Jan/', getline(1)) 645 bwipe! 646 set completefunc= 647endfunc 648 649func 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,'$')) 661 bwipe! 662endfunc 663 664func Test_popup_and_window_resize() 665 CheckFeature terminal 666 CheckFeature quickfix 667 CheckNotGui 668 let g:test_is_flaky = 1 669 670 let h = winheight(0) 671 if h < 15 672 return 673 endif 674 let rows = h / 3 675 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': rows}) 676 call term_sendkeys(buf, (h / 3 - 1) . "o\<esc>") 677 " Wait for the nested Vim to exit insert mode, where it will show the ruler. 678 " Need to trigger a redraw. 679 call WaitFor({-> execute("redraw") == "" && term_getline(buf, rows) =~ '\<' . rows . ',.*Bot'}) 680 681 call term_sendkeys(buf, "Gi\<c-x>") 682 call term_sendkeys(buf, "\<c-v>") 683 call TermWait(buf, 50) 684 " popup first entry "!" must be at the top 685 call WaitForAssert({-> assert_match('^!\s*$', term_getline(buf, 1))}) 686 exe 'resize +' . (h - 1) 687 call TermWait(buf, 50) 688 redraw! 689 " popup shifted down, first line is now empty 690 call WaitForAssert({-> assert_equal('', term_getline(buf, 1))}) 691 sleep 100m 692 " popup is below cursor line and shows first match "!" 693 call WaitForAssert({-> assert_match('^!\s*$', term_getline(buf, term_getcursor(buf)[0] + 1))}) 694 " cursor line also shows ! 695 call assert_match('^!\s*$', term_getline(buf, term_getcursor(buf)[0])) 696 bwipe! 697endfunc 698 699func Test_popup_and_preview_autocommand() 700 CheckFeature python 701 CheckFeature quickfix 702 if winheight(0) < 15 703 throw 'Skipped: window height insufficient' 704 endif 705 706 " This used to crash Vim 707 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') 718 call assert_equal("import os", getline(1)) 719 call assert_match(' os.\(EX_IOERR\|O_CREAT\)$', getline(2)) 720 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 726 call assert_equal(10, tabpagenr('$')) 727 tabonly 728 pclose 729 augroup MyBufAdd 730 au! 731 augroup END 732 augroup! MyBufAdd 733 bw! 734endfunc 735 736func Test_popup_and_previewwindow_dump() 737 CheckScreendump 738 CheckFeature quickfix 739 740 let lines =<< trim END 741 set previewheight=9 742 silent! pedit 743 call setline(1, map(repeat(["ab"], 10), "v:val .. v:key")) 744 exec "norm! G\<C-E>\<C-E>" 745 END 746 call writefile(lines, 'Xscript') 747 let buf = RunVimInTerminal('-S Xscript', {}) 748 749 " wait for the script to finish 750 call TermWait(buf) 751 752 " Test that popup and previewwindow do not overlap. 753 call term_sendkeys(buf, "o") 754 call TermWait(buf, 50) 755 call term_sendkeys(buf, "\<C-X>\<C-N>") 756 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 763func Test_balloon_split() 764 CheckFunction balloon_split 765 766 call assert_equal([ 767 \ 'tempname: 0x555555e380a0 "/home/mool/.viminfz.tmp"', 768 \ ], balloon_split( 769 \ 'tempname: 0x555555e380a0 "/home/mool/.viminfz.tmp"')) 770 call assert_equal([ 771 \ '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 776 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 \ ]) 784 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}')) 801 call assert_equal([ 802 \ 'Some comment', 803 \ '', 804 \ 'typedef this that;', 805 \ ], balloon_split( 806 \ "Some comment\n\ntypedef this that;")) 807endfunc 808 809func Test_popup_position() 810 CheckScreendump 811 812 let lines =<< trim END 813 123456789_123456789_123456789_a 814 123456789_123456789_123456789_b 815 123 816 END 817 call writefile(lines, 'Xtest') 818 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 837 " 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 846 call term_sendkeys(buf, "\<Esc>u") 847 call StopVimInTerminal(buf) 848 call delete('Xtest') 849endfunc 850 851func Test_popup_command() 852 CheckScreendump 853 CheckFeature menu 854 855 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 861 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 873 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') 879 let buf = RunVimInTerminal('-S XtimerScript Xtest', {}) 880 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 884 " go to the Paste entry in the menu 885 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>") 893 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 904 call StopVimInTerminal(buf) 905 call delete('Xtest') 906 call delete('XtimerScript') 907endfunc 908 909func 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 918 919func 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 929func Test_complete_o_tab() 930 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 937 endfunc 938 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 956endfunc 957 958func Test_menu_only_exists_in_terminal() 959 CheckCommand tlmenu 960 CheckNotGui 961 962 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 971 972func 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'], 994 \ ["\<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'], 998 \ ["\<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 1037 let g:compl_info = g:compl_what->complete_info() 1038 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 1077func 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 1091func 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& 1121 delfunc! OnPumChange 1122 bw! 1123endfunc 1124 1125function! 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 1153" Test for the popup menu with the 'rightleft' option set 1154func Test_pum_rightleft() 1155 CheckFeature rightleft 1156 CheckScreendump 1157 1158 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>") 1167 call term_wait(buf) 1168 call VerifyScreenDump(buf, 'Test_pum_rightleft_01', {'rows': 8}) 1169 call term_sendkeys(buf, "\<C-P>\<C-Y>") 1170 call term_wait(buf) 1171 redraw! 1172 call assert_match('\s*miv', Screenline(5)) 1173 1174 " Test for expanding tabs to spaces in the popup menu 1175 let lines =<< trim END 1176 one two 1177 one three 1178 four 1179 END 1180 call writefile(lines, 'Xtest2') 1181 call term_sendkeys(buf, "\<Esc>:e! Xtest2\<CR>") 1182 call term_wait(buf) 1183 call term_sendkeys(buf, "Goone\<C-X>\<C-L>") 1184 call term_wait(buf) 1185 redraw! 1186 call VerifyScreenDump(buf, 'Test_pum_rightleft_02', {'rows': 7}) 1187 call term_sendkeys(buf, "\<C-Y>") 1188 call term_wait(buf) 1189 redraw! 1190 call assert_match('\s*eerht eno', Screenline(4)) 1191 1192 call StopVimInTerminal(buf) 1193 call delete('Xtest1') 1194 call delete('Xtest2') 1195endfunc 1196 1197" Test for a popup menu with a scrollbar 1198func Test_pum_scrollbar() 1199 CheckScreendump 1200 let lines =<< trim END 1201 one 1202 two 1203 three 1204 END 1205 call writefile(lines, 'Xtest1') 1206 let buf = RunVimInTerminal('--cmd "set pumheight=2" Xtest1', {}) 1207 call term_wait(buf) 1208 call term_sendkeys(buf, "Go\<C-P>\<C-P>\<C-P>") 1209 call term_wait(buf) 1210 call VerifyScreenDump(buf, 'Test_pum_scrollbar_01', {'rows': 7}) 1211 call term_sendkeys(buf, "\<C-E>\<Esc>dd") 1212 call term_wait(buf) 1213 1214 if has('rightleft') 1215 call term_sendkeys(buf, ":set rightleft\<CR>") 1216 call term_wait(buf) 1217 call term_sendkeys(buf, "Go\<C-P>\<C-P>\<C-P>") 1218 call term_wait(buf) 1219 call VerifyScreenDump(buf, 'Test_pum_scrollbar_02', {'rows': 7}) 1220 endif 1221 1222 call StopVimInTerminal(buf) 1223 call delete('Xtest1') 1224endfunc 1225 1226" vim: shiftwidth=2 sts=2 expandtab 1227