cmdline_spec.lua (28641B)
1 local n = require('test.functional.testnvim')() 2 local Screen = require('test.functional.ui.screen') 3 4 local clear = n.clear 5 local command = n.command 6 local feed = n.feed 7 local feed_command = n.feed_command 8 local exec = n.exec 9 local api = n.api 10 11 describe('cmdline', function() 12 before_each(clear) 13 14 -- oldtest: Test_cmdlineclear_tabenter() 15 it('is cleared when switching tabs', function() 16 local screen = Screen.new(30, 10) 17 18 feed_command([[call setline(1, range(30))]]) 19 screen:expect([[ 20 ^0 | 21 1 | 22 2 | 23 3 | 24 4 | 25 5 | 26 6 | 27 7 | 28 8 | 29 :call setline(1, range(30)) | 30 ]]) 31 32 feed [[:tabnew<cr>]] 33 screen:expect { 34 grid = [[ 35 {24: + [No Name] }{5: [No Name] }{2: }{24:X}| 36 ^ | 37 {1:~ }|*7 38 :tabnew | 39 ]], 40 } 41 42 feed [[<C-w>-<C-w>-]] 43 screen:expect { 44 grid = [[ 45 {24: + [No Name] }{5: [No Name] }{2: }{24:X}| 46 ^ | 47 {1:~ }|*5 48 |*3 49 ]], 50 } 51 52 feed [[gt]] 53 screen:expect { 54 grid = [[ 55 {5: + [No Name] }{24: [No Name] }{2: }{24:X}| 56 ^0 | 57 1 | 58 2 | 59 3 | 60 4 | 61 5 | 62 6 | 63 7 | 64 | 65 ]], 66 } 67 68 feed [[gt]] 69 screen:expect([[ 70 {24: + [No Name] }{5: [No Name] }{2: }{24:X}| 71 ^ | 72 {1:~ }|*5 73 |*3 74 ]]) 75 end) 76 77 -- oldtest: Test_verbose_option() 78 it('prints every executed Ex command if verbose >= 16', function() 79 local screen = Screen.new(60, 12) 80 exec([[ 81 command DoSomething echo 'hello' |set ts=4 |let v = '123' |echo v 82 call feedkeys("\r", 't') " for the hit-enter prompt 83 set verbose=20 84 ]]) 85 feed_command('DoSomething') 86 screen:expect([[ 87 | 88 {1:~ }|*2 89 {3: }| 90 Executing: DoSomething | 91 Executing: echo 'hello' |set ts=4 |let v = '123' |echo v | 92 hello | 93 Executing: set ts=4 |let v = '123' |echo v | 94 Executing: let v = '123' |echo v | 95 Executing: echo v | 96 123 | 97 {6:Press ENTER or type command to continue}^ | 98 ]]) 99 end) 100 101 -- oldtest: Test_cmdline_redraw_tabline() 102 it('tabline is redrawn on entering cmdline', function() 103 local screen = Screen.new(30, 6) 104 exec([[ 105 set showtabline=2 106 autocmd CmdlineEnter * set tabline=foo 107 ]]) 108 feed(':') 109 screen:expect([[ 110 {2:foo }| 111 | 112 {1:~ }|*3 113 :^ | 114 ]]) 115 end) 116 117 -- oldtest: Test_wildmenu_with_input_func() 118 it('wildmenu works with input() function', function() 119 local screen = Screen.new(60, 8) 120 screen:add_extra_attr_ids({ 121 [100] = { background = Screen.colors.Yellow, foreground = Screen.colors.Black }, 122 }) 123 124 feed(":call input('Command? ', '', 'command')<CR>") 125 screen:expect([[ 126 | 127 {1:~ }|*6 128 Command? ^ | 129 ]]) 130 feed('ech<Tab>') 131 screen:expect([[ 132 | 133 {1:~ }|*5 134 {100:echo}{3: echoerr echohl echomsg echon }| 135 Command? echo^ | 136 ]]) 137 feed('<Space>') 138 screen:expect([[ 139 | 140 {1:~ }|*6 141 Command? echo ^ | 142 ]]) 143 feed('bufn<Tab>') 144 screen:expect([[ 145 | 146 {1:~ }|*5 147 {100:bufname(}{3: bufnr( }| 148 Command? echo bufname(^ | 149 ]]) 150 feed('<CR>') 151 152 command('set wildoptions+=pum') 153 154 feed(":call input('Command? ', '', 'command')<CR>") 155 screen:expect([[ 156 | 157 {1:~ }|*6 158 Command? ^ | 159 ]]) 160 feed('ech<Tab>') 161 screen:expect([[ 162 | 163 {1:~ }| 164 {1:~ }{12: echo }{1: }| 165 {1:~ }{4: echoerr }{1: }| 166 {1:~ }{4: echohl }{1: }| 167 {1:~ }{4: echomsg }{1: }| 168 {1:~ }{4: echon }{1: }| 169 Command? echo^ | 170 ]]) 171 feed('<Space>') 172 screen:expect([[ 173 | 174 {1:~ }|*6 175 Command? echo ^ | 176 ]]) 177 feed('bufn<Tab>') 178 screen:expect([[ 179 | 180 {1:~ }|*4 181 {1:~ }{12: bufname( }{1: }| 182 {1:~ }{4: bufnr( }{1: }| 183 Command? echo bufname(^ | 184 ]]) 185 feed('<CR>') 186 end) 187 188 -- oldtest: Test_redraw_in_autocmd() 189 it('cmdline cursor position is correct after :redraw with cmdheight=2', function() 190 local screen = Screen.new(30, 6) 191 exec([[ 192 set cmdheight=2 193 autocmd CmdlineChanged * redraw 194 ]]) 195 feed(':for i in range(3)<CR>') 196 screen:expect([[ 197 | 198 {1:~ }|*3 199 :for i in range(3) | 200 : ^ | 201 ]]) 202 feed(':let i =') 203 -- Note: this may still be considered broken, ref #18140 204 screen:expect([[ 205 | 206 {1:~ }|*3 207 : :let i =^ | 208 | 209 ]]) 210 end) 211 212 -- oldtest: Test_changing_cmdheight() 213 it("changing 'cmdheight'", function() 214 local screen = Screen.new(60, 8) 215 exec([[ 216 set cmdheight=1 laststatus=2 217 func EchoOne() 218 set laststatus=2 cmdheight=1 219 echo 'foo' 220 echo 'bar' 221 set cmdheight=2 222 endfunc 223 func EchoTwo() 224 set laststatus=2 225 set cmdheight=5 226 echo 'foo' 227 echo 'bar' 228 set cmdheight=1 229 endfunc 230 ]]) 231 232 feed(':resize -3<CR>') 233 screen:expect([[ 234 ^ | 235 {1:~ }|*2 236 {3:[No Name] }| 237 |*4 238 ]]) 239 240 -- :resize now also changes 'cmdheight' accordingly 241 feed(':set cmdheight+=1<CR>') 242 screen:expect([[ 243 ^ | 244 {1:~ }| 245 {3:[No Name] }| 246 |*5 247 ]]) 248 249 -- using more space moves the status line up 250 feed(':set cmdheight+=1<CR>') 251 screen:expect([[ 252 ^ | 253 {3:[No Name] }| 254 |*6 255 ]]) 256 257 -- reducing cmdheight moves status line down 258 feed(':set cmdheight-=3<CR>') 259 screen:expect([[ 260 ^ | 261 {1:~ }|*3 262 {3:[No Name] }| 263 |*3 264 ]]) 265 266 -- reducing window size and then setting cmdheight 267 feed(':resize -1<CR>') 268 feed(':set cmdheight=1<CR>') 269 screen:expect([[ 270 ^ | 271 {1:~ }|*5 272 {3:[No Name] }| 273 | 274 ]]) 275 276 -- setting 'cmdheight' works after outputting two messages 277 feed(':call EchoTwo()') 278 screen:expect([[ 279 | 280 {1:~ }|*5 281 {3:[No Name] }| 282 :call EchoTwo()^ | 283 ]]) 284 feed('<CR>') 285 screen:expect([[ 286 ^ | 287 {1:~ }|*5 288 {3:[No Name] }| 289 | 290 ]]) 291 292 -- increasing 'cmdheight' doesn't clear the messages that need hit-enter 293 feed(':call EchoOne()<CR>') 294 screen:expect([[ 295 | 296 {1:~ }|*3 297 {3: }| 298 foo | 299 bar | 300 {6:Press ENTER or type command to continue}^ | 301 ]]) 302 303 -- window commands do not reduce 'cmdheight' to value lower than :set by user 304 feed('<CR>:wincmd _<CR>') 305 screen:expect([[ 306 ^ | 307 {1:~ }|*4 308 {3:[No Name] }| 309 :wincmd _ | 310 | 311 ]]) 312 end) 313 314 -- oldtest: Test_cmdheight_tabline() 315 it("changing 'cmdheight' when there is a tabline", function() 316 local screen = Screen.new(60, 8) 317 api.nvim_set_option_value('laststatus', 2, {}) 318 api.nvim_set_option_value('showtabline', 2, {}) 319 api.nvim_set_option_value('cmdheight', 1, {}) 320 screen:expect([[ 321 {5: [No Name] }{2: }| 322 ^ | 323 {1:~ }|*4 324 {3:[No Name] }| 325 | 326 ]]) 327 end) 328 329 -- oldtest: Test_wildmenu_with_pum_foldexpr() 330 it('pum when using &foldtext', function() 331 local screen = Screen.new(60, 10) 332 exec([[ 333 call setline(1, ['folded one', 'folded two', 'some more text']) 334 func MyFoldText() 335 return 'foo' 336 endfunc 337 set foldtext=MyFoldText() wildoptions=pum 338 normal ggzfj 339 ]]) 340 feed(':set<Tab>') 341 screen:expect([[ 342 {13:foo·························································}| 343 some more text | 344 {1:~ }|*3 345 {12: set }{1: }| 346 {4: setfiletype }{1: }| 347 {4: setglobal }{1: }| 348 {4: setlocal }{1: }| 349 :set^ | 350 ]]) 351 feed('<Esc>') 352 screen:expect([[ 353 {13:^foo·························································}| 354 some more text | 355 {1:~ }|*7 356 | 357 ]]) 358 end) 359 360 -- oldtest: Test_rulerformat_position() 361 it("ruler has correct position with 'rulerformat' set", function() 362 local screen = Screen.new(20, 3) 363 api.nvim_set_option_value('ruler', true, {}) 364 api.nvim_set_option_value('rulerformat', 'longish', {}) 365 api.nvim_set_option_value('laststatus', 0, {}) 366 api.nvim_set_option_value('winwidth', 1, {}) 367 feed [[<C-W>v<C-W>|<C-W>p]] 368 screen:expect [[ 369 │^ | 370 {1:~ }│{1:~}| 371 longish | 372 ]] 373 end) 374 375 -- oldtest: Test_rulerformat_function() 376 it("'rulerformat' can use %!", function() 377 local screen = Screen.new(40, 2) 378 exec([[ 379 func TestRulerFn() 380 return '10,20%=30%%' 381 endfunc 382 ]]) 383 api.nvim_set_option_value('ruler', true, {}) 384 api.nvim_set_option_value('rulerformat', '%!TestRulerFn()', {}) 385 screen:expect([[ 386 ^ | 387 10,20 30% | 388 ]]) 389 end) 390 391 -- oldtest: Test_search_wildmenu_screendump() 392 it('wildmenu for search completion', function() 393 local screen = Screen.new(60, 10) 394 screen:add_extra_attr_ids({ 395 [100] = { background = Screen.colors.Yellow, foreground = Screen.colors.Black }, 396 }) 397 exec([[ 398 set wildmenu wildcharm=<f5> wildoptions-=pum 399 call setline(1, ['the', 'these', 'the', 'foobar', 'thethe', 'thethere']) 400 ]]) 401 402 -- Pattern has newline at EOF 403 feed('gg2j/e\\n<f5>') 404 screen:expect([[ 405 the | 406 these | 407 the | 408 foobar | 409 thethe | 410 thethere | 411 {1:~ }|*2 412 {100:e\nfoobar}{3: e\nthethere e\nthese e\nthe }| 413 /e\nfoobar^ | 414 ]]) 415 416 -- longest:full 417 feed('<esc>') 418 command('set wim=longest,full') 419 feed('gg/t<f5>') 420 screen:expect([[ 421 the | 422 these | 423 the | 424 foobar | 425 thethe | 426 thethere | 427 {1:~ }|*3 428 /the^ | 429 ]]) 430 431 -- list:full 432 feed('<esc>') 433 command('set wim=list,full') 434 feed('gg/t<f5>') 435 screen:expect([[ 436 {10:t}he | 437 {10:t}hese | 438 {10:t}he | 439 foobar | 440 {10:t}he{10:t}he | 441 {10:t}he{10:t}here | 442 {3: }| 443 /t | 444 these the thethe thethere there | 445 /t^ | 446 ]]) 447 448 -- noselect:full 449 feed('<esc>') 450 command('set wim=noselect,full') 451 feed('gg/t<f5>') 452 screen:expect([[ 453 the | 454 these | 455 the | 456 foobar | 457 thethe | 458 thethere | 459 {1:~ }|*2 460 {3:these the thethe thethere there }| 461 /t^ | 462 ]]) 463 464 -- Multiline 465 feed('<esc>gg/t.*\\n.*\\n.<tab>') 466 screen:expect([[ 467 the | 468 these | 469 the | 470 foobar | 471 thethe | 472 thethere | 473 {1:~ }|*2 474 {3:t.*\n.*\n.oobar t.*\n.*\n.hethe t.*\n.*\n.he }| 475 /t.*\n.*\n.^ | 476 ]]) 477 478 -- 'incsearch' is redrawn after accepting completion 479 feed('<esc>') 480 command('set wim=full') 481 command('set incsearch hlsearch') 482 feed('/th') 483 screen:expect([[ 484 {10:th}e | 485 {2:th}ese | 486 {10:th}e | 487 foobar | 488 {10:th}e{10:th}e | 489 {10:th}e{10:th}ere | 490 {1:~ }|*3 491 /th^ | 492 ]]) 493 feed('<f5>') 494 screen:expect([[ 495 {10:th}e | 496 {2:th}ese | 497 {10:th}e | 498 foobar | 499 {10:th}e{10:th}e | 500 {10:th}e{10:th}ere | 501 {1:~ }|*2 502 {100:these}{3: the thethe thethere there }| 503 /these^ | 504 ]]) 505 feed('<c-n><c-y>') 506 screen:expect([[ 507 {10:the} | 508 {2:the}se | 509 {10:the} | 510 foobar | 511 {10:thethe} | 512 {10:thethe}re | 513 {1:~ }|*3 514 /the^ | 515 ]]) 516 517 -- 'incsearch' highlight is restored after dismissing popup (Ctrl_E) 518 feed('<esc>') 519 command('set wop=pum is nohls') 520 feed('gg/th<tab><c-e>') 521 screen:expect([[ 522 the | 523 {2:th}ese | 524 the | 525 foobar | 526 thethe | 527 thethere | 528 {1:~ }|*3 529 /th^ | 530 ]]) 531 532 feed('<esc>') 533 end) 534 535 -- oldtest: Test_search_wildmenu_iminsert() 536 it('search wildmenu pum with iminsert=1', function() 537 local screen = Screen.new(65, 12) 538 exec([[ 539 set wop=pum imi=1 540 setlocal iskeyword=!-~,192-255 541 call setline(1, [ 542 \ "global toggle global-local global/local glyphs toggles English", 543 \ "accordingly. toggled accordingly single-byte", 544 \ ]) 545 call cursor(2, 42) 546 ]]) 547 feed('/gl<Tab>') 548 screen:expect([[ 549 {12: global }obal-local global/local glyphs toggles English | 550 {4: gle }gled accordingly single-byte | 551 {4: global-local }{1: }| 552 {4: global/local }{1: }| 553 {4: glyphs }{1: }| 554 {4: gles }{1: }| 555 {4: glish }{1: }| 556 {4: gly. }{1: }| 557 {4: gled }{1: }| 558 {4: gly }{1: }| 559 {4: gle-byte }{1: }| 560 /global^ | 561 ]]) 562 end) 563 564 -- oldtest: Test_wildtrigger_update_screen() 565 it('pum by wildtrigger() avoids flicker', function() 566 local screen = Screen.new(40, 10) 567 exec([[ 568 command! -nargs=* -complete=customlist,TestFn TestCmd echo 569 func TestFn(cmdarg, b, c) 570 if a:cmdarg == 'ax' 571 return [] 572 else 573 return map(range(1, 5), 'printf("abc%d", v:val)') 574 endif 575 endfunc 576 set wildmode=noselect,full 577 set wildoptions=pum 578 set wildmenu 579 cnoremap <F8> <C-R>=wildtrigger()[-1]<CR> 580 ]]) 581 582 feed(':TestCmd a<F8>') 583 local s1 = [[ 584 | 585 {1:~ }|*3 586 {1:~ }{4: abc1 }{1: }| 587 {1:~ }{4: abc2 }{1: }| 588 {1:~ }{4: abc3 }{1: }| 589 {1:~ }{4: abc4 }{1: }| 590 {1:~ }{4: abc5 }{1: }| 591 :TestCmd a^ | 592 ]] 593 screen:expect(s1) 594 595 -- Typing a character when pum is open does not close the pum window 596 -- This is needed to prevent pum window from flickering during 597 -- ':h cmdline-autocompletion'. 598 feed('x') 599 local s2 = [[ 600 | 601 {1:~ }|*3 602 {1:~ }{4: abc1 }{1: }| 603 {1:~ }{4: abc2 }{1: }| 604 {1:~ }{4: abc3 }{1: }| 605 {1:~ }{4: abc4 }{1: }| 606 {1:~ }{4: abc5 }{1: }| 607 :TestCmd ax^ | 608 ]] 609 screen:expect(s2) 610 611 -- pum is closed when no completion candidates are available 612 feed('<F8>') 613 local s3 = [[ 614 | 615 {1:~ }|*8 616 :TestCmd ax^ | 617 ]] 618 screen:expect(s3) 619 620 feed('<BS><F8>') 621 screen:expect(s1) 622 623 feed('x') 624 screen:expect(s2) 625 626 -- pum is closed when leaving cmdline mode 627 feed('<Esc>') 628 screen:expect([[ 629 ^ | 630 {1:~ }|*8 631 | 632 ]]) 633 634 feed(':TestCmd a<F8>') 635 screen:expect(s1) 636 command('redraw') 637 screen:expect_unchanged() 638 feed('x') 639 screen:expect(s2) 640 -- outdated pum is closed by :redraw #36808 641 command('redraw') 642 screen:expect(s3) 643 end) 644 645 -- oldtest: Test_long_line_noselect() 646 it("long line is shown properly with noselect in 'wildmode'", function() 647 local screen = Screen.new(60, 8) 648 exec([[ 649 set wildmenu wildoptions=pum wildmode=noselect,full 650 command -nargs=1 -complete=custom,Entries DoubleEntry echo 651 func Entries(a, b, c) 652 return 'loooooooooooooooong quite loooooooooooong, really loooooooooooong, probably too looooooooooooooooooooooooooong entry' 653 endfunc 654 ]]) 655 656 feed(':DoubleEntry <Tab>') 657 screen:expect([[ 658 | 659 {1:~ }|*5 660 {1:~ }{4: loooooooooooooooong quite loooooooooooong, rea>}| 661 :DoubleEntry ^ | 662 ]]) 663 664 feed('<C-N>') 665 screen:expect([[ 666 | 667 {1:~ }|*3 668 {3: }| 669 :DoubleEntry loooooooooooooooong quite loooooooooooong, real| 670 ly loooooooo{12: loooooooooooooooong quite loooooooooooong, rea>}| 671 ong entry^ | 672 ]]) 673 674 feed('<C-N>') 675 screen:expect([[ 676 | 677 {1:~ }|*3 678 {3: }{4: loooooooooooooooong quite loooooooooooong, rea>}| 679 :DoubleEntry ^ | 680 |*2 681 ]]) 682 683 feed('<Esc>') 684 end) 685 686 -- oldtest: Test_update_screen_after_wildtrigger() 687 it('pum is dismissed after wildtrigger() and whitespace', function() 688 local screen = Screen.new(40, 10) 689 exec([[ 690 set wildmode=noselect:lastused,full wildmenu wildoptions=pum 691 autocmd CmdlineChanged : if getcmdcompltype() != 'shellcmd' | call wildtrigger() | endif 692 ]]) 693 694 feed(':term') 695 screen:expect([[ 696 | 697 {1:~ }|*7 698 {4: terminal }{1: }| 699 :term^ | 700 ]]) 701 feed(' ') 702 screen:expect([[ 703 | 704 {1:~ }|*8 705 :term ^ | 706 ]]) 707 feed('foo') 708 screen:expect([[ 709 | 710 {1:~ }|*8 711 :term foo^ | 712 ]]) 713 end) 714 end)