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-E>", 'scroll'], 994 \ ["\<C-X>\<C-Y>", 'scroll'], 995 \ ["\<C-X>\<C-E>\<C-E>\<C-Y>", 'scroll'], 996 \ ["\<C-X>\<C-Y>\<C-E>\<C-Y>", 'scroll'], 997 \ ["\<C-X>\<C-L>", 'whole_line'], 998 \ ["\<C-X>\<C-F>", 'files'], 999 \ ["\<C-X>\<C-]>", 'tags'], 1000 \ ["\<C-X>\<C-D>", 'path_defines'], 1001 \ ["\<C-X>\<C-I>", 'path_patterns'], 1002 \ ["\<C-X>\<C-K>", 'dictionary'], 1003 \ ["\<C-X>\<C-T>", 'thesaurus'], 1004 \ ["\<C-X>\<C-V>", 'cmdline'], 1005 \ ["\<C-X>\<C-U>", 'function'], 1006 \ ["\<C-X>\<C-O>", 'omni'], 1007 \ ["\<C-X>s", 'spell'], 1008 \ ["\<F6>", 'eval'], 1009 \] 1010 call feedkeys("i" . keys . "\<F5>\<Esc>", 'tx') 1011 call assert_equal(mode_name, getline('.')) 1012 %d 1013 endfor 1014 call delete('Xdummy.txt') 1015 bwipe! 1016endfunc 1017 1018func UserDefinedComplete(findstart, base) 1019 if a:findstart 1020 return 0 1021 else 1022 return [ 1023 \ { 'word': 'Jan', 'menu': 'January' }, 1024 \ { 'word': 'Feb', 'menu': 'February' }, 1025 \ { 'word': 'Mar', 'menu': 'March' }, 1026 \ { 'word': 'Apr', 'menu': 'April' }, 1027 \ { 'word': 'May', 'menu': 'May' }, 1028 \ ] 1029 endif 1030endfunc 1031 1032func GetCompleteInfo() 1033 if empty(g:compl_what) 1034 let g:compl_info = complete_info() 1035 else 1036 let g:compl_info = g:compl_what->complete_info() 1037 endif 1038 return '' 1039endfunc 1040 1041func Test_popup_complete_info_02() 1042 new 1043 inoremap <buffer><F5> <C-R>=GetCompleteInfo()<CR> 1044 setlocal completefunc=UserDefinedComplete 1045 1046 let d = { 1047 \ 'mode': 'function', 1048 \ 'pum_visible': 1, 1049 \ 'items': [ 1050 \ {'word': 'Jan', 'menu': 'January', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, 1051 \ {'word': 'Feb', 'menu': 'February', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, 1052 \ {'word': 'Mar', 'menu': 'March', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, 1053 \ {'word': 'Apr', 'menu': 'April', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''}, 1054 \ {'word': 'May', 'menu': 'May', 'user_data': '', 'info': '', 'kind': '', 'abbr': ''} 1055 \ ], 1056 \ 'selected': 0, 1057 \ } 1058 1059 let g:compl_what = [] 1060 call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx') 1061 call assert_equal(d, g:compl_info) 1062 1063 let g:compl_what = ['mode', 'pum_visible', 'selected'] 1064 call remove(d, 'items') 1065 call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx') 1066 call assert_equal(d, g:compl_info) 1067 1068 let g:compl_what = ['mode'] 1069 call remove(d, 'selected') 1070 call remove(d, 'pum_visible') 1071 call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx') 1072 call assert_equal(d, g:compl_info) 1073 bwipe! 1074endfunc 1075 1076func Test_popup_complete_info_no_pum() 1077 new 1078 call assert_false( pumvisible() ) 1079 let no_pum_info = complete_info() 1080 let d = { 1081 \ 'mode': '', 1082 \ 'pum_visible': 0, 1083 \ 'items': [], 1084 \ 'selected': -1, 1085 \ } 1086 call assert_equal( d, complete_info() ) 1087 bwipe! 1088endfunc 1089 1090func Test_CompleteChanged() 1091 new 1092 call setline(1, ['foo', 'bar', 'foobar', '']) 1093 set complete=. completeopt=noinsert,noselect,menuone 1094 function! OnPumChange() 1095 let g:event = copy(v:event) 1096 let g:item = get(v:event, 'completed_item', {}) 1097 let g:word = get(g:item, 'word', v:null) 1098 endfunction 1099 augroup AAAAA_Group 1100 au! 1101 autocmd CompleteChanged * :call OnPumChange() 1102 augroup END 1103 call cursor(4, 1) 1104 1105 call feedkeys("Sf\<C-N>", 'tx') 1106 call assert_equal({'completed_item': {}, 'width': 15, 1107 \ 'height': 2, 'size': 2, 1108 \ 'col': 0, 'row': 4, 'scrollbar': v:false}, g:event) 1109 call feedkeys("a\<C-N>\<C-N>\<C-E>", 'tx') 1110 call assert_equal('foo', g:word) 1111 call feedkeys("a\<C-N>\<C-N>\<C-N>\<C-E>", 'tx') 1112 call assert_equal('foobar', g:word) 1113 call feedkeys("a\<C-N>\<C-N>\<C-N>\<C-N>\<C-E>", 'tx') 1114 call assert_equal(v:null, g:word) 1115 call feedkeys("a\<C-N>\<C-N>\<C-N>\<C-N>\<C-P>", 'tx') 1116 call assert_equal('foobar', g:word) 1117 1118 autocmd! AAAAA_Group 1119 set complete& completeopt& 1120 delfunc! OnPumChange 1121 bw! 1122endfunc 1123 1124function! GetPumPosition() 1125 call assert_true( pumvisible() ) 1126 let g:pum_pos = pum_getpos() 1127 return '' 1128endfunction 1129 1130func Test_pum_getpos() 1131 new 1132 inoremap <buffer><F5> <C-R>=GetPumPosition()<CR> 1133 setlocal completefunc=UserDefinedComplete 1134 1135 let d = { 1136 \ 'height': 5, 1137 \ 'width': 15, 1138 \ 'row': 1, 1139 \ 'col': 0, 1140 \ 'size': 5, 1141 \ 'scrollbar': v:false, 1142 \ } 1143 call feedkeys("i\<C-X>\<C-U>\<F5>", 'tx') 1144 call assert_equal(d, g:pum_pos) 1145 1146 call assert_false( pumvisible() ) 1147 call assert_equal( {}, pum_getpos() ) 1148 bw! 1149 unlet g:pum_pos 1150endfunc 1151 1152" Test for the popup menu with the 'rightleft' option set 1153func Test_pum_rightleft() 1154 CheckFeature rightleft 1155 CheckScreendump 1156 1157 let lines =<< trim END 1158 abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz 1159 vim 1160 victory 1161 END 1162 call writefile(lines, 'Xtest1') 1163 let buf = RunVimInTerminal('--cmd "set rightleft" Xtest1', {}) 1164 call term_wait(buf) 1165 call term_sendkeys(buf, "Go\<C-P>") 1166 call term_wait(buf) 1167 call VerifyScreenDump(buf, 'Test_pum_rightleft_01', {'rows': 8}) 1168 call term_sendkeys(buf, "\<C-P>\<C-Y>") 1169 call term_wait(buf) 1170 redraw! 1171 call assert_match('\s*miv', Screenline(5)) 1172 1173 " Test for expanding tabs to spaces in the popup menu 1174 let lines =<< trim END 1175 one two 1176 one three 1177 four 1178 END 1179 call writefile(lines, 'Xtest2') 1180 call term_sendkeys(buf, "\<Esc>:e! Xtest2\<CR>") 1181 call term_wait(buf) 1182 call term_sendkeys(buf, "Goone\<C-X>\<C-L>") 1183 call term_wait(buf) 1184 redraw! 1185 call VerifyScreenDump(buf, 'Test_pum_rightleft_02', {'rows': 7}) 1186 call term_sendkeys(buf, "\<C-Y>") 1187 call term_wait(buf) 1188 redraw! 1189 call assert_match('\s*eerht eno', Screenline(4)) 1190 1191 call StopVimInTerminal(buf) 1192 call delete('Xtest1') 1193 call delete('Xtest2') 1194endfunc 1195 1196" Test for a popup menu with a scrollbar 1197func Test_pum_scrollbar() 1198 CheckScreendump 1199 let lines =<< trim END 1200 one 1201 two 1202 three 1203 END 1204 call writefile(lines, 'Xtest1') 1205 let buf = RunVimInTerminal('--cmd "set pumheight=2" Xtest1', {}) 1206 call term_wait(buf) 1207 call term_sendkeys(buf, "Go\<C-P>\<C-P>\<C-P>") 1208 call term_wait(buf) 1209 call VerifyScreenDump(buf, 'Test_pum_scrollbar_01', {'rows': 7}) 1210 call term_sendkeys(buf, "\<C-E>\<Esc>dd") 1211 call term_wait(buf) 1212 1213 if has('rightleft') 1214 call term_sendkeys(buf, ":set rightleft\<CR>") 1215 call term_wait(buf) 1216 call term_sendkeys(buf, "Go\<C-P>\<C-P>\<C-P>") 1217 call term_wait(buf) 1218 call VerifyScreenDump(buf, 'Test_pum_scrollbar_02', {'rows': 7}) 1219 endif 1220 1221 call StopVimInTerminal(buf) 1222 call delete('Xtest1') 1223endfunc 1224 1225" vim: shiftwidth=2 sts=2 expandtab 1226