conceal_spec.lua (39141B)
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 11 local expect_pos = function(row, col) 12 return t.eq({ row, col }, n.eval('[screenrow(), screencol()]')) 13 end 14 15 describe('Conceal', function() 16 before_each(function() 17 clear() 18 command('set nohlsearch') 19 end) 20 21 -- oldtest: Test_conceal_two_windows() 22 it('works', function() 23 local screen = Screen.new(75, 12) 24 exec([[ 25 let lines = ["one one one one one", "two |hidden| here", "three |hidden| three"] 26 call setline(1, lines) 27 syntax match test /|hidden|/ conceal 28 set conceallevel=2 29 set concealcursor= 30 exe "normal /here\r" 31 new 32 call setline(1, lines) 33 call setline(4, "Second window") 34 syntax match test /|hidden|/ conceal 35 set conceallevel=2 36 set concealcursor=nc 37 exe "normal /here\r" 38 ]]) 39 40 -- Check that cursor line is concealed 41 screen:expect([[ 42 one one one one one | 43 two ^here | 44 three three | 45 Second window | 46 {1:~ }| 47 {3:[No Name] [+] }| 48 one one one one one | 49 two here | 50 three three | 51 {1:~ }| 52 {2:[No Name] [+] }| 53 /here | 54 ]]) 55 56 -- Check that with concealed text vertical cursor movement is correct. 57 feed('k') 58 screen:expect([[ 59 one one one o^ne one | 60 two here | 61 three three | 62 Second window | 63 {1:~ }| 64 {3:[No Name] [+] }| 65 one one one one one | 66 two here | 67 three three | 68 {1:~ }| 69 {2:[No Name] [+] }| 70 /here | 71 ]]) 72 73 -- Check that with cursor line is not concealed 74 feed('j') 75 command('set concealcursor=') 76 screen:expect([[ 77 one one one one one | 78 two |hidden| ^here | 79 three three | 80 Second window | 81 {1:~ }| 82 {3:[No Name] [+] }| 83 one one one one one | 84 two here | 85 three three | 86 {1:~ }| 87 {2:[No Name] [+] }| 88 /here | 89 ]]) 90 91 -- Check that with cursor line is not concealed when moving cursor down 92 feed('j') 93 screen:expect([[ 94 one one one one one | 95 two here | 96 three |hidden^| three | 97 Second window | 98 {1:~ }| 99 {3:[No Name] [+] }| 100 one one one one one | 101 two here | 102 three three | 103 {1:~ }| 104 {2:[No Name] [+] }| 105 /here | 106 ]]) 107 108 -- Check that with cursor line is not concealed when switching windows 109 feed('<C-W><C-W>') 110 screen:expect([[ 111 one one one one one | 112 two here | 113 three three | 114 Second window | 115 {1:~ }| 116 {2:[No Name] [+] }| 117 one one one one one | 118 two |hidden| ^here | 119 three three | 120 {1:~ }| 121 {3:[No Name] [+] }| 122 /here | 123 ]]) 124 125 -- Check that with cursor line is only concealed in Normal mode 126 command('set concealcursor=n') 127 screen:expect([[ 128 one one one one one | 129 two here | 130 three three | 131 Second window | 132 {1:~ }| 133 {2:[No Name] [+] }| 134 one one one one one | 135 two ^here | 136 three three | 137 {1:~ }| 138 {3:[No Name] [+] }| 139 /here | 140 ]]) 141 feed('a') 142 screen:expect([[ 143 one one one one one | 144 two here | 145 three three | 146 Second window | 147 {1:~ }| 148 {2:[No Name] [+] }| 149 one one one one one | 150 two |hidden| h^ere | 151 three three | 152 {1:~ }| 153 {3:[No Name] [+] }| 154 {5:-- INSERT --} | 155 ]]) 156 feed('<Esc>/e') 157 screen:expect([[ 158 one one one one one | 159 two here | 160 three three | 161 Second window | 162 {1:~ }| 163 {2:[No Name] [+] }| 164 one one one one one | 165 two |hidden| h{2:e}re | 166 three three | 167 {1:~ }| 168 {3:[No Name] [+] }| 169 /e^ | 170 ]]) 171 feed('<Esc>v') 172 screen:expect([[ 173 one one one one one | 174 two here | 175 three three | 176 Second window | 177 {1:~ }| 178 {2:[No Name] [+] }| 179 one one one one one | 180 two |hidden| ^here | 181 three three | 182 {1:~ }| 183 {3:[No Name] [+] }| 184 {5:-- VISUAL --} | 185 ]]) 186 feed('<Esc>') 187 188 -- Check that with cursor line is only concealed in Insert mode 189 command('set concealcursor=i') 190 screen:expect([[ 191 one one one one one | 192 two here | 193 three three | 194 Second window | 195 {1:~ }| 196 {2:[No Name] [+] }| 197 one one one one one | 198 two |hidden| ^here | 199 three three | 200 {1:~ }| 201 {3:[No Name] [+] }| 202 | 203 ]]) 204 feed('a') 205 screen:expect([[ 206 one one one one one | 207 two here | 208 three three | 209 Second window | 210 {1:~ }| 211 {2:[No Name] [+] }| 212 one one one one one | 213 two h^ere | 214 three three | 215 {1:~ }| 216 {3:[No Name] [+] }| 217 {5:-- INSERT --} | 218 ]]) 219 feed('<Esc>/e') 220 screen:expect([[ 221 one one one one one | 222 two here | 223 three three | 224 Second window | 225 {1:~ }| 226 {2:[No Name] [+] }| 227 one one one one one | 228 two |hidden| h{2:e}re | 229 three three | 230 {1:~ }| 231 {3:[No Name] [+] }| 232 /e^ | 233 ]]) 234 feed('<Esc>v') 235 screen:expect([[ 236 one one one one one | 237 two here | 238 three three | 239 Second window | 240 {1:~ }| 241 {2:[No Name] [+] }| 242 one one one one one | 243 two |hidden| ^here | 244 three three | 245 {1:~ }| 246 {3:[No Name] [+] }| 247 {5:-- VISUAL --} | 248 ]]) 249 feed('<Esc>') 250 251 -- Check that with cursor line is only concealed in Visual mode 252 command('set concealcursor=v') 253 screen:expect([[ 254 one one one one one | 255 two here | 256 three three | 257 Second window | 258 {1:~ }| 259 {2:[No Name] [+] }| 260 one one one one one | 261 two |hidden| ^here | 262 three three | 263 {1:~ }| 264 {3:[No Name] [+] }| 265 | 266 ]]) 267 feed('a') 268 screen:expect([[ 269 one one one one one | 270 two here | 271 three three | 272 Second window | 273 {1:~ }| 274 {2:[No Name] [+] }| 275 one one one one one | 276 two |hidden| h^ere | 277 three three | 278 {1:~ }| 279 {3:[No Name] [+] }| 280 {5:-- INSERT --} | 281 ]]) 282 feed('<Esc>/e') 283 screen:expect([[ 284 one one one one one | 285 two here | 286 three three | 287 Second window | 288 {1:~ }| 289 {2:[No Name] [+] }| 290 one one one one one | 291 two |hidden| h{2:e}re | 292 three three | 293 {1:~ }| 294 {3:[No Name] [+] }| 295 /e^ | 296 ]]) 297 feed('<Esc>v') 298 screen:expect([[ 299 one one one one one | 300 two here | 301 three three | 302 Second window | 303 {1:~ }| 304 {2:[No Name] [+] }| 305 one one one one one | 306 two ^here | 307 three three | 308 {1:~ }| 309 {3:[No Name] [+] }| 310 {5:-- VISUAL --} | 311 ]]) 312 feed('<Esc>') 313 314 -- Check moving the cursor while in insert mode. 315 command('set concealcursor=') 316 feed('a') 317 screen:expect([[ 318 one one one one one | 319 two here | 320 three three | 321 Second window | 322 {1:~ }| 323 {2:[No Name] [+] }| 324 one one one one one | 325 two |hidden| h^ere | 326 three three | 327 {1:~ }| 328 {3:[No Name] [+] }| 329 {5:-- INSERT --} | 330 ]]) 331 feed('<Down>') 332 screen:expect([[ 333 one one one one one | 334 two here | 335 three three | 336 Second window | 337 {1:~ }| 338 {2:[No Name] [+] }| 339 one one one one one | 340 two here | 341 three |hidden|^ three | 342 {1:~ }| 343 {3:[No Name] [+] }| 344 {5:-- INSERT --} | 345 ]]) 346 feed('<Esc>') 347 348 -- Check the "o" command 349 screen:expect([[ 350 one one one one one | 351 two here | 352 three three | 353 Second window | 354 {1:~ }| 355 {2:[No Name] [+] }| 356 one one one one one | 357 two here | 358 three |hidden^| three | 359 {1:~ }| 360 {3:[No Name] [+] }| 361 | 362 ]]) 363 feed('o') 364 screen:expect([[ 365 one one one one one | 366 two here | 367 three three | 368 Second window | 369 {1:~ }| 370 {2:[No Name] [+] }| 371 one one one one one | 372 two here | 373 three three | 374 ^ | 375 {3:[No Name] [+] }| 376 {5:-- INSERT --} | 377 ]]) 378 feed('<Esc>') 379 end) 380 381 -- oldtest: Test_conceal_with_cursorcolumn() 382 it('CursorColumn and ColorColumn on wrapped line', function() 383 local screen = Screen.new(40, 10) 384 screen:add_extra_attr_ids { 385 [100] = { background = Screen.colors.LightRed }, 386 } 387 -- Check that cursorcolumn and colorcolumn don't get broken in presence of 388 -- wrapped lines containing concealed text 389 -- luacheck: push ignore 613 (trailing whitespace in a string) 390 exec([[ 391 let lines = ["one one one |hidden| one one one one one one one one", 392 \ "two two two two |hidden| here two two", 393 \ "three |hidden| three three three three three three three three"] 394 call setline(1, lines) 395 set wrap linebreak 396 set showbreak=\ >>>\ 397 syntax match test /|hidden|/ conceal 398 set conceallevel=2 399 set concealcursor= 400 exe "normal /here\r" 401 set cursorcolumn 402 set colorcolumn=50 403 ]]) 404 -- luacheck: pop 405 406 screen:expect([[ 407 one one one one one one {21:o}ne | 408 {1: >>> }one {100:o}ne one one | 409 two two two two |hidden| ^here two two | 410 three three three three {21:t}hree | 411 {1: >>> }thre{100:e} three three three | 412 {1:~ }|*4 413 /here | 414 ]]) 415 416 -- move cursor to the end of line (the cursor jumps to the next screen line) 417 feed('$') 418 screen:expect([[ 419 one one one one one one one | 420 {1: >>> }one {100:o}ne one one | 421 two two two two |hidden| here two tw^o | 422 three three three three three | 423 {1: >>> }thre{100:e} three three three | 424 {1:~ }|*4 425 /here | 426 ]]) 427 end) 428 429 -- oldtest: Test_conceal_wrapped_cursorline_wincolor() 430 it('CursorLine highlight on wrapped lines', function() 431 local screen = Screen.new(40, 4) 432 screen:add_extra_attr_ids { 433 [100] = { background = Screen.colors.WebGreen }, 434 } 435 exec([[ 436 call setline(1, 'one one one |hidden| one one one one one one one one') 437 syntax match test /|hidden|/ conceal 438 set conceallevel=2 concealcursor=n cursorline 439 normal! g$ 440 hi! CursorLine guibg=Green 441 ]]) 442 screen:expect([[ 443 {100:one one one one one one one on^e }| 444 {100: one one one }| 445 {1:~ }| 446 | 447 ]]) 448 command('hi! CursorLine guibg=NONE guifg=Red') 449 screen:expect([[ 450 {19:one one one one one one one on^e }| 451 {19: one one one }| 452 {1:~ }| 453 | 454 ]]) 455 end) 456 457 -- oldtest: Test_conceal_wrapped_cursorline_wincolor_rightleft() 458 it('CursorLine highlight on wrapped lines with rightleft', function() 459 local screen = Screen.new(40, 4) 460 screen:add_extra_attr_ids { 461 [100] = { background = Screen.colors.WebGreen }, 462 } 463 exec([[ 464 call setline(1, 'one one one |hidden| one one one one one one one one') 465 syntax match test /|hidden|/ conceal 466 set conceallevel=2 concealcursor=n cursorline rightleft 467 normal! g$ 468 hi! CursorLine guibg=Green 469 ]]) 470 screen:expect([[ 471 {100: ^eno eno eno eno eno eno eno eno}| 472 {100: eno eno eno }| 473 {1: ~}| 474 | 475 ]]) 476 command('hi! CursorLine guibg=NONE guifg=Red') 477 screen:expect([[ 478 {19: ^eno eno eno eno eno eno eno eno}| 479 {19: eno eno eno }| 480 {1: ~}| 481 | 482 ]]) 483 end) 484 485 -- oldtest: Test_conceal_resize_term() 486 it('resize editor', function() 487 local screen = Screen.new(75, 6) 488 exec([[ 489 call setline(1, '`one` `two` `three` `four` `five`, the backticks should be concealed') 490 setl cocu=n cole=3 491 syn region CommentCodeSpan matchgroup=Comment start=/`/ end=/`/ concealends 492 normal fb 493 ]]) 494 screen:expect([[ 495 one two three four five, the ^backticks should be concealed | 496 {1:~ }|*4 497 | 498 ]]) 499 500 screen:try_resize(75, 7) 501 screen:expect([[ 502 one two three four five, the ^backticks should be concealed | 503 {1:~ }|*5 504 | 505 ]]) 506 end) 507 508 -- oldtest: Test_conceal_linebreak() 509 it('with linebreak', function() 510 local screen = Screen.new(75, 8) 511 exec([[ 512 let &wrap = v:true 513 let &conceallevel = 2 514 let &concealcursor = 'nc' 515 let &linebreak = v:true 516 let &showbreak = '+ ' 517 let line = 'a`a`a`a`' 518 \ .. 'a'->repeat(&columns - 15) 519 \ .. ' b`b`' 520 \ .. 'b'->repeat(&columns - 10) 521 \ .. ' cccccc' 522 eval ['x'->repeat(&columns), '', line]->setline(1) 523 syntax region CodeSpan matchgroup=Delimiter start=/\z(`\+\)/ end=/\z1/ concealends 524 ]]) 525 screen:expect([[ 526 ^xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| 527 | 528 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 529 {1:+ }bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb | 530 {1:+ }cccccc | 531 {1:~ }|*2 532 | 533 ]]) 534 end) 535 536 -- Tests for correct display (cursor column position) with +conceal and tabulators. 537 -- oldtest: Test_conceal_cursor_pos() 538 it('cursor and column position with conceal and tabulators', function() 539 exec([[ 540 let l = ['start:', '.concealed. text', "|concealed|\ttext"] 541 let l += ['', "\t.concealed.\ttext", "\t|concealed|\ttext", ''] 542 let l += [".a.\t.b.\t.c.\t.d.", "|a|\t|b|\t|c|\t|d|"] 543 call append(0, l) 544 call cursor(1, 1) 545 " Conceal settings. 546 set conceallevel=2 547 set concealcursor=nc 548 syntax match test /|/ conceal 549 ]]) 550 feed('ztj') 551 expect_pos(2, 1) 552 -- We should end up in the same column when running these commands on the 553 -- two lines. 554 feed('ft') 555 expect_pos(2, 17) 556 feed('$') 557 expect_pos(2, 20) 558 feed('0j') 559 expect_pos(3, 1) 560 feed('ft') 561 expect_pos(3, 17) 562 feed('$') 563 expect_pos(3, 20) 564 feed('j0j') 565 expect_pos(5, 8) 566 -- Same for next test block. 567 feed('ft') 568 expect_pos(5, 25) 569 feed('$') 570 expect_pos(5, 28) 571 feed('0j') 572 expect_pos(6, 8) 573 feed('ft') 574 expect_pos(6, 25) 575 feed('$') 576 expect_pos(6, 28) 577 feed('0j0j') 578 expect_pos(8, 1) 579 -- And check W with multiple tabs and conceals in a line. 580 feed('W') 581 expect_pos(8, 9) 582 feed('W') 583 expect_pos(8, 17) 584 feed('W') 585 expect_pos(8, 25) 586 feed('$') 587 expect_pos(8, 27) 588 feed('0j') 589 expect_pos(9, 1) 590 feed('W') 591 expect_pos(9, 9) 592 feed('W') 593 expect_pos(9, 17) 594 feed('W') 595 expect_pos(9, 25) 596 feed('$') 597 expect_pos(9, 26) 598 command('set lbr') 599 feed('$') 600 expect_pos(9, 26) 601 command('set list listchars=tab:>-') 602 feed('0') 603 expect_pos(9, 1) 604 feed('W') 605 expect_pos(9, 9) 606 feed('W') 607 expect_pos(9, 17) 608 feed('W') 609 expect_pos(9, 25) 610 feed('$') 611 expect_pos(9, 26) 612 end) 613 614 local function test_conceal_virtualedit_after_eol(wrap) 615 local screen = Screen.new(60, 3) 616 api.nvim_set_option_value('wrap', wrap, {}) 617 exec([[ 618 call setline(1, 'abcdefgh|hidden|ijklmnpop') 619 syntax match test /|hidden|/ conceal 620 set conceallevel=2 concealcursor=n virtualedit=all 621 normal! $ 622 ]]) 623 screen:expect([[ 624 abcdefghijklmnpo^p | 625 {1:~ }| 626 | 627 ]]) 628 feed('l') 629 screen:expect([[ 630 abcdefghijklmnpop^ | 631 {1:~ }| 632 | 633 ]]) 634 feed('l') 635 screen:expect([[ 636 abcdefghijklmnpop ^ | 637 {1:~ }| 638 | 639 ]]) 640 feed('l') 641 screen:expect([[ 642 abcdefghijklmnpop ^ | 643 {1:~ }| 644 | 645 ]]) 646 feed('rr') 647 screen:expect([[ 648 abcdefghijklmnpop ^r | 649 {1:~ }| 650 | 651 ]]) 652 end 653 654 -- oldtest: Test_conceal_virtualedit_after_eol() 655 describe('cursor drawn at correct column with virtualedit', function() 656 it('with wrapping', function() 657 test_conceal_virtualedit_after_eol(true) 658 end) 659 it('without wrapping', function() 660 test_conceal_virtualedit_after_eol(false) 661 end) 662 end) 663 664 local function test_conceal_virtualedit_after_eol_rightleft(wrap) 665 local screen = Screen.new(60, 3) 666 api.nvim_set_option_value('wrap', wrap, {}) 667 exec([[ 668 call setline(1, 'abcdefgh|hidden|ijklmnpop') 669 syntax match test /|hidden|/ conceal 670 set conceallevel=2 concealcursor=n virtualedit=all rightleft 671 normal! $ 672 ]]) 673 screen:expect([[ 674 ^popnmlkjihgfedcba| 675 {1: ~}| 676 | 677 ]]) 678 feed('h') 679 screen:expect([[ 680 ^ popnmlkjihgfedcba| 681 {1: ~}| 682 | 683 ]]) 684 feed('h') 685 screen:expect([[ 686 ^ popnmlkjihgfedcba| 687 {1: ~}| 688 | 689 ]]) 690 feed('h') 691 screen:expect([[ 692 ^ popnmlkjihgfedcba| 693 {1: ~}| 694 | 695 ]]) 696 feed('rr') 697 screen:expect([[ 698 ^r popnmlkjihgfedcba| 699 {1: ~}| 700 | 701 ]]) 702 end 703 704 -- oldtest: Test_conceal_virtualedit_after_eol_rightleft() 705 describe('cursor drawn correctly with virtualedit and rightleft', function() 706 it('with wrapping', function() 707 test_conceal_virtualedit_after_eol_rightleft(true) 708 end) 709 it('without wrapping', function() 710 test_conceal_virtualedit_after_eol_rightleft(false) 711 end) 712 end) 713 714 local function test_conceal_double_width(wrap) 715 local screen = Screen.new(60, 4) 716 screen:add_extra_attr_ids { 717 [100] = { background = Screen.colors.LightRed }, 718 } 719 api.nvim_set_option_value('wrap', wrap, {}) 720 exec([[ 721 call setline(1, ['aaaaa口=口bbbbb口=口ccccc', 'foobar']) 722 syntax match test /口=口/ conceal cchar=β 723 set conceallevel=2 concealcursor=n colorcolumn=30 724 normal! $ 725 ]]) 726 screen:expect([[ 727 aaaaa{14:β}bbbbb{14:β}cccc^c {100: } | 728 foobar {100: } | 729 {1:~ }| 730 | 731 ]]) 732 feed('gM') 733 screen:expect([[ 734 aaaaa{14:β}bb^bbb{14:β}ccccc {100: } | 735 foobar {100: } | 736 {1:~ }| 737 | 738 ]]) 739 command('set conceallevel=3') 740 screen:expect([[ 741 aaaaabb^bbbccccc {100: } | 742 foobar {100: } | 743 {1:~ }| 744 | 745 ]]) 746 feed('$') 747 screen:expect([[ 748 aaaaabbbbbcccc^c {100: } | 749 foobar {100: } | 750 {1:~ }| 751 | 752 ]]) 753 end 754 755 -- oldtest: Test_conceal_double_width() 756 describe('cursor drawn correctly when double-width chars are concealed', function() 757 it('with wrapping', function() 758 test_conceal_double_width(true) 759 end) 760 it('without wrapping', function() 761 test_conceal_double_width(false) 762 end) 763 end) 764 765 -- oldtest: Test_conceal_double_width_wrap() 766 it('line wraps correctly when double-width chars are concealed', function() 767 local screen = Screen.new(20, 4) 768 screen:add_extra_attr_ids { 769 [100] = { background = Screen.colors.LightRed }, 770 } 771 exec([[ 772 call setline(1, 'aaaaaaaaaa口=口bbbbbbbbbb口=口cccccccccc') 773 syntax match test /口=口/ conceal cchar=β 774 set conceallevel=2 concealcursor=n 775 normal! $ 776 ]]) 777 screen:expect([[ 778 aaaaaaaaaa{14:β}bbbbb | 779 bbbbb{14:β}ccccccccc^c | 780 {1:~ }| 781 | 782 ]]) 783 feed('gM') 784 screen:expect([[ 785 aaaaaaaaaa{14:β}bbbbb | 786 ^bbbbb{14:β}cccccccccc | 787 {1:~ }| 788 | 789 ]]) 790 command('set conceallevel=3') 791 screen:expect([[ 792 aaaaaaaaaabbbbb | 793 ^bbbbbcccccccccc | 794 {1:~ }| 795 | 796 ]]) 797 feed('$') 798 screen:expect([[ 799 aaaaaaaaaabbbbb | 800 bbbbbccccccccc^c | 801 {1:~ }| 802 | 803 ]]) 804 end) 805 end)