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' opens 338" a new window (no completion, no crash) 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")', 'E839:') 346 call assert_notequal(winid, win_getid()) 347 q! 348 call assert_equal(winid, win_getid()) 349 call assert_equal('', getline(1)) 350 q! 351endfunc 352 353" Test that nothing happens if the 'completefunc' opens 354" a new window (no completion, no crash) 355func DummyCompleteTwo(findstart, base) 356 if a:findstart 357 wincmd n 358 return 0 359 else 360 return ['twodef', 'twoDEF'] 361 endif 362endfunc 363 364" Test that nothing happens if the 'completefunc' opens 365" a new window (no completion, no crash) 366func Test_completefunc_opens_new_window_two() 367 new 368 let winid = win_getid() 369 setlocal completefunc=DummyCompleteTwo 370 call setline(1, 'two') 371 /^two 372 call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E764:') 373 call assert_notequal(winid, win_getid()) 374 q! 375 call assert_equal(winid, win_getid()) 376 call assert_equal('two', getline(1)) 377 q! 378endfunc 379 380func DummyCompleteThree(findstart, base) 381 if a:findstart 382 return 0 383 else 384 return ['threedef', 'threeDEF'] 385 endif 386endfunc 387 388:"Test that 'completefunc' works when it's OK. 389func Test_completefunc_works() 390 new 391 let winid = win_getid() 392 setlocal completefunc=DummyCompleteThree 393 call setline(1, 'three') 394 /^three 395 call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x") 396 call assert_equal(winid, win_getid()) 397 call assert_equal('threeDEF', getline(1)) 398 q! 399endfunc 400 401func DummyCompleteFour(findstart, base) 402 if a:findstart 403 return 0 404 else 405 call complete_add('four1') 406 eval 'four2'->complete_add() 407 call complete_check() 408 call complete_add('four3') 409 call complete_add('four4') 410 call complete_check() 411 call complete_add('four5') 412 call complete_add('four6') 413 return [] 414 endif 415endfunc 416 417" Test that 'omnifunc' works when it's OK. 418func Test_omnifunc_with_check() 419 new 420 setlocal omnifunc=DummyCompleteFour 421 call setline(1, 'four') 422 /^four 423 call feedkeys("A\<C-X>\<C-O>\<C-N>\<Esc>", "x") 424 call assert_equal('four2', getline(1)) 425 426 call setline(1, 'four') 427 /^four 428 call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<Esc>", "x") 429 call assert_equal('four3', getline(1)) 430 431 call setline(1, 'four') 432 /^four 433 call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<C-N>\<C-N>\<Esc>", "x") 434 call assert_equal('four5', getline(1)) 435 436 q! 437endfunc 438 439func UndoComplete() 440 call complete(1, ['January', 'February', 'March', 441 \ 'April', 'May', 'June', 'July', 'August', 'September', 442 \ 'October', 'November', 'December']) 443 return '' 444endfunc 445 446" Test that no undo item is created when no completion is inserted 447func Test_complete_no_undo() 448 set completeopt=menu,preview,noinsert,noselect 449 inoremap <Right> <C-R>=UndoComplete()<CR> 450 new 451 call feedkeys("ixxx\<CR>\<CR>yyy\<Esc>k", 'xt') 452 call feedkeys("iaaa\<Esc>0", 'xt') 453 call assert_equal('aaa', getline(2)) 454 call feedkeys("i\<Right>\<Esc>", 'xt') 455 call assert_equal('aaa', getline(2)) 456 call feedkeys("u", 'xt') 457 call assert_equal('', getline(2)) 458 459 call feedkeys("ibbb\<Esc>0", 'xt') 460 call assert_equal('bbb', getline(2)) 461 call feedkeys("A\<Right>\<Down>\<CR>\<Esc>", 'xt') 462 call assert_equal('January', getline(2)) 463 call feedkeys("u", 'xt') 464 call assert_equal('bbb', getline(2)) 465 466 call feedkeys("A\<Right>\<C-N>\<Esc>", 'xt') 467 call assert_equal('January', getline(2)) 468 call feedkeys("u", 'xt') 469 call assert_equal('bbb', getline(2)) 470 471 iunmap <Right> 472 set completeopt& 473 q! 474endfunc 475 476func DummyCompleteFive(findstart, base) 477 if a:findstart 478 return 0 479 else 480 return [ 481 \ { 'word': 'January', 'info': "info1-1\n1-2\n1-3" }, 482 \ { 'word': 'February', 'info': "info2-1\n2-2\n2-3" }, 483 \ { 'word': 'March', 'info': "info3-1\n3-2\n3-3" }, 484 \ { 'word': 'April', 'info': "info4-1\n4-2\n4-3" }, 485 \ { 'word': 'May', 'info': "info5-1\n5-2\n5-3" }, 486 \ ] 487 endif 488endfunc 489 490" Test that 'completefunc' on Scratch buffer with preview window works when 491" it's OK. 492func Test_completefunc_with_scratch_buffer() 493 CheckFeature quickfix 494 495 new +setlocal\ buftype=nofile\ bufhidden=wipe\ noswapfile 496 set completeopt+=preview 497 setlocal completefunc=DummyCompleteFive 498 call feedkeys("A\<C-X>\<C-U>\<C-N>\<C-N>\<C-N>\<Esc>", "x") 499 call assert_equal(['April'], getline(1, '$')) 500 pclose 501 q! 502 set completeopt& 503endfunc 504 505" <C-E> - select original typed text before the completion started without 506" auto-wrap text. 507func Test_completion_ctrl_e_without_autowrap() 508 new 509 let tw_save = &tw 510 set tw=78 511 let li = [ 512 \ '" zzz', 513 \ '" zzzyyyyyyyyyyyyyyyyyyy'] 514 call setline(1, li) 515 0 516 call feedkeys("A\<C-X>\<C-N>\<C-E>\<Esc>", "tx") 517 call assert_equal(li, getline(1, '$')) 518 519 let &tw = tw_save 520 q! 521endfunc 522 523func DummyCompleteSix() 524 call complete(1, ['Hello', 'World']) 525 return '' 526endfunction 527 528" complete() correctly clears the list of autocomplete candidates 529" See #1411 530func Test_completion_clear_candidate_list() 531 new 532 %d 533 " select first entry from the completion popup 534 call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>", "tx") 535 call assert_equal('Hello', getline(1)) 536 %d 537 " select second entry from the completion popup 538 call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>", "tx") 539 call assert_equal('World', getline(1)) 540 %d 541 " select original text 542 call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>\<C-N>", "tx") 543 call assert_equal(' xxx', getline(1)) 544 %d 545 " back at first entry from completion list 546 call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>\<C-N>\<C-N>", "tx") 547 call assert_equal('Hello', getline(1)) 548 549 bw! 550endfunc 551 552func Test_completion_respect_bs_option() 553 new 554 let li = ["aaa", "aaa12345", "aaaabcdef", "aaaABC"] 555 556 set bs=indent,eol 557 call setline(1, li) 558 1 559 call feedkeys("A\<C-X>\<C-N>\<C-P>\<BS>\<BS>\<BS>\<Esc>", "tx") 560 call assert_equal('aaa', getline(1)) 561 562 %d 563 set bs=indent,eol,start 564 call setline(1, li) 565 1 566 call feedkeys("A\<C-X>\<C-N>\<C-P>\<BS>\<BS>\<BS>\<Esc>", "tx") 567 call assert_equal('', getline(1)) 568 569 bw! 570endfunc 571 572func CompleteUndo() abort 573 call complete(1, g:months) 574 return '' 575endfunc 576 577func Test_completion_can_undo() 578 inoremap <Right> <c-r>=CompleteUndo()<cr> 579 set completeopt+=noinsert,noselect 580 581 new 582 call feedkeys("a\<Right>a\<Esc>", 'xt') 583 call assert_equal('a', getline(1)) 584 undo 585 call assert_equal('', getline(1)) 586 587 bwipe! 588 set completeopt& 589 iunmap <Right> 590endfunc 591 592func Test_completion_comment_formatting() 593 new 594 setl formatoptions=tcqro 595 call feedkeys("o/*\<cr>\<cr>/\<esc>", 'tx') 596 call assert_equal(['', '/*', ' *', ' */'], getline(1,4)) 597 %d 598 call feedkeys("o/*\<cr>foobar\<cr>/\<esc>", 'tx') 599 call assert_equal(['', '/*', ' * foobar', ' */'], getline(1,4)) 600 %d 601 try 602 call feedkeys("o/*\<cr>\<cr>\<c-x>\<c-u>/\<esc>", 'tx') 603 call assert_report('completefunc not set, should have failed') 604 catch 605 call assert_exception('E764:') 606 endtry 607 call assert_equal(['', '/*', ' *', ' */'], getline(1,4)) 608 bwipe! 609endfunc 610 611func MessCompleteMonths() 612 for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep") 613 call complete_add(m) 614 if complete_check() 615 break 616 endif 617 endfor 618 return [] 619endfunc 620 621func MessCompleteMore() 622 call complete(1, split("Oct Nov Dec")) 623 return [] 624endfunc 625 626func MessComplete(findstart, base) 627 if a:findstart 628 let line = getline('.') 629 let start = col('.') - 1 630 while start > 0 && line[start - 1] =~ '\a' 631 let start -= 1 632 endwhile 633 return start 634 else 635 call MessCompleteMonths() 636 call MessCompleteMore() 637 return [] 638 endif 639endfunc 640 641func Test_complete_func_mess() 642 " Calling complete() after complete_add() in 'completefunc' is wrong, but it 643 " should not crash. 644 set completefunc=MessComplete 645 new 646 call setline(1, 'Ju') 647 call feedkeys("A\<c-x>\<c-u>/\<esc>", 'tx') 648 call assert_equal('Oct/Oct', getline(1)) 649 bwipe! 650 set completefunc= 651endfunc 652 653func Test_complete_CTRLN_startofbuffer() 654 new 655 call setline(1, [ 'organize(cupboard, 3, 2);', 656 \ 'prioritize(bureau, 8, 7);', 657 \ 'realize(bannister, 4, 4);', 658 \ 'moralize(railing, 3,9);']) 659 let expected=['cupboard.organize(3, 2);', 660 \ 'bureau.prioritize(8, 7);', 661 \ 'bannister.realize(4, 4);', 662 \ 'railing.moralize(3,9);'] 663 call feedkeys("qai\<c-n>\<c-n>.\<esc>3wdW\<cr>q3@a", 'tx') 664 call assert_equal(expected, getline(1,'$')) 665 bwipe! 666endfunc 667 668func Test_popup_and_window_resize() 669 CheckFeature terminal 670 CheckFeature quickfix 671 CheckNotGui 672 673 let h = winheight(0) 674 if h < 15 675 return 676 endif 677 let rows = h / 3 678 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': rows}) 679 call term_sendkeys(buf, (h / 3 - 1) . "o\<esc>") 680 " Wait for the nested Vim to exit insert mode, where it will show the ruler. 681 " Need to trigger a redraw. 682 call WaitFor({-> execute("redraw") == "" && term_getline(buf, rows) =~ '\<' . rows . ',.*Bot'}) 683 684 call term_sendkeys(buf, "Gi\<c-x>") 685 call term_sendkeys(buf, "\<c-v>") 686 call term_wait(buf, 100) 687 " popup first entry "!" must be at the top 688 call WaitForAssert({-> assert_match('^!\s*$', term_getline(buf, 1))}) 689 exe 'resize +' . (h - 1) 690 call term_wait(buf, 100) 691 redraw! 692 " popup shifted down, first line is now empty 693 call WaitForAssert({-> assert_equal('', term_getline(buf, 1))}) 694 sleep 100m 695 " popup is below cursor line and shows first match "!" 696 call WaitForAssert({-> assert_match('^!\s*$', term_getline(buf, term_getcursor(buf)[0] + 1))}) 697 " cursor line also shows ! 698 call assert_match('^!\s*$', term_getline(buf, term_getcursor(buf)[0])) 699 bwipe! 700endfunc 701 702func Test_popup_and_preview_autocommand() 703 CheckFeature python 704 CheckFeature quickfix 705 if winheight(0) < 15 706 throw 'Skipped: window height insufficient' 707 endif 708 709 " This used to crash Vim 710 new 711 augroup MyBufAdd 712 au! 713 au BufAdd * nested tab sball 714 augroup END 715 set omnifunc=pythoncomplete#Complete 716 call setline(1, 'import os') 717 " make the line long 718 call setline(2, ' os.') 719 $ 720 call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<C-N>\<enter>\<esc>", 'tx') 721 call assert_equal("import os", getline(1)) 722 call assert_match(' os.\(EX_IOERR\|O_CREAT\)$', getline(2)) 723 call assert_equal(1, winnr('$')) 724 " previewwindow option is not set 725 call assert_equal(0, &previewwindow) 726 norm! gt 727 call assert_equal(0, &previewwindow) 728 norm! gT 729 call assert_equal(10, tabpagenr('$')) 730 tabonly 731 pclose 732 augroup MyBufAdd 733 au! 734 augroup END 735 augroup! MyBufAdd 736 bw! 737endfunc 738 739func Test_popup_and_previewwindow_dump() 740 CheckScreendump 741 CheckFeature quickfix 742 743 let lines =<< trim END 744 set previewheight=9 745 silent! pedit 746 call setline(1, map(repeat(["ab"], 10), "v:val. v:key")) 747 exec "norm! G\<C-E>\<C-E>" 748 END 749 call writefile(lines, 'Xscript') 750 let buf = RunVimInTerminal('-S Xscript', {}) 751 752 " Test that popup and previewwindow do not overlap. 753 call term_sendkeys(buf, "o\<C-X>\<C-N>") 754 sleep 100m 755 call VerifyScreenDump(buf, 'Test_popup_and_previewwindow_01', {}) 756 757 call term_sendkeys(buf, "\<Esc>u") 758 call StopVimInTerminal(buf) 759 call delete('Xscript') 760endfunc 761 762func Test_balloon_split() 763 CheckFunction balloon_split 764 765 call assert_equal([ 766 \ 'tempname: 0x555555e380a0 "/home/mool/.viminfz.tmp"', 767 \ ], balloon_split( 768 \ 'tempname: 0x555555e380a0 "/home/mool/.viminfz.tmp"')) 769 call assert_equal([ 770 \ 'one two three four one two three four one two thre', 771 \ 'e four', 772 \ ], balloon_split( 773 \ 'one two three four one two three four one two three four')) 774 775 eval 'struct = {one = 1, two = 2, three = 3}' 776 \ ->balloon_split() 777 \ ->assert_equal([ 778 \ 'struct = {', 779 \ ' one = 1,', 780 \ ' two = 2,', 781 \ ' three = 3}', 782 \ ]) 783 784 call assert_equal([ 785 \ 'struct = {', 786 \ ' one = 1,', 787 \ ' nested = {', 788 \ ' n1 = "yes",', 789 \ ' n2 = "no"}', 790 \ ' two = 2}', 791 \ ], balloon_split( 792 \ 'struct = {one = 1, nested = {n1 = "yes", n2 = "no"} two = 2}')) 793 call assert_equal([ 794 \ 'struct = 0x234 {', 795 \ ' long = 2343 "\\"some long string that will be wr', 796 \ 'apped in two\\"",', 797 \ ' next = 123}', 798 \ ], balloon_split( 799 \ 'struct = 0x234 {long = 2343 "\\"some long string that will be wrapped in two\\"", next = 123}')) 800 call assert_equal([ 801 \ 'Some comment', 802 \ '', 803 \ 'typedef this that;', 804 \ ], balloon_split( 805 \ "Some comment\n\ntypedef this that;")) 806endfunc 807 808func Test_popup_position() 809 CheckScreendump 810 811 let lines =<< trim END 812 123456789_123456789_123456789_a 813 123456789_123456789_123456789_b 814 123 815 END 816 call writefile(lines, 'Xtest') 817 let buf = RunVimInTerminal('Xtest', {}) 818 call term_sendkeys(buf, ":vsplit\<CR>") 819 820 " default pumwidth in left window: overlap in right window 821 call term_sendkeys(buf, "GA\<C-N>") 822 call VerifyScreenDump(buf, 'Test_popup_position_01', {'rows': 8}) 823 call term_sendkeys(buf, "\<Esc>u") 824 825 " default pumwidth: fill until right of window 826 call term_sendkeys(buf, "\<C-W>l") 827 call term_sendkeys(buf, "GA\<C-N>") 828 call VerifyScreenDump(buf, 'Test_popup_position_02', {'rows': 8}) 829 830 " larger pumwidth: used as minimum width 831 call term_sendkeys(buf, "\<Esc>u") 832 call term_sendkeys(buf, ":set pumwidth=30\<CR>") 833 call term_sendkeys(buf, "GA\<C-N>") 834 call VerifyScreenDump(buf, 'Test_popup_position_03', {'rows': 8}) 835 836 " completed text wider than the window and 'pumwidth' smaller than available 837 " space 838 call term_sendkeys(buf, "\<Esc>u") 839 call term_sendkeys(buf, ":set pumwidth=20\<CR>") 840 call term_sendkeys(buf, "ggI123456789_\<Esc>") 841 call term_sendkeys(buf, "jI123456789_\<Esc>") 842 call term_sendkeys(buf, "GA\<C-N>") 843 call VerifyScreenDump(buf, 'Test_popup_position_04', {'rows': 10}) 844 845 call term_sendkeys(buf, "\<Esc>u") 846 call StopVimInTerminal(buf) 847 call delete('Xtest') 848endfunc 849 850func Test_popup_command() 851 CheckScreendump 852 CheckFeature menu 853 854 let lines =<< trim END 855 one two three four five 856 and one two Xthree four five 857 one more two three four five 858 END 859 call writefile(lines, 'Xtest') 860 let buf = RunVimInTerminal('Xtest', {}) 861 call term_sendkeys(buf, ":source $VIMRUNTIME/menu.vim\<CR>") 862 call term_sendkeys(buf, "/X\<CR>:popup PopUp\<CR>") 863 call VerifyScreenDump(buf, 'Test_popup_command_01', {}) 864 865 " Select a word 866 call term_sendkeys(buf, "jj") 867 call VerifyScreenDump(buf, 'Test_popup_command_02', {}) 868 869 " Select a word 870 call term_sendkeys(buf, "j\<CR>") 871 call VerifyScreenDump(buf, 'Test_popup_command_03', {}) 872 873 call term_sendkeys(buf, "\<Esc>") 874 call StopVimInTerminal(buf) 875 call delete('Xtest') 876endfunc 877 878func Test_popup_complete_backwards() 879 new 880 call setline(1, ['Post', 'Port', 'Po']) 881 let expected=['Post', 'Port', 'Port'] 882 call cursor(3,2) 883 call feedkeys("A\<C-X>". repeat("\<C-P>", 3). "rt\<cr>", 'tx') 884 call assert_equal(expected, getline(1,'$')) 885 bwipe! 886endfunc 887 888func Test_popup_complete_backwards_ctrl_p() 889 new 890 call setline(1, ['Post', 'Port', 'Po']) 891 let expected=['Post', 'Port', 'Port'] 892 call cursor(3,2) 893 call feedkeys("A\<C-P>\<C-N>rt\<cr>", 'tx') 894 call assert_equal(expected, getline(1,'$')) 895 bwipe! 896endfunc 897 898func Test_complete_o_tab() 899 let s:o_char_pressed = 0 900 901 fun! s:act_on_text_changed() 902 if s:o_char_pressed 903 let s:o_char_pressed = 0 904 call feedkeys("\<c-x>\<c-n>", 'i') 905 endif 906 endfunc 907 908 set completeopt=menu,noselect 909 new 910 imap <expr> <buffer> <tab> pumvisible() ? "\<c-p>" : "X" 911 autocmd! InsertCharPre <buffer> let s:o_char_pressed = (v:char ==# 'o') 912 autocmd! TextChangedI <buffer> call <sid>act_on_text_changed() 913 call setline(1, ['hoard', 'hoax', 'hoarse', '']) 914 let l:expected = ['hoard', 'hoax', 'hoarse', 'hoax', 'hoax'] 915 call cursor(4,1) 916 call test_override("char_avail", 1) 917 call feedkeys("Ahoa\<tab>\<tab>\<c-y>\<esc>", 'tx') 918 call feedkeys("oho\<tab>\<tab>\<c-y>\<esc>", 'tx') 919 call assert_equal(l:expected, getline(1,'$')) 920 921 call test_override("char_avail", 0) 922 bwipe! 923 set completeopt& 924 delfunc s:act_on_text_changed 925endfunc 926 927func Test_menu_only_exists_in_terminal() 928 CheckCommand tlmenu 929 CheckNotGui 930 931 tlnoremenu &Edit.&Paste<Tab>"+gP <C-W>"+ 932 aunmenu * 933 try 934 popup Edit 935 call assert_false(1, 'command should have failed') 936 catch 937 call assert_exception('E328:') 938 endtry 939endfunc 940 941func Test_popup_complete_info_01() 942 new 943 inoremap <buffer><F5> <C-R>=complete_info().mode<CR> 944 func s:complTestEval() abort 945 call complete(1, ['aa', 'ab']) 946 return '' 947 endfunc 948 inoremap <buffer><F6> <C-R>=s:complTestEval()<CR> 949 call writefile([ 950 \ 'dummy dummy.txt 1', 951 \], 'Xdummy.txt') 952 setlocal tags=Xdummy.txt 953 setlocal dictionary=Xdummy.txt 954 setlocal thesaurus=Xdummy.txt 955 setlocal omnifunc=syntaxcomplete#Complete 956 setlocal completefunc=syntaxcomplete#Complete 957 setlocal spell 958 for [keys, mode_name] in [ 959 \ ["", ''], 960 \ ["\<C-X>", 'ctrl_x'], 961 \ ["\<C-X>\<C-N>", 'keyword'], 962 \ ["\<C-X>\<C-P>", 'keyword'], 963 \ ["\<C-X>\<C-L>", 'whole_line'], 964 \ ["\<C-X>\<C-F>", 'files'], 965 \ ["\<C-X>\<C-]>", 'tags'], 966 \ ["\<C-X>\<C-D>", 'path_defines'], 967 \ ["\<C-X>\<C-I>", 'path_patterns'], 968 \ ["\<C-X>\<C-K>", 'dictionary'], 969 \ ["\<C-X>\<C-T>", 'thesaurus'], 970 \ ["\<C-X>\<C-V>", 'cmdline'], 971 \ ["\<C-X>\<C-U>", 'function'], 972 \ ["\<C-X>\<C-O>", 'omni'], 973 \ ["\<C-X>s", 'spell'], 974 \ ["\<F6>", 'eval'], 975 \] 976 call feedkeys("i" . keys . "\<F5>\<Esc>", 'tx') 977 call assert_equal(mode_name, getline('.')) 978 %d 979 endfor 980 call delete('Xdummy.txt') 981 bwipe! 982endfunc 983 984func UserDefinedComplete(findstart, base) 985 if a:findstart 986 return 0 987 else 988 return [ 989 \ { 'word': 'Jan', 'menu': 'January' }, 990 \ { 'word': 'Feb', 'menu': 'February' }, 991 \ { 'word': 'Mar', 'menu': 'March' }, 992 \ { 'word': 'Apr', 'menu': 'April' }, 993 \ { 'word': 'May', 'menu': 'May' }, 994 \ ] 995 endif 996endfunc 997 998func GetCompleteInfo() 999 if empty(g:compl_what) 1000 let g:compl_info = complete_info() 1001 else 1002 let g:compl_info = g:compl_what->complete_info() 1003 endif 1004 return '' 1005endfunc 1006 1007func Test_popup_complete_info_02() 1008 new 1009 inoremap <buffer><F5> <C-R>=GetCompleteInfo()<CR> 1010 setlocal completefunc=UserDefinedComplete 1011 1012 let d = { 1013 \ 'mode': 'function', 1014 \ 'pum_visible': 1, 1015 \ 'items': [ 1016 \ {'word': 'Jan', 'menu': 'January', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, 1017 \ {'word': 'Feb', 'menu': 'February', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, 1018 \ {'word': 'Mar', 'menu': 'March', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, 1019 \ {'word': 'Apr', 'menu': 'April', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, 1020 \ {'word': 'May', 'menu': 'May', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''} 1021 \ ], 1022 \ 'selected': 0, 1023 \ } 1024 1025 let g:compl_what = [] 1026 call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx') 1027 call assert_equal(d, g:compl_info) 1028 1029 let g:compl_what = ['mode', 'pum_visible', 'selected'] 1030 call remove(d, 'items') 1031 call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx') 1032 call assert_equal(d, g:compl_info) 1033 1034 let g:compl_what = ['mode'] 1035 call remove(d, 'selected') 1036 call remove(d, 'pum_visible') 1037 call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx') 1038 call assert_equal(d, g:compl_info) 1039 bwipe! 1040endfunc 1041 1042func Test_popup_complete_info_no_pum() 1043 new 1044 call assert_false( pumvisible() ) 1045 let no_pum_info = complete_info() 1046 let d = { 1047 \ 'mode': '', 1048 \ 'pum_visible': 0, 1049 \ 'items': [], 1050 \ 'selected': -1, 1051 \ } 1052 call assert_equal( d, complete_info() ) 1053 bwipe! 1054endfunc 1055 1056func Test_CompleteChanged() 1057 new 1058 call setline(1, ['foo', 'bar', 'foobar', '']) 1059 set complete=. completeopt=noinsert,noselect,menuone 1060 function! OnPumChange() 1061 let g:event = copy(v:event) 1062 let g:item = get(v:event, 'completed_item', {}) 1063 let g:word = get(g:item, 'word', v:null) 1064 endfunction 1065 augroup AAAAA_Group 1066 au! 1067 autocmd CompleteChanged * :call OnPumChange() 1068 augroup END 1069 call cursor(4, 1) 1070 1071 call feedkeys("Sf\<C-N>", 'tx') 1072 call assert_equal({'completed_item': {}, 'width': 15, 1073 \ 'height': 2, 'size': 2, 1074 \ 'col': 0, 'row': 4, 'scrollbar': v:false}, g:event) 1075 call feedkeys("a\<C-N>\<C-N>\<C-E>", 'tx') 1076 call assert_equal('foo', g:word) 1077 call feedkeys("a\<C-N>\<C-N>\<C-N>\<C-E>", 'tx') 1078 call assert_equal('foobar', g:word) 1079 call feedkeys("a\<C-N>\<C-N>\<C-N>\<C-N>\<C-E>", 'tx') 1080 call assert_equal(v:null, g:word) 1081 call feedkeys("a\<C-N>\<C-N>\<C-N>\<C-N>\<C-P>", 'tx') 1082 call assert_equal('foobar', g:word) 1083 1084 autocmd! AAAAA_Group 1085 set complete& completeopt& 1086 delfunc! OnPumChange 1087 bw! 1088endfunc 1089 1090function! GetPumPosition() 1091 call assert_true( pumvisible() ) 1092 let g:pum_pos = pum_getpos() 1093 return '' 1094endfunction 1095 1096func Test_pum_getpos() 1097 new 1098 inoremap <buffer><F5> <C-R>=GetPumPosition()<CR> 1099 setlocal completefunc=UserDefinedComplete 1100 1101 let d = { 1102 \ 'height': 5, 1103 \ 'width': 15, 1104 \ 'row': 1, 1105 \ 'col': 0, 1106 \ 'size': 5, 1107 \ 'scrollbar': v:false, 1108 \ } 1109 call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx') 1110 call assert_equal(d, g:pum_pos) 1111 1112 call assert_false( pumvisible() ) 1113 call assert_equal( {}, pum_getpos() ) 1114 bw! 1115 unlet g:pum_pos 1116endfunc 1117 1118" vim: shiftwidth=2 sts=2 expandtab 1119