highlight_spec.lua (93999B)
1 local t = require('test.testutil') 2 local n = require('test.functional.testnvim')() 3 local Screen = require('test.functional.ui.screen') 4 local os = require('os') 5 6 local clear, feed, insert = n.clear, n.feed, n.insert 7 local command, exec = n.command, n.exec 8 local eval = n.eval 9 local feed_command, eq = n.feed_command, t.eq 10 local fn = n.fn 11 local api = n.api 12 local exec_lua = n.exec_lua 13 14 describe('colorscheme compatibility', function() 15 before_each(function() 16 clear() 17 end) 18 19 it('&t_Co exists and is set to 256 by default', function() 20 eq(1, fn.exists('&t_Co')) 21 eq(1, fn.exists('+t_Co')) 22 eq('256', eval('&t_Co')) 23 end) 24 end) 25 26 describe('highlight: `:syntax manual`', function() 27 -- When using manual syntax highlighting, it should be preserved even when 28 -- switching buffers... bug did only occur without :set hidden 29 -- Ref: vim patch 7.4.1236 30 local screen 31 32 before_each(function() 33 clear() 34 screen = Screen.new(20, 5) 35 -- syntax highlight for vimscript's "echo" 36 end) 37 38 after_each(function() 39 os.remove('Xtest-functional-ui-highlight.tmp.vim') 40 end) 41 42 it("works with buffer switch and 'hidden'", function() 43 command('e tmp1.vim') 44 command('e Xtest-functional-ui-highlight.tmp.vim') 45 command('filetype on') 46 command('syntax manual') 47 command('set ft=vim') 48 command('set syntax=ON') 49 feed('iecho 1<esc>0') 50 51 command('set hidden') 52 command('w') 53 command('bn') 54 feed_command('bp') 55 screen:expect([[ 56 {15:^echo} {26:1} | 57 {1:~ }|*3 58 :bp | 59 ]]) 60 end) 61 62 it("works with buffer switch and 'nohidden'", function() 63 command('e tmp1.vim') 64 command('e Xtest-functional-ui-highlight.tmp.vim') 65 command('filetype on') 66 command('syntax manual') 67 command('set filetype=vim fileformat=unix') 68 command('set syntax=ON') 69 feed('iecho 1<esc>0') 70 71 command('set nohidden') 72 command('w') 73 command('silent bn') 74 eq('tmp1.vim', eval("fnamemodify(bufname('%'), ':t')")) 75 feed_command('silent bp') 76 eq('Xtest-functional-ui-highlight.tmp.vim', eval("fnamemodify(bufname('%'), ':t')")) 77 screen:expect([[ 78 {15:^echo} {26:1} | 79 {1:~ }|*3 80 :silent bp | 81 ]]) 82 end) 83 end) 84 85 describe('highlight defaults', function() 86 local screen 87 88 before_each(function() 89 clear() 90 screen = Screen.new() 91 screen:add_extra_attr_ids { 92 [100] = { foreground = Screen.colors.Red, background = Screen.colors.WebGreen }, 93 [101] = { italic = true }, 94 } 95 end) 96 97 it('window status bar', function() 98 feed_command('sp', 'vsp', 'vsp') 99 screen:expect([[ 100 ^ │ │ | 101 {1:~ }│{1:~ }│{1:~ }|*5 102 {3:[No Name] }{2:[No Name] [No Name] }| 103 | 104 {1:~ }|*4 105 {2:[No Name] }| 106 :vsp | 107 ]]) 108 -- navigate to verify that the attributes are properly moved 109 feed('<c-w>j') 110 screen:expect([[ 111 │ │ | 112 {1:~ }│{1:~ }│{1:~ }|*5 113 {2:[No Name] [No Name] [No Name] }| 114 ^ | 115 {1:~ }|*4 116 {3:[No Name] }| 117 :vsp | 118 ]]) 119 -- note that when moving to a window with small width nvim will increase 120 -- the width of the new active window at the expense of a inactive window 121 -- (upstream vim has the same behavior) 122 feed('<c-w>k<c-w>l') 123 screen:expect([[ 124 │^ │ | 125 {1:~ }│{1:~ }│{1:~ }|*5 126 {2:[No Name] }{3:[No Name] }{2:[No Name] }| 127 | 128 {1:~ }|*4 129 {2:[No Name] }| 130 :vsp | 131 ]]) 132 feed('<c-w>l') 133 screen:expect([[ 134 │ │^ | 135 {1:~ }│{1:~ }│{1:~ }|*5 136 {2:[No Name] [No Name] }{3:[No Name] }| 137 | 138 {1:~ }|*4 139 {2:[No Name] }| 140 :vsp | 141 ]]) 142 feed('<c-w>h<c-w>h') 143 screen:expect([[ 144 ^ │ │ | 145 {1:~ }│{1:~ }│{1:~ }|*5 146 {3:[No Name] }{2:[No Name] [No Name] }| 147 | 148 {1:~ }|*4 149 {2:[No Name] }| 150 :vsp | 151 ]]) 152 end) 153 154 it('insert mode text', function() 155 feed('i') 156 screen:try_resize(53, 4) 157 screen:expect([[ 158 ^ | 159 {1:~ }|*2 160 {5:-- INSERT --} | 161 ]]) 162 end) 163 164 it('end of file markers', function() 165 screen:try_resize(53, 4) 166 screen:expect([[ 167 ^ | 168 {1:~ }|*2 169 | 170 ]]) 171 end) 172 173 it('"wait return" text', function() 174 screen:try_resize(53, 4) 175 feed(':ls<cr>') 176 screen:expect([[ 177 {3: }| 178 :ls | 179 1 %a "[No Name]" line 1 | 180 {6:Press ENTER or type command to continue}^ | 181 ]]) 182 feed('<cr>') -- skip the "Press ENTER..." state or tests will hang 183 end) 184 185 it('can be cleared and linked to other highlight groups', function() 186 screen:try_resize(53, 4) 187 feed_command('highlight clear ModeMsg') 188 feed('i') 189 screen:expect([[ 190 ^ | 191 {1:~ }|*2 192 -- INSERT -- | 193 ]]) 194 feed('<esc>') 195 feed_command('highlight CustomHLGroup guifg=red guibg=green') 196 feed_command('highlight link ModeMsg CustomHLGroup') 197 feed('i') 198 screen:expect([[ 199 ^ | 200 {1:~ }|*2 201 {100:-- INSERT --} | 202 ]]) 203 end) 204 205 it('can be cleared by assigning NONE', function() 206 screen:try_resize(53, 4) 207 feed_command('syn keyword TmpKeyword neovim') 208 feed_command('hi link TmpKeyword ErrorMsg') 209 insert('neovim') 210 screen:expect([[ 211 {9:neovi^m} | 212 {1:~ }|*2 213 | 214 ]]) 215 feed_command( 216 'hi ErrorMsg term=NONE cterm=NONE ctermfg=NONE ctermbg=NONE' 217 .. ' gui=NONE guifg=NONE guibg=NONE guisp=NONE' 218 ) 219 screen:expect([[ 220 neovi^m | 221 {1:~ }|*2 222 | 223 ]]) 224 end) 225 226 it('linking updates window highlight immediately #16552', function() 227 screen:try_resize(53, 4) 228 screen:expect([[ 229 ^ | 230 {1:~ }|*2 231 | 232 ]]) 233 feed_command('hi NonTextAlt guifg=Red') 234 feed_command('hi! link NonText NonTextAlt') 235 screen:expect([[ 236 ^ | 237 {19:~ }|*2 238 :hi! link NonText NonTextAlt | 239 ]]) 240 end) 241 242 it('Cursor after `:hi clear|syntax reset` #6508', function() 243 command('highlight clear|syntax reset') 244 eq('guifg=bg guibg=fg', eval([[matchstr(execute('hi Cursor'), '\v(gui|cterm).*$')]])) 245 end) 246 247 it('Whitespace highlight', function() 248 screen:try_resize(53, 4) 249 feed_command('highlight NonText gui=NONE guifg=#FF0000') 250 feed_command('set listchars=space:.,tab:>-,trail:*,eol:¬ list') 251 insert(' ne \t o\tv im ') 252 screen:expect([[ 253 ne{19:.>----.}o{19:>-----}v{19:..}im{19:*^*¬} | 254 {19:~ }|*2 255 | 256 ]]) 257 feed_command('highlight Whitespace gui=NONE guifg=#0000FF') 258 screen:expect([[ 259 ne{18:.>----.}o{18:>-----}v{18:..}im{18:*^*}{19:¬} | 260 {19:~ }|*2 261 :highlight Whitespace gui=NONE guifg=#0000FF | 262 ]]) 263 end) 264 265 it('are sent to UIs', function() 266 screen:try_resize(53, 4) 267 268 screen:expect { 269 grid = [[ 270 ^ | 271 {1:~ }|*2 272 | 273 ]], 274 hl_groups = { EndOfBuffer = 1, MsgSeparator = 3 }, 275 } 276 277 command('highlight EndOfBuffer gui=italic') 278 screen:expect { 279 grid = [[ 280 ^ | 281 {101:~ }|*2 282 | 283 ]], 284 hl_groups = { EndOfBuffer = 101, MsgSeparator = 3 }, 285 } 286 287 command('highlight clear EndOfBuffer') 288 screen:expect { 289 grid = [[ 290 ^ | 291 {1:~ }|*2 292 | 293 ]], 294 hl_groups = { EndOfBuffer = 1, MsgSeparator = 3 }, 295 } 296 end) 297 end) 298 299 describe('highlight', function() 300 before_each(clear) 301 302 it('Visual', function() 303 local screen = Screen.new(45, 5) 304 insert([[ 305 line1 foo bar 306 abcdefghijklmnopqrs 307 ABCDEFGHIJKLMNOPQRS 308 ]]) 309 feed('gg') 310 command('vsplit') 311 312 -- Non-blinking block cursor: does NOT highlight char-at-cursor. 313 command('set guicursor=a:block-blinkon0') 314 feed('V') 315 screen:expect([[ 316 {17: }^l{17:ine1 foo bar} │{17: line1 foo bar} | 317 abcdefghijklmnopqrs │abcdefghijklmnopqrs | 318 ABCDEFGHIJKLMNOPQRS │ABCDEFGHIJKLMNOPQRS | 319 {3:[No Name] [+] }{2:[No Name] [+] }| 320 {5:-- VISUAL LINE --} | 321 ]]) 322 323 feed('<Esc>$vhhh') 324 screen:expect([[ 325 line1 foo^ {17:bar} │ line1 foo{17: bar} | 326 abcdefghijklmnopqrs │abcdefghijklmnopqrs | 327 ABCDEFGHIJKLMNOPQRS │ABCDEFGHIJKLMNOPQRS | 328 {3:[No Name] [+] }{2:[No Name] [+] }| 329 {5:-- VISUAL --} | 330 ]]) 331 332 -- Vertical cursor: highlights char-at-cursor. #8983 333 command('set guicursor=a:block-blinkon175') 334 screen:expect([[ 335 line1 foo{17:^ bar} │ line1 foo{17: bar} | 336 abcdefghijklmnopqrs │abcdefghijklmnopqrs | 337 ABCDEFGHIJKLMNOPQRS │ABCDEFGHIJKLMNOPQRS | 338 {3:[No Name] [+] }{2:[No Name] [+] }| 339 {5:-- VISUAL --} | 340 ]]) 341 342 command('set selection=exclusive') 343 screen:expect([[ 344 line1 foo{17:^ ba}r │ line1 foo{17: ba}r | 345 abcdefghijklmnopqrs │abcdefghijklmnopqrs | 346 ABCDEFGHIJKLMNOPQRS │ABCDEFGHIJKLMNOPQRS | 347 {3:[No Name] [+] }{2:[No Name] [+] }| 348 {5:-- VISUAL --} | 349 ]]) 350 351 feed('o') 352 screen:expect([[ 353 line1 foo{17: ba}^r │ line1 foo{17: ba}r | 354 abcdefghijklmnopqrs │abcdefghijklmnopqrs | 355 ABCDEFGHIJKLMNOPQRS │ABCDEFGHIJKLMNOPQRS | 356 {3:[No Name] [+] }{2:[No Name] [+] }| 357 {5:-- VISUAL --} | 358 ]]) 359 360 feed('V') 361 screen:expect([[ 362 {17: line1 foo ba^r} │{17: line1 foo bar} | 363 abcdefghijklmnopqrs │abcdefghijklmnopqrs | 364 ABCDEFGHIJKLMNOPQRS │ABCDEFGHIJKLMNOPQRS | 365 {3:[No Name] [+] }{2:[No Name] [+] }| 366 {5:-- VISUAL LINE --} | 367 ]]) 368 369 command('set cursorcolumn') 370 feed('<C-V>') 371 screen:expect([[ 372 line1 foo{17: ba}^r │ line1 foo{17: ba}r | 373 abcdefghijklmn{21:o}pqrs │abcdefghijklmnopqrs | 374 ABCDEFGHIJKLMN{21:O}PQRS │ABCDEFGHIJKLMNOPQRS | 375 {3:[No Name] [+] }{2:[No Name] [+] }| 376 {5:-- VISUAL BLOCK --} | 377 ]]) 378 379 command('set selection&') 380 screen:expect([[ 381 line1 foo{17: ba^r} │ line1 foo{17: bar} | 382 abcdefghijklmn{21:o}pqrs │abcdefghijklmnopqrs | 383 ABCDEFGHIJKLMN{21:O}PQRS │ABCDEFGHIJKLMNOPQRS | 384 {3:[No Name] [+] }{2:[No Name] [+] }| 385 {5:-- VISUAL BLOCK --} | 386 ]]) 387 388 feed('^') 389 screen:expect([[ 390 {17:^line1 foo }bar │ {17:line1 foo }bar | 391 ab{21:c}defghijklmnopqrs │abcdefghijklmnopqrs | 392 AB{21:C}DEFGHIJKLMNOPQRS │ABCDEFGHIJKLMNOPQRS | 393 {3:[No Name] [+] }{2:[No Name] [+] }| 394 {5:-- VISUAL BLOCK --} | 395 ]]) 396 397 feed('2j') 398 screen:expect([[ 399 {17:line1 foo }bar │ {17:line1 foo }bar | 400 ab{17:cdefghijkl}mnopqrs │ab{17:cdefghijkl}mnopqrs | 401 AB{17:^CDEFGHIJKL}MNOPQRS │AB{17:CDEFGHIJKL}MNOPQRS | 402 {3:[No Name] [+] }{2:[No Name] [+] }| 403 {5:-- VISUAL BLOCK --} | 404 ]]) 405 406 command('set nocursorcolumn') 407 feed('O') 408 screen:expect([[ 409 {17:line1 foo }bar │ {17:line1 foo }bar | 410 ab{17:cdefghijkl}mnopqrs │ab{17:cdefghijkl}mnopqrs | 411 AB{17:CDEFGHIJK^L}MNOPQRS │AB{17:CDEFGHIJKL}MNOPQRS | 412 {3:[No Name] [+] }{2:[No Name] [+] }| 413 {5:-- VISUAL BLOCK --} | 414 ]]) 415 416 command('set selection=exclusive') 417 screen:expect([[ 418 {17:line1 foo} bar │ {17:line1 foo} bar | 419 ab{17:cdefghijk}lmnopqrs │ab{17:cdefghijk}lmnopqrs | 420 AB{17:CDEFGHIJK}^LMNOPQRS │AB{17:CDEFGHIJK}LMNOPQRS | 421 {3:[No Name] [+] }{2:[No Name] [+] }| 422 {5:-- VISUAL BLOCK --} | 423 ]]) 424 end) 425 426 it('blockwise Visual highlight with virtualedit=block #34235', function() 427 local screen = Screen.new(45, 5) 428 command('set virtualedit=block') 429 insert('foobar\nfoo') 430 feed('0<C-V>k$') 431 screen:expect([[ 432 {17:foobar}^ | 433 {17:foo } | 434 {1:~ }|*2 435 {5:-- VISUAL BLOCK --} | 436 ]]) 437 feed('10l') 438 screen:expect([[ 439 {17:foobar }^ | 440 {17:foo } | 441 {1:~ }|*2 442 {5:-- VISUAL BLOCK --} | 443 ]]) 444 end) 445 446 it("is updated with H/L and 'scrolloff' #36059", function() 447 local screen = Screen.new(40, 10) 448 exec([[ 449 call setline(1, map(range(1, 100), "'line ' .. v:val")) 450 set scrolloff=2 nostartofline 451 call cursor(50, 1) 452 ]]) 453 feed('z<CR>V') 454 screen:expect([[ 455 line 48 | 456 line 49 | 457 ^l{17:ine 50} | 458 line 51 | 459 line 52 | 460 line 53 | 461 line 54 | 462 line 55 | 463 line 56 | 464 {5:-- VISUAL LINE --} | 465 ]]) 466 feed('L') 467 screen:expect([[ 468 line 48 | 469 line 49 | 470 {17:line 50} | 471 {17:line 51} | 472 {17:line 52} | 473 {17:line 53} | 474 ^l{17:ine 54} | 475 line 55 | 476 line 56 | 477 {5:-- VISUAL LINE --} | 478 ]]) 479 feed('<Esc>V') 480 screen:expect([[ 481 line 48 | 482 line 49 | 483 line 50 | 484 line 51 | 485 line 52 | 486 line 53 | 487 ^l{17:ine 54} | 488 line 55 | 489 line 56 | 490 {5:-- VISUAL LINE --} | 491 ]]) 492 feed('H') 493 screen:expect([[ 494 line 48 | 495 line 49 | 496 ^l{17:ine 50} | 497 {17:line 51} | 498 {17:line 52} | 499 {17:line 53} | 500 {17:line 54} | 501 line 55 | 502 line 56 | 503 {5:-- VISUAL LINE --} | 504 ]]) 505 end) 506 507 it('cterm=standout gui=standout', function() 508 local screen = Screen.new(20, 5) 509 screen:add_extra_attr_ids { 510 [100] = { 511 foreground = Screen.colors.Blue1, 512 bold = true, 513 background = Screen.colors.Grey90, 514 underline = true, 515 standout = true, 516 }, 517 [101] = { underline = true, standout = true, background = Screen.colors.Grey90 }, 518 } 519 feed_command('hi CursorLine cterm=standout,underline gui=standout,underline') 520 feed_command('set cursorline') 521 feed_command('set listchars=space:.,eol:¬,tab:>-,extends:>,precedes:<,trail:* list') 522 feed('i\t abcd <cr>\t abcd <cr><esc>k') 523 screen:expect([[ 524 {1:>-------.}abcd{1:*¬} | 525 {100:^>-------.}{101:abcd}{100:*¬}{101: }| 526 {1:¬} | 527 {1:~ }| 528 | 529 ]]) 530 end) 531 532 it('strikethrough', function() 533 local screen = Screen.new(25, 6) 534 feed_command('syntax on') 535 feed_command('syn keyword TmpKeyword foo') 536 feed_command('hi! Awesome cterm=strikethrough gui=strikethrough') 537 feed_command('hi link TmpKeyword Awesome') 538 insert([[ 539 foo 540 foo bar 541 foobarfoobar 542 ]]) 543 screen:expect( 544 [[ 545 {1:foo} | 546 {1:foo} bar | 547 foobarfoobar | 548 ^ | 549 {2:~ }| 550 | 551 ]], 552 { 553 [1] = { strikethrough = true }, 554 [2] = { bold = true, foreground = Screen.colors.Blue1 }, 555 } 556 ) 557 end) 558 559 it('nocombine', function() 560 local screen = Screen.new(25, 6) 561 screen:add_extra_attr_ids { 562 [100] = { underline = true, reverse = true, foreground = Screen.colors.SlateBlue }, 563 [101] = { 564 foreground = Screen.colors.SlateBlue, 565 reverse = true, 566 background = Screen.colors.Yellow, 567 }, 568 } 569 feed_command('syntax on') 570 feed_command('hi! Underlined cterm=underline gui=underline') 571 feed_command('syn keyword Underlined foobar') 572 feed_command('hi Search cterm=inverse,nocombine gui=inverse,nocombine') 573 insert([[ 574 foobar 575 foobar 576 ]]) 577 screen:expect { 578 grid = [[ 579 {28:foobar} |*2 580 ^ | 581 {1:~ }|*2 582 | 583 ]], 584 } 585 586 feed('/foo') 587 screen:expect { 588 grid = [[ 589 {100:foo}{28:bar} | 590 {101:foo}{28:bar} | 591 | 592 {1:~ }|*2 593 /foo^ | 594 ]], 595 } 596 feed('<cr>') 597 screen:expect { 598 grid = [[ 599 {101:^foo}{28:bar} | 600 {101:foo}{28:bar} | 601 | 602 {1:~ }|*2 603 {19:search hit...uing at TOP} | 604 ]], 605 } 606 end) 607 608 it('guisp (special/undercurl)', function() 609 local screen = Screen.new(25, 10) 610 feed_command('syntax on') 611 feed_command('syn keyword TmpKeyword neovim') 612 feed_command('syn keyword TmpKeyword1 special') 613 feed_command('syn keyword TmpKeyword2 specialwithbg') 614 feed_command('syn keyword TmpKeyword3 specialwithfg') 615 feed_command('hi! Awesome guifg=red guibg=yellow guisp=red') 616 feed_command('hi! Awesome1 guisp=red') 617 feed_command('hi! Awesome2 guibg=yellow guisp=red') 618 feed_command('hi! Awesome3 guifg=red guisp=red') 619 feed_command('hi link TmpKeyword Awesome') 620 feed_command('hi link TmpKeyword1 Awesome1') 621 feed_command('hi link TmpKeyword2 Awesome2') 622 feed_command('hi link TmpKeyword3 Awesome3') 623 insert([[ 624 neovim 625 awesome neovim 626 wordcontainingneovim 627 special 628 specialwithbg 629 specialwithfg 630 ]]) 631 feed('Go<tab>neovim tabbed') 632 screen:expect( 633 [[ 634 {1:neovim} | 635 awesome {1:neovim} | 636 wordcontainingneovim | 637 {2:special} | 638 {3:specialwithbg} | 639 {4:specialwithfg} | 640 | 641 {1:neovim} tabbed^ | 642 {0:~ }| 643 {5:-- INSERT --} | 644 ]], 645 { 646 [0] = { bold = true, foreground = Screen.colors.Blue }, 647 [1] = { 648 background = Screen.colors.Yellow, 649 foreground = Screen.colors.Red, 650 special = Screen.colors.Red, 651 }, 652 [2] = { special = Screen.colors.Red }, 653 [3] = { special = Screen.colors.Red, background = Screen.colors.Yellow }, 654 [4] = { foreground = Screen.colors.Red, special = Screen.colors.Red }, 655 [5] = { bold = true }, 656 } 657 ) 658 end) 659 660 it("'diff', syntax and extmark #23722", function() 661 local screen = Screen.new(25, 10) 662 exec([[ 663 new 664 call setline(1, ['', '01234 6789']) 665 windo diffthis 666 wincmd w 667 syn match WarningMsg "^.*$" 668 call nvim_buf_add_highlight(0, -1, 'ErrorMsg', 1, 2, 8) 669 ]]) 670 screen:expect( 671 [[ 672 {1: }{5:^ }| 673 {1: }{2:01}{3:234 67}{2:89}{5: }| 674 {4:~ }|*2 675 {7:[No Name] [+] }| 676 {1: }{6:-----------------------}|*2 677 {1: } | 678 {8:[No Name] }| 679 | 680 ]], 681 { 682 [0] = { Screen.colors.WebGray, foreground = Screen.colors.DarkBlue }, 683 [1] = { background = Screen.colors.Grey, foreground = Screen.colors.Blue4 }, 684 [2] = { foreground = Screen.colors.Red, background = Screen.colors.LightBlue }, 685 [3] = { foreground = Screen.colors.Grey100, background = Screen.colors.LightBlue }, 686 [4] = { bold = true, foreground = Screen.colors.Blue }, 687 [5] = { background = Screen.colors.LightBlue }, 688 [6] = { 689 bold = true, 690 background = Screen.colors.LightCyan, 691 foreground = Screen.colors.Blue1, 692 }, 693 [7] = { reverse = true, bold = true }, 694 [8] = { reverse = true }, 695 } 696 ) 697 end) 698 end) 699 700 describe("'listchars' highlight", function() 701 local screen 702 703 before_each(function() 704 clear() 705 screen = Screen.new(20, 5) 706 end) 707 708 it("'cursorline' and 'cursorcolumn'", function() 709 feed_command('highlight clear ModeMsg') 710 feed_command('set cursorline') 711 feed('i') 712 screen:expect([[ 713 {21:^ }| 714 {1:~ }|*3 715 -- INSERT -- | 716 ]]) 717 feed('abcdefg<cr>kkasdf') 718 screen:expect([[ 719 abcdefg | 720 {21:kkasdf^ }| 721 {1:~ }|*2 722 -- INSERT -- | 723 ]]) 724 feed('<esc>') 725 screen:expect([[ 726 abcdefg | 727 {21:kkasd^f }| 728 {1:~ }|*2 729 | 730 ]]) 731 feed_command('set nocursorline') 732 screen:expect([[ 733 abcdefg | 734 kkasd^f | 735 {1:~ }|*2 736 :set nocursorline | 737 ]]) 738 feed('k') 739 screen:expect([[ 740 abcde^fg | 741 kkasdf | 742 {1:~ }|*2 743 :set nocursorline | 744 ]]) 745 feed('jjji<cr><cr><cr><esc>') 746 screen:expect([[ 747 kkasd | 748 |*2 749 ^f | 750 | 751 ]]) 752 feed_command('set cursorline') 753 feed_command('set cursorcolumn') 754 feed('kkiabcdefghijk<esc>hh') 755 screen:expect([[ 756 kkasd {21: } | 757 {21:abcdefgh^ijk }| 758 {21: } | 759 f {21: } | 760 | 761 ]]) 762 feed('khh') 763 screen:expect([[ 764 {21:kk^asd }| 765 ab{21:c}defghijk | 766 {21: } | 767 f {21: } | 768 | 769 ]]) 770 end) 771 772 it("'cursorline' and with 'listchars' option", function() 773 screen:add_extra_attr_ids { 774 [100] = { foreground = Screen.colors.Red, background = Screen.colors.Grey90 }, 775 [101] = { foreground = Screen.colors.Blue1, bold = true, background = Screen.colors.Grey90 }, 776 } 777 feed_command('highlight clear ModeMsg') 778 feed_command('highlight Whitespace guifg=#FF0000') 779 feed_command('set cursorline') 780 feed_command('set tabstop=8') 781 feed_command('set listchars=space:.,eol:¬,tab:>-,extends:>,precedes:<,trail:* list') 782 feed('i\t abcd <cr>\t abcd <cr><esc>k') 783 screen:expect([[ 784 {19:>-------.}abcd{19:*}{1:¬} | 785 {100:^>-------.}{21:abcd}{100:*}{101:¬}{21: }| 786 {1:¬} | 787 {1:~ }| 788 | 789 ]]) 790 feed('k') 791 screen:expect([[ 792 {100:^>-------.}{21:abcd}{100:*}{101:¬}{21: }| 793 {19:>-------.}abcd{19:*}{1:¬} | 794 {1:¬} | 795 {1:~ }| 796 | 797 ]]) 798 feed_command('set nocursorline') 799 screen:expect([[ 800 {19:^>-------.}abcd{19:*}{1:¬} | 801 {19:>-------.}abcd{19:*}{1:¬} | 802 {1:¬} | 803 {1:~ }| 804 :set nocursorline | 805 ]]) 806 feed_command('set nowrap') 807 feed('ALorem ipsum dolor sit amet<ESC>0') 808 screen:expect([[ 809 {19:^>-------.}abcd{19:.}Lorem{1:>}| 810 {19:>-------.}abcd{19:*}{1:¬} | 811 {1:¬} | 812 {1:~ }| 813 | 814 ]]) 815 feed_command('set cursorline') 816 screen:expect([[ 817 {100:^>-------.}{21:abcd}{100:.}{21:Lorem}{101:>}| 818 {19:>-------.}abcd{19:*}{1:¬} | 819 {1:¬} | 820 {1:~ }| 821 :set cursorline | 822 ]]) 823 feed('$') 824 screen:expect([[ 825 {101:<}{21:r}{100:.}{21:sit}{100:.}{21:ame^t}{101:¬}{21: }| 826 {1:<} |*2 827 {1:~ }| 828 :set cursorline | 829 ]]) 830 feed('G') 831 screen:expect([[ 832 {19:>-------.}abcd{19:.}Lorem{1:>}| 833 {19:>-------.}abcd{19:*}{1:¬} | 834 {101:^¬}{21: }| 835 {1:~ }| 836 :set cursorline | 837 ]]) 838 end) 839 840 it("'listchar' with wrap", function() 841 feed_command('set wrap') 842 feed_command('set listchars=eol:¬,precedes:< list') 843 feed('90ia<esc>') 844 screen:expect([[ 845 {1:<}aaaaaaaaaaaaaaaaaaa| 846 aaaaaaaaaaaaaaaaaaaa|*2 847 aaaaaaaaa^a{1:¬} | 848 | 849 ]]) 850 feed('0') 851 screen:expect([[ 852 ^aaaaaaaaaaaaaaaaaaaa| 853 aaaaaaaaaaaaaaaaaaaa|*3 854 | 855 ]]) 856 end) 857 858 it("'listchar' in visual mode", function() 859 screen:add_extra_attr_ids { 860 [100] = { 861 foreground = Screen.colors.Blue1, 862 bold = true, 863 background = Screen.colors.LightGray, 864 }, 865 [101] = { foreground = Screen.colors.Red, background = Screen.colors.Grey90 }, 866 [102] = { foreground = Screen.colors.Blue1, bold = true, background = Screen.colors.Grey90 }, 867 [103] = { foreground = Screen.colors.Red, background = Screen.colors.LightGray }, 868 } 869 command('highlight clear ModeMsg') 870 command('highlight Whitespace guifg=#FF0000') 871 command('set cursorline') 872 command('set tabstop=8') 873 command('set nowrap') 874 command('set listchars=space:.,eol:¬,tab:>-,extends:>,precedes:<,trail:* list') 875 feed('i\t abcd <cr>\t abcd Lorem ipsum dolor sit amet<cr><esc>kkk0') 876 screen:expect([[ 877 {101:^>-------.}{21:abcd}{101:*}{102:¬}{21: }| 878 {19:>-------.}abcd{19:.}Lorem{1:>}| 879 {1:¬} | 880 {1:~ }| 881 | 882 ]]) 883 feed('lllvj') 884 screen:expect([[ 885 {19:>-------.}a{17:bcd}{103:*}{100:¬} | 886 {103:>-------.}{17:a}^bcd{19:.}Lorem{1:>}| 887 {1:¬} | 888 {1:~ }| 889 -- VISUAL -- | 890 ]]) 891 feed('<esc>V') 892 screen:expect([[ 893 {19:>-------.}abcd{19:*}{1:¬} | 894 {103:>-------.}{17:a}^b{17:cd}{103:.}{17:Lorem}{1:>}| 895 {1:¬} | 896 {1:~ }| 897 -- VISUAL LINE -- | 898 ]]) 899 feed('<esc>$') 900 screen:expect([[ 901 {1:<} | 902 {102:<}{21:r}{101:.}{21:sit}{101:.}{21:ame^t}{102:¬}{21: }| 903 {1:<} | 904 {1:~ }| 905 | 906 ]]) 907 end) 908 909 it("'cursorline' with :match", function() 910 screen:add_extra_attr_ids { 911 [100] = { foreground = Screen.colors.Lime, background = Screen.colors.Red }, 912 } 913 feed_command('highlight clear ModeMsg') 914 feed_command('highlight Whitespace guifg=#FF0000') 915 feed_command('highlight Error guifg=#00FF00') 916 feed_command('set nowrap') 917 feed('ia \t bc \t <esc>') 918 screen:expect([[ 919 a bc ^ | 920 {1:~ }|*3 921 | 922 ]]) 923 feed_command('set listchars=space:.,eol:¬,tab:>-,extends:>,precedes:<,trail:* list') 924 screen:expect([[ 925 a{19:.>-----.}bc{19:*>---*^*}{1:¬} | 926 {1:~ }|*3 927 | 928 ]]) 929 feed_command('match Error /\\s\\+$/') 930 screen:expect([[ 931 a{19:.>-----.}bc{100:*>---*^*}{1:¬} | 932 {1:~ }|*3 933 | 934 ]]) 935 end) 936 end) 937 938 describe('CursorLine and CursorLineNr highlights', function() 939 before_each(clear) 940 941 it('overridden by Error, ColorColumn if fg not set', function() 942 local screen = Screen.new(50, 5) 943 screen:add_extra_attr_ids { 944 [100] = { background = Screen.colors.LightRed }, 945 [101] = { foreground = Screen.colors.SlateBlue, background = Screen.colors.Grey90 }, 946 } 947 948 command('filetype on') 949 command('syntax on') 950 command('set cursorline ft=json') 951 feed('i{<cr>"a" : abc // 10;<cr>}<cr><esc>') 952 screen:expect([[ 953 {16:{} | 954 "{15:a}" : {9:abc} {9:// 10;} | 955 {16:}} | 956 {21:^ }| 957 | 958 ]]) 959 960 command('set colorcolumn=3') 961 feed('i <esc>') 962 screen:expect([[ 963 {16:{} {100: } | 964 "{15:a}{100:"} : {9:abc} {9:// 10;} | 965 {16:}} {100: } | 966 {21: ^ }{100: }{21: }| 967 | 968 ]]) 969 end) 970 971 it("overridden by NonText in 'showbreak' characters", function() 972 local screen = Screen.new(20, 5) 973 screen:add_extra_attr_ids { 974 [100] = { foreground = Screen.colors.Yellow1 }, 975 [101] = { foreground = Screen.colors.Yellow1, background = Screen.colors.Blue }, 976 [102] = { foreground = Screen.colors.Grey0, background = Screen.colors.Grey100 }, 977 [103] = { foreground = Screen.colors.Yellow1, background = Screen.colors.Grey100 }, 978 } 979 980 feed_command('set wrap cursorline') 981 feed_command('set showbreak=>>>') 982 feed_command('highlight clear NonText') 983 feed_command('highlight clear CursorLine') 984 feed_command('highlight NonText guifg=Yellow guibg=Blue gui=NONE') 985 feed_command('highlight CursorLine guifg=Black guibg=White gui=NONE') 986 987 feed('30iø<esc>o<esc>30ia<esc>') 988 screen:expect([[ 989 øøøøøøøøøøøøøøøøøøøø| 990 {101:>>>}øøøøøøøøøø | 991 {102:aaaaaaaaaaaaaaaaaaaa}| 992 {101:>>>}{102:aaaaaaaaa^a }| 993 | 994 ]]) 995 feed('k') 996 screen:expect([[ 997 {102:øøøøøøøøøøøøøøøøøøøø}| 998 {101:>>>}{102:øøøøøøøøø^ø }| 999 aaaaaaaaaaaaaaaaaaaa| 1000 {101:>>>}aaaaaaaaaa | 1001 | 1002 ]]) 1003 feed_command('highlight NonText guibg=NONE') 1004 screen:expect([[ 1005 {102:øøøøøøøøøøøøøøøøøøøø}| 1006 {103:>>>}{102:øøøøøøøøø^ø }| 1007 aaaaaaaaaaaaaaaaaaaa| 1008 {100:>>>}aaaaaaaaaa | 1009 | 1010 ]]) 1011 feed_command('set nocursorline') 1012 screen:expect([[ 1013 øøøøøøøøøøøøøøøøøøøø| 1014 {100:>>>}øøøøøøøøø^ø | 1015 aaaaaaaaaaaaaaaaaaaa| 1016 {100:>>>}aaaaaaaaaa | 1017 :set nocursorline | 1018 ]]) 1019 end) 1020 1021 it("'cursorlineopt' screenline", function() 1022 local screen = Screen.new(20, 5) 1023 screen:add_extra_attr_ids { 1024 [100] = { foreground = Screen.colors.Yellow }, 1025 [101] = { foreground = Screen.colors.Red, background = Screen.colors.WebGreen }, 1026 [102] = { foreground = Screen.colors.Black, background = Screen.colors.Grey100 }, 1027 [103] = { foreground = Screen.colors.WebGreen, background = Screen.colors.Red }, 1028 } 1029 1030 command('set wrap cursorline cursorlineopt=screenline') 1031 command('set showbreak=>>>') 1032 command('highlight clear NonText') 1033 command('highlight clear CursorLine') 1034 command('highlight NonText guifg=Yellow gui=NONE') 1035 command('highlight LineNr guifg=Red guibg=Green gui=NONE') 1036 command('highlight CursorLine guifg=Black guibg=White gui=NONE') 1037 command('highlight CursorLineNr guifg=Green guibg=Red gui=NONE') 1038 1039 feed('30iø<esc>o<esc>30ia<esc>') 1040 1041 -- CursorLine should not apply to 'showbreak' when 'cursorlineopt' contains "screenline" 1042 screen:expect([[ 1043 øøøøøøøøøøøøøøøøøøøø| 1044 {100:>>>}øøøøøøøøøø | 1045 aaaaaaaaaaaaaaaaaaaa| 1046 {100:>>>}{102:aaaaaaaaa^a }| 1047 | 1048 ]]) 1049 feed('gk') 1050 screen:expect([[ 1051 øøøøøøøøøøøøøøøøøøøø| 1052 {100:>>>}øøøøøøøøøø | 1053 {102:aaaaaaaaaaaa^aaaaaaaa}| 1054 {100:>>>}aaaaaaaaaa | 1055 | 1056 ]]) 1057 feed('k') 1058 screen:expect([[ 1059 {102:øøøøøøøøøøøø^øøøøøøøø}| 1060 {100:>>>}øøøøøøøøøø | 1061 aaaaaaaaaaaaaaaaaaaa| 1062 {100:>>>}aaaaaaaaaa | 1063 | 1064 ]]) 1065 1066 -- CursorLineNr should not apply to line number when 'cursorlineopt' does not contain "number" 1067 command('set relativenumber numberwidth=2') 1068 screen:expect([[ 1069 {101:0 }{102:øøøøøøøøøøøø^øøøøøø}| 1070 {101: }{100:>>>}øøøøøøøøøøøø | 1071 {101:1 }aaaaaaaaaaaaaaaaaa| 1072 {101: }{100:>>>}aaaaaaaaaaaa | 1073 | 1074 ]]) 1075 1076 -- CursorLineNr should apply to line number when 'cursorlineopt' contains "number" 1077 command('set cursorlineopt+=number') 1078 screen:expect([[ 1079 {103:0 }{102:øøøøøøøøøøøø^øøøøøø}| 1080 {101: }{100:>>>}øøøøøøøøøøøø | 1081 {101:1 }aaaaaaaaaaaaaaaaaa| 1082 {101: }{100:>>>}aaaaaaaaaaaa | 1083 | 1084 ]]) 1085 feed('gj') 1086 screen:expect([[ 1087 {103:0 }øøøøøøøøøøøøøøøøøø| 1088 {101: }{100:>>>}{102:øøøøøøøøø^øøø }| 1089 {101:1 }aaaaaaaaaaaaaaaaaa| 1090 {101: }{100:>>>}aaaaaaaaaaaa | 1091 | 1092 ]]) 1093 feed('gj') 1094 screen:expect([[ 1095 {101:1 }øøøøøøøøøøøøøøøøøø| 1096 {101: }{100:>>>}øøøøøøøøøøøø | 1097 {103:0 }{102:aaaaaaaaaaaa^aaaaaa}| 1098 {101: }{100:>>>}aaaaaaaaaaaa | 1099 | 1100 ]]) 1101 feed('gj') 1102 screen:expect([[ 1103 {101:1 }øøøøøøøøøøøøøøøøøø| 1104 {101: }{100:>>>}øøøøøøøøøøøø | 1105 {103:0 }aaaaaaaaaaaaaaaaaa| 1106 {101: }{100:>>>}{102:aaaaaaaaa^aaa }| 1107 | 1108 ]]) 1109 1110 -- updated in Insert mode 1111 feed('I') 1112 screen:expect([[ 1113 {101:1 }øøøøøøøøøøøøøøøøøø| 1114 {101: }{100:>>>}øøøøøøøøøøøø | 1115 {103:0 }{102:^aaaaaaaaaaaaaaaaaa}| 1116 {101: }{100:>>>}aaaaaaaaaaaa | 1117 {5:-- INSERT --} | 1118 ]]) 1119 1120 feed('<Esc>gg') 1121 screen:expect([[ 1122 {103:0 }{102:^øøøøøøøøøøøøøøøøøø}| 1123 {101: }{100:>>>}øøøøøøøøøøøø | 1124 {101:1 }aaaaaaaaaaaaaaaaaa| 1125 {101: }{100:>>>}aaaaaaaaaaaa | 1126 | 1127 ]]) 1128 end) 1129 1130 -- oldtest: Test_cursorline_screenline_resize() 1131 it("'cursorlineopt' screenline is updated on window resize", function() 1132 local screen = Screen.new(75, 8) 1133 exec([[ 1134 50vnew 1135 call setline(1, repeat('xyz ', 30)) 1136 setlocal number cursorline cursorlineopt=screenline 1137 normal! $ 1138 ]]) 1139 screen:expect([[ 1140 {8: 1 }xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xy│ | 1141 {8: }z xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz │{1:~ }| 1142 {8: }{21:xyz xyz xyz xyz xyz xyz xyz^ }│{1:~ }| 1143 {1:~ }│{1:~ }|*3 1144 {3:[No Name] [+] }{2:[No Name] }| 1145 | 1146 ]]) 1147 command('vertical resize -4') 1148 screen:expect([[ 1149 {8: 1 }xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xy│ | 1150 {8: }z xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz │{1:~ }| 1151 {8: }{21:xyz xyz xyz xyz xyz xyz xyz xyz xyz^ }│{1:~ }| 1152 {1:~ }│{1:~ }|*3 1153 {3:[No Name] [+] }{2:[No Name] }| 1154 | 1155 ]]) 1156 command('set cpoptions+=n') 1157 screen:expect([[ 1158 {8: 1 }xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xy│ | 1159 z xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz │{1:~ }| 1160 {21:xyz xyz xyz xyz xyz xyz xyz xyz^ }│{1:~ }| 1161 {1:~ }│{1:~ }|*3 1162 {3:[No Name] [+] }{2:[No Name] }| 1163 | 1164 ]]) 1165 end) 1166 1167 -- oldtest: Test_cursorline_screenline_update() 1168 it("'cursorlineopt' screenline is updated on various movements", function() 1169 local screen = Screen.new(75, 8) 1170 exec([[ 1171 func TestRetab() 1172 let w = winwidth(0) 1173 call cursor([1, w + 1, 0, w + 1]) 1174 call line('w0') 1175 retab 8 1176 endfunc 1177 1178 call setline(1, repeat('xyz ', 30)) 1179 set cursorline cursorlineopt=screenline tabstop=8 1180 inoremap <F2> <Cmd>call cursor(1, 1)<CR> 1181 inoremap <F3> <Cmd>call TestRetab()<CR> 1182 ]]) 1183 1184 feed('A') 1185 screen:expect([[ 1186 xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz| 1187 {21: xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz ^ }| 1188 {1:~ }|*5 1189 {5:-- INSERT --} | 1190 ]]) 1191 feed('<F2>') 1192 screen:expect([[ 1193 {21:^xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz}| 1194 xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz | 1195 {1:~ }|*5 1196 {5:-- INSERT --} | 1197 ]]) 1198 feed('<F3>') 1199 screen:expect([[ 1200 xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz| 1201 {21:^ xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz }| 1202 {1:~ }|*5 1203 {5:-- INSERT --} | 1204 ]]) 1205 feed('<Esc>') 1206 end) 1207 1208 -- oldtest: Test_cursorline_after_yank() 1209 it('always updated. vim-patch:8.1.0849', function() 1210 local screen = Screen.new(50, 5) 1211 screen:add_extra_attr_ids { 1212 [100] = { background = Screen.colors.LightRed }, 1213 [101] = { foreground = Screen.colors.SlateBlue, background = Screen.colors.Grey90 }, 1214 } 1215 command('set cursorline relativenumber') 1216 command('call setline(1, ["","1","2","3",""])') 1217 feed('Gy3k') 1218 screen:expect([[ 1219 {15: 0 }{21:^1 }| 1220 {8: 1 }2 | 1221 {8: 2 }3 | 1222 {8: 3 } | 1223 4 lines yanked | 1224 ]]) 1225 feed('jj') 1226 screen:expect([[ 1227 {8: 2 }1 | 1228 {8: 1 }2 | 1229 {15: 0 }{21:^3 }| 1230 {8: 1 } | 1231 4 lines yanked | 1232 ]]) 1233 end) 1234 1235 -- oldtest: Test_cursorline_with_visualmode() 1236 it('with visual area. vim-patch:8.1.1001', function() 1237 local screen = Screen.new(50, 5) 1238 screen:add_extra_attr_ids { 1239 [100] = { foreground = Screen.colors.SlateBlue, background = Screen.colors.Grey90 }, 1240 [101] = { background = Screen.colors.LightRed }, 1241 } 1242 command('set cursorline') 1243 command('call setline(1, repeat(["abc"], 50))') 1244 feed('V<C-f>zbkkjk') 1245 screen:expect([[ 1246 {17:abc} | 1247 ^a{17:bc} | 1248 abc |*2 1249 {5:-- VISUAL LINE --} | 1250 ]]) 1251 end) 1252 1253 -- oldtest: Test_cursorline_callback() 1254 it('is updated if cursor is moved up from timer vim-patch:8.2.4591', function() 1255 local screen = Screen.new(50, 8) 1256 exec([[ 1257 call setline(1, ['aaaaa', 'bbbbb', 'ccccc', 'ddddd']) 1258 set cursorline 1259 call cursor(4, 1) 1260 1261 func Func(timer) 1262 call cursor(2, 1) 1263 endfunc 1264 ]]) 1265 screen:expect([[ 1266 aaaaa | 1267 bbbbb | 1268 ccccc | 1269 {21:^ddddd }| 1270 {1:~ }|*3 1271 | 1272 ]]) 1273 command([[call timer_start(300, 'Func')]]) 1274 screen:expect_unchanged(false, 100) 1275 screen:expect([[ 1276 aaaaa | 1277 {21:^bbbbb }| 1278 ccccc | 1279 ddddd | 1280 {1:~ }|*3 1281 | 1282 ]]) 1283 end) 1284 1285 it('with split windows in diff mode', function() 1286 local screen = Screen.new(50, 12) 1287 screen:add_extra_attr_ids { 1288 [100] = { background = Screen.colors.Plum1, underline = true }, 1289 [101] = { background = Screen.colors.Red1, bold = true, underline = true }, 1290 } 1291 1292 command('hi CursorLine ctermbg=red ctermfg=white guibg=red guifg=white') 1293 command('set cursorline') 1294 feed('iline 1 some text<cr>line 2 more text<cr>extra line!<cr>extra line!<cr>last line ...<cr>') 1295 feed('<esc>gg') 1296 command('vsplit') 1297 command('enew') 1298 feed( 1299 'iline 1 some text<cr>line 2 moRe text!<cr>extra line!<cr>extra line!<cr>extra line!<cr>last line ...<cr>' 1300 ) 1301 feed('<esc>gg') 1302 command('windo diffthis') 1303 screen:expect([[ 1304 {7: }{9:line 1 some text }│{7: }{9:^line 1 some text }| 1305 {7: }{4:line 2 mo}{27:R}{4:e text}{27:!}{4: }│{7: }{4:line 2 mo}{27:r}{4:e text }| 1306 {7: }{22:extra line! }│{7: }{23:----------------------}| 1307 {7: }extra line! │{7: }extra line! |*2 1308 {7: }last line ... │{7: }last line ... | 1309 {7: } │{7: } | 1310 {1:~ }│{1:~ }|*3 1311 {2:[No Name] [+] }{3:[No Name] [+] }| 1312 | 1313 ]]) 1314 feed('jjjjj') 1315 screen:expect([[ 1316 {7: }line 1 some text │{7: }line 1 some text | 1317 {7: }{4:line 2 mo}{27:R}{4:e text}{27:!}{4: }│{7: }{4:line 2 mo}{27:r}{4:e text }| 1318 {7: }{22:extra line! }│{7: }{23:----------------------}| 1319 {7: }extra line! │{7: }extra line! |*2 1320 {7: }last line ... │{7: }last line ... | 1321 {7: }{9: }│{7: }{9:^ }| 1322 {1:~ }│{1:~ }|*3 1323 {2:[No Name] [+] }{3:[No Name] [+] }| 1324 | 1325 ]]) 1326 1327 -- CursorLine with fg=NONE is "low-priority". 1328 -- Rendered as underline in a diff-line. #9028 1329 command('hi CursorLine ctermbg=red ctermfg=NONE guibg=red guifg=NONE') 1330 feed('kkkk') 1331 screen:expect([[ 1332 {7: }line 1 some text │{7: }line 1 some text | 1333 {7: }{100:line 2 mo}{101:R}{100:e text}{101:!}{100: }│{7: }{100:^line 2 mo}{101:r}{100:e text }| 1334 {7: }{22:extra line! }│{7: }{23:----------------------}| 1335 {7: }extra line! │{7: }extra line! |*2 1336 {7: }last line ... │{7: }last line ... | 1337 {7: } │{7: } | 1338 {1:~ }│{1:~ }|*3 1339 {2:[No Name] [+] }{3:[No Name] [+] }| 1340 | 1341 ]]) 1342 end) 1343 1344 -- oldtest: Test_diff_with_cursorline_number() 1345 it('CursorLineNr shows correctly just below filler lines', function() 1346 local screen = Screen.new(50, 12) 1347 screen:add_extra_attr_ids { 1348 [100] = { foreground = Screen.colors.Black, bold = true, background = Screen.colors.Grey100 }, 1349 } 1350 1351 command('hi CursorLine guibg=red guifg=white') 1352 command('hi CursorLineNr guibg=white guifg=black gui=bold') 1353 command('set cursorline number') 1354 command('call setline(1, ["baz", "foo", "foo", "bar"])') 1355 feed('2gg0') 1356 command('vnew') 1357 command('call setline(1, ["foo", "foo", "bar"])') 1358 command('windo diffthis') 1359 command('1wincmd w') 1360 screen:expect([[ 1361 {7: }{8: }{23:-------------------}│{7: }{8: 1 }{22:baz }| 1362 {7: }{100: 1 }{9:^foo }│{7: }{100: 2 }{9:foo }| 1363 {7: }{8: 2 }foo │{7: }{8: 3 }foo | 1364 {7: }{8: 3 }bar │{7: }{8: 4 }bar | 1365 {1:~ }│{1:~ }|*6 1366 {3:[No Name] [+] }{2:[No Name] [+] }| 1367 | 1368 ]]) 1369 command('set cursorlineopt=number') 1370 screen:expect([[ 1371 {7: }{8: }{23:-------------------}│{7: }{8: 1 }{22:baz }| 1372 {7: }{100: 1 }^foo │{7: }{100: 2 }{9:foo }| 1373 {7: }{8: 2 }foo │{7: }{8: 3 }foo | 1374 {7: }{8: 3 }bar │{7: }{8: 4 }bar | 1375 {1:~ }│{1:~ }|*6 1376 {3:[No Name] [+] }{2:[No Name] [+] }| 1377 | 1378 ]]) 1379 end) 1380 1381 it('CursorLine overlays hl group linked to Normal', function() 1382 local screen = Screen.new(50, 12) 1383 screen:add_extra_attr_ids({ 1384 [101] = { background = Screen.colors.Grey90, foreground = Screen.colors.Grey100 }, 1385 [102] = { background = Screen.colors.DarkGray, foreground = Screen.colors.WebGreen }, 1386 }) 1387 command('hi Normal guibg=black guifg=white') 1388 command('hi def link Test Normal') 1389 feed('ifoo bar<ESC>') 1390 feed(':call matchadd("Test", "bar")<cr>') 1391 command('set cursorline') 1392 screen:expect([[ 1393 {21:foo }{101:ba^r}{21: }| 1394 {1:~ }|*10 1395 :call matchadd("Test", "bar") | 1396 ]]) 1397 api.nvim_buf_set_lines(0, 0, -1, false, { 'aaaaa', 'bbbbb' }) 1398 command('hi AAA guifg=Green guibg=DarkGrey ctermfg=Green ctermbg=DarkGrey') 1399 fn.matchadd('AAA', 'aaaaa') 1400 command('setlocal winhighlight=Normal:NormalFloat') 1401 screen:expect([[ 1402 {102:aaaa^a}{21: }| 1403 {4:bbbbb }| 1404 {11:~ }|*9 1405 :call matchadd("Test", "bar") | 1406 ]]) 1407 end) 1408 end) 1409 1410 describe('CursorColumn highlight', function() 1411 local screen 1412 before_each(function() 1413 clear() 1414 screen = Screen.new(50, 8) 1415 screen:add_extra_attr_ids { 1416 [100] = { background = Screen.colors.Blue1 }, 1417 } 1418 end) 1419 1420 it('is updated when pressing "i" on a TAB character', function() 1421 exec([[ 1422 call setline(1, ['123456789', "a\tb"]) 1423 set cursorcolumn 1424 call cursor(2, 2) 1425 ]]) 1426 screen:expect([[ 1427 1234567{21:8}9 | 1428 a ^ b | 1429 {1:~ }|*5 1430 | 1431 ]]) 1432 feed('i') 1433 screen:expect([[ 1434 1{21:2}3456789 | 1435 a^ b | 1436 {1:~ }|*5 1437 {5:-- INSERT --} | 1438 ]]) 1439 feed('<C-O>') 1440 screen:expect([[ 1441 1234567{21:8}9 | 1442 a ^ b | 1443 {1:~ }|*5 1444 {5:-- (insert) --} | 1445 ]]) 1446 feed('i') 1447 screen:expect([[ 1448 1{21:2}3456789 | 1449 a^ b | 1450 {1:~ }|*5 1451 {5:-- INSERT --} | 1452 ]]) 1453 end) 1454 1455 -- oldtest: Test_cursorcolumn_callback() 1456 it('is updated if cursor is moved from timer', function() 1457 exec([[ 1458 call setline(1, ['aaaaa', 'bbbbb', 'ccccc', 'ddddd']) 1459 set cursorcolumn 1460 call cursor(4, 5) 1461 1462 func Func(timer) 1463 call cursor(1, 1) 1464 endfunc 1465 ]]) 1466 screen:expect([[ 1467 aaaa{21:a} | 1468 bbbb{21:b} | 1469 cccc{21:c} | 1470 dddd^d | 1471 {1:~ }|*3 1472 | 1473 ]]) 1474 command([[call timer_start(300, 'Func')]]) 1475 screen:expect_unchanged(false, 100) 1476 screen:expect([[ 1477 ^aaaaa | 1478 {21:b}bbbb | 1479 {21:c}cccc | 1480 {21:d}dddd | 1481 {1:~ }|*3 1482 | 1483 ]]) 1484 end) 1485 1486 it('is not shown on current line with virtualedit', function() 1487 exec([[ 1488 hi! CursorColumn guibg=Red 1489 hi! CursorLine guibg=Blue 1490 set virtualedit=all cursorline cursorcolumn 1491 ]]) 1492 insert('line 1\nline 2\nline 3') 1493 feed('k') 1494 screen:expect([[ 1495 line {30:1} | 1496 {100:line ^2 }| 1497 line {30:3} | 1498 {1:~ }|*4 1499 | 1500 ]]) 1501 feed('l') 1502 screen:expect([[ 1503 line 1{30: } | 1504 {100:line 2^ }| 1505 line 3{30: } | 1506 {1:~ }|*4 1507 | 1508 ]]) 1509 feed('l') 1510 screen:expect([[ 1511 line 1 {30: } | 1512 {100:line 2 ^ }| 1513 line 3 {30: } | 1514 {1:~ }|*4 1515 | 1516 ]]) 1517 feed('l') 1518 screen:expect([[ 1519 line 1 {30: } | 1520 {100:line 2 ^ }| 1521 line 3 {30: } | 1522 {1:~ }|*4 1523 | 1524 ]]) 1525 end) 1526 end) 1527 1528 describe('ColorColumn highlight', function() 1529 local screen 1530 1531 before_each(function() 1532 clear() 1533 screen = Screen.new(40, 15) 1534 screen:add_extra_attr_ids { 1535 [100] = { foreground = Screen.colors.Red, background = Screen.colors.Grey90 }, 1536 [101] = { background = Screen.colors.LightRed }, 1537 [102] = { foreground = Screen.colors.Blue1, bold = true, background = Screen.colors.LightRed }, 1538 } 1539 end) 1540 1541 -- oldtest: Test_colorcolumn() 1542 it('when entering a buffer vim-patch:8.1.2073', function() 1543 exec([[ 1544 set nohidden 1545 split 1546 edit X 1547 call setline(1, ["1111111111","22222222222","3333333333"]) 1548 set nomodified 1549 set colorcolumn=3,9 1550 set number cursorline cursorlineopt=number 1551 wincmd w 1552 buf X 1553 ]]) 1554 screen:expect([[ 1555 {15: 1 }11{101:1}11111{101:1}1 | 1556 {8: 2 }22{101:2}22222{101:2}22 | 1557 {8: 3 }33{101:3}33333{101:3}3 | 1558 {1:~ }|*3 1559 {2:X }| 1560 {15: 1 }^11{101:1}11111{101:1}1 | 1561 {8: 2 }22{101:2}22222{101:2}22 | 1562 {8: 3 }33{101:3}33333{101:3}3 | 1563 {1:~ }|*3 1564 {3:X }| 1565 | 1566 ]]) 1567 end) 1568 1569 -- oldtest: Test_colorcolumn_bri() 1570 it("in 'breakindent' vim-patch:8.2.1689", function() 1571 exec([[ 1572 call setline(1, 'The quick brown fox jumped over the lazy dogs') 1573 set co=40 linebreak bri briopt=shift:2 cc=40,41,43 1574 ]]) 1575 screen:expect([[ 1576 ^The quick brown fox jumped over the {101: }| 1577 {101: } {101:l}azy dogs | 1578 {1:~ }|*12 1579 | 1580 ]]) 1581 end) 1582 1583 -- oldtest: Test_colorcolumn_sbr() 1584 it("in 'showbreak' vim-patch:8.2.1689", function() 1585 exec([[ 1586 call setline(1, 'The quick brown fox jumped over the lazy dogs') 1587 set co=40 showbreak=+++>\\ cc=40,41,43 1588 ]]) 1589 screen:expect([[ 1590 ^The quick brown fox jumped over the laz{101:y}| 1591 {102:+}{1:+}{102:+}{1:>\} dogs | 1592 {1:~ }|*12 1593 | 1594 ]]) 1595 end) 1596 1597 it('is combined with low-priority CursorLine highlight #23016', function() 1598 screen:try_resize(40, 2) 1599 command('set colorcolumn=30 cursorline') 1600 screen:expect([[ 1601 {21:^ }{101: }{21: }| 1602 | 1603 ]]) 1604 command('hi clear ColorColumn') 1605 screen:expect([[ 1606 {21:^ }| 1607 | 1608 ]]) 1609 command('hi ColorColumn guifg=Red') 1610 screen:expect([[ 1611 {21:^ }{100: }{21: }| 1612 | 1613 ]]) 1614 end) 1615 end) 1616 1617 describe('MsgSeparator highlight and msgsep fillchar', function() 1618 local screen 1619 before_each(function() 1620 clear() 1621 screen = Screen.new(50, 5) 1622 screen:set_default_attr_ids({ 1623 [1] = { bold = true, foreground = Screen.colors.Blue }, 1624 [2] = { bold = true, reverse = true }, 1625 [3] = { bold = true, foreground = Screen.colors.SeaGreen4 }, 1626 [4] = { background = Screen.colors.Cyan, bold = true, reverse = true }, 1627 [5] = { bold = true, background = Screen.colors.Magenta }, 1628 [6] = { background = Screen.colors.WebGray }, 1629 [7] = { 1630 background = Screen.colors.WebGray, 1631 bold = true, 1632 foreground = Screen.colors.SeaGreen4, 1633 }, 1634 [8] = { foreground = Screen.colors.Grey0, background = Screen.colors.Gray60 }, 1635 [9] = { foreground = Screen.colors.Grey40, background = Screen.colors.Gray60 }, 1636 [10] = { foreground = tonumber('0x000019'), background = Screen.colors.Gray60 }, 1637 [11] = { background = Screen.colors.Gray60, bold = true, foreground = tonumber('0x666699') }, 1638 [12] = { background = Screen.colors.Gray60, bold = true, foreground = tonumber('0x297d4e') }, 1639 [13] = { background = tonumber('0xff4cff'), bold = true, foreground = tonumber('0xb200ff') }, 1640 }) 1641 end) 1642 1643 it('works', function() 1644 -- defaults 1645 feed_command('ls') 1646 screen:expect([[ 1647 | 1648 {2: }| 1649 :ls | 1650 1 %a "[No Name]" line 1 | 1651 {3:Press ENTER or type command to continue}^ | 1652 ]]) 1653 feed('<cr>') 1654 1655 feed_command('set fillchars+=msgsep:-') 1656 feed_command('ls') 1657 screen:expect([[ 1658 | 1659 {2:--------------------------------------------------}| 1660 :ls | 1661 1 %a "[No Name]" line 1 | 1662 {3:Press ENTER or type command to continue}^ | 1663 ]]) 1664 1665 -- linked to StatusLine per default 1666 feed_command('hi StatusLine guibg=Cyan') 1667 feed_command('ls') 1668 screen:expect([[ 1669 | 1670 {4:--------------------------------------------------}| 1671 :ls | 1672 1 %a "[No Name]" line 1 | 1673 {3:Press ENTER or type command to continue}^ | 1674 ]]) 1675 1676 -- but can be unlinked 1677 feed_command('hi clear MsgSeparator') 1678 feed_command('hi MsgSeparator guibg=Magenta gui=bold') 1679 feed_command('ls') 1680 screen:expect([[ 1681 | 1682 {5:--------------------------------------------------}| 1683 :ls | 1684 1 %a "[No Name]" line 1 | 1685 {3:Press ENTER or type command to continue}^ | 1686 ]]) 1687 end) 1688 1689 it('and MsgArea', function() 1690 feed_command('hi MsgArea guibg=Gray') 1691 screen:expect { 1692 grid = [[ 1693 ^ | 1694 {1:~ }|*3 1695 {6: }| 1696 ]], 1697 } 1698 feed(':ls') 1699 screen:expect { 1700 grid = [[ 1701 | 1702 {1:~ }|*3 1703 {6::ls^ }| 1704 ]], 1705 } 1706 feed(':<cr>') 1707 screen:expect { 1708 grid = [[ 1709 | 1710 {2: }| 1711 {6::ls: }| 1712 {6: 1 %a "[No Name]" line 1 }| 1713 {7:Press ENTER or type command to continue}{6:^ }| 1714 ]], 1715 } 1716 1717 -- support madness^Wblending of message "overlay" 1718 feed_command('hi MsgArea blend=20') 1719 feed_command('hi clear MsgSeparator') 1720 feed_command('hi MsgSeparator blend=30 guibg=Magenta') 1721 screen:expect { 1722 grid = [[ 1723 ^ | 1724 {1:~ }|*3 1725 {8::hi}{9: }{8:MsgSeparator}{9: }{8:blend=30}{9: }{8:guibg=Magenta}{9: }| 1726 ]], 1727 } 1728 feed(':ls') 1729 screen:expect { 1730 grid = [[ 1731 | 1732 {1:~ }|*3 1733 {8::ls}{9:^ }| 1734 ]], 1735 } 1736 feed('<cr>') 1737 screen:expect { 1738 grid = [[ 1739 | 1740 {13:~ }| 1741 {10::ls}{11: }| 1742 {11:~ }{10:1}{11: }{10:%a}{11: }{10:"[No}{11: }{10:Name]"}{11: }{10:line}{11: }{10:1}{11: }| 1743 {12:Press}{9: }{12:ENTER}{9: }{12:or}{9: }{12:type}{9: }{12:command}{9: }{12:to}{9: }{12:continue}{9:^ }| 1744 ]], 1745 } 1746 end) 1747 end) 1748 1749 describe("'winhighlight' highlight", function() 1750 local screen 1751 1752 before_each(function() 1753 clear() 1754 screen = Screen.new(20, 8) 1755 screen:set_default_attr_ids { 1756 [0] = { bold = true, foreground = Screen.colors.Blue }, 1757 [1] = { background = Screen.colors.DarkBlue }, 1758 [2] = { background = Screen.colors.DarkBlue, bold = true, foreground = Screen.colors.Blue1 }, 1759 [3] = { bold = true, reverse = true }, 1760 [4] = { reverse = true }, 1761 [5] = { background = Screen.colors.DarkGreen }, 1762 [6] = { background = Screen.colors.DarkGreen, bold = true, foreground = Screen.colors.Blue1 }, 1763 [7] = { background = Screen.colors.DarkMagenta }, 1764 [8] = { 1765 background = Screen.colors.DarkMagenta, 1766 bold = true, 1767 foreground = Screen.colors.Blue1, 1768 }, 1769 [9] = { foreground = Screen.colors.Brown }, 1770 [10] = { foreground = Screen.colors.Brown, background = Screen.colors.DarkBlue }, 1771 [11] = { background = Screen.colors.DarkBlue, bold = true, reverse = true }, 1772 [12] = { background = Screen.colors.DarkGreen, reverse = true }, 1773 [13] = { background = Screen.colors.Magenta4, reverse = true }, 1774 [14] = { background = Screen.colors.DarkBlue, reverse = true }, 1775 [15] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, 1776 [16] = { foreground = Screen.colors.Blue1 }, 1777 [17] = { background = Screen.colors.LightRed }, 1778 [18] = { background = Screen.colors.Gray90 }, 1779 [19] = { foreground = Screen.colors.LightGrey, background = Screen.colors.DarkGray }, 1780 [20] = { background = Screen.colors.LightGrey, underline = true }, 1781 [21] = { bold = true }, 1782 [22] = { bold = true, foreground = Screen.colors.SeaGreen4 }, 1783 [23] = { background = Screen.colors.LightMagenta }, 1784 [24] = { background = Screen.colors.WebGray }, 1785 [25] = { bold = true, foreground = Screen.colors.Green1 }, 1786 [26] = { background = Screen.colors.Red }, 1787 [27] = { background = Screen.colors.DarkBlue, bold = true, foreground = Screen.colors.Green1 }, 1788 [28] = { bold = true, foreground = Screen.colors.Brown }, 1789 [29] = { foreground = Screen.colors.Blue1, background = Screen.colors.Red, bold = true }, 1790 [30] = { background = tonumber('0xff8800') }, 1791 [31] = { background = tonumber('0xff8800'), bold = true, foreground = Screen.colors.Blue }, 1792 [32] = { bold = true, reverse = true, background = Screen.colors.DarkGreen }, 1793 } 1794 command('hi Background1 guibg=DarkBlue') 1795 command('hi Background2 guibg=DarkGreen') 1796 end) 1797 1798 it('works for background color', function() 1799 insert('aa') 1800 command('split') 1801 command('set winhl=Normal:Background1') 1802 screen:expect([[ 1803 {1:a^a }| 1804 {2:~ }|*2 1805 {3:[No Name] [+] }| 1806 aa | 1807 {0:~ }| 1808 {4:[No Name] [+] }| 1809 | 1810 ]]) 1811 1812 command('enew') 1813 screen:expect([[ 1814 {1:^ }| 1815 {2:~ }|*2 1816 {3:[No Name] }| 1817 aa | 1818 {0:~ }| 1819 {4:[No Name] [+] }| 1820 | 1821 ]]) 1822 end) 1823 1824 it('works for background color in rightleft window #22640', function() 1825 -- Use a wide screen to also check that this doesn't overflow linebuf_attr. 1826 screen:try_resize(80, 6) 1827 insert('aa') 1828 command('setlocal rightleft') 1829 command('setlocal winhl=Normal:Background1') 1830 screen:expect([[ 1831 {1: ^aa}| 1832 {2: ~}|*4 1833 | 1834 ]]) 1835 command('botright vsplit') 1836 screen:expect([[ 1837 {1: aa│ ^aa}| 1838 {2: ~}{1:│}{2: ~}|*3 1839 {4:[No Name] [+] }{3:[No Name] [+] }| 1840 | 1841 ]]) 1842 end) 1843 1844 it('handles undefined groups', function() 1845 command('set winhl=Normal:Background1') 1846 screen:expect([[ 1847 {1:^ }| 1848 {2:~ }|*6 1849 | 1850 ]]) 1851 1852 command('set winhl=xxx:yyy') 1853 eq('xxx:yyy', eval('&winhl')) 1854 screen:expect { 1855 grid = [[ 1856 ^ | 1857 {0:~ }|*6 1858 | 1859 ]], 1860 } 1861 end) 1862 1863 it('can be changed to define different groups', function() 1864 command('set winhl=EndOfBuffer:Background1') 1865 screen:expect { 1866 grid = [[ 1867 ^ | 1868 {1:~ }|*6 1869 | 1870 ]], 1871 } 1872 1873 command('set winhl=Normal:ErrorMsg') 1874 screen:expect { 1875 grid = [[ 1876 {15:^ }| 1877 {29:~ }|*6 1878 | 1879 ]], 1880 } 1881 end) 1882 1883 it('works local to the window', function() 1884 insert('aa') 1885 command('split') 1886 command('setlocal winhl=Normal:Background1') 1887 screen:expect([[ 1888 {1:a^a }| 1889 {2:~ }|*2 1890 {3:[No Name] [+] }| 1891 aa | 1892 {0:~ }| 1893 {4:[No Name] [+] }| 1894 | 1895 ]]) 1896 1897 command('enew') 1898 screen:expect([[ 1899 ^ | 1900 {0:~ }|*2 1901 {3:[No Name] }| 1902 aa | 1903 {0:~ }| 1904 {4:[No Name] [+] }| 1905 | 1906 ]]) 1907 1908 command('bnext') 1909 screen:expect([[ 1910 {1:^aa }| 1911 {2:~ }|*2 1912 {3:[No Name] [+] }| 1913 aa | 1914 {0:~ }| 1915 {4:[No Name] [+] }| 1916 | 1917 ]]) 1918 end) 1919 1920 it('for inactive window background works', function() 1921 command('set winhl=Normal:Background1,NormalNC:Background2') 1922 -- tests global value is copied across split 1923 command('split') 1924 screen:expect([[ 1925 {1:^ }| 1926 {2:~ }|*2 1927 {3:[No Name] }| 1928 {5: }| 1929 {6:~ }| 1930 {4:[No Name] }| 1931 | 1932 ]]) 1933 1934 feed('<c-w><c-w>') 1935 screen:expect([[ 1936 {5: }| 1937 {6:~ }|*2 1938 {4:[No Name] }| 1939 {1:^ }| 1940 {2:~ }| 1941 {3:[No Name] }| 1942 | 1943 ]]) 1944 1945 feed('<c-w><c-w>') 1946 screen:expect([[ 1947 {1:^ }| 1948 {2:~ }|*2 1949 {3:[No Name] }| 1950 {5: }| 1951 {6:~ }| 1952 {4:[No Name] }| 1953 | 1954 ]]) 1955 end) 1956 1957 it('works with NormalNC', function() 1958 command('hi NormalNC guibg=DarkMagenta') 1959 -- tests global value is copied across split 1960 command('split') 1961 screen:expect([[ 1962 ^ | 1963 {0:~ }|*2 1964 {3:[No Name] }| 1965 {7: }| 1966 {8:~ }| 1967 {4:[No Name] }| 1968 | 1969 ]]) 1970 1971 command('wincmd w') 1972 screen:expect([[ 1973 {7: }| 1974 {8:~ }|*2 1975 {4:[No Name] }| 1976 ^ | 1977 {0:~ }| 1978 {3:[No Name] }| 1979 | 1980 ]]) 1981 1982 -- winbg=Normal:... overrides global NormalNC 1983 command('set winhl=Normal:Background1') 1984 screen:expect([[ 1985 {7: }| 1986 {8:~ }|*2 1987 {4:[No Name] }| 1988 {1:^ }| 1989 {2:~ }| 1990 {3:[No Name] }| 1991 | 1992 ]]) 1993 1994 command('wincmd w') 1995 screen:expect([[ 1996 ^ | 1997 {0:~ }|*2 1998 {3:[No Name] }| 1999 {1: }| 2000 {2:~ }| 2001 {4:[No Name] }| 2002 | 2003 ]]) 2004 2005 command('wincmd w') 2006 command('set winhl=Normal:Background1,NormalNC:Background2') 2007 screen:expect([[ 2008 {7: }| 2009 {8:~ }|*2 2010 {4:[No Name] }| 2011 {1:^ }| 2012 {2:~ }| 2013 {3:[No Name] }| 2014 | 2015 ]]) 2016 2017 command('wincmd w') 2018 screen:expect([[ 2019 ^ | 2020 {0:~ }|*2 2021 {3:[No Name] }| 2022 {5: }| 2023 {6:~ }| 2024 {4:[No Name] }| 2025 | 2026 ]]) 2027 end) 2028 2029 it('updates background to changed linked group', function() 2030 command('split') 2031 command('setlocal winhl=Normal:FancyGroup') -- does not yet exist 2032 screen:expect { 2033 grid = [[ 2034 ^ | 2035 {0:~ }|*2 2036 {3:[No Name] }| 2037 | 2038 {0:~ }| 2039 {4:[No Name] }| 2040 | 2041 ]], 2042 } 2043 2044 command('hi FancyGroup guibg=#FF8800') -- nice orange 2045 screen:expect { 2046 grid = [[ 2047 {30:^ }| 2048 {31:~ }|*2 2049 {3:[No Name] }| 2050 | 2051 {0:~ }| 2052 {4:[No Name] }| 2053 | 2054 ]], 2055 } 2056 end) 2057 2058 it('background applies also to non-text', function() 2059 command('set sidescroll=0') 2060 insert('Lorem ipsum dolor sit amet ') 2061 command('set shiftwidth=2') 2062 feed('>>') 2063 command('set number') 2064 command('set breakindent') 2065 command('set briopt=shift:5,min:0') 2066 command('set list') 2067 command('set showbreak=↪') 2068 screen:expect([[ 2069 {9: 1 } ^Lorem ipsum do| 2070 {9: } {0:↪}lor sit | 2071 {9: } {0:↪}amet{0:-} | 2072 {0:~ }|*4 2073 | 2074 ]]) 2075 2076 command('set winhl=Normal:Background1') 2077 screen:expect([[ 2078 {10: 1 }{1: ^Lorem ipsum do}| 2079 {10: }{1: }{2:↪}{1:lor sit }| 2080 {10: }{1: }{2:↪}{1:amet}{2:-}{1: }| 2081 {2:~ }|*4 2082 | 2083 ]]) 2084 2085 command('set nowrap') 2086 command('set listchars+=extends:❯,precedes:❮') 2087 feed('3w') 2088 screen:expect([[ 2089 {10: 1 }{2:❮}{1: dolor ^sit ame}{2:❯}| 2090 {2:~ }|*6 2091 | 2092 ]]) 2093 end) 2094 2095 it("background doesn't override syntax background", function() 2096 command('syntax on') 2097 command('syntax keyword Foobar foobar') 2098 command('syntax keyword Article the') 2099 command('hi Foobar guibg=#FF0000') 2100 command('hi Article guifg=#00FF00 gui=bold') 2101 insert('the foobar was foobar') 2102 screen:expect([[ 2103 {25:the} {26:foobar} was {26:fooba}| 2104 {26:^r} | 2105 {0:~ }|*5 2106 | 2107 ]]) 2108 2109 -- winhl=Normal:Group with background doesn't override syntax background, 2110 -- but does combine with syntax foreground. 2111 command('set winhl=Normal:Background1') 2112 screen:expect([[ 2113 {27:the}{1: }{26:foobar}{1: was }{26:fooba}| 2114 {26:^r}{1: }| 2115 {2:~ }|*5 2116 | 2117 ]]) 2118 end) 2119 2120 it('can override NonText, Conceal and EndOfBuffer', function() 2121 api.nvim_buf_set_lines(0, 0, -1, true, { 'raa\000' }) 2122 command('call matchaddpos("Conceal", [[1,2]], 0, -1, {"conceal": "#"})') 2123 command('set cole=2 cocu=nvic') 2124 command('split') 2125 command('call matchaddpos("Conceal", [[1,2]], 0, -1, {"conceal": "#"})') 2126 command('set winhl=SpecialKey:ErrorMsg,EndOfBuffer:Background1,' .. 'Conceal:Background2') 2127 2128 screen:expect([[ 2129 ^r{5:#}a{15:^@} | 2130 {1:~ }|*2 2131 {3:[No Name] [+] }| 2132 r{19:#}a{16:^@} | 2133 {0:~ }| 2134 {4:[No Name] [+] }| 2135 | 2136 ]]) 2137 end) 2138 2139 it('can override LineNr, CursorColumn and ColorColumn', function() 2140 insert('very text\nmore text') 2141 command('set number') 2142 command('set colorcolumn=2') 2143 command('set cursorcolumn') 2144 feed('k') 2145 2146 command('split') 2147 command('set winhl=LineNr:Background1,CursorColumn:Background2,' .. 'ColorColumn:ErrorMsg') 2148 screen:expect([[ 2149 {1: 1 }v{15:e}ry tex^t | 2150 {1: 2 }m{15:o}re tex{5:t} | 2151 {0:~ }| 2152 {3:[No Name] [+] }| 2153 {9: 1 }v{17:e}ry text | 2154 {9: 2 }m{17:o}re tex{18:t} | 2155 {4:[No Name] [+] }| 2156 | 2157 ]]) 2158 end) 2159 2160 it('can override Tabline', function() 2161 command('tabnew') 2162 command('set winhl=TabLine:Background1,TabLineSel:ErrorMsg') 2163 2164 screen:expect([[ 2165 {20: No Name] }{15: No Name]}{20:X}| 2166 ^ | 2167 {0:~ }|*5 2168 | 2169 ]]) 2170 command('tabnext') 2171 screen:expect([[ 2172 {21: No Name] }{1: No Name]}{20:X}| 2173 ^ | 2174 {0:~ }|*5 2175 | 2176 ]]) 2177 end) 2178 2179 it('can override popupmenu', function() 2180 insert('word wording wordy') 2181 command('split') 2182 command( 2183 'set winhl=Pmenu:Background1,PmenuSel:Background2,' .. 'PmenuSbar:ErrorMsg,PmenuThumb:Normal' 2184 ) 2185 screen:expect([[ 2186 word wording word^y | 2187 {0:~ }|*2 2188 {3:[No Name] [+] }| 2189 word wording wordy | 2190 {0:~ }| 2191 {4:[No Name] [+] }| 2192 | 2193 ]]) 2194 2195 feed('oword<c-x><c-p>') 2196 screen:expect([[ 2197 word wording wordy | 2198 wordy^ | 2199 {1:word }{0: }| 2200 {1:wording }{3: }| 2201 {5:wordy }rdy | 2202 wordy | 2203 {4:[No Name] [+] }| 2204 {21:-- }{22:match 1 of 3} | 2205 ]]) 2206 2207 feed('<esc>u<c-w><c-w>oword<c-x><c-p>') 2208 screen:expect([[ 2209 word wording wordy | 2210 wordy | 2211 {23:word }{0: }| 2212 {23:wording }{4: }| 2213 {24:wordy }rdy | 2214 wordy^ | 2215 {3:[No Name] [+] }| 2216 {21:-- }{22:match 1 of 3} | 2217 ]]) 2218 end) 2219 2220 it('can override CursorLine and CursorLineNr', function() 2221 -- CursorLine used to be parsed as CursorLineNr, because strncmp 2222 command('set cursorline number') 2223 command('split') 2224 command('set winhl=CursorLine:Background1') 2225 screen:expect { 2226 grid = [[ 2227 {28: 1 }{1:^ }| 2228 {0:~ }|*2 2229 {3:[No Name] }| 2230 {28: 1 }{18: }| 2231 {0:~ }| 2232 {4:[No Name] }| 2233 | 2234 ]], 2235 } 2236 2237 command('set winhl=CursorLineNr:Background2,CursorLine:Background1') 2238 screen:expect { 2239 grid = [[ 2240 {5: 1 }{1:^ }| 2241 {0:~ }|*2 2242 {3:[No Name] }| 2243 {28: 1 }{18: }| 2244 {0:~ }| 2245 {4:[No Name] }| 2246 | 2247 ]], 2248 } 2249 2250 feed('<c-w>w') 2251 screen:expect { 2252 grid = [[ 2253 {5: 1 }{1: }| 2254 {0:~ }|*2 2255 {4:[No Name] }| 2256 {28: 1 }{18:^ }| 2257 {0:~ }| 2258 {3:[No Name] }| 2259 | 2260 ]], 2261 } 2262 end) 2263 2264 it('can override StatusLine and StatusLineNC', function() 2265 command('set winhighlight=StatusLine:Background1,StatusLineNC:Background2') 2266 command('split') 2267 screen:expect([[ 2268 ^ | 2269 {0:~ }|*2 2270 {1:[No Name] }| 2271 | 2272 {0:~ }| 2273 {5:[No Name] }| 2274 | 2275 ]]) 2276 end) 2277 2278 it('can override WinBar and WinBarNC #19345', function() 2279 command('setlocal winbar=foobar') 2280 command('set winhighlight=WinBar:Background1,WinBarNC:Background2') 2281 command('split') 2282 screen:expect([[ 2283 {1:foobar }| 2284 ^ | 2285 {0:~ }| 2286 {3:[No Name] }| 2287 {5:foobar }| 2288 | 2289 {4:[No Name] }| 2290 | 2291 ]]) 2292 end) 2293 2294 it('can override syntax groups', function() 2295 command('syntax on') 2296 command('syntax keyword Foobar foobar') 2297 command('syntax keyword Article the') 2298 command('hi Foobar guibg=#FF0000') 2299 command('hi Article guifg=#00FF00 gui=bold') 2300 insert('the foobar was foobar') 2301 screen:expect([[ 2302 {25:the} {26:foobar} was {26:fooba}| 2303 {26:^r} | 2304 {0:~ }|*5 2305 | 2306 ]]) 2307 2308 command('split') 2309 command('set winhl=Foobar:Background1,Article:ErrorMsg') 2310 screen:expect { 2311 grid = [[ 2312 {15:the} {1:foobar} was {1:fooba}| 2313 {1:^r} | 2314 {0:~ }| 2315 {3:[No Name] [+] }| 2316 {25:the} {26:foobar} was {26:fooba}| 2317 {26:r} | 2318 {4:[No Name] [+] }| 2319 | 2320 ]], 2321 } 2322 end) 2323 2324 it('can be disabled in newly opened window #19823', function() 2325 command('split | set winhl=Normal:ErrorMsg | set winhl=') 2326 screen:expect { 2327 grid = [[ 2328 ^ | 2329 {0:~ }|*2 2330 {3:[No Name] }| 2331 | 2332 {0:~ }| 2333 {4:[No Name] }| 2334 | 2335 ]], 2336 } 2337 2338 n.assert_alive() 2339 end) 2340 2341 it('can redraw statusline on cursor movement', function() 2342 screen:try_resize(40, 8) 2343 exec [[ 2344 set statusline=%f%=%#Background1#%l,%c%V\ %P 2345 split 2346 ]] 2347 insert [[ 2348 some text 2349 more text]] 2350 screen:expect { 2351 grid = [[ 2352 some text | 2353 more tex^t | 2354 {0:~ }| 2355 {3:[No Name] }{11:2,9 All}| 2356 some text | 2357 more text | 2358 {4:[No Name] }{14:1,1 All}| 2359 | 2360 ]], 2361 } 2362 2363 command 'set winhl=Background1:Background2' 2364 screen:expect { 2365 grid = [[ 2366 some text | 2367 more tex^t | 2368 {0:~ }| 2369 {3:[No Name] }{32:2,9 All}| 2370 some text | 2371 more text | 2372 {4:[No Name] }{14:1,1 All}| 2373 | 2374 ]], 2375 } 2376 2377 feed 'k' 2378 screen:expect { 2379 grid = [[ 2380 some tex^t | 2381 more text | 2382 {0:~ }| 2383 {3:[No Name] }{32:1,9 All}| 2384 some text | 2385 more text | 2386 {4:[No Name] }{14:1,1 All}| 2387 | 2388 ]], 2389 } 2390 end) 2391 2392 it('can link to empty highlight group', function() 2393 command 'hi NormalNC guibg=Red' -- czerwone time 2394 command 'set winhl=NormalNC:Normal' 2395 command 'split' 2396 2397 screen:expect { 2398 grid = [[ 2399 ^ | 2400 {0:~ }|*2 2401 {3:[No Name] }| 2402 | 2403 {0:~ }| 2404 {4:[No Name] }| 2405 | 2406 ]], 2407 } 2408 end) 2409 end) 2410 2411 describe('highlight namespaces', function() 2412 local screen 2413 local ns1, ns2 2414 2415 before_each(function() 2416 clear() 2417 screen = Screen.new(25, 10) 2418 screen:set_default_attr_ids { 2419 [1] = { foreground = Screen.colors.Blue, bold = true }, 2420 [2] = { background = Screen.colors.DarkGrey }, 2421 [3] = { 2422 italic = true, 2423 foreground = Screen.colors.DarkCyan, 2424 background = Screen.colors.DarkOrange4, 2425 }, 2426 [4] = { background = Screen.colors.Magenta4 }, 2427 [5] = { background = Screen.colors.Magenta4, foreground = Screen.colors.Crimson }, 2428 [6] = { bold = true, reverse = true }, 2429 [7] = { reverse = true }, 2430 [8] = { foreground = Screen.colors.Gray20 }, 2431 [9] = { foreground = Screen.colors.Blue }, 2432 [10] = { bold = true, foreground = Screen.colors.SeaGreen }, 2433 } 2434 2435 ns1 = api.nvim_create_namespace 'grungy' 2436 ns2 = api.nvim_create_namespace 'ultrared' 2437 2438 api.nvim_set_hl(ns1, 'Normal', { bg = 'DarkGrey' }) 2439 api.nvim_set_hl(ns1, 'NonText', { bg = 'DarkOrange4', fg = 'DarkCyan', italic = true }) 2440 api.nvim_set_hl(ns2, 'Normal', { bg = 'DarkMagenta' }) 2441 api.nvim_set_hl(ns2, 'NonText', { fg = 'Crimson' }) 2442 end) 2443 2444 it('can be used globally', function() 2445 screen:expect { 2446 grid = [[ 2447 ^ | 2448 {1:~ }|*8 2449 | 2450 ]], 2451 } 2452 2453 api.nvim_set_hl_ns(ns1) 2454 screen:expect { 2455 grid = [[ 2456 {2:^ }| 2457 {3:~ }|*8 2458 | 2459 ]], 2460 } 2461 2462 api.nvim_set_hl_ns(ns2) 2463 screen:expect { 2464 grid = [[ 2465 {4:^ }| 2466 {5:~ }|*8 2467 | 2468 ]], 2469 } 2470 2471 api.nvim_set_hl_ns(0) 2472 screen:expect { 2473 grid = [[ 2474 ^ | 2475 {1:~ }|*8 2476 | 2477 ]], 2478 } 2479 end) 2480 2481 it('can be used per window', function() 2482 local win1 = api.nvim_get_current_win() 2483 command 'split' 2484 local win2 = api.nvim_get_current_win() 2485 command 'split' 2486 2487 api.nvim_win_set_hl_ns(win1, ns1) 2488 api.nvim_win_set_hl_ns(win2, ns2) 2489 2490 screen:expect { 2491 grid = [[ 2492 ^ | 2493 {1:~ }| 2494 {6:[No Name] }| 2495 {4: }| 2496 {5:~ }| 2497 {7:[No Name] }| 2498 {2: }| 2499 {3:~ }| 2500 {7:[No Name] }| 2501 | 2502 ]], 2503 } 2504 end) 2505 2506 it('redraws correctly when ns=0', function() 2507 screen:expect { 2508 grid = [[ 2509 ^ | 2510 {1:~ }|*8 2511 | 2512 ]], 2513 } 2514 2515 api.nvim_set_hl(0, 'EndOfBuffer', { fg = '#333333' }) 2516 screen:expect { 2517 grid = [[ 2518 ^ | 2519 {8:~ }|*8 2520 | 2521 ]], 2522 } 2523 end) 2524 2525 it('winhl does not accept invalid value #24586', function() 2526 command('set winhl=Normal:Visual') 2527 for _, cmd in ipairs({ 2528 [[set winhl='Normal:Wrong']], 2529 [[set winhl=Normal:Wrong']], 2530 [[set winhl='Normal:Wrong]], 2531 }) do 2532 local res = exec_lua( 2533 [[ 2534 local _, msg = pcall(vim.api.nvim_command, ...) 2535 return { msg, vim.wo.winhl } 2536 ]], 2537 cmd 2538 ) 2539 eq({ 2540 'Vim(set):E5248: Invalid character in group name', 2541 'Normal:Visual', 2542 }, res) 2543 end 2544 end) 2545 2546 it('Normal in set_hl #25474', function() 2547 command('highlight Ignore guifg=bg ctermfg=White') 2548 api.nvim_set_hl(0, 'Normal', { bg = '#333333' }) 2549 command('highlight Ignore') 2550 screen:expect { 2551 grid = [[ 2552 | 2553 {1:~ }|*2 2554 {6: }| 2555 | 2556 Ignore {8:xxx} {9:ctermf}| 2557 {9:g=}15 {9:guifg=}| 2558 bg | 2559 {10:Press ENTER or type comma}| 2560 {10:nd to continue}^ | 2561 ]], 2562 } 2563 end) 2564 end) 2565 2566 describe('synIDattr()', function() 2567 before_each(function() 2568 clear() 2569 command('highlight Normal ctermfg=252 guifg=#ff0000 guibg=Black') 2570 -- Salmon #fa8072 Maroon #800000 2571 command( 2572 'highlight Keyword ctermfg=79 guifg=Salmon guisp=Maroon cterm=strikethrough gui=strikethrough' 2573 ) 2574 end) 2575 2576 it('returns cterm-color if RGB-capable UI is _not_ attached', function() 2577 eq('252', eval('synIDattr(hlID("Normal"), "fg")')) 2578 eq('252', eval('synIDattr(hlID("Normal"), "fg#")')) 2579 eq('', eval('synIDattr(hlID("Normal"), "bg")')) 2580 eq('', eval('synIDattr(hlID("Normal"), "bg#")')) 2581 eq('79', eval('synIDattr(hlID("Keyword"), "fg")')) 2582 eq('79', eval('synIDattr(hlID("Keyword"), "fg#")')) 2583 eq('', eval('synIDattr(hlID("Keyword"), "sp")')) 2584 eq('', eval('synIDattr(hlID("Keyword"), "sp#")')) 2585 end) 2586 2587 it('returns gui-color if "gui" arg is passed', function() 2588 eq('Black', eval('synIDattr(hlID("Normal"), "bg", "gui")')) 2589 eq('Maroon', eval('synIDattr(hlID("Keyword"), "sp", "gui")')) 2590 end) 2591 2592 it('returns gui-color if RGB-capable UI is attached', function() 2593 local _ = Screen.new(50, 7, { rgb = true }) 2594 eq('#ff0000', eval('synIDattr(hlID("Normal"), "fg")')) 2595 eq('Black', eval('synIDattr(hlID("Normal"), "bg")')) 2596 eq('Salmon', eval('synIDattr(hlID("Keyword"), "fg")')) 2597 eq('Maroon', eval('synIDattr(hlID("Keyword"), "sp")')) 2598 end) 2599 2600 it('returns #RRGGBB value for fg#/bg#/sp#', function() 2601 local _ = Screen.new(50, 7, { rgb = true }) 2602 eq('#ff0000', eval('synIDattr(hlID("Normal"), "fg#")')) 2603 eq('#000000', eval('synIDattr(hlID("Normal"), "bg#")')) 2604 eq('#fa8072', eval('synIDattr(hlID("Keyword"), "fg#")')) 2605 eq('#800000', eval('synIDattr(hlID("Keyword"), "sp#")')) 2606 end) 2607 2608 it('returns color number if non-RGB GUI', function() 2609 local _ = Screen.new(50, 7, { rgb = false }) 2610 eq('252', eval('synIDattr(hlID("Normal"), "fg")')) 2611 eq('79', eval('synIDattr(hlID("Keyword"), "fg")')) 2612 end) 2613 2614 it('returns "1" if group has given highlight attribute', function() 2615 local hl_attrs = { 2616 'underline', 2617 'undercurl', 2618 'underdouble', 2619 'underdotted', 2620 'underdashed', 2621 'strikethrough', 2622 } 2623 for _, hl_attr in ipairs(hl_attrs) do 2624 local context = 'using ' .. hl_attr .. ' attr' 2625 command('highlight Keyword cterm=' .. hl_attr .. ' gui=' .. hl_attr) 2626 eq('', eval('synIDattr(hlID("Normal"), "' .. hl_attr .. '")'), context) 2627 eq('1', eval('synIDattr(hlID("Keyword"), "' .. hl_attr .. '")'), context) 2628 eq('1', eval('synIDattr(hlID("Keyword"), "' .. hl_attr .. '", "gui")'), context) 2629 end 2630 end) 2631 end) 2632 2633 describe('fg/bg special colors', function() 2634 before_each(function() 2635 clear() 2636 command('highlight Normal ctermfg=145 ctermbg=16 guifg=#ff0000 guibg=Black') 2637 command('highlight Visual ctermfg=bg ctermbg=fg guifg=bg guibg=fg guisp=bg') 2638 end) 2639 2640 it('resolve to "Normal" values', function() 2641 eq(eval('synIDattr(hlID("Normal"), "bg")'), eval('synIDattr(hlID("Visual"), "fg")')) 2642 eq(eval('synIDattr(hlID("Normal"), "bg#")'), eval('synIDattr(hlID("Visual"), "fg#")')) 2643 eq(eval('synIDattr(hlID("Normal"), "fg")'), eval('synIDattr(hlID("Visual"), "bg")')) 2644 eq(eval('synIDattr(hlID("Normal"), "fg#")'), eval('synIDattr(hlID("Visual"), "bg#")')) 2645 eq('bg', eval('synIDattr(hlID("Visual"), "fg", "gui")')) 2646 eq('bg', eval('synIDattr(hlID("Visual"), "fg#", "gui")')) 2647 eq('fg', eval('synIDattr(hlID("Visual"), "bg", "gui")')) 2648 eq('fg', eval('synIDattr(hlID("Visual"), "bg#", "gui")')) 2649 eq('bg', eval('synIDattr(hlID("Visual"), "sp", "gui")')) 2650 eq('bg', eval('synIDattr(hlID("Visual"), "sp#", "gui")')) 2651 end) 2652 2653 it('resolve to "Normal" values in RGB-capable UI', function() 2654 local _ = Screen.new(50, 7, { rgb = true }) 2655 eq('bg', eval('synIDattr(hlID("Visual"), "fg")')) 2656 eq(eval('synIDattr(hlID("Normal"), "bg#")'), eval('synIDattr(hlID("Visual"), "fg#")')) 2657 eq('fg', eval('synIDattr(hlID("Visual"), "bg")')) 2658 eq(eval('synIDattr(hlID("Normal"), "fg#")'), eval('synIDattr(hlID("Visual"), "bg#")')) 2659 eq('bg', eval('synIDattr(hlID("Visual"), "sp")')) 2660 eq(eval('synIDattr(hlID("Normal"), "bg#")'), eval('synIDattr(hlID("Visual"), "sp#")')) 2661 end) 2662 2663 it('resolve after the "Normal" group is modified', function() 2664 local _ = Screen.new(50, 7, { rgb = true }) 2665 local new_guibg = '#282c34' 2666 local new_guifg = '#abb2bf' 2667 command('highlight Normal guifg=' .. new_guifg .. ' guibg=' .. new_guibg) 2668 eq(new_guibg, eval('synIDattr(hlID("Visual"), "fg#")')) 2669 eq(new_guifg, eval('synIDattr(hlID("Visual"), "bg#")')) 2670 eq(new_guibg, eval('synIDattr(hlID("Visual"), "sp#")')) 2671 end) 2672 2673 it('changed highlight is reflected in messages before redraw #17832', function() 2674 local screen = Screen.new(50, 7, { rgb = true }) 2675 command('set termguicolors') 2676 -- :echomsg in the same request, before the next redraw. 2677 command('call nvim_set_hl(0, "MsgArea", {"fg": "Red"}) | echomsg "foo"') 2678 screen:expect({ 2679 grid = [[ 2680 ^ | 2681 {1:~ }|*5 2682 {19:foo }| 2683 ]], 2684 }) 2685 end) 2686 end)