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