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 throw 'Skipped: cannot make screendumps' 739 endif 740 let lines =<< trim END 741 set previewheight=9 742 silent! pedit 743 call setline(1, map(repeat(["ab"], 10), "v:val. v:key")) 744 exec "norm! G\<C-E>\<C-E>" 745 END 746 call writefile(lines, 'Xscript') 747 let buf = RunVimInTerminal('-S Xscript', {}) 748 749 " Test that popup and previewwindow do not overlap. 750 call term_sendkeys(buf, "o\<C-X>\<C-N>") 751 sleep 100m 752 call VerifyScreenDump(buf, 'Test_popup_and_previewwindow_01', {}) 753 754 call term_sendkeys(buf, "\<Esc>u") 755 call StopVimInTerminal(buf) 756 call delete('Xscript') 757endfunc 758 759func Test_balloon_split() 760 if !exists('*balloon_split') 761 return 762 endif 763 call assert_equal([ 764 \ 'tempname: 0x555555e380a0 "/home/mool/.viminfz.tmp"', 765 \ ], balloon_split( 766 \ 'tempname: 0x555555e380a0 "/home/mool/.viminfz.tmp"')) 767 call assert_equal([ 768 \ 'one two three four one two three four one two thre', 769 \ 'e four', 770 \ ], balloon_split( 771 \ 'one two three four one two three four one two three four')) 772 773 call assert_equal([ 774 \ 'struct = {', 775 \ ' one = 1,', 776 \ ' two = 2,', 777 \ ' three = 3}', 778 \ ], balloon_split( 779 \ 'struct = {one = 1, two = 2, three = 3}')) 780 781 call assert_equal([ 782 \ 'struct = {', 783 \ ' one = 1,', 784 \ ' nested = {', 785 \ ' n1 = "yes",', 786 \ ' n2 = "no"}', 787 \ ' two = 2}', 788 \ ], balloon_split( 789 \ 'struct = {one = 1, nested = {n1 = "yes", n2 = "no"} two = 2}')) 790 call assert_equal([ 791 \ 'struct = 0x234 {', 792 \ ' long = 2343 "\\"some long string that will be wr', 793 \ 'apped in two\\"",', 794 \ ' next = 123}', 795 \ ], balloon_split( 796 \ 'struct = 0x234 {long = 2343 "\\"some long string that will be wrapped in two\\"", next = 123}')) 797endfunc 798 799func Test_popup_position() 800 if !CanRunVimInTerminal() 801 throw 'Skipped: cannot make screendumps' 802 endif 803 let lines =<< trim END 804 123456789_123456789_123456789_a 805 123456789_123456789_123456789_b 806 123 807 END 808 call writefile(lines, 'Xtest') 809 let buf = RunVimInTerminal('Xtest', {}) 810 call term_sendkeys(buf, ":vsplit\<CR>") 811 812 " default pumwidth in left window: overlap in right window 813 call term_sendkeys(buf, "GA\<C-N>") 814 call VerifyScreenDump(buf, 'Test_popup_position_01', {'rows': 8}) 815 call term_sendkeys(buf, "\<Esc>u") 816 817 " default pumwidth: fill until right of window 818 call term_sendkeys(buf, "\<C-W>l") 819 call term_sendkeys(buf, "GA\<C-N>") 820 call VerifyScreenDump(buf, 'Test_popup_position_02', {'rows': 8}) 821 822 " larger pumwidth: used as minimum width 823 call term_sendkeys(buf, "\<Esc>u") 824 call term_sendkeys(buf, ":set pumwidth=30\<CR>") 825 call term_sendkeys(buf, "GA\<C-N>") 826 call VerifyScreenDump(buf, 'Test_popup_position_03', {'rows': 8}) 827 828 " completed text wider than the window and 'pumwidth' smaller than available 829 " space 830 call term_sendkeys(buf, "\<Esc>u") 831 call term_sendkeys(buf, ":set pumwidth=20\<CR>") 832 call term_sendkeys(buf, "ggI123456789_\<Esc>") 833 call term_sendkeys(buf, "jI123456789_\<Esc>") 834 call term_sendkeys(buf, "GA\<C-N>") 835 call VerifyScreenDump(buf, 'Test_popup_position_04', {'rows': 10}) 836 837 call term_sendkeys(buf, "\<Esc>u") 838 call StopVimInTerminal(buf) 839 call delete('Xtest') 840endfunc 841 842func Test_popup_command() 843 if !CanRunVimInTerminal() || !has('menu') 844 throw 'Skipped: cannot make screendumps and/or menu feature missing' 845 endif 846 847 let lines =<< trim END 848 one two three four five 849 and one two Xthree four five 850 one more two three four five 851 END 852 call writefile(lines, 'Xtest') 853 let buf = RunVimInTerminal('Xtest', {}) 854 call term_sendkeys(buf, ":source $VIMRUNTIME/menu.vim\<CR>") 855 call term_sendkeys(buf, "/X\<CR>:popup PopUp\<CR>") 856 call VerifyScreenDump(buf, 'Test_popup_command_01', {}) 857 858 " Select a word 859 call term_sendkeys(buf, "jj") 860 call VerifyScreenDump(buf, 'Test_popup_command_02', {}) 861 862 " Select a word 863 call term_sendkeys(buf, "j\<CR>") 864 call VerifyScreenDump(buf, 'Test_popup_command_03', {}) 865 866 call term_sendkeys(buf, "\<Esc>") 867 call StopVimInTerminal(buf) 868 call delete('Xtest') 869endfunc 870 871func Test_popup_complete_backwards() 872 new 873 call setline(1, ['Post', 'Port', 'Po']) 874 let expected=['Post', 'Port', 'Port'] 875 call cursor(3,2) 876 call feedkeys("A\<C-X>". repeat("\<C-P>", 3). "rt\<cr>", 'tx') 877 call assert_equal(expected, getline(1,'$')) 878 bwipe! 879endfunc 880 881func Test_popup_complete_backwards_ctrl_p() 882 new 883 call setline(1, ['Post', 'Port', 'Po']) 884 let expected=['Post', 'Port', 'Port'] 885 call cursor(3,2) 886 call feedkeys("A\<C-P>\<C-N>rt\<cr>", 'tx') 887 call assert_equal(expected, getline(1,'$')) 888 bwipe! 889endfunc 890 891func Test_complete_o_tab() 892 let s:o_char_pressed = 0 893 894 fun! s:act_on_text_changed() 895 if s:o_char_pressed 896 let s:o_char_pressed = 0 897 call feedkeys("\<c-x>\<c-n>", 'i') 898 endif 899 endfunc 900 901 set completeopt=menu,noselect 902 new 903 imap <expr> <buffer> <tab> pumvisible() ? "\<c-p>" : "X" 904 autocmd! InsertCharPre <buffer> let s:o_char_pressed = (v:char ==# 'o') 905 autocmd! TextChangedI <buffer> call <sid>act_on_text_changed() 906 call setline(1, ['hoard', 'hoax', 'hoarse', '']) 907 let l:expected = ['hoard', 'hoax', 'hoarse', 'hoax', 'hoax'] 908 call cursor(4,1) 909 call test_override("char_avail", 1) 910 call feedkeys("Ahoa\<tab>\<tab>\<c-y>\<esc>", 'tx') 911 call feedkeys("oho\<tab>\<tab>\<c-y>\<esc>", 'tx') 912 call assert_equal(l:expected, getline(1,'$')) 913 914 call test_override("char_avail", 0) 915 bwipe! 916 set completeopt& 917 delfunc s:act_on_text_changed 918endfunc 919 920func Test_menu_only_exists_in_terminal() 921 if !exists(':tlmenu') || has('gui_running') 922 return 923 endif 924 tlnoremenu &Edit.&Paste<Tab>"+gP <C-W>"+ 925 aunmenu * 926 try 927 popup Edit 928 call assert_false(1, 'command should have failed') 929 catch 930 call assert_exception('E328:') 931 endtry 932endfunc 933 934func Test_popup_complete_info_01() 935 new 936 inoremap <buffer><F5> <C-R>=complete_info().mode<CR> 937 func s:complTestEval() abort 938 call complete(1, ['aa', 'ab']) 939 return '' 940 endfunc 941 inoremap <buffer><F6> <C-R>=s:complTestEval()<CR> 942 call writefile([ 943 \ 'dummy dummy.txt 1', 944 \], 'Xdummy.txt') 945 setlocal tags=Xdummy.txt 946 setlocal dictionary=Xdummy.txt 947 setlocal thesaurus=Xdummy.txt 948 setlocal omnifunc=syntaxcomplete#Complete 949 setlocal completefunc=syntaxcomplete#Complete 950 setlocal spell 951 for [keys, mode_name] in [ 952 \ ["", ''], 953 \ ["\<C-X>", 'ctrl_x'], 954 \ ["\<C-X>\<C-N>", 'keyword'], 955 \ ["\<C-X>\<C-P>", 'keyword'], 956 \ ["\<C-X>\<C-L>", 'whole_line'], 957 \ ["\<C-X>\<C-F>", 'files'], 958 \ ["\<C-X>\<C-]>", 'tags'], 959 \ ["\<C-X>\<C-D>", 'path_defines'], 960 \ ["\<C-X>\<C-I>", 'path_patterns'], 961 \ ["\<C-X>\<C-K>", 'dictionary'], 962 \ ["\<C-X>\<C-T>", 'thesaurus'], 963 \ ["\<C-X>\<C-V>", 'cmdline'], 964 \ ["\<C-X>\<C-U>", 'function'], 965 \ ["\<C-X>\<C-O>", 'omni'], 966 \ ["\<C-X>s", 'spell'], 967 \ ["\<F6>", 'eval'], 968 \] 969 call feedkeys("i" . keys . "\<F5>\<Esc>", 'tx') 970 call assert_equal(mode_name, getline('.')) 971 %d 972 endfor 973 call delete('Xdummy.txt') 974 bwipe! 975endfunc 976 977func UserDefinedComplete(findstart, base) 978 if a:findstart 979 return 0 980 else 981 return [ 982 \ { 'word': 'Jan', 'menu': 'January' }, 983 \ { 'word': 'Feb', 'menu': 'February' }, 984 \ { 'word': 'Mar', 'menu': 'March' }, 985 \ { 'word': 'Apr', 'menu': 'April' }, 986 \ { 'word': 'May', 'menu': 'May' }, 987 \ ] 988 endif 989endfunc 990 991func GetCompleteInfo() 992 if empty(g:compl_what) 993 let g:compl_info = complete_info() 994 else 995 let g:compl_info = complete_info(g:compl_what) 996 endif 997 return '' 998endfunc 999 1000func Test_popup_complete_info_02() 1001 new 1002 inoremap <buffer><F5> <C-R>=GetCompleteInfo()<CR> 1003 setlocal completefunc=UserDefinedComplete 1004 1005 let d = { 1006 \ 'mode': 'function', 1007 \ 'pum_visible': 1, 1008 \ 'items': [ 1009 \ {'word': 'Jan', 'menu': 'January', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, 1010 \ {'word': 'Feb', 'menu': 'February', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, 1011 \ {'word': 'Mar', 'menu': 'March', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, 1012 \ {'word': 'Apr', 'menu': 'April', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, 1013 \ {'word': 'May', 'menu': 'May', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''} 1014 \ ], 1015 \ 'selected': 0, 1016 \ } 1017 1018 let g:compl_what = [] 1019 call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx') 1020 call assert_equal(d, g:compl_info) 1021 1022 let g:compl_what = ['mode', 'pum_visible', 'selected'] 1023 call remove(d, 'items') 1024 call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx') 1025 call assert_equal(d, g:compl_info) 1026 1027 let g:compl_what = ['mode'] 1028 call remove(d, 'selected') 1029 call remove(d, 'pum_visible') 1030 call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx') 1031 call assert_equal(d, g:compl_info) 1032 bwipe! 1033endfunc 1034 1035func Test_CompleteChanged() 1036 new 1037 call setline(1, ['foo', 'bar', 'foobar', '']) 1038 set complete=. completeopt=noinsert,noselect,menuone 1039 function! OnPumChange() 1040 let g:event = copy(v:event) 1041 let g:item = get(v:event, 'completed_item', {}) 1042 let g:word = get(g:item, 'word', v:null) 1043 endfunction 1044 augroup AAAAA_Group 1045 au! 1046 autocmd CompleteChanged * :call OnPumChange() 1047 augroup END 1048 call cursor(4, 1) 1049 1050 call feedkeys("Sf\<C-N>", 'tx') 1051 call assert_equal({'completed_item': {}, 'width': 15, 1052 \ 'height': 2, 'size': 2, 1053 \ 'col': 0, 'row': 4, 'scrollbar': v:false}, g:event) 1054 call feedkeys("a\<C-N>\<C-N>\<C-E>", 'tx') 1055 call assert_equal('foo', g:word) 1056 call feedkeys("a\<C-N>\<C-N>\<C-N>\<C-E>", 'tx') 1057 call assert_equal('foobar', g:word) 1058 call feedkeys("a\<C-N>\<C-N>\<C-N>\<C-N>\<C-E>", 'tx') 1059 call assert_equal(v:null, g:word) 1060 call feedkeys("a\<C-N>\<C-N>\<C-N>\<C-N>\<C-P>", 'tx') 1061 call assert_equal('foobar', g:word) 1062 1063 autocmd! AAAAA_Group 1064 set complete& completeopt& 1065 delfunc! OnPumchange 1066 bw! 1067endfunc 1068 1069" vim: shiftwidth=2 sts=2 expandtab 1070