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