cmdline_highlight_spec.lua (27437B)
1 local t = require('test.testutil') 2 local n = require('test.functional.testnvim')() 3 local Screen = require('test.functional.ui.screen') 4 5 local eq = t.eq 6 local feed = n.feed 7 local clear = n.clear 8 local api = n.api 9 local fn = n.fn 10 local source = n.source 11 local exec_capture = n.exec_capture 12 local dedent = t.dedent 13 local command = n.command 14 15 local screen 16 17 -- Bug in input() handling: :redraw! will erase the whole prompt up until 18 -- user types something. It exists in Vim as well, so using `h<BS>` as 19 -- a workaround. 20 local function redraw_input() 21 feed('{REDRAW}h<BS>') 22 end 23 24 before_each(function() 25 clear() 26 screen = Screen.new(40, 8) 27 source([[ 28 highlight RBP1 guibg=Red 29 highlight RBP2 guibg=Yellow 30 highlight RBP3 guibg=Green 31 highlight RBP4 guibg=Blue 32 let g:NUM_LVLS = 4 33 function Redraw() 34 mode 35 return "\<Ignore>" 36 endfunction 37 let g:id = '' 38 cnoremap <expr> {REDRAW} Redraw() 39 function DoPrompt(do_return) abort 40 let id = g:id 41 let Cb = g:Nvim_color_input{g:id} 42 let out = input({'prompt': ':', 'highlight': Cb}) 43 let g:out{id} = out 44 return (a:do_return ? out : "\<Ignore>") 45 endfunction 46 nnoremap <expr> {PROMPT} DoPrompt(0) 47 cnoremap <expr> {PROMPT} DoPrompt(1) 48 function RainBowParens(cmdline) 49 let ret = [] 50 let i = 0 51 let lvl = 0 52 while i < len(a:cmdline) 53 if a:cmdline[i] is# '(' 54 call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)]) 55 let lvl += 1 56 elseif a:cmdline[i] is# ')' 57 let lvl -= 1 58 call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)]) 59 endif 60 let i += 1 61 endwhile 62 return ret 63 endfunction 64 function SplitMultibyteStart(cmdline) 65 let ret = [] 66 let i = 0 67 while i < len(a:cmdline) 68 let char = nr2char(char2nr(a:cmdline[i:])) 69 if a:cmdline[i:i + len(char) - 1] is# char 70 if len(char) > 1 71 call add(ret, [i + 1, i + len(char), 'RBP2']) 72 endif 73 let i += len(char) 74 else 75 let i += 1 76 endif 77 endwhile 78 return ret 79 endfunction 80 function SplitMultibyteEnd(cmdline) 81 let ret = [] 82 let i = 0 83 while i < len(a:cmdline) 84 let char = nr2char(char2nr(a:cmdline[i:])) 85 if a:cmdline[i:i + len(char) - 1] is# char 86 if len(char) > 1 87 call add(ret, [i, i + 1, 'RBP1']) 88 endif 89 let i += len(char) 90 else 91 let i += 1 92 endif 93 endwhile 94 return ret 95 endfunction 96 function Echoing(cmdline) 97 echo 'HERE' 98 return v:_null_list 99 endfunction 100 function Echoning(cmdline) 101 echon 'HERE' 102 return v:_null_list 103 endfunction 104 function Echomsging(cmdline) 105 echomsg 'HERE' 106 return v:_null_list 107 endfunction 108 function Echoerring(cmdline) 109 echoerr 'HERE' 110 return v:_null_list 111 endfunction 112 function Redrawing(cmdline) 113 redraw! 114 return v:_null_list 115 endfunction 116 function Throwing(cmdline) 117 throw "ABC" 118 return v:_null_list 119 endfunction 120 function Halting(cmdline) 121 while 1 122 endwhile 123 endfunction 124 function ReturningGlobal(cmdline) 125 return g:callback_return 126 endfunction 127 function ReturningGlobal2(cmdline) 128 return g:callback_return[:len(a:cmdline)-1] 129 endfunction 130 function ReturningGlobalN(n, cmdline) 131 return g:callback_return{a:n} 132 endfunction 133 let g:recording_calls = [] 134 function Recording(cmdline) 135 call add(g:recording_calls, a:cmdline) 136 return [] 137 endfunction 138 ]]) 139 screen:set_default_attr_ids({ 140 RBP1 = { background = Screen.colors.Red }, 141 RBP2 = { background = Screen.colors.Yellow }, 142 RBP3 = { background = Screen.colors.Green }, 143 RBP4 = { background = Screen.colors.Blue }, 144 EOB = { bold = true, foreground = Screen.colors.Blue1 }, 145 ERR = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, 146 SK = { foreground = Screen.colors.Blue }, 147 PE = { bold = true, foreground = Screen.colors.SeaGreen4 }, 148 NUM = { foreground = Screen.colors.Blue2 }, 149 NPAR = { foreground = Screen.colors.Yellow }, 150 SQ = { foreground = Screen.colors.Blue3 }, 151 SB = { foreground = Screen.colors.Blue4 }, 152 E = { foreground = Screen.colors.Red, background = Screen.colors.Blue }, 153 M = { bold = true }, 154 MSEP = { bold = true, reverse = true }, 155 }) 156 end) 157 158 local function set_color_cb(funcname, callback_return, id) 159 api.nvim_set_var('id', id or '') 160 if id and id ~= '' and fn.exists('*' .. funcname .. 'N') == 1 then 161 command(('let g:Nvim_color_input%s = {cmdline -> %sN(%s, cmdline)}'):format(id, funcname, id)) 162 if callback_return then 163 api.nvim_set_var('callback_return' .. id, callback_return) 164 end 165 else 166 api.nvim_set_var('Nvim_color_input', funcname) 167 if callback_return then 168 api.nvim_set_var('callback_return', callback_return) 169 end 170 end 171 end 172 local function start_prompt(text) 173 feed('{PROMPT}' .. (text or '')) 174 end 175 176 describe('Command-line coloring', function() 177 it('works', function() 178 set_color_cb('RainBowParens') 179 api.nvim_set_option_value('more', false, {}) 180 start_prompt() 181 screen:expect([[ 182 | 183 {EOB:~ }|*6 184 :^ | 185 ]]) 186 feed('e') 187 screen:expect([[ 188 | 189 {EOB:~ }|*6 190 :e^ | 191 ]]) 192 feed('cho ') 193 screen:expect([[ 194 | 195 {EOB:~ }|*6 196 :echo ^ | 197 ]]) 198 feed('(') 199 screen:expect([[ 200 | 201 {EOB:~ }|*6 202 :echo {RBP1:(}^ | 203 ]]) 204 feed('(') 205 screen:expect([[ 206 | 207 {EOB:~ }|*6 208 :echo {RBP1:(}{RBP2:(}^ | 209 ]]) 210 feed('42') 211 screen:expect([[ 212 | 213 {EOB:~ }|*6 214 :echo {RBP1:(}{RBP2:(}42^ | 215 ]]) 216 feed('))') 217 screen:expect([[ 218 | 219 {EOB:~ }|*6 220 :echo {RBP1:(}{RBP2:(}42{RBP2:)}{RBP1:)}^ | 221 ]]) 222 feed('<BS>') 223 screen:expect([[ 224 | 225 {EOB:~ }|*6 226 :echo {RBP1:(}{RBP2:(}42{RBP2:)}^ | 227 ]]) 228 redraw_input() 229 screen:expect { 230 grid = [[ 231 | 232 {EOB:~ }|*6 233 :echo {RBP1:(}{RBP2:(}42{RBP2:)}^ | 234 ]], 235 reset = true, 236 } 237 end) 238 for _, func_part in ipairs({ '', 'n', 'msg' }) do 239 it('disables :echo' .. func_part .. ' messages', function() 240 set_color_cb('Echo' .. func_part .. 'ing') 241 start_prompt('echo') 242 screen:expect([[ 243 | 244 {EOB:~ }|*6 245 :echo^ | 246 ]]) 247 end) 248 end 249 it('does the right thing when hl start appears to split multibyte char', function() 250 set_color_cb('SplitMultibyteStart') 251 start_prompt('echo "«') 252 screen:expect { 253 grid = [[ 254 | 255 {EOB:~ }|*2 256 {MSEP: }| 257 :echo " | 258 {ERR:E5405: Chunk 0 start 7 splits multibyte }| 259 {ERR:character} | 260 :echo "«^ | 261 ]], 262 } 263 feed('»') 264 screen:expect([[ 265 | 266 {EOB:~ }|*2 267 {MSEP: }| 268 :echo " | 269 {ERR:E5405: Chunk 0 start 7 splits multibyte }| 270 {ERR:character} | 271 :echo "«»^ | 272 ]]) 273 end) 274 it('does the right thing when hl end appears to split multibyte char', function() 275 set_color_cb('SplitMultibyteEnd') 276 start_prompt('echo "«') 277 screen:expect([[ 278 | 279 {EOB:~ }|*2 280 {MSEP: }| 281 :echo " | 282 {ERR:E5406: Chunk 0 end 7 splits multibyte ch}| 283 {ERR:aracter} | 284 :echo "«^ | 285 ]]) 286 end) 287 it('does the right thing when erroring', function() 288 set_color_cb('Echoerring') 289 start_prompt('e') 290 screen:expect([[ 291 | 292 {EOB:~ }| 293 {MSEP: }| 294 : | 295 {ERR:E5407: Callback has thrown an exception:}| 296 {ERR: function DoPrompt[3]..Echoerring, line }| 297 {ERR:1: Vim(echoerr):HERE} | 298 :e^ | 299 ]]) 300 end) 301 it('silences :echo', function() 302 set_color_cb('Echoing') 303 start_prompt('e') 304 screen:expect([[ 305 | 306 {EOB:~ }|*6 307 :e^ | 308 ]]) 309 eq('', exec_capture('messages')) 310 end) 311 it('silences :echon', function() 312 set_color_cb('Echoning') 313 start_prompt('e') 314 screen:expect([[ 315 | 316 {EOB:~ }|*6 317 :e^ | 318 ]]) 319 eq('', exec_capture('messages')) 320 end) 321 it('silences :echomsg', function() 322 set_color_cb('Echomsging') 323 start_prompt('e') 324 screen:expect([[ 325 | 326 {EOB:~ }|*6 327 :e^ | 328 ]]) 329 eq('', exec_capture('messages')) 330 end) 331 it('does the right thing when throwing', function() 332 set_color_cb('Throwing') 333 start_prompt('e') 334 screen:expect([[ 335 | 336 {EOB:~ }| 337 {MSEP: }| 338 : | 339 {ERR:E5407: Callback has thrown an exception:}| 340 {ERR: function DoPrompt[3]..Throwing, line 1:}| 341 {ERR: ABC} | 342 :e^ | 343 ]]) 344 end) 345 it('stops executing callback after a number of errors', function() 346 set_color_cb('SplitMultibyteStart') 347 start_prompt('let x = "«»«»«»«»«»"') 348 screen:expect([[ 349 | 350 {EOB:~ }|*2 351 {MSEP: }| 352 :let x = " | 353 {ERR:E5405: Chunk 0 start 10 splits multibyte}| 354 {ERR: character} | 355 :let x = "«»«»«»«»«»"^ | 356 ]]) 357 feed('\n') 358 screen:expect([[ 359 ^ | 360 {EOB:~ }|*6 361 | 362 ]]) 363 feed('\n') 364 eq('let x = "«»«»«»«»«»"', api.nvim_get_var('out')) 365 local msg = '\nE5405: Chunk 0 start 10 splits multibyte character' 366 eq(msg:rep(1), fn.execute('messages')) 367 end) 368 it('allows interrupting callback with <C-c>', function() 369 set_color_cb('Halting') 370 start_prompt('echo 42') 371 screen:expect([[ 372 ^ | 373 {EOB:~ }|*6 374 | 375 ]]) 376 screen:sleep(500) 377 feed('<C-c>') 378 screen:expect([[ 379 | 380 {EOB:~ }|*2 381 {MSEP: }| 382 : | 383 {ERR:E5407: Callback has thrown an exception:}| 384 {ERR: Keyboard interrupt} | 385 :echo 42^ | 386 ]]) 387 redraw_input() 388 screen:expect([[ 389 | 390 {EOB:~ }|*6 391 :echo 42^ | 392 ]]) 393 feed('\n') 394 screen:expect([[ 395 ^ | 396 {EOB:~ }|*6 397 :echo 42 | 398 ]]) 399 feed('\n') 400 eq('echo 42', api.nvim_get_var('out')) 401 feed('<C-c>') 402 screen:expect([[ 403 ^ | 404 {EOB:~ }|*6 405 Type :qa and pre...nter> to exit Nvim | 406 ]]) 407 end) 408 it('works fine with NUL, NL, CR', function() 409 set_color_cb('RainBowParens') 410 start_prompt('echo ("<C-v><CR><C-v><Nul><C-v><NL>")') 411 screen:expect([[ 412 | 413 {EOB:~ }|*6 414 :echo {RBP1:(}"{SK:^M^@^@}"{RBP1:)}^ | 415 ]]) 416 end) 417 it('errors out when callback returns something wrong', function() 418 command('cnoremap + ++') 419 set_color_cb('ReturningGlobal', '') 420 start_prompt('#') 421 screen:expect([[ 422 | 423 {EOB:~ }|*3 424 {MSEP: }| 425 : | 426 {ERR:E5400: Callback should return list} | 427 :#^ | 428 ]]) 429 430 feed('<CR><CR><CR>') 431 set_color_cb('ReturningGlobal', { { 0, 1, 'Normal' }, 42 }) 432 start_prompt('#') 433 screen:expect([[ 434 | 435 {EOB:~ }|*3 436 {MSEP: }| 437 : | 438 {ERR:E5401: List item 1 is not a List} | 439 :#^ | 440 ]]) 441 442 feed('<CR><CR><CR>') 443 set_color_cb('ReturningGlobal2', { { 0, 1, 'Normal' }, { 1 } }) 444 start_prompt('+') 445 screen:expect([[ 446 | 447 {EOB:~ }|*2 448 {MSEP: }| 449 :+ | 450 {ERR:E5402: List item 1 has incorrect length:}| 451 {ERR: 1 /= 3} | 452 :++^ | 453 ]]) 454 455 feed('<CR><CR><CR>') 456 set_color_cb('ReturningGlobal2', { { 0, 1, 'Normal' }, { 2, 3, 'Normal' } }) 457 start_prompt('+') 458 screen:expect([[ 459 | 460 {EOB:~ }|*2 461 {MSEP: }| 462 :+ | 463 {ERR:E5403: Chunk 1 start 2 not in range [1, }| 464 {ERR:2)} | 465 :++^ | 466 ]]) 467 468 feed('<CR><CR><CR>') 469 set_color_cb('ReturningGlobal2', { { 0, 1, 'Normal' }, { 1, 3, 'Normal' } }) 470 start_prompt('+') 471 screen:expect([[ 472 | 473 {EOB:~ }|*3 474 {MSEP: }| 475 :+ | 476 {ERR:E5404: Chunk 1 end 3 not in range (1, 2]}| 477 :++^ | 478 ]]) 479 end) 480 it('does not error out when called from a errored out cycle', function() 481 set_color_cb('ReturningGlobal', { { 0, 1, 'Normal' } }) 482 feed(dedent([[ 483 :set regexpengine=2 484 :for pat in [' \ze*', ' \zs*'] 485 : try 486 : let l = matchlist('x x', pat) 487 : $put =input({'prompt':'>','highlight':'ReturningGlobal'}) 488 : 489 : $put ='E888 NOT detected for ' . pat 490 : catch 491 : $put =input({'prompt':'>','highlight':'ReturningGlobal'}) 492 : 493 : $put ='E888 detected for ' . pat 494 : endtry 495 :endfor 496 : 497 : 498 : 499 : 500 : 501 : 502 ]])) 503 eq( 504 { '', ':', 'E888 detected for \\ze*', ':', 'E888 detected for \\zs*' }, 505 api.nvim_buf_get_lines(0, 0, -1, false) 506 ) 507 eq('', fn.execute('messages')) 508 end) 509 it('allows nesting input()s', function() 510 set_color_cb('ReturningGlobal', { { 0, 1, 'RBP1' } }, '') 511 start_prompt('1') 512 screen:expect([[ 513 | 514 {EOB:~ }|*6 515 :{RBP1:1}^ | 516 ]]) 517 518 set_color_cb('ReturningGlobal', { { 0, 1, 'RBP2' } }, '1') 519 start_prompt('2') 520 screen:expect([[ 521 | 522 {EOB:~ }|*6 523 :{RBP2:2}^ | 524 ]]) 525 526 set_color_cb('ReturningGlobal', { { 0, 1, 'RBP3' } }, '2') 527 start_prompt('3') 528 screen:expect([[ 529 | 530 {EOB:~ }|*6 531 :{RBP3:3}^ | 532 ]]) 533 534 set_color_cb('ReturningGlobal', { { 0, 1, 'RBP4' } }, '3') 535 start_prompt('4') 536 screen:expect([[ 537 | 538 {EOB:~ }|*6 539 :{RBP4:4}^ | 540 ]]) 541 542 feed('<CR>') 543 screen:expect([[ 544 | 545 {EOB:~ }|*6 546 :{RBP3:3}4^ | 547 ]]) 548 feed('<CR>') 549 screen:expect([[ 550 | 551 {EOB:~ }|*6 552 :{RBP2:2}34^ | 553 ]]) 554 feed('<CR>') 555 screen:expect([[ 556 | 557 {EOB:~ }|*6 558 :{RBP1:1}234^ | 559 ]]) 560 feed('<CR><CR><C-l>') 561 screen:expect([[ 562 ^ | 563 {EOB:~ }|*6 564 | 565 ]]) 566 eq('1234', api.nvim_get_var('out')) 567 eq('234', api.nvim_get_var('out1')) 568 eq('34', api.nvim_get_var('out2')) 569 eq('4', api.nvim_get_var('out3')) 570 eq(0, fn.exists('g:out4')) 571 end) 572 it('runs callback with the same data only once', function() 573 local function new_recording_calls(...) 574 eq({ ... }, api.nvim_get_var('recording_calls')) 575 api.nvim_set_var('recording_calls', {}) 576 end 577 set_color_cb('Recording') 578 start_prompt('') 579 -- Regression test. Disambiguation: 580 -- 581 -- new_recording_calls(expected_result) -- (actual_before_fix) 582 -- 583 feed('a') 584 new_recording_calls('a') -- ('a', 'a') 585 feed('b') 586 new_recording_calls('ab') -- ('a', 'ab', 'ab') 587 feed('c') 588 new_recording_calls('abc') -- ('ab', 'abc', 'abc') 589 feed('<BS>') 590 new_recording_calls('ab') -- ('abc', 'ab', 'ab') 591 feed('<BS>') 592 new_recording_calls('a') -- ('ab', 'a', 'a') 593 feed('<BS>') 594 new_recording_calls() -- ('a') 595 feed('<CR><CR>') 596 eq('', api.nvim_get_var('out')) 597 end) 598 it('does not crash when callback has caught not-a-editor-command exception', function() 599 source([[ 600 function CaughtExc(cmdline) abort 601 try 602 gibberish 603 catch 604 " Do nothing 605 endtry 606 return [] 607 endfunction 608 ]]) 609 set_color_cb('CaughtExc') 610 start_prompt('1') 611 eq(1, api.nvim_eval('1')) 612 end) 613 end) 614 describe('Ex commands coloring', function() 615 it('works', function() 616 api.nvim_set_var('Nvim_color_cmdline', 'RainBowParens') 617 feed(':echo (((1)))') 618 screen:expect([[ 619 | 620 {EOB:~ }|*6 621 :echo {RBP1:(}{RBP2:(}{RBP3:(}1{RBP3:)}{RBP2:)}{RBP1:)}^ | 622 ]]) 623 end) 624 it('still executes command-line even if errored out', function() 625 api.nvim_set_var('Nvim_color_cmdline', 'SplitMultibyteStart') 626 feed(':let x = "«"\n') 627 eq('«', api.nvim_get_var('x')) 628 local msg = 'E5405: Chunk 0 start 10 splits multibyte character' 629 eq('\n' .. msg, fn.execute('messages')) 630 end) 631 it('does not error out when called from a errored out cycle', function() 632 -- Apparently when there is a cycle in which one of the commands errors out 633 -- this error may be caught by color_cmdline before it is presented to the 634 -- user. 635 feed(dedent([[ 636 :set regexpengine=2 637 :for pat in [' \ze*', ' \zs*'] 638 : try 639 : let l = matchlist('x x', pat) 640 : $put ='E888 NOT detected for ' . pat 641 : catch 642 : $put ='E888 detected for ' . pat 643 : endtry 644 :endfor 645 ]])) 646 eq( 647 { '', 'E888 detected for \\ze*', 'E888 detected for \\zs*' }, 648 api.nvim_buf_get_lines(0, 0, -1, false) 649 ) 650 eq('', fn.execute('messages')) 651 end) 652 it('does not crash when using `n` in debug mode', function() 653 feed(':debug execute "echo 1"\n') 654 screen:expect([[ 655 | 656 {EOB:~ }|*2 657 {MSEP: }| 658 Entering Debug mode. Type "cont" to con| 659 tinue. | 660 cmd: execute "echo 1" | 661 >^ | 662 ]]) 663 feed('n\n') 664 screen:expect([[ 665 | 666 {MSEP: }| 667 Entering Debug mode. Type "cont" to con| 668 tinue. | 669 cmd: execute "echo 1" | 670 >n | 671 1 | 672 {PE:Press ENTER or type command to continue}^ | 673 ]]) 674 feed('\n') 675 screen:expect([[ 676 ^ | 677 {EOB:~ }|*6 678 | 679 ]]) 680 end) 681 it('mapping error does not cancel prompt', function() 682 command("cnoremap <expr> x execute('throw 42')[-1]") 683 feed(':#x') 684 screen:expect([[ 685 | 686 {EOB:~ }|*2 687 {MSEP: }| 688 :# | 689 {ERR:Error in :} | 690 {ERR:E605: Exception not caught: 42} | 691 :#^ | 692 ]]) 693 feed('<CR>') 694 screen:expect([[ 695 | 696 {EOB:~ }| 697 {MSEP: }| 698 :# | 699 {ERR:Error in :} | 700 {ERR:E605: Exception not caught: 42} | 701 {ERR:E749: Empty buffer} | 702 {PE:Press ENTER or type command to continue}^ | 703 ]]) 704 feed('<CR>') 705 eq('Error in :\nE605: Exception not caught: 42\nE749: Empty buffer', exec_capture('messages')) 706 end) 707 it('errors out when failing to get callback', function() 708 api.nvim_set_var('Nvim_color_cmdline', 42) 709 feed(':#') 710 screen:expect([[ 711 | 712 {EOB:~ }| 713 {MSEP: }| 714 : | 715 {ERR:E5408: Unable to get g:Nvim_color_cmdlin}| 716 {ERR:e callback: Vim:E6000: Argument is not a}| 717 {ERR: function or function name} | 718 :#^ | 719 ]]) 720 end) 721 end) 722 describe('Expressions coloring support', function() 723 it('works', function() 724 command('hi clear NvimNumber') 725 command('hi clear NvimNestingParenthesis') 726 command('hi NvimNumber guifg=Blue2') 727 command('hi NvimNestingParenthesis guifg=Yellow') 728 feed(':echo <C-r>=(((1)))') 729 screen:expect([[ 730 | 731 {EOB:~ }|*6 732 ={NPAR:(((}{NUM:1}{NPAR:)))}^ | 733 ]]) 734 end) 735 it('does not use Nvim_color_expr', function() 736 api.nvim_set_var('Nvim_color_expr', 42) 737 -- Used to error out due to failing to get callback. 738 command('hi clear NvimNumber') 739 command('hi NvimNumber guifg=Blue2') 740 feed(':<C-r>=1') 741 screen:expect([[ 742 | 743 {EOB:~ }|*6 744 ={NUM:1}^ | 745 ]]) 746 end) 747 it('works correctly with non-ASCII and control characters', function() 748 command('hi clear NvimStringBody') 749 command('hi clear NvimStringQuote') 750 command('hi clear NvimInvalid') 751 command('hi NvimStringQuote guifg=Blue3') 752 command('hi NvimStringBody guifg=Blue4') 753 command('hi NvimInvalid guifg=Red guibg=Blue') 754 feed('i<C-r>="«»"«»') 755 screen:expect([[ 756 | 757 {EOB:~ }|*6 758 ={SQ:"}{SB:«»}{SQ:"}{E:«»}^ | 759 ]]) 760 feed('<C-c>') 761 screen:expect([[ 762 ^ | 763 {EOB:~ }|*6 764 {M:-- INSERT --} | 765 ]]) 766 feed('<Esc>') 767 screen:expect([[ 768 ^ | 769 {EOB:~ }|*6 770 | 771 ]]) 772 feed(':<C-\\>e"<C-v><C-x>"<C-v><C-x>') 773 -- TODO(ZyX-I): Parser highlighting should not override special character 774 -- highlighting. 775 screen:expect([[ 776 | 777 {EOB:~ }|*6 778 ={SQ:"}{SB:^X}{SQ:"}{ERR:^X}^ | 779 ]]) 780 feed('<C-c>') 781 screen:expect([[ 782 | 783 {EOB:~ }|*6 784 :^ | 785 ]]) 786 fn.setreg('a', { '\192' }) 787 feed('<C-r>="<C-r><C-r>a"<C-r><C-r>a"foo"') 788 screen:expect([[ 789 | 790 {EOB:~ }|*6 791 ={SQ:"}{SB:<c0>}{SQ:"}{E:<c0>"}{SB:foo}{E:"}^ | 792 ]]) 793 end) 794 end)