1" Test for completion menu 2 3source shared.vim 4source screendump.vim 5 6let g:months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] 7let g:setting = '' 8 9func ListMonths() 10 if g:setting != '' 11 exe ":set" g:setting 12 endif 13 let mth = copy(g:months) 14 let entered = strcharpart(getline('.'),0,col('.')) 15 if !empty(entered) 16 let mth = filter(mth, 'v:val=~"^".entered') 17 endif 18 call complete(1, mth) 19 return '' 20endfunc 21 22func Test_popup_complete2() 23 " Although the popupmenu is not visible, this does not mean completion mode 24 " has ended. After pressing <f5> to complete the currently typed char, Vim 25 " still stays in the first state of the completion (:h ins-completion-menu), 26 " although the popupmenu wasn't shown <c-e> will remove the inserted 27 " completed text (:h complete_CTRL-E), while the following <c-e> will behave 28 " like expected (:h i_CTRL-E) 29 new 30 inoremap <f5> <c-r>=ListMonths()<cr> 31 call append(1, ["December2015"]) 32 :1 33 call feedkeys("aD\<f5>\<C-E>\<C-E>\<C-E>\<C-E>\<enter>\<esc>", 'tx') 34 call assert_equal(["Dece", "", "December2015"], getline(1,3)) 35 %d 36 bw! 37endfunc 38 39func Test_popup_complete() 40 new 41 inoremap <f5> <c-r>=ListMonths()<cr> 42 43 " <C-E> - select original typed text before the completion started 44 call feedkeys("aJu\<f5>\<down>\<c-e>\<esc>", 'tx') 45 call assert_equal(["Ju"], getline(1,2)) 46 %d 47 48 " <C-Y> - accept current match 49 call feedkeys("a\<f5>". repeat("\<down>",7). "\<c-y>\<esc>", 'tx') 50 call assert_equal(["August"], getline(1,2)) 51 %d 52 53 " <BS> - Delete one character from the inserted text (state: 1) 54 " TODO: This should not end the completion, but it does. 55 " This should according to the documentation: 56 " January 57 " but instead, this does 58 " Januar 59 " (idea is, C-L inserts the match from the popup menu 60 " but if the menu is closed, it will insert the character <c-l> 61 call feedkeys("aJ\<f5>\<bs>\<c-l>\<esc>", 'tx') 62 call assert_equal(["Januar"], getline(1,2)) 63 %d 64 65 " any-non special character: Stop completion without changing the match 66 " and insert the typed character 67 call feedkeys("a\<f5>20", 'tx') 68 call assert_equal(["January20"], getline(1,2)) 69 %d 70 71 " any-non printable, non-white character: Add this character and 72 " reduce number of matches 73 call feedkeys("aJu\<f5>\<c-p>l\<c-y>", 'tx') 74 call assert_equal(["Jul"], getline(1,2)) 75 %d 76 77 " any-non printable, non-white character: Add this character and 78 " reduce number of matches 79 call feedkeys("aJu\<f5>\<c-p>l\<c-n>\<c-y>", 'tx') 80 call assert_equal(["July"], getline(1,2)) 81 %d 82 83 " any-non printable, non-white character: Add this character and 84 " reduce number of matches 85 call feedkeys("aJu\<f5>\<c-p>l\<c-e>", 'tx') 86 call assert_equal(["Jul"], getline(1,2)) 87 %d 88 89 " <BS> - Delete one character from the inserted text (state: 2) 90 call feedkeys("a\<f5>\<c-n>\<bs>", 'tx') 91 call assert_equal(["Februar"], getline(1,2)) 92 %d 93 94 " <c-l> - Insert one character from the current match 95 call feedkeys("aJ\<f5>".repeat("\<c-n>",3)."\<c-l>\<esc>", 'tx') 96 call assert_equal(["J"], getline(1,2)) 97 %d 98 99 " <c-l> - Insert one character from the current match 100 call feedkeys("aJ\<f5>".repeat("\<c-n>",4)."\<c-l>\<esc>", 'tx') 101 call assert_equal(["January"], getline(1,2)) 102 %d 103 104 " <c-y> - Accept current selected match 105 call feedkeys("aJ\<f5>\<c-y>\<esc>", 'tx') 106 call assert_equal(["January"], getline(1,2)) 107 %d 108 109 " <c-e> - End completion, go back to what was there before selecting a match 110 call feedkeys("aJu\<f5>\<c-e>\<esc>", 'tx') 111 call assert_equal(["Ju"], getline(1,2)) 112 %d 113 114 " <PageUp> - Select a match several entries back 115 call feedkeys("a\<f5>\<PageUp>\<c-y>\<esc>", 'tx') 116 call assert_equal([""], getline(1,2)) 117 %d 118 119 " <PageUp><PageUp> - Select a match several entries back 120 call feedkeys("a\<f5>\<PageUp>\<PageUp>\<c-y>\<esc>", 'tx') 121 call assert_equal(["December"], getline(1,2)) 122 %d 123 124 " <PageUp><PageUp><PageUp> - Select a match several entries back 125 call feedkeys("a\<f5>\<PageUp>\<PageUp>\<PageUp>\<c-y>\<esc>", 'tx') 126 call assert_equal(["February"], getline(1,2)) 127 %d 128 129 " <PageDown> - Select a match several entries further 130 call feedkeys("a\<f5>\<PageDown>\<c-y>\<esc>", 'tx') 131 call assert_equal(["November"], getline(1,2)) 132 %d 133 134 " <PageDown><PageDown> - Select a match several entries further 135 call feedkeys("a\<f5>\<PageDown>\<PageDown>\<c-y>\<esc>", 'tx') 136 call assert_equal(["December"], getline(1,2)) 137 %d 138 139 " <PageDown><PageDown><PageDown> - Select a match several entries further 140 call feedkeys("a\<f5>\<PageDown>\<PageDown>\<PageDown>\<c-y>\<esc>", 'tx') 141 call assert_equal([""], getline(1,2)) 142 %d 143 144 " <PageDown><PageDown><PageDown><PageDown> - Select a match several entries further 145 call feedkeys("a\<f5>".repeat("\<PageDown>",4)."\<c-y>\<esc>", 'tx') 146 call assert_equal(["October"], getline(1,2)) 147 %d 148 149 " <Up> - Select a match don't insert yet 150 call feedkeys("a\<f5>\<Up>\<c-y>\<esc>", 'tx') 151 call assert_equal([""], getline(1,2)) 152 %d 153 154 " <Up><Up> - Select a match don't insert yet 155 call feedkeys("a\<f5>\<Up>\<Up>\<c-y>\<esc>", 'tx') 156 call assert_equal(["December"], getline(1,2)) 157 %d 158 159 " <Up><Up><Up> - Select a match don't insert yet 160 call feedkeys("a\<f5>\<Up>\<Up>\<Up>\<c-y>\<esc>", 'tx') 161 call assert_equal(["November"], getline(1,2)) 162 %d 163 164 " <Tab> - Stop completion and insert the match 165 call feedkeys("a\<f5>\<Tab>\<c-y>\<esc>", 'tx') 166 call assert_equal(["January "], getline(1,2)) 167 %d 168 169 " <Space> - Stop completion and insert the match 170 call feedkeys("a\<f5>".repeat("\<c-p>",5)." \<esc>", 'tx') 171 call assert_equal(["September "], getline(1,2)) 172 %d 173 174 " <Enter> - Use the text and insert line break (state: 1) 175 call feedkeys("a\<f5>\<enter>\<esc>", 'tx') 176 call assert_equal(["January", ''], getline(1,2)) 177 %d 178 179 " <Enter> - Insert the current selected text (state: 2) 180 call feedkeys("a\<f5>".repeat("\<Up>",5)."\<enter>\<esc>", 'tx') 181 call assert_equal(["September"], getline(1,2)) 182 %d 183 184 " Insert match immediately, if there is only one match 185 " <c-y> selects a character from the line above 186 call append(0, ["December2015"]) 187 call feedkeys("aD\<f5>\<C-Y>\<C-Y>\<C-Y>\<C-Y>\<enter>\<esc>", 'tx') 188 call assert_equal(["December2015", "December2015", ""], getline(1,3)) 189 %d 190 191 " use menuone for 'completeopt' 192 " Since for the first <c-y> the menu is still shown, will only select 193 " three letters from the line above 194 set completeopt&vim 195 set completeopt+=menuone 196 call append(0, ["December2015"]) 197 call feedkeys("aD\<f5>\<C-Y>\<C-Y>\<C-Y>\<C-Y>\<enter>\<esc>", 'tx') 198 call assert_equal(["December2015", "December201", ""], getline(1,3)) 199 %d 200 201 " use longest for 'completeopt' 202 set completeopt&vim 203 call feedkeys("aM\<f5>\<C-N>\<C-P>\<c-e>\<enter>\<esc>", 'tx') 204 set completeopt+=longest 205 call feedkeys("aM\<f5>\<C-N>\<C-P>\<c-e>\<enter>\<esc>", 'tx') 206 call assert_equal(["M", "Ma", ""], getline(1,3)) 207 %d 208 209 " use noselect/noinsert for 'completeopt' 210 set completeopt&vim 211 call feedkeys("aM\<f5>\<enter>\<esc>", 'tx') 212 set completeopt+=noselect 213 call feedkeys("aM\<f5>\<enter>\<esc>", 'tx') 214 set completeopt-=noselect completeopt+=noinsert 215 call feedkeys("aM\<f5>\<enter>\<esc>", 'tx') 216 call assert_equal(["March", "M", "March"], getline(1,4)) 217 %d 218endfunc 219 220 221func Test_popup_completion_insertmode() 222 new 223 inoremap <F5> <C-R>=ListMonths()<CR> 224 225 call feedkeys("a\<f5>\<down>\<enter>\<esc>", 'tx') 226 call assert_equal('February', getline(1)) 227 %d 228 " Set noinsertmode 229 let g:setting = 'noinsertmode' 230 call feedkeys("a\<f5>\<down>\<enter>\<esc>", 'tx') 231 call assert_equal('February', getline(1)) 232 call assert_false(pumvisible()) 233 %d 234 " Go through all matches, until none is selected 235 let g:setting = '' 236 call feedkeys("a\<f5>". repeat("\<c-n>",12)."\<enter>\<esc>", 'tx') 237 call assert_equal('', getline(1)) 238 %d 239 " select previous entry 240 call feedkeys("a\<f5>\<c-p>\<enter>\<esc>", 'tx') 241 call assert_equal('', getline(1)) 242 %d 243 " select last entry 244 call feedkeys("a\<f5>\<c-p>\<c-p>\<enter>\<esc>", 'tx') 245 call assert_equal('December', getline(1)) 246 247 iunmap <F5> 248endfunc 249 250func Test_noinsert_complete() 251 func! s:complTest1() abort 252 call complete(1, ['source', 'soundfold']) 253 return '' 254 endfunc 255 256 func! s:complTest2() abort 257 call complete(1, ['source', 'soundfold']) 258 return '' 259 endfunc 260 261 new 262 set completeopt+=noinsert 263 inoremap <F5> <C-R>=s:complTest1()<CR> 264 call feedkeys("i\<F5>soun\<CR>\<CR>\<ESC>.", 'tx') 265 call assert_equal('soundfold', getline(1)) 266 call assert_equal('soundfold', getline(2)) 267 bwipe! 268 269 new 270 inoremap <F5> <C-R>=s:complTest2()<CR> 271 call feedkeys("i\<F5>\<CR>\<ESC>", 'tx') 272 call assert_equal('source', getline(1)) 273 bwipe! 274 275 set completeopt-=noinsert 276 iunmap <F5> 277endfunc 278 279func Test_complete_no_filter() 280 func! s:complTest1() abort 281 call complete(1, [{'word': 'foobar'}]) 282 return '' 283 endfunc 284 func! s:complTest2() abort 285 call complete(1, [{'word': 'foobar', 'equal': 1}]) 286 return '' 287 endfunc 288 289 let completeopt = &completeopt 290 291 " without equal=1 292 new 293 set completeopt=menuone,noinsert,menu 294 inoremap <F5> <C-R>=s:complTest1()<CR> 295 call feedkeys("i\<F5>z\<CR>\<CR>\<ESC>.", 'tx') 296 call assert_equal('z', getline(1)) 297 bwipe! 298 299 " with equal=1 300 new 301 set completeopt=menuone,noinsert,menu 302 inoremap <F5> <C-R>=s:complTest2()<CR> 303 call feedkeys("i\<F5>z\<CR>\<CR>\<ESC>.", 'tx') 304 call assert_equal('foobar', getline(1)) 305 bwipe! 306 307 let &completeopt = completeopt 308 iunmap <F5> 309endfunc 310 311func Test_compl_vim_cmds_after_register_expr() 312 func! s:test_func() 313 return 'autocmd ' 314 endfunc 315 augroup AAAAA_Group 316 au! 317 augroup END 318 319 new 320 call feedkeys("i\<c-r>=s:test_func()\<CR>\<C-x>\<C-v>\<Esc>", 'tx') 321 call assert_equal('autocmd AAAAA_Group', getline(1)) 322 autocmd! AAAAA_Group 323 augroup! AAAAA_Group 324 bwipe! 325endfunc 326 327func DummyCompleteOne(findstart, base) 328 if a:findstart 329 return 0 330 else 331 wincmd n 332 return ['onedef', 'oneDEF'] 333 endif 334endfunc 335 336" Test that nothing happens if the 'completefunc' opens 337" a new window (no completion, no crash) 338func Test_completefunc_opens_new_window_one() 339 new 340 let winid = win_getid() 341 setlocal completefunc=DummyCompleteOne 342 call setline(1, 'one') 343 /^one 344 call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E839:') 345 call assert_notequal(winid, win_getid()) 346 q! 347 call assert_equal(winid, win_getid()) 348 call assert_equal('', getline(1)) 349 q! 350endfunc 351 352" Test that nothing happens if the 'completefunc' opens 353" a new window (no completion, no crash) 354func DummyCompleteTwo(findstart, base) 355 if a:findstart 356 wincmd n 357 return 0 358 else 359 return ['twodef', 'twoDEF'] 360 endif 361endfunc 362 363" Test that nothing happens if the 'completefunc' opens 364" a new window (no completion, no crash) 365func Test_completefunc_opens_new_window_two() 366 new 367 let winid = win_getid() 368 setlocal completefunc=DummyCompleteTwo 369 call setline(1, 'two') 370 /^two 371 call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E764:') 372 call assert_notequal(winid, win_getid()) 373 q! 374 call assert_equal(winid, win_getid()) 375 call assert_equal('two', getline(1)) 376 q! 377endfunc 378 379func DummyCompleteThree(findstart, base) 380 if a:findstart 381 return 0 382 else 383 return ['threedef', 'threeDEF'] 384 endif 385endfunc 386 387:"Test that 'completefunc' works when it's OK. 388func Test_completefunc_works() 389 new 390 let winid = win_getid() 391 setlocal completefunc=DummyCompleteThree 392 call setline(1, 'three') 393 /^three 394 call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x") 395 call assert_equal(winid, win_getid()) 396 call assert_equal('threeDEF', getline(1)) 397 q! 398endfunc 399 400func DummyCompleteFour(findstart, base) 401 if a:findstart 402 return 0 403 else 404 call complete_add('four1') 405 call complete_add('four2') 406 call complete_check() 407 call complete_add('four3') 408 call complete_add('four4') 409 call complete_check() 410 call complete_add('four5') 411 call complete_add('four6') 412 return [] 413 endif 414endfunc 415 416" Test that 'omnifunc' works when it's OK. 417func Test_omnifunc_with_check() 418 new 419 setlocal omnifunc=DummyCompleteFour 420 call setline(1, 'four') 421 /^four 422 call feedkeys("A\<C-X>\<C-O>\<C-N>\<Esc>", "x") 423 call assert_equal('four2', getline(1)) 424 425 call setline(1, 'four') 426 /^four 427 call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<Esc>", "x") 428 call assert_equal('four3', getline(1)) 429 430 call setline(1, 'four') 431 /^four 432 call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<C-N>\<C-N>\<Esc>", "x") 433 call assert_equal('four5', getline(1)) 434 435 q! 436endfunc 437 438func UndoComplete() 439 call complete(1, ['January', 'February', 'March', 440 \ 'April', 'May', 'June', 'July', 'August', 'September', 441 \ 'October', 'November', 'December']) 442 return '' 443endfunc 444 445" Test that no undo item is created when no completion is inserted 446func Test_complete_no_undo() 447 set completeopt=menu,preview,noinsert,noselect 448 inoremap <Right> <C-R>=UndoComplete()<CR> 449 new 450 call feedkeys("ixxx\<CR>\<CR>yyy\<Esc>k", 'xt') 451 call feedkeys("iaaa\<Esc>0", 'xt') 452 call assert_equal('aaa', getline(2)) 453 call feedkeys("i\<Right>\<Esc>", 'xt') 454 call assert_equal('aaa', getline(2)) 455 call feedkeys("u", 'xt') 456 call assert_equal('', getline(2)) 457 458 call feedkeys("ibbb\<Esc>0", 'xt') 459 call assert_equal('bbb', getline(2)) 460 call feedkeys("A\<Right>\<Down>\<CR>\<Esc>", 'xt') 461 call assert_equal('January', getline(2)) 462 call feedkeys("u", 'xt') 463 call assert_equal('bbb', getline(2)) 464 465 call feedkeys("A\<Right>\<C-N>\<Esc>", 'xt') 466 call assert_equal('January', getline(2)) 467 call feedkeys("u", 'xt') 468 call assert_equal('bbb', getline(2)) 469 470 iunmap <Right> 471 set completeopt& 472 q! 473endfunc 474 475func DummyCompleteFive(findstart, base) 476 if a:findstart 477 return 0 478 else 479 return [ 480 \ { 'word': 'January', 'info': "info1-1\n1-2\n1-3" }, 481 \ { 'word': 'February', 'info': "info2-1\n2-2\n2-3" }, 482 \ { 'word': 'March', 'info': "info3-1\n3-2\n3-3" }, 483 \ { 'word': 'April', 'info': "info4-1\n4-2\n4-3" }, 484 \ { 'word': 'May', 'info': "info5-1\n5-2\n5-3" }, 485 \ ] 486 endif 487endfunc 488 489" Test that 'completefunc' on Scratch buffer with preview window works when 490" it's OK. 491func Test_completefunc_with_scratch_buffer() 492 new +setlocal\ buftype=nofile\ bufhidden=wipe\ noswapfile 493 set completeopt+=preview 494 setlocal completefunc=DummyCompleteFive 495 call feedkeys("A\<C-X>\<C-U>\<C-N>\<C-N>\<C-N>\<Esc>", "x") 496 call assert_equal(['April'], getline(1, '$')) 497 pclose 498 q! 499 set completeopt& 500endfunc 501 502" <C-E> - select original typed text before the completion started without 503" auto-wrap text. 504func Test_completion_ctrl_e_without_autowrap() 505 new 506 let tw_save = &tw 507 set tw=78 508 let li = [ 509 \ '" zzz', 510 \ '" zzzyyyyyyyyyyyyyyyyyyy'] 511 call setline(1, li) 512 0 513 call feedkeys("A\<C-X>\<C-N>\<C-E>\<Esc>", "tx") 514 call assert_equal(li, getline(1, '$')) 515 516 let &tw = tw_save 517 q! 518endfunc 519 520func DummyCompleteSix() 521 call complete(1, ['Hello', 'World']) 522 return '' 523endfunction 524 525" complete() correctly clears the list of autocomplete candidates 526" See #1411 527func Test_completion_clear_candidate_list() 528 new 529 %d 530 " select first entry from the completion popup 531 call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>", "tx") 532 call assert_equal('Hello', getline(1)) 533 %d 534 " select second entry from the completion popup 535 call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>", "tx") 536 call assert_equal('World', getline(1)) 537 %d 538 " select original text 539 call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>\<C-N>", "tx") 540 call assert_equal(' xxx', getline(1)) 541 %d 542 " back at first entry from completion list 543 call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>\<C-N>\<C-N>", "tx") 544 call assert_equal('Hello', getline(1)) 545 546 bw! 547endfunc 548 549func Test_completion_respect_bs_option() 550 new 551 let li = ["aaa", "aaa12345", "aaaabcdef", "aaaABC"] 552 553 set bs=indent,eol 554 call setline(1, li) 555 1 556 call feedkeys("A\<C-X>\<C-N>\<C-P>\<BS>\<BS>\<BS>\<Esc>", "tx") 557 call assert_equal('aaa', getline(1)) 558 559 %d 560 set bs=indent,eol,start 561 call setline(1, li) 562 1 563 call feedkeys("A\<C-X>\<C-N>\<C-P>\<BS>\<BS>\<BS>\<Esc>", "tx") 564 call assert_equal('', getline(1)) 565 566 bw! 567endfunc 568 569func CompleteUndo() abort 570 call complete(1, g:months) 571 return '' 572endfunc 573 574func Test_completion_can_undo() 575 inoremap <Right> <c-r>=CompleteUndo()<cr> 576 set completeopt+=noinsert,noselect 577 578 new 579 call feedkeys("a\<Right>a\<Esc>", 'xt') 580 call assert_equal('a', getline(1)) 581 undo 582 call assert_equal('', getline(1)) 583 584 bwipe! 585 set completeopt& 586 iunmap <Right> 587endfunc 588 589func Test_completion_comment_formatting() 590 new 591 setl formatoptions=tcqro 592 call feedkeys("o/*\<cr>\<cr>/\<esc>", 'tx') 593 call assert_equal(['', '/*', ' *', ' */'], getline(1,4)) 594 %d 595 call feedkeys("o/*\<cr>foobar\<cr>/\<esc>", 'tx') 596 call assert_equal(['', '/*', ' * foobar', ' */'], getline(1,4)) 597 %d 598 try 599 call feedkeys("o/*\<cr>\<cr>\<c-x>\<c-u>/\<esc>", 'tx') 600 call assert_report('completefunc not set, should have failed') 601 catch 602 call assert_exception('E764:') 603 endtry 604 call assert_equal(['', '/*', ' *', ' */'], getline(1,4)) 605 bwipe! 606endfunc 607 608func MessCompleteMonths() 609 for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep") 610 call complete_add(m) 611 if complete_check() 612 break 613 endif 614 endfor 615 return [] 616endfunc 617 618func MessCompleteMore() 619 call complete(1, split("Oct Nov Dec")) 620 return [] 621endfunc 622 623func MessComplete(findstart, base) 624 if a:findstart 625 let line = getline('.') 626 let start = col('.') - 1 627 while start > 0 && line[start - 1] =~ '\a' 628 let start -= 1 629 endwhile 630 return start 631 else 632 call MessCompleteMonths() 633 call MessCompleteMore() 634 return [] 635 endif 636endfunc 637 638func Test_complete_func_mess() 639 " Calling complete() after complete_add() in 'completefunc' is wrong, but it 640 " should not crash. 641 set completefunc=MessComplete 642 new 643 call setline(1, 'Ju') 644 call feedkeys("A\<c-x>\<c-u>/\<esc>", 'tx') 645 call assert_equal('Oct/Oct', getline(1)) 646 bwipe! 647 set completefunc= 648endfunc 649 650func Test_complete_CTRLN_startofbuffer() 651 new 652 call setline(1, [ 'organize(cupboard, 3, 2);', 653 \ 'prioritize(bureau, 8, 7);', 654 \ 'realize(bannister, 4, 4);', 655 \ 'moralize(railing, 3,9);']) 656 let expected=['cupboard.organize(3, 2);', 657 \ 'bureau.prioritize(8, 7);', 658 \ 'bannister.realize(4, 4);', 659 \ 'railing.moralize(3,9);'] 660 call feedkeys("qai\<c-n>\<c-n>.\<esc>3wdW\<cr>q3@a", 'tx') 661 call assert_equal(expected, getline(1,'$')) 662 bwipe! 663endfunc 664 665func Test_popup_and_window_resize() 666 if !has('terminal') || has('gui_running') 667 return 668 endif 669 let h = winheight(0) 670 if h < 15 671 return 672 endif 673 let rows = h / 3 674 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': rows}) 675 call term_sendkeys(buf, (h / 3 - 1) . "o\<esc>") 676 " Wait for the nested Vim to exit insert mode, where it will show the ruler. 677 " Need to trigger a redraw. 678 call WaitFor({-> execute("redraw") == "" && term_getline(buf, rows) =~ '\<' . rows . ',.*Bot'}) 679 680 call term_sendkeys(buf, "Gi\<c-x>") 681 call term_sendkeys(buf, "\<c-v>") 682 call term_wait(buf, 100) 683 " popup first entry "!" must be at the top 684 call WaitForAssert({-> assert_match('^!\s*$', term_getline(buf, 1))}) 685 exe 'resize +' . (h - 1) 686 call term_wait(buf, 100) 687 redraw! 688 " popup shifted down, first line is now empty 689 call WaitForAssert({-> assert_equal('', term_getline(buf, 1))}) 690 sleep 100m 691 " popup is below cursor line and shows first match "!" 692 call WaitForAssert({-> assert_match('^!\s*$', term_getline(buf, term_getcursor(buf)[0] + 1))}) 693 " cursor line also shows ! 694 call assert_match('^!\s*$', term_getline(buf, term_getcursor(buf)[0])) 695 bwipe! 696endfunc 697 698func Test_popup_and_preview_autocommand() 699 " This used to crash Vim 700 if !has('python') 701 return 702 endif 703 let h = winheight(0) 704 if h < 15 705 return 706 endif 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 if !CanRunVimInTerminal() 738 return 739 endif 740 call writefile([ 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 \ ], 'Xscript') 746 let buf = RunVimInTerminal('-S Xscript', {}) 747 748 " Test that popup and previewwindow do not overlap. 749 call term_sendkeys(buf, "o\<C-X>\<C-N>") 750 sleep 100m 751 call VerifyScreenDump(buf, 'Test_popup_and_previewwindow_01', {}) 752 753 call term_sendkeys(buf, "\<Esc>u") 754 call StopVimInTerminal(buf) 755 call delete('Xscript') 756endfunc 757 758func Test_balloon_split() 759 if !exists('*balloon_split') 760 return 761 endif 762 call assert_equal([ 763 \ 'tempname: 0x555555e380a0 "/home/mool/.viminfz.tmp"', 764 \ ], balloon_split( 765 \ 'tempname: 0x555555e380a0 "/home/mool/.viminfz.tmp"')) 766 call assert_equal([ 767 \ 'one two three four one two three four one two thre', 768 \ 'e four', 769 \ ], balloon_split( 770 \ 'one two three four one two three four one two three four')) 771 772 call assert_equal([ 773 \ 'struct = {', 774 \ ' one = 1,', 775 \ ' two = 2,', 776 \ ' three = 3}', 777 \ ], balloon_split( 778 \ 'struct = {one = 1, two = 2, three = 3}')) 779 780 call assert_equal([ 781 \ 'struct = {', 782 \ ' one = 1,', 783 \ ' nested = {', 784 \ ' n1 = "yes",', 785 \ ' n2 = "no"}', 786 \ ' two = 2}', 787 \ ], balloon_split( 788 \ 'struct = {one = 1, nested = {n1 = "yes", n2 = "no"} two = 2}')) 789 call assert_equal([ 790 \ 'struct = 0x234 {', 791 \ ' long = 2343 "\\"some long string that will be wr', 792 \ 'apped in two\\"",', 793 \ ' next = 123}', 794 \ ], balloon_split( 795 \ 'struct = 0x234 {long = 2343 "\\"some long string that will be wrapped in two\\"", next = 123}')) 796endfunc 797 798func Test_popup_position() 799 if !CanRunVimInTerminal() 800 return 801 endif 802 call writefile([ 803 \ '123456789_123456789_123456789_a', 804 \ '123456789_123456789_123456789_b', 805 \ ' 123', 806 \ ], 'Xtest') 807 let buf = RunVimInTerminal('Xtest', {}) 808 call term_sendkeys(buf, ":vsplit\<CR>") 809 810 " default pumwidth in left window: overlap in right window 811 call term_sendkeys(buf, "GA\<C-N>") 812 call VerifyScreenDump(buf, 'Test_popup_position_01', {'rows': 8}) 813 call term_sendkeys(buf, "\<Esc>u") 814 815 " default pumwidth: fill until right of window 816 call term_sendkeys(buf, "\<C-W>l") 817 call term_sendkeys(buf, "GA\<C-N>") 818 call VerifyScreenDump(buf, 'Test_popup_position_02', {'rows': 8}) 819 820 " larger pumwidth: used as minimum width 821 call term_sendkeys(buf, "\<Esc>u") 822 call term_sendkeys(buf, ":set pumwidth=30\<CR>") 823 call term_sendkeys(buf, "GA\<C-N>") 824 call VerifyScreenDump(buf, 'Test_popup_position_03', {'rows': 8}) 825 826 " completed text wider than the window and 'pumwidth' smaller than available 827 " space 828 call term_sendkeys(buf, "\<Esc>u") 829 call term_sendkeys(buf, ":set pumwidth=20\<CR>") 830 call term_sendkeys(buf, "ggI123456789_\<Esc>") 831 call term_sendkeys(buf, "jI123456789_\<Esc>") 832 call term_sendkeys(buf, "GA\<C-N>") 833 call VerifyScreenDump(buf, 'Test_popup_position_04', {'rows': 10}) 834 835 call term_sendkeys(buf, "\<Esc>u") 836 call StopVimInTerminal(buf) 837 call delete('Xtest') 838endfunc 839 840func Test_popup_command() 841 if !CanRunVimInTerminal() || !has('menu') 842 return 843 endif 844 845 call writefile([ 846 \ 'one two three four five', 847 \ 'and one two Xthree four five', 848 \ 'one more two three four five', 849 \ ], 'Xtest') 850 let buf = RunVimInTerminal('Xtest', {}) 851 call term_sendkeys(buf, ":source $VIMRUNTIME/menu.vim\<CR>") 852 call term_sendkeys(buf, "/X\<CR>:popup PopUp\<CR>") 853 call VerifyScreenDump(buf, 'Test_popup_command_01', {}) 854 855 " Select a word 856 call term_sendkeys(buf, "jj") 857 call VerifyScreenDump(buf, 'Test_popup_command_02', {}) 858 859 " Select a word 860 call term_sendkeys(buf, "j\<CR>") 861 call VerifyScreenDump(buf, 'Test_popup_command_03', {}) 862 863 call term_sendkeys(buf, "\<Esc>") 864 call StopVimInTerminal(buf) 865 call delete('Xtest') 866endfunc 867 868func Test_popup_complete_backwards() 869 new 870 call setline(1, ['Post', 'Port', 'Po']) 871 let expected=['Post', 'Port', 'Port'] 872 call cursor(3,2) 873 call feedkeys("A\<C-X>". repeat("\<C-P>", 3). "rt\<cr>", 'tx') 874 call assert_equal(expected, getline(1,'$')) 875 bwipe! 876endfunc 877 878func Test_popup_complete_backwards_ctrl_p() 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-P>\<C-N>rt\<cr>", 'tx') 884 call assert_equal(expected, getline(1,'$')) 885 bwipe! 886endfunc 887 888func Test_complete_o_tab() 889 let s:o_char_pressed = 0 890 891 fun! s:act_on_text_changed() 892 if s:o_char_pressed 893 let s:o_char_pressed = 0 894 call feedkeys("\<c-x>\<c-n>", 'i') 895 endif 896 endfunc 897 898 set completeopt=menu,noselect 899 new 900 imap <expr> <buffer> <tab> pumvisible() ? "\<c-p>" : "X" 901 autocmd! InsertCharPre <buffer> let s:o_char_pressed = (v:char ==# 'o') 902 autocmd! TextChangedI <buffer> call <sid>act_on_text_changed() 903 call setline(1, ['hoard', 'hoax', 'hoarse', '']) 904 let l:expected = ['hoard', 'hoax', 'hoarse', 'hoax', 'hoax'] 905 call cursor(4,1) 906 call test_override("char_avail", 1) 907 call feedkeys("Ahoa\<tab>\<tab>\<c-y>\<esc>", 'tx') 908 call feedkeys("oho\<tab>\<tab>\<c-y>\<esc>", 'tx') 909 call assert_equal(l:expected, getline(1,'$')) 910 911 call test_override("char_avail", 0) 912 bwipe! 913 set completeopt& 914 delfunc s:act_on_text_changed 915endfunc 916 917func Test_menu_only_exists_in_terminal() 918 if !exists(':tlmenu') || has('gui_running') 919 return 920 endif 921 tlnoremenu &Edit.&Paste<Tab>"+gP <C-W>"+ 922 aunmenu * 923 try 924 popup Edit 925 call assert_false(1, 'command should have failed') 926 catch 927 call assert_exception('E328:') 928 endtry 929endfunc 930 931func Test_popup_complete_info_01() 932 new 933 inoremap <buffer><F5> <C-R>=complete_info().mode<CR> 934 func s:complTestEval() abort 935 call complete(1, ['aa', 'ab']) 936 return '' 937 endfunc 938 inoremap <buffer><F6> <C-R>=s:complTestEval()<CR> 939 call writefile([ 940 \ 'dummy dummy.txt 1', 941 \], 'Xdummy.txt') 942 setlocal tags=Xdummy.txt 943 setlocal dictionary=Xdummy.txt 944 setlocal thesaurus=Xdummy.txt 945 setlocal omnifunc=syntaxcomplete#Complete 946 setlocal completefunc=syntaxcomplete#Complete 947 setlocal spell 948 for [keys, mode_name] in [ 949 \ ["", ''], 950 \ ["\<C-X>", 'ctrl_x'], 951 \ ["\<C-X>\<C-N>", 'keyword'], 952 \ ["\<C-X>\<C-P>", 'keyword'], 953 \ ["\<C-X>\<C-L>", 'whole_line'], 954 \ ["\<C-X>\<C-F>", 'files'], 955 \ ["\<C-X>\<C-]>", 'tags'], 956 \ ["\<C-X>\<C-D>", 'path_defines'], 957 \ ["\<C-X>\<C-I>", 'path_patterns'], 958 \ ["\<C-X>\<C-K>", 'dictionary'], 959 \ ["\<C-X>\<C-T>", 'thesaurus'], 960 \ ["\<C-X>\<C-V>", 'cmdline'], 961 \ ["\<C-X>\<C-U>", 'function'], 962 \ ["\<C-X>\<C-O>", 'omni'], 963 \ ["\<C-X>s", 'spell'], 964 \ ["\<F6>", 'eval'], 965 \] 966 call feedkeys("i" . keys . "\<F5>\<Esc>", 'tx') 967 call assert_equal(mode_name, getline('.')) 968 %d 969 endfor 970 call delete('Xdummy.txt') 971 bwipe! 972endfunc 973 974func UserDefinedComplete(findstart, base) 975 if a:findstart 976 return 0 977 else 978 return [ 979 \ { 'word': 'Jan', 'menu': 'January' }, 980 \ { 'word': 'Feb', 'menu': 'February' }, 981 \ { 'word': 'Mar', 'menu': 'March' }, 982 \ { 'word': 'Apr', 'menu': 'April' }, 983 \ { 'word': 'May', 'menu': 'May' }, 984 \ ] 985 endif 986endfunc 987 988func GetCompleteInfo() 989 if empty(g:compl_what) 990 let g:compl_info = complete_info() 991 else 992 let g:compl_info = complete_info(g:compl_what) 993 endif 994 return '' 995endfunc 996 997func Test_popup_complete_info_02() 998 new 999 inoremap <buffer><F5> <C-R>=GetCompleteInfo()<CR> 1000 setlocal completefunc=UserDefinedComplete 1001 1002 let d = { 1003 \ 'mode': 'function', 1004 \ 'pum_visible': 1, 1005 \ 'items': [ 1006 \ {'word': 'Jan', 'menu': 'January', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, 1007 \ {'word': 'Feb', 'menu': 'February', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, 1008 \ {'word': 'Mar', 'menu': 'March', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, 1009 \ {'word': 'Apr', 'menu': 'April', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, 1010 \ {'word': 'May', 'menu': 'May', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''} 1011 \ ], 1012 \ 'selected': 0, 1013 \ } 1014 1015 let g:compl_what = [] 1016 call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx') 1017 call assert_equal(d, g:compl_info) 1018 1019 let g:compl_what = ['mode', 'pum_visible', 'selected'] 1020 call remove(d, 'items') 1021 call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx') 1022 call assert_equal(d, g:compl_info) 1023 1024 let g:compl_what = ['mode'] 1025 call remove(d, 'selected') 1026 call remove(d, 'pum_visible') 1027 call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx') 1028 call assert_equal(d, g:compl_info) 1029 bwipe! 1030endfunc 1031 1032func Test_CompleteChanged() 1033 new 1034 call setline(1, ['foo', 'bar', 'foobar', '']) 1035 set complete=. completeopt=noinsert,noselect,menuone 1036 function! OnPumChange() 1037 let g:event = copy(v:event) 1038 let g:item = get(v:event, 'completed_item', {}) 1039 let g:word = get(g:item, 'word', v:null) 1040 endfunction 1041 augroup AAAAA_Group 1042 au! 1043 autocmd CompleteChanged * :call OnPumChange() 1044 augroup END 1045 call cursor(4, 1) 1046 1047 call feedkeys("Sf\<C-N>", 'tx') 1048 call assert_equal({'completed_item': {}, 'width': 15, 1049 \ 'height': 2, 'size': 2, 1050 \ 'col': 0, 'row': 4, 'scrollbar': v:false}, g:event) 1051 call feedkeys("a\<C-N>\<C-N>\<C-E>", 'tx') 1052 call assert_equal('foo', g:word) 1053 call feedkeys("a\<C-N>\<C-N>\<C-N>\<C-E>", 'tx') 1054 call assert_equal('foobar', g:word) 1055 call feedkeys("a\<C-N>\<C-N>\<C-N>\<C-N>\<C-E>", 'tx') 1056 call assert_equal(v:null, g:word) 1057 call feedkeys("a\<C-N>\<C-N>\<C-N>\<C-N>\<C-P>", 'tx') 1058 call assert_equal('foobar', g:word) 1059 1060 autocmd! AAAAA_Group 1061 set complete& completeopt& 1062 delfunc! OnPumchange 1063 bw! 1064endfunc 1065 1066" vim: shiftwidth=2 sts=2 expandtab 1067