messages_spec.lua (43732B)
1 local t = require('test.testutil') 2 local n = require('test.functional.testnvim')() 3 local Screen = require('test.functional.ui.screen') 4 5 local clear = n.clear 6 local command = n.command 7 local exec = n.exec 8 local feed = n.feed 9 local api = n.api 10 local fn = n.fn 11 local nvim_dir = n.nvim_dir 12 local assert_alive = n.assert_alive 13 14 before_each(clear) 15 16 describe('messages', function() 17 local screen 18 19 -- oldtest: Test_warning_scroll() 20 it('a warning causes scrolling if and only if it has a stacktrace', function() 21 screen = Screen.new(75, 6) 22 23 -- When the warning comes from a script, messages are scrolled so that the 24 -- stacktrace is visible. 25 -- It is a bit hard to assert the screen when sourcing a script, so skip this part. 26 27 -- When the warning does not come from a script, messages are not scrolled. 28 command('enew') 29 command('set readonly') 30 feed('u') 31 screen:expect({ 32 grid = [[ 33 | 34 {1:~ }|*4 35 {19:W10: Warning: Changing a readonly file}^ | 36 ]], 37 timeout = 500, 38 }) 39 screen:expect([[ 40 ^ | 41 {1:~ }|*4 42 Already at oldest change | 43 ]]) 44 end) 45 46 -- oldtest: Test_message_not_cleared_after_mode() 47 it('clearing mode does not remove message', function() 48 screen = Screen.new(60, 10) 49 exec([[ 50 nmap <silent> gx :call DebugSilent('normal')<CR> 51 vmap <silent> gx :call DebugSilent('visual')<CR> 52 function DebugSilent(arg) 53 echomsg "from DebugSilent" a:arg 54 endfunction 55 set showmode 56 set cmdheight=1 57 call setline(1, ['one', 'NoSuchFile', 'three']) 58 ]]) 59 60 feed('gx') 61 screen:expect([[ 62 ^one | 63 NoSuchFile | 64 three | 65 {1:~ }|*6 66 from DebugSilent normal | 67 ]]) 68 69 -- removing the mode message used to also clear the intended message 70 feed('vEgx') 71 screen:expect([[ 72 ^one | 73 NoSuchFile | 74 three | 75 {1:~ }|*6 76 from DebugSilent visual | 77 ]]) 78 79 -- removing the mode message used to also clear the error message 80 command('set cmdheight=2') 81 feed('2GvEgf') 82 screen:expect([[ 83 one | 84 NoSuchFil^e | 85 three | 86 {1:~ }|*5 87 | 88 {9:E447: Can't find file "NoSuchFile" in path} | 89 ]]) 90 end) 91 92 -- oldtest: Test_mode_cleared_after_silent_message() 93 it('mode is cleared properly after silent message', function() 94 screen = Screen.new(60, 10) 95 exec([[ 96 edit XsilentMessageMode.txt 97 call setline(1, 'foobar') 98 autocmd TextChanged * silent update 99 ]]) 100 finally(function() 101 os.remove('XsilentMessageMode.txt') 102 end) 103 104 feed('v') 105 screen:expect([[ 106 ^foobar | 107 {1:~ }|*8 108 {5:-- VISUAL --} | 109 ]]) 110 111 feed('d') 112 screen:expect([[ 113 ^oobar | 114 {1:~ }|*8 115 | 116 ]]) 117 end) 118 119 describe('more prompt', function() 120 before_each(function() 121 command('set more') 122 end) 123 124 -- oldtest: Test_message_more() 125 it('works', function() 126 screen = Screen.new(75, 6) 127 128 command('call setline(1, range(1, 100))') 129 130 feed(':%pfoo<C-H><C-H><C-H>#') 131 screen:expect([[ 132 1 | 133 2 | 134 3 | 135 4 | 136 5 | 137 :%p#^ | 138 ]]) 139 feed('\n') 140 screen:expect([[ 141 {8: 1 }1 | 142 {8: 2 }2 | 143 {8: 3 }3 | 144 {8: 4 }4 | 145 {8: 5 }5 | 146 {6:-- More --}^ | 147 ]]) 148 149 feed('?') 150 screen:expect([[ 151 {8: 1 }1 | 152 {8: 2 }2 | 153 {8: 3 }3 | 154 {8: 4 }4 | 155 {8: 5 }5 | 156 {6:-- More -- SPACE/d/j: screen/page/line down, b/u/k: up, q: quit }^ | 157 ]]) 158 159 -- Down a line with j, <CR>, <NL> or <Down>. 160 feed('j') 161 screen:expect([[ 162 {8: 2 }2 | 163 {8: 3 }3 | 164 {8: 4 }4 | 165 {8: 5 }5 | 166 {8: 6 }6 | 167 {6:-- More --}^ | 168 ]]) 169 feed('<NL>') 170 screen:expect([[ 171 {8: 3 }3 | 172 {8: 4 }4 | 173 {8: 5 }5 | 174 {8: 6 }6 | 175 {8: 7 }7 | 176 {6:-- More --}^ | 177 ]]) 178 feed('<CR>') 179 screen:expect([[ 180 {8: 4 }4 | 181 {8: 5 }5 | 182 {8: 6 }6 | 183 {8: 7 }7 | 184 {8: 8 }8 | 185 {6:-- More --}^ | 186 ]]) 187 feed('<Down>') 188 screen:expect([[ 189 {8: 5 }5 | 190 {8: 6 }6 | 191 {8: 7 }7 | 192 {8: 8 }8 | 193 {8: 9 }9 | 194 {6:-- More --}^ | 195 ]]) 196 197 -- Down a screen with <Space>, f, <C-F>, or <PageDown>. 198 feed('f') 199 screen:expect([[ 200 {8: 10 }10 | 201 {8: 11 }11 | 202 {8: 12 }12 | 203 {8: 13 }13 | 204 {8: 14 }14 | 205 {6:-- More --}^ | 206 ]]) 207 feed('\6') 208 screen:expect([[ 209 {8: 15 }15 | 210 {8: 16 }16 | 211 {8: 17 }17 | 212 {8: 18 }18 | 213 {8: 19 }19 | 214 {6:-- More --}^ | 215 ]]) 216 feed(' ') 217 screen:expect([[ 218 {8: 20 }20 | 219 {8: 21 }21 | 220 {8: 22 }22 | 221 {8: 23 }23 | 222 {8: 24 }24 | 223 {6:-- More --}^ | 224 ]]) 225 feed('<PageDown>') 226 screen:expect([[ 227 {8: 25 }25 | 228 {8: 26 }26 | 229 {8: 27 }27 | 230 {8: 28 }28 | 231 {8: 29 }29 | 232 {6:-- More --}^ | 233 ]]) 234 235 -- Down a page (half a screen) with d. 236 feed('d') 237 screen:expect([[ 238 {8: 28 }28 | 239 {8: 29 }29 | 240 {8: 30 }30 | 241 {8: 31 }31 | 242 {8: 32 }32 | 243 {6:-- More --}^ | 244 ]]) 245 246 -- Down all the way with 'G'. 247 feed('G') 248 screen:expect([[ 249 {8: 96 }96 | 250 {8: 97 }97 | 251 {8: 98 }98 | 252 {8: 99 }99 | 253 {8:100 }100 | 254 {6:Press ENTER or type command to continue}^ | 255 ]]) 256 257 -- Up a line k, <BS> or <Up>. 258 feed('k') 259 screen:expect([[ 260 {8: 95 }95 | 261 {8: 96 }96 | 262 {8: 97 }97 | 263 {8: 98 }98 | 264 {8: 99 }99 | 265 {6:-- More --}^ | 266 ]]) 267 feed('<BS>') 268 screen:expect([[ 269 {8: 94 }94 | 270 {8: 95 }95 | 271 {8: 96 }96 | 272 {8: 97 }97 | 273 {8: 98 }98 | 274 {6:-- More --}^ | 275 ]]) 276 feed('<Up>') 277 screen:expect([[ 278 {8: 93 }93 | 279 {8: 94 }94 | 280 {8: 95 }95 | 281 {8: 96 }96 | 282 {8: 97 }97 | 283 {6:-- More --}^ | 284 ]]) 285 286 -- Up a screen with b, <C-B> or <PageUp>. 287 feed('b') 288 screen:expect([[ 289 {8: 88 }88 | 290 {8: 89 }89 | 291 {8: 90 }90 | 292 {8: 91 }91 | 293 {8: 92 }92 | 294 {6:-- More --}^ | 295 ]]) 296 feed('\2') 297 screen:expect([[ 298 {8: 83 }83 | 299 {8: 84 }84 | 300 {8: 85 }85 | 301 {8: 86 }86 | 302 {8: 87 }87 | 303 {6:-- More --}^ | 304 ]]) 305 feed('<PageUp>') 306 screen:expect([[ 307 {8: 78 }78 | 308 {8: 79 }79 | 309 {8: 80 }80 | 310 {8: 81 }81 | 311 {8: 82 }82 | 312 {6:-- More --}^ | 313 ]]) 314 315 -- Up a page (half a screen) with u. 316 feed('u') 317 screen:expect([[ 318 {8: 75 }75 | 319 {8: 76 }76 | 320 {8: 77 }77 | 321 {8: 78 }78 | 322 {8: 79 }79 | 323 {6:-- More --}^ | 324 ]]) 325 326 -- Test <C-F> and <C-B> as keycodes instead of raw control chars. 327 feed('<C-F>') 328 screen:expect([[ 329 {8: 80 }80 | 330 {8: 81 }81 | 331 {8: 82 }82 | 332 {8: 83 }83 | 333 {8: 84 }84 | 334 {6:-- More --}^ | 335 ]]) 336 feed('<C-B>') 337 screen:expect([[ 338 {8: 75 }75 | 339 {8: 76 }76 | 340 {8: 77 }77 | 341 {8: 78 }78 | 342 {8: 79 }79 | 343 {6:-- More --}^ | 344 ]]) 345 346 -- Up all the way with 'g'. 347 feed('g') 348 screen:expect([[ 349 :%p# | 350 {8: 1 }1 | 351 {8: 2 }2 | 352 {8: 3 }3 | 353 {8: 4 }4 | 354 {6:-- More --}^ | 355 ]]) 356 357 -- All the way down. Pressing f or CTRL-F should do nothing but pressing 358 -- space should end the more prompt. 359 feed('G') 360 screen:expect([[ 361 {8: 96 }96 | 362 {8: 97 }97 | 363 {8: 98 }98 | 364 {8: 99 }99 | 365 {8:100 }100 | 366 {6:Press ENTER or type command to continue}^ | 367 ]]) 368 feed('f') 369 screen:expect_unchanged() 370 feed('<C-F>') 371 screen:expect_unchanged() 372 feed('<Space>') 373 screen:expect([[ 374 96 | 375 97 | 376 98 | 377 99 | 378 ^100 | 379 | 380 ]]) 381 382 -- Pressing g< shows the previous command output. 383 feed('g<lt>') 384 screen:expect([[ 385 {8: 96 }96 | 386 {8: 97 }97 | 387 {8: 98 }98 | 388 {8: 99 }99 | 389 {8:100 }100 | 390 {6:Press ENTER or type command to continue}^ | 391 ]]) 392 393 -- A command line that doesn't print text is appended to scrollback, 394 -- even if it invokes a nested command line. 395 feed([[:<C-R>=':'<CR>:<CR>g<lt>]]) 396 screen:expect([[ 397 {8: 97 }97 | 398 {8: 98 }98 | 399 {8: 99 }99 | 400 {8:100 }100 | 401 ::: | 402 {6:Press ENTER or type command to continue}^ | 403 ]]) 404 405 feed(':%p#\n') 406 screen:expect([[ 407 {8: 1 }1 | 408 {8: 2 }2 | 409 {8: 3 }3 | 410 {8: 4 }4 | 411 {8: 5 }5 | 412 {6:-- More --}^ | 413 ]]) 414 415 -- Stop command output with q, <Esc> or CTRL-C. 416 feed('q') 417 screen:expect([[ 418 96 | 419 97 | 420 98 | 421 99 | 422 ^100 | 423 | 424 ]]) 425 426 -- Execute a : command from the more prompt 427 feed(':%p#\n') 428 screen:expect([[ 429 {8: 1 }1 | 430 {8: 2 }2 | 431 {8: 3 }3 | 432 {8: 4 }4 | 433 {8: 5 }5 | 434 {6:-- More --}^ | 435 ]]) 436 feed(':') 437 screen:expect([[ 438 {8: 1 }1 | 439 {8: 2 }2 | 440 {8: 3 }3 | 441 {8: 4 }4 | 442 {8: 5 }5 | 443 :^ | 444 ]]) 445 feed("echo 'Hello'\n") 446 screen:expect([[ 447 {8: 2 }2 | 448 {8: 3 }3 | 449 {8: 4 }4 | 450 {8: 5 }5 | 451 Hello | 452 {6:Press ENTER or type command to continue}^ | 453 ]]) 454 end) 455 456 -- oldtest: Test_message_more_recording() 457 it("hitting 'q' at hit-enter prompt does not start recording", function() 458 screen = Screen.new(60, 6) 459 command('call setline(1, range(1, 100))') 460 feed(':%p\n') 461 screen:expect([[ 462 1 | 463 2 | 464 3 | 465 4 | 466 5 | 467 {6:-- More --}^ | 468 ]]) 469 feed('G') 470 screen:expect([[ 471 96 | 472 97 | 473 98 | 474 99 | 475 100 | 476 {6:Press ENTER or type command to continue}^ | 477 ]]) 478 479 -- Hitting 'q' at the end of the more prompt should not start recording 480 feed('q') 481 screen:expect([[ 482 96 | 483 97 | 484 98 | 485 99 | 486 ^100 | 487 | 488 ]]) 489 -- Hitting 'k' now should move the cursor up instead of recording keys 490 feed('k') 491 screen:expect([[ 492 96 | 493 97 | 494 98 | 495 ^99 | 496 100 | 497 | 498 ]]) 499 end) 500 501 -- oldtest: Test_echo_verbose_system() 502 it('verbose message before echo command', function() 503 screen = Screen.new(60, 10) 504 505 command('cd ' .. nvim_dir) 506 api.nvim_set_option_value('shell', './shell-test', {}) 507 api.nvim_set_option_value('shellcmdflag', 'REP 20', {}) 508 api.nvim_set_option_value('shellxquote', '', {}) -- win: avoid extra quotes 509 510 -- display a page and go back, results in exactly the same view 511 feed([[:4 verbose echo system('foo')<CR>]]) 512 screen:expect([[ 513 Executing command: "'./shell-test' 'REP' '20' 'foo'" | 514 | 515 0: foo | 516 1: foo | 517 2: foo | 518 3: foo | 519 4: foo | 520 5: foo | 521 6: foo | 522 {6:-- More --}^ | 523 ]]) 524 feed('<Space>') 525 screen:expect([[ 526 7: foo | 527 8: foo | 528 9: foo | 529 10: foo | 530 11: foo | 531 12: foo | 532 13: foo | 533 14: foo | 534 15: foo | 535 {6:-- More --}^ | 536 ]]) 537 feed('b') 538 screen:expect([[ 539 Executing command: "'./shell-test' 'REP' '20' 'foo'" | 540 | 541 0: foo | 542 1: foo | 543 2: foo | 544 3: foo | 545 4: foo | 546 5: foo | 547 6: foo | 548 {6:-- More --}^ | 549 ]]) 550 551 -- do the same with 'cmdheight' set to 2 552 feed('q') 553 command('set ch=2') 554 screen:expect([[ 555 ^ | 556 {1:~ }|*7 557 |*2 558 ]]) 559 feed([[:4 verbose echo system('foo')<CR>]]) 560 screen:expect([[ 561 Executing command: "'./shell-test' 'REP' '20' 'foo'" | 562 | 563 0: foo | 564 1: foo | 565 2: foo | 566 3: foo | 567 4: foo | 568 5: foo | 569 6: foo | 570 {6:-- More --}^ | 571 ]]) 572 feed('<Space>') 573 screen:expect([[ 574 7: foo | 575 8: foo | 576 9: foo | 577 10: foo | 578 11: foo | 579 12: foo | 580 13: foo | 581 14: foo | 582 15: foo | 583 {6:-- More --}^ | 584 ]]) 585 feed('b') 586 screen:expect([[ 587 Executing command: "'./shell-test' 'REP' '20' 'foo'" | 588 | 589 0: foo | 590 1: foo | 591 2: foo | 592 3: foo | 593 4: foo | 594 5: foo | 595 6: foo | 596 {6:-- More --}^ | 597 ]]) 598 end) 599 600 -- oldtest: Test_quit_long_message() 601 it('with control characters can be quit vim-patch:8.2.1844', function() 602 screen = Screen.new(40, 10) 603 604 feed([[:echom range(9999)->join("\x01")<CR>]]) 605 screen:expect([[ 606 0{18:^A}1{18:^A}2{18:^A}3{18:^A}4{18:^A}5{18:^A}6{18:^A}7{18:^A}8{18:^A}9{18:^A}10{18:^A}11{18:^A}12| 607 {18:^A}13{18:^A}14{18:^A}15{18:^A}16{18:^A}17{18:^A}18{18:^A}19{18:^A}20{18:^A}21{18:^A}22| 608 {18:^A}23{18:^A}24{18:^A}25{18:^A}26{18:^A}27{18:^A}28{18:^A}29{18:^A}30{18:^A}31{18:^A}32| 609 {18:^A}33{18:^A}34{18:^A}35{18:^A}36{18:^A}37{18:^A}38{18:^A}39{18:^A}40{18:^A}41{18:^A}42| 610 {18:^A}43{18:^A}44{18:^A}45{18:^A}46{18:^A}47{18:^A}48{18:^A}49{18:^A}50{18:^A}51{18:^A}52| 611 {18:^A}53{18:^A}54{18:^A}55{18:^A}56{18:^A}57{18:^A}58{18:^A}59{18:^A}60{18:^A}61{18:^A}62| 612 {18:^A}63{18:^A}64{18:^A}65{18:^A}66{18:^A}67{18:^A}68{18:^A}69{18:^A}70{18:^A}71{18:^A}72| 613 {18:^A}73{18:^A}74{18:^A}75{18:^A}76{18:^A}77{18:^A}78{18:^A}79{18:^A}80{18:^A}81{18:^A}82| 614 {18:^A}83{18:^A}84{18:^A}85{18:^A}86{18:^A}87{18:^A}88{18:^A}89{18:^A}90{18:^A}91{18:^A}92| 615 {6:-- More --}^ | 616 ]]) 617 feed('q') 618 screen:expect([[ 619 ^ | 620 {1:~ }|*8 621 | 622 ]]) 623 end) 624 end) 625 626 describe('mode is cleared when', function() 627 before_each(function() 628 screen = Screen.new(40, 6) 629 end) 630 631 -- oldtest: Test_mode_message_at_leaving_insert_by_ctrl_c() 632 it('leaving Insert mode with Ctrl-C vim-patch:8.1.1189', function() 633 exec([[ 634 func StatusLine() abort 635 return "" 636 endfunc 637 set statusline=%!StatusLine() 638 set laststatus=2 639 ]]) 640 feed('i') 641 screen:expect([[ 642 ^ | 643 {1:~ }|*3 644 {3: }| 645 {5:-- INSERT --} | 646 ]]) 647 feed('<C-C>') 648 screen:expect([[ 649 ^ | 650 {1:~ }|*3 651 {3: }| 652 | 653 ]]) 654 end) 655 656 -- oldtest: Test_mode_message_at_leaving_insert_with_esc_mapped() 657 it('leaving Insert mode with ESC in the middle of a mapping vim-patch:8.1.1192', function() 658 exec([[ 659 set laststatus=2 660 inoremap <Esc> <Esc>00 661 ]]) 662 feed('i') 663 screen:expect([[ 664 ^ | 665 {1:~ }|*3 666 {3:[No Name] }| 667 {5:-- INSERT --} | 668 ]]) 669 feed('<Esc>') 670 screen:expect([[ 671 ^ | 672 {1:~ }|*3 673 {3:[No Name] }| 674 | 675 ]]) 676 end) 677 678 -- oldtest: Test_mode_updated_after_ctrl_c() 679 it('pressing Ctrl-C in i_CTRL-O', function() 680 feed('i<C-O>') 681 screen:expect([[ 682 ^ | 683 {1:~ }|*4 684 {5:-- (insert) --} | 685 ]]) 686 feed('<C-C>') 687 screen:expect([[ 688 ^ | 689 {1:~ }|*4 690 | 691 ]]) 692 end) 693 end) 694 695 -- oldtest: Test_ask_yesno() 696 it('y/n prompt works', function() 697 screen = Screen.new(75, 6) 698 command('set noincsearch nohlsearch inccommand=') 699 command('call setline(1, range(1, 2))') 700 701 feed(':2,1s/^/n/\n') 702 screen:expect([[ 703 1 | 704 2 | 705 {1:~ }|*3 706 {6:Backwards range given, OK to swap (y/n)?}^ | 707 ]]) 708 feed('n') 709 screen:expect([[ 710 ^1 | 711 2 | 712 {1:~ }|*3 713 {6:Backwards range given, OK to swap (y/n)?}n | 714 ]]) 715 716 feed(':2,1s/^/Esc/\n') 717 screen:expect([[ 718 1 | 719 2 | 720 {1:~ }|*3 721 {6:Backwards range given, OK to swap (y/n)?}^ | 722 ]]) 723 feed('<Esc>') 724 screen:expect([[ 725 ^1 | 726 2 | 727 {1:~ }|*3 728 {6:Backwards range given, OK to swap (y/n)?}n | 729 ]]) 730 731 feed(':2,1s/^/y/\n') 732 screen:expect([[ 733 1 | 734 2 | 735 {1:~ }|*3 736 {6:Backwards range given, OK to swap (y/n)?}^ | 737 ]]) 738 feed('y') 739 screen:expect([[ 740 y1 | 741 ^y2 | 742 {1:~ }|*3 743 {6:Backwards range given, OK to swap (y/n)?}y | 744 ]]) 745 end) 746 747 -- oldtest: Test_fileinfo_tabpage_cmdheight() 748 it("fileinfo works when 'cmdheight' has just decreased", function() 749 screen = Screen.new(40, 6) 750 751 exec([[ 752 set shortmess-=o 753 set shortmess-=O 754 set shortmess-=F 755 tabnew 756 set cmdheight=2 757 ]]) 758 screen:expect([[ 759 {24: [No Name] }{5: [No Name] }{2: }{24:X}| 760 ^ | 761 {1:~ }|*2 762 |*2 763 ]]) 764 765 feed(':tabprev | edit Xfileinfo.txt<CR>') 766 screen:expect([[ 767 {5: Xfileinfo.txt }{24: [No Name] }{2: }{24:X}| 768 ^ | 769 {1:~ }|*3 770 "Xfileinfo.txt" [New] | 771 ]]) 772 assert_alive() 773 end) 774 775 -- oldtest: Test_fileinfo_after_echo() 776 it('fileinfo does not overwrite echo message vim-patch:8.2.4156', function() 777 screen = Screen.new(40, 6) 778 779 exec([[ 780 set shortmess-=F 781 782 file a.txt 783 784 hide edit b.txt 785 call setline(1, "hi") 786 setlocal modified 787 788 hide buffer a.txt 789 790 autocmd CursorHold * buf b.txt | w | echo "'b' written" 791 ]]) 792 793 command('set updatetime=50') 794 feed('0$') 795 screen:expect([[ 796 ^hi | 797 {1:~ }|*4 798 'b' written | 799 ]]) 800 os.remove('b.txt') 801 end) 802 803 -- oldtest: Test_messagesopt_wait() 804 it('&messagesopt "wait"', function() 805 screen = Screen.new(45, 6) 806 command('set cmdheight=1') 807 808 -- Check hit-enter prompt 809 command('set messagesopt=hit-enter,history:500') 810 feed(":echo 'foo' | echo 'bar' | echo 'baz'\n") 811 screen:expect([[ 812 | 813 {3: }| 814 foo | 815 bar | 816 baz | 817 {6:Press ENTER or type command to continue}^ | 818 ]]) 819 feed('<CR>') 820 821 -- Check no hit-enter prompt when "wait:" is set 822 command('set messagesopt=wait:500,history:500') 823 feed(":echo 'foo' | echo 'bar' | echo 'baz'\n") 824 screen:expect({ 825 grid = [[ 826 | 827 {1:~ }| 828 {3: }| 829 foo | 830 bar | 831 baz | 832 ]], 833 timeout = 500, 834 }) 835 screen:expect([[ 836 ^ | 837 {1:~ }|*4 838 | 839 ]]) 840 end) 841 842 -- oldtest: Test_long_formatprg_no_hit_enter() 843 it("long 'formatprg' doesn't cause hit-enter prompt or wrong cursor pos", function() 844 t.skip(fn.executable('sed') == 0, 'missing "sed" command') 845 846 screen = Screen.new(75, 10) 847 exec([[ 848 setlocal scrolloff=0 849 call setline(1, range(1, 40)) 850 let &l:formatprg = $'sed{repeat(' ', &columns)}p' 851 normal 20Gmz 852 normal 10Gzt 853 ]]) 854 screen:expect([[ 855 ^10 | 856 11 | 857 12 | 858 13 | 859 14 | 860 15 | 861 16 | 862 17 | 863 18 | 864 | 865 ]]) 866 feed('gq2j') 867 screen:expect([[ 868 10 |*2 869 11 |*2 870 12 | 871 ^12 | 872 13 | 873 14 | 874 15 | 875 | 876 ]]) 877 feed(':messages<CR>') 878 screen:expect([[ 879 10 |*2 880 11 |*2 881 12 | 882 ^12 | 883 13 | 884 14 | 885 15 | 886 3 lines filtered | 887 ]]) 888 end) 889 end)