1" Tests for decoding escape sequences sent by the terminal. 2 3" This only works for Unix in a terminal 4source check.vim 5CheckNotGui 6CheckUnix 7 8source shared.vim 9 10" xterm2 and sgr always work, urxvt is optional. 11let s:ttymouse_values = ['xterm2', 'sgr'] 12if has('mouse_urxvt') 13 call add(s:ttymouse_values, 'urxvt') 14endif 15 16" dec doesn't support all the functionality 17if has('mouse_dec') 18 let s:ttymouse_dec = ['dec'] 19else 20 let s:ttymouse_dec = [] 21endif 22 23" netterm only supports left click 24if has('mouse_netterm') 25 let s:ttymouse_netterm = ['netterm'] 26else 27 let s:ttymouse_netterm = [] 28endif 29 30" Helper function to emit a terminal escape code. 31func TerminalEscapeCode(code, row, col, m) 32 if &ttymouse ==# 'xterm2' 33 " need to use byte encoding here. 34 let str = list2str([a:code + 0x20, a:col + 0x20, a:row + 0x20]) 35 if has('iconv') 36 let bytes = str->iconv('utf-8', 'latin1') 37 else 38 " Hopefully the numbers are not too big. 39 let bytes = str 40 endif 41 return "\<Esc>[M" .. bytes 42 elseif &ttymouse ==# 'sgr' 43 return printf("\<Esc>[<%d;%d;%d%s", a:code, a:col, a:row, a:m) 44 elseif &ttymouse ==# 'urxvt' 45 return printf("\<Esc>[%d;%d;%dM", a:code + 0x20, a:col, a:row) 46 endif 47endfunc 48 49func DecEscapeCode(code, down, row, col) 50 return printf("\<Esc>[%d;%d;%d;%d&w", a:code, a:down, a:row, a:col) 51endfunc 52 53func NettermEscapeCode(row, col) 54 return printf("\<Esc>}%d,%d\r", a:row, a:col) 55endfunc 56 57func MouseLeftClickCode(row, col) 58 if &ttymouse ==# 'dec' 59 return DecEscapeCode(2, 4, a:row, a:col) 60 elseif &ttymouse ==# 'netterm' 61 return NettermEscapeCode(a:row, a:col) 62 else 63 return TerminalEscapeCode(0, a:row, a:col, 'M') 64 endif 65endfunc 66 67func MouseLeftClick(row, col) 68 call feedkeys(MouseLeftClickCode(a:row, a:col), 'Lx!') 69endfunc 70 71func MouseMiddleClickCode(row, col) 72 if &ttymouse ==# 'dec' 73 return DecEscapeCode(4, 2, a:row, a:col) 74 else 75 return TerminalEscapeCode(1, a:row, a:col, 'M') 76 endif 77endfunc 78 79func MouseMiddleClick(row, col) 80 call feedkeys(MouseMiddleClickCode(a:row, a:col), 'Lx!') 81endfunc 82 83func MouseRightClickCode(row, col) 84 if &ttymouse ==# 'dec' 85 return DecEscapeCode(6, 1, a:row, a:col) 86 else 87 return TerminalEscapeCode(2, a:row, a:col, 'M') 88 endif 89endfunc 90 91func MouseRightClick(row, col) 92 call feedkeys(MouseRightClickCode(a:row, a:col), 'Lx!') 93endfunc 94 95func MouseCtrlLeftClickCode(row, col) 96 let ctrl = 0x10 97 return TerminalEscapeCode(0 + ctrl, a:row, a:col, 'M') 98endfunc 99 100func MouseCtrlLeftClick(row, col) 101 call feedkeys(MouseCtrlLeftClickCode(a:row, a:col), 'Lx!') 102endfunc 103 104func MouseCtrlRightClickCode(row, col) 105 let ctrl = 0x10 106 return TerminalEscapeCode(2 + ctrl, a:row, a:col, 'M') 107endfunc 108 109func MouseCtrlRightClick(row, col) 110 call feedkeys(MouseCtrlRightClickCode(a:row, a:col), 'Lx!') 111endfunc 112 113func MouseLeftReleaseCode(row, col) 114 if &ttymouse ==# 'dec' 115 return DecEscapeCode(3, 0, a:row, a:col) 116 elseif &ttymouse ==# 'netterm' 117 return '' 118 else 119 return TerminalEscapeCode(3, a:row, a:col, 'm') 120 endif 121endfunc 122 123func MouseLeftRelease(row, col) 124 call feedkeys(MouseLeftReleaseCode(a:row, a:col), 'Lx!') 125endfunc 126 127func MouseMiddleReleaseCode(row, col) 128 if &ttymouse ==# 'dec' 129 return DecEscapeCode(5, 0, a:row, a:col) 130 else 131 return TerminalEscapeCode(3, a:row, a:col, 'm') 132 endif 133endfunc 134 135func MouseMiddleRelease(row, col) 136 call feedkeys(MouseMiddleReleaseCode(a:row, a:col), 'Lx!') 137endfunc 138 139func MouseRightReleaseCode(row, col) 140 if &ttymouse ==# 'dec' 141 return DecEscapeCode(7, 0, a:row, a:col) 142 else 143 return TerminalEscapeCode(3, a:row, a:col, 'm') 144 endif 145endfunc 146 147func MouseRightRelease(row, col) 148 call feedkeys(MouseRightReleaseCode(a:row, a:col), 'Lx!') 149endfunc 150 151func MouseLeftDragCode(row, col) 152 if &ttymouse ==# 'dec' 153 return DecEscapeCode(1, 4, a:row, a:col) 154 else 155 return TerminalEscapeCode(0x20, a:row, a:col, 'M') 156 endif 157endfunc 158 159func MouseLeftDrag(row, col) 160 call feedkeys(MouseLeftDragCode(a:row, a:col), 'Lx!') 161endfunc 162 163func MouseWheelUpCode(row, col) 164 return TerminalEscapeCode(0x40, a:row, a:col, 'M') 165endfunc 166 167func MouseWheelUp(row, col) 168 call feedkeys(MouseWheelUpCode(a:row, a:col), 'Lx!') 169endfunc 170 171func MouseWheelDownCode(row, col) 172 return TerminalEscapeCode(0x41, a:row, a:col, 'M') 173endfunc 174 175func MouseWheelDown(row, col) 176 call feedkeys(MouseWheelDownCode(a:row, a:col), 'Lx!') 177endfunc 178 179func Test_term_mouse_left_click() 180 new 181 let save_mouse = &mouse 182 let save_term = &term 183 let save_ttymouse = &ttymouse 184 call test_override('no_query_mouse', 1) 185 set mouse=a term=xterm 186 call setline(1, ['line 1', 'line 2', 'line 3 is a bit longer']) 187 188 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec + s:ttymouse_netterm 189 let msg = 'ttymouse=' .. ttymouse_val 190 exe 'set ttymouse=' .. ttymouse_val 191 go 192 call assert_equal([0, 1, 1, 0], getpos('.'), msg) 193 let row = 2 194 let col = 6 195 call MouseLeftClick(row, col) 196 call MouseLeftRelease(row, col) 197 call assert_equal([0, 2, 6, 0], getpos('.'), msg) 198 endfor 199 200 let &mouse = save_mouse 201 let &term = save_term 202 let &ttymouse = save_ttymouse 203 call test_override('no_query_mouse', 0) 204 bwipe! 205endfunc 206 207func Test_xterm_mouse_right_click_extends_visual() 208 if has('mac') 209 throw "Skipped: test right click in visual mode does not work on macOs (why?)" 210 endif 211 let save_mouse = &mouse 212 let save_term = &term 213 let save_ttymouse = &ttymouse 214 call test_override('no_query_mouse', 1) 215 set mouse=a term=xterm 216 217 for visual_mode in ["v", "V", "\<C-V>"] 218 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec 219 let msg = 'visual=' .. visual_mode .. ' ttymouse=' .. ttymouse_val 220 exe 'set ttymouse=' .. ttymouse_val 221 222 call setline(1, repeat([repeat('-', 7)], 7)) 223 call MouseLeftClick(4, 4) 224 call MouseLeftRelease(4, 4) 225 exe "norm! " .. visual_mode 226 227 " Right click extends top left of visual area. 228 call MouseRightClick(2, 2) 229 call MouseRightRelease(2, 2) 230 231 " Right click extends bottom right of visual area. 232 call MouseRightClick(6, 6) 233 call MouseRightRelease(6, 6) 234 norm! r1gv 235 236 " Right click shrinks top left of visual area. 237 call MouseRightClick(3, 3) 238 call MouseRightRelease(3, 3) 239 240 " Right click shrinks bottom right of visual area. 241 call MouseRightClick(5, 5) 242 call MouseRightRelease(5, 5) 243 norm! r2 244 245 if visual_mode ==# 'v' 246 call assert_equal(['-------', 247 \ '-111111', 248 \ '1122222', 249 \ '2222222', 250 \ '2222211', 251 \ '111111-', 252 \ '-------'], getline(1, '$'), msg) 253 elseif visual_mode ==# 'V' 254 call assert_equal(['-------', 255 \ '1111111', 256 \ '2222222', 257 \ '2222222', 258 \ '2222222', 259 \ '1111111', 260 \ '-------'], getline(1, '$'), msg) 261 else 262 call assert_equal(['-------', 263 \ '-11111-', 264 \ '-12221-', 265 \ '-12221-', 266 \ '-12221-', 267 \ '-11111-', 268 \ '-------'], getline(1, '$'), msg) 269 endif 270 endfor 271 endfor 272 273 let &mouse = save_mouse 274 let &term = save_term 275 let &ttymouse = save_ttymouse 276 call test_override('no_query_mouse', 0) 277 bwipe! 278endfunc 279 280" Test that <C-LeftMouse> jumps to help tag and <C-RightMouse> jumps back. 281func Test_xterm_mouse_ctrl_click() 282 let save_mouse = &mouse 283 let save_term = &term 284 let save_ttymouse = &ttymouse 285 set mouse=a term=xterm 286 287 for ttymouse_val in s:ttymouse_values 288 let msg = 'ttymouse=' .. ttymouse_val 289 exe 'set ttymouse=' .. ttymouse_val 290 help 291 /usr_02.txt 292 norm! zt 293 let row = 1 294 let col = 1 295 call MouseCtrlLeftClick(row, col) 296 call MouseLeftRelease(row, col) 297 call assert_match('usr_02.txt$', bufname('%'), msg) 298 call assert_equal('*usr_02.txt*', expand('<cWORD>'), msg) 299 300 call MouseCtrlRightClick(row, col) 301 call MouseRightRelease(row, col) 302 call assert_match('help.txt$', bufname('%'), msg) 303 call assert_equal('|usr_02.txt|', expand('<cWORD>'), msg) 304 305 helpclose 306 endfor 307 308 let &mouse = save_mouse 309 let &term = save_term 310 let &ttymouse = save_ttymouse 311endfunc 312 313func Test_term_mouse_middle_click() 314 CheckFeature clipboard_working 315 316 new 317 let save_mouse = &mouse 318 let save_term = &term 319 let save_ttymouse = &ttymouse 320 call test_override('no_query_mouse', 1) 321 let save_quotestar = @* 322 let @* = 'abc' 323 set mouse=a term=xterm 324 325 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec 326 let msg = 'ttymouse=' .. ttymouse_val 327 exe 'set ttymouse=' .. ttymouse_val 328 call setline(1, ['123456789', '123456789']) 329 330 " Middle-click in the middle of the line pastes text where clicked. 331 let row = 1 332 let col = 6 333 call MouseMiddleClick(row, col) 334 call MouseMiddleRelease(row, col) 335 call assert_equal(['12345abc6789', '123456789'], getline(1, '$'), msg) 336 337 " Middle-click beyond end of the line pastes text at the end of the line. 338 let col = 20 339 call MouseMiddleClick(row, col) 340 call MouseMiddleRelease(row, col) 341 call assert_equal(['12345abc6789abc', '123456789'], getline(1, '$'), msg) 342 343 " Middle-click beyond the last line pastes in the last line. 344 let row = 5 345 let col = 3 346 call MouseMiddleClick(row, col) 347 call MouseMiddleRelease(row, col) 348 call assert_equal(['12345abc6789abc', '12abc3456789'], getline(1, '$'), msg) 349 endfor 350 351 let &mouse = save_mouse 352 let &term = save_term 353 let &ttymouse = save_ttymouse 354 call test_override('no_query_mouse', 0) 355 let @* = save_quotestar 356 bwipe! 357endfunc 358 359" TODO: for unclear reasons this test fails if it comes after 360" Test_xterm_mouse_ctrl_click() 361func Test_1xterm_mouse_wheel() 362 new 363 let save_mouse = &mouse 364 let save_term = &term 365 let save_ttymouse = &ttymouse 366 set mouse=a term=xterm 367 call setline(1, range(1, 100)) 368 369 for ttymouse_val in s:ttymouse_values 370 let msg = 'ttymouse=' .. ttymouse_val 371 exe 'set ttymouse=' .. ttymouse_val 372 go 373 call assert_equal(1, line('w0'), msg) 374 call assert_equal([0, 1, 1, 0], getpos('.'), msg) 375 376 call MouseWheelDown(1, 1) 377 call assert_equal(4, line('w0'), msg) 378 call assert_equal([0, 4, 1, 0], getpos('.'), msg) 379 380 call MouseWheelDown(1, 1) 381 call assert_equal(7, line('w0'), msg) 382 call assert_equal([0, 7, 1, 0], getpos('.'), msg) 383 384 call MouseWheelUp(1, 1) 385 call assert_equal(4, line('w0'), msg) 386 call assert_equal([0, 7, 1, 0], getpos('.'), msg) 387 388 call MouseWheelUp(1, 1) 389 call assert_equal(1, line('w0'), msg) 390 call assert_equal([0, 7, 1, 0], getpos('.'), msg) 391 endfor 392 393 let &mouse = save_mouse 394 let &term = save_term 395 let &ttymouse = save_ttymouse 396 bwipe! 397endfunc 398 399" Test that dragging beyond the window (at the bottom and at the top) 400" scrolls window content by the number of lines beyond the window. 401func Test_term_mouse_drag_beyond_window() 402 let save_mouse = &mouse 403 let save_term = &term 404 let save_ttymouse = &ttymouse 405 call test_override('no_query_mouse', 1) 406 set mouse=a term=xterm 407 let col = 1 408 call setline(1, range(1, 100)) 409 410 " Split into 3 windows, and go into the middle window 411 " so we test dragging mouse below and above the window. 412 2split 413 wincmd j 414 2split 415 416 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec 417 let msg = 'ttymouse=' .. ttymouse_val 418 exe 'set ttymouse=' .. ttymouse_val 419 420 " Line #10 at the top. 421 norm! 10zt 422 redraw 423 call assert_equal(10, winsaveview().topline, msg) 424 call assert_equal(2, winheight(0), msg) 425 426 let row = 4 427 call MouseLeftClick(row, col) 428 call assert_equal(10, winsaveview().topline, msg) 429 430 " Drag downwards. We're still in the window so topline should 431 " not change yet. 432 let row += 1 433 call MouseLeftDrag(row, col) 434 call assert_equal(10, winsaveview().topline, msg) 435 436 " We now leave the window at the bottom, so the window content should 437 " scroll by 1 line, then 2 lines (etc) as we drag further away. 438 let row += 1 439 call MouseLeftDrag(row, col) 440 call assert_equal(11, winsaveview().topline, msg) 441 442 let row += 1 443 call MouseLeftDrag(row, col) 444 call assert_equal(13, winsaveview().topline, msg) 445 446 " Now drag upwards. 447 let row -= 1 448 call MouseLeftDrag(row, col) 449 call assert_equal(14, winsaveview().topline, msg) 450 451 " We're now back in the window so the topline should not change. 452 let row -= 1 453 call MouseLeftDrag(row, col) 454 call assert_equal(14, winsaveview().topline, msg) 455 456 let row -= 1 457 call MouseLeftDrag(row, col) 458 call assert_equal(14, winsaveview().topline, msg) 459 460 " We now leave the window at the top so the window content should 461 " scroll by 1 line, then 2, then 3 (etc) in the opposite direction. 462 let row -= 1 463 call MouseLeftDrag(row, col) 464 call assert_equal(13, winsaveview().topline, msg) 465 466 let row -= 1 467 call MouseLeftDrag(row, col) 468 call assert_equal(11, winsaveview().topline, msg) 469 470 let row -= 1 471 call MouseLeftDrag(row, col) 472 call assert_equal(8, winsaveview().topline, msg) 473 474 call MouseLeftRelease(row, col) 475 call assert_equal(8, winsaveview().topline, msg) 476 call assert_equal(2, winheight(0), msg) 477 endfor 478 479 let &mouse = save_mouse 480 let &term = save_term 481 let &ttymouse = save_ttymouse 482 call test_override('no_query_mouse', 0) 483 bwipe! 484endfunc 485 486func Test_term_mouse_drag_window_separator() 487 let save_mouse = &mouse 488 let save_term = &term 489 let save_ttymouse = &ttymouse 490 call test_override('no_query_mouse', 1) 491 set mouse=a term=xterm 492 493 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec 494 let msg = 'ttymouse=' .. ttymouse_val 495 exe 'set ttymouse=' .. ttymouse_val 496 497 " Split horizontally and test dragging the horizontal window separator. 498 split 499 let rowseparator = winheight(0) + 1 500 let row = rowseparator 501 let col = 1 502 503 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported. 504 if ttymouse_val !=# 'xterm2' || row <= 223 505 call MouseLeftClick(row, col) 506 let row -= 1 507 call MouseLeftDrag(row, col) 508 call assert_equal(rowseparator - 1, winheight(0) + 1, msg) 509 let row += 1 510 call MouseLeftDrag(row, col) 511 call assert_equal(rowseparator, winheight(0) + 1, msg) 512 call MouseLeftRelease(row, col) 513 call assert_equal(rowseparator, winheight(0) + 1, msg) 514 endif 515 bwipe! 516 517 " Split vertically and test dragging the vertical window separator. 518 vsplit 519 let colseparator = winwidth(0) + 1 520 let row = 1 521 let col = colseparator 522 523 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported. 524 if ttymouse_val !=# 'xterm2' || col <= 223 525 call MouseLeftClick(row, col) 526 let col -= 1 527 call MouseLeftDrag(row, col) 528 call assert_equal(colseparator - 1, winwidth(0) + 1, msg) 529 let col += 1 530 call MouseLeftDrag(row, col) 531 call assert_equal(colseparator, winwidth(0) + 1, msg) 532 call MouseLeftRelease(row, col) 533 call assert_equal(colseparator, winwidth(0) + 1, msg) 534 endif 535 bwipe! 536 endfor 537 538 let &mouse = save_mouse 539 let &term = save_term 540 let &ttymouse = save_ttymouse 541 call test_override('no_query_mouse', 0) 542endfunc 543 544func Test_term_mouse_drag_statusline() 545 let save_mouse = &mouse 546 let save_term = &term 547 let save_ttymouse = &ttymouse 548 call test_override('no_query_mouse', 1) 549 let save_laststatus = &laststatus 550 set mouse=a term=xterm laststatus=2 551 552 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec 553 let msg = 'ttymouse=' .. ttymouse_val 554 exe 'set ttymouse=' .. ttymouse_val 555 556 call assert_equal(1, &cmdheight, msg) 557 let rowstatusline = winheight(0) + 1 558 let row = rowstatusline 559 let col = 1 560 561 if ttymouse_val ==# 'xterm2' && row > 223 562 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported. 563 continue 564 endif 565 566 call MouseLeftClick(row, col) 567 let row -= 1 568 call MouseLeftDrag(row, col) 569 call assert_equal(2, &cmdheight, msg) 570 call assert_equal(rowstatusline - 1, winheight(0) + 1, msg) 571 let row += 1 572 call MouseLeftDrag(row, col) 573 call assert_equal(1, &cmdheight, msg) 574 call assert_equal(rowstatusline, winheight(0) + 1, msg) 575 call MouseLeftRelease(row, col) 576 call assert_equal(1, &cmdheight, msg) 577 call assert_equal(rowstatusline, winheight(0) + 1, msg) 578 endfor 579 580 let &mouse = save_mouse 581 let &term = save_term 582 let &ttymouse = save_ttymouse 583 call test_override('no_query_mouse', 0) 584 let &laststatus = save_laststatus 585endfunc 586 587func Test_term_mouse_click_tab() 588 let save_mouse = &mouse 589 let save_term = &term 590 let save_ttymouse = &ttymouse 591 call test_override('no_query_mouse', 1) 592 set mouse=a term=xterm 593 let row = 1 594 595 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec + s:ttymouse_netterm 596 let msg = 'ttymouse=' .. ttymouse_val 597 exe 'set ttymouse=' .. ttymouse_val 598 e Xfoo 599 tabnew Xbar 600 601 let a = split(execute(':tabs'), "\n") 602 call assert_equal(['Tab page 1', 603 \ ' Xfoo', 604 \ 'Tab page 2', 605 \ '> Xbar'], a, msg) 606 607 " Test clicking on tab names in the tabline at the top. 608 let col = 2 609 redraw 610 call MouseLeftClick(row, col) 611 call MouseLeftRelease(row, col) 612 let a = split(execute(':tabs'), "\n") 613 call assert_equal(['Tab page 1', 614 \ '> Xfoo', 615 \ 'Tab page 2', 616 \ ' Xbar'], a, msg) 617 618 let col = 9 619 call MouseLeftClick(row, col) 620 call MouseLeftRelease(row, col) 621 let a = split(execute(':tabs'), "\n") 622 call assert_equal(['Tab page 1', 623 \ ' Xfoo', 624 \ 'Tab page 2', 625 \ '> Xbar'], a, msg) 626 627 %bwipe! 628 endfor 629 630 let &mouse = save_mouse 631 let &term = save_term 632 let &ttymouse = save_ttymouse 633 call test_override('no_query_mouse', 0) 634endfunc 635 636func Test_term_mouse_click_X_to_close_tab() 637 let save_mouse = &mouse 638 let save_term = &term 639 let save_ttymouse = &ttymouse 640 call test_override('no_query_mouse', 1) 641 set mouse=a term=xterm 642 let row = 1 643 let col = &columns 644 645 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec + s:ttymouse_netterm 646 if ttymouse_val ==# 'xterm2' && col > 223 647 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported. 648 continue 649 endif 650 let msg = 'ttymouse=' .. ttymouse_val 651 exe 'set ttymouse=' .. ttymouse_val 652 e Xtab1 653 tabnew Xtab2 654 tabnew Xtab3 655 tabn 2 656 657 let a = split(execute(':tabs'), "\n") 658 call assert_equal(['Tab page 1', 659 \ ' Xtab1', 660 \ 'Tab page 2', 661 \ '> Xtab2', 662 \ 'Tab page 3', 663 \ ' Xtab3'], a, msg) 664 665 " Click on "X" in tabline to close current tab i.e. Xtab2. 666 redraw 667 call MouseLeftClick(row, col) 668 call MouseLeftRelease(row, col) 669 let a = split(execute(':tabs'), "\n") 670 call assert_equal(['Tab page 1', 671 \ ' Xtab1', 672 \ 'Tab page 2', 673 \ '> Xtab3'], a, msg) 674 675 %bwipe! 676 endfor 677 678 let &mouse = save_mouse 679 let &term = save_term 680 let &ttymouse = save_ttymouse 681 call test_override('no_query_mouse', 0) 682endfunc 683 684func Test_term_mouse_drag_to_move_tab() 685 let save_mouse = &mouse 686 let save_term = &term 687 let save_ttymouse = &ttymouse 688 call test_override('no_query_mouse', 1) 689 " Set 'mousetime' to 1 to avoid recognizing a double-click in the loop 690 set mouse=a term=xterm mousetime=1 691 let row = 1 692 693 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec 694 let msg = 'ttymouse=' .. ttymouse_val 695 exe 'set ttymouse=' .. ttymouse_val 696 e Xtab1 697 tabnew Xtab2 698 699 let a = split(execute(':tabs'), "\n") 700 call assert_equal(['Tab page 1', 701 \ ' Xtab1', 702 \ 'Tab page 2', 703 \ '> Xtab2'], a, msg) 704 redraw 705 706 " Click in tab2 and drag it to tab1. 707 " Check getcharmod() to verify that click is not 708 " interpreted as a spurious double-click. 709 call MouseLeftClick(row, 10) 710 call assert_equal(0, getcharmod(), msg) 711 for col in [9, 8, 7, 6] 712 call MouseLeftDrag(row, col) 713 endfor 714 call MouseLeftRelease(row, col) 715 let a = split(execute(':tabs'), "\n") 716 call assert_equal(['Tab page 1', 717 \ '> Xtab2', 718 \ 'Tab page 2', 719 \ ' Xtab1'], a, msg) 720 721 " Click elsewhere so that click in next iteration is not 722 " interpreted as unwanted double-click. 723 call MouseLeftClick(row, 11) 724 call MouseLeftRelease(row, 11) 725 726 %bwipe! 727 endfor 728 729 let &mouse = save_mouse 730 let &term = save_term 731 let &ttymouse = save_ttymouse 732 call test_override('no_query_mouse', 0) 733 set mousetime& 734endfunc 735 736func Test_term_mouse_double_click_to_create_tab() 737 let save_mouse = &mouse 738 let save_term = &term 739 let save_ttymouse = &ttymouse 740 call test_override('no_query_mouse', 1) 741 " Set 'mousetime' to a small value, so that double-click works but we don't 742 " have to wait long to avoid a triple-click. 743 set mouse=a term=xterm mousetime=200 744 let row = 1 745 let col = 10 746 747 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec 748 let msg = 'ttymouse=' .. ttymouse_val 749 exe 'set ttymouse=' .. ttymouse_val 750 e Xtab1 751 tabnew Xtab2 752 753 let a = split(execute(':tabs'), "\n") 754 call assert_equal(['Tab page 1', 755 \ ' Xtab1', 756 \ 'Tab page 2', 757 \ '> Xtab2'], a, msg) 758 759 redraw 760 call MouseLeftClick(row, col) 761 " Check getcharmod() to verify that first click is not 762 " interpreted as a spurious double-click. 763 call assert_equal(0, getcharmod(), msg) 764 call MouseLeftRelease(row, col) 765 call MouseLeftClick(row, col) 766 call assert_equal(32, getcharmod(), msg) " double-click 767 call MouseLeftRelease(row, col) 768 let a = split(execute(':tabs'), "\n") 769 call assert_equal(['Tab page 1', 770 \ ' Xtab1', 771 \ 'Tab page 2', 772 \ '> [No Name]', 773 \ 'Tab page 3', 774 \ ' Xtab2'], a, msg) 775 776 " Click elsewhere so that click in next iteration is not 777 " interpreted as unwanted double click. 778 call MouseLeftClick(row, col + 1) 779 call MouseLeftRelease(row, col + 1) 780 781 %bwipe! 782 endfor 783 784 let &mouse = save_mouse 785 let &term = save_term 786 let &ttymouse = save_ttymouse 787 call test_override('no_query_mouse', 0) 788 set mousetime& 789endfunc 790 791" Test double/triple/quadruple click in normal mode to visually select. 792func Test_term_mouse_multiple_clicks_to_visually_select() 793 let save_mouse = &mouse 794 let save_term = &term 795 let save_ttymouse = &ttymouse 796 call test_override('no_query_mouse', 1) 797 set mouse=a term=xterm mousetime=200 798 new 799 800 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec 801 let msg = 'ttymouse=' .. ttymouse_val 802 exe 'set ttymouse=' .. ttymouse_val 803 call setline(1, ['foo [foo bar] foo', 'foo']) 804 805 " Double-click on word should visually select the word. 806 call MouseLeftClick(1, 2) 807 call assert_equal(0, getcharmod(), msg) 808 call MouseLeftRelease(1, 2) 809 call MouseLeftClick(1, 2) 810 call assert_equal(32, getcharmod(), msg) " double-click 811 call MouseLeftRelease(1, 2) 812 call assert_equal('v', mode(), msg) 813 norm! r1 814 call assert_equal(['111 [foo bar] foo', 'foo'], getline(1, '$'), msg) 815 816 " Double-click on opening square bracket should visually 817 " select the whole [foo bar]. 818 call MouseLeftClick(1, 5) 819 call assert_equal(0, getcharmod(), msg) 820 call MouseLeftRelease(1, 5) 821 call MouseLeftClick(1, 5) 822 call assert_equal(32, getcharmod(), msg) " double-click 823 call MouseLeftRelease(1, 5) 824 call assert_equal('v', mode(), msg) 825 norm! r2 826 call assert_equal(['111 222222222 foo', 'foo'], getline(1, '$'), msg) 827 828 " Triple-click should visually select the whole line. 829 call MouseLeftClick(1, 3) 830 call assert_equal(0, getcharmod(), msg) 831 call MouseLeftRelease(1, 3) 832 call MouseLeftClick(1, 3) 833 call assert_equal(32, getcharmod(), msg) " double-click 834 call MouseLeftRelease(1, 3) 835 call MouseLeftClick(1, 3) 836 call assert_equal(64, getcharmod(), msg) " triple-click 837 call MouseLeftRelease(1, 3) 838 call assert_equal('V', mode(), msg) 839 norm! r3 840 call assert_equal(['33333333333333333', 'foo'], getline(1, '$'), msg) 841 842 " Quadruple-click should start visual block select. 843 call MouseLeftClick(1, 2) 844 call assert_equal(0, getcharmod(), msg) 845 call MouseLeftRelease(1, 2) 846 call MouseLeftClick(1, 2) 847 call assert_equal(32, getcharmod(), msg) " double-click 848 call MouseLeftRelease(1, 2) 849 call MouseLeftClick(1, 2) 850 call assert_equal(64, getcharmod(), msg) " triple-click 851 call MouseLeftRelease(1, 2) 852 call MouseLeftClick(1, 2) 853 call assert_equal(96, getcharmod(), msg) " quadruple-click 854 call MouseLeftRelease(1, 2) 855 call assert_equal("\<c-v>", mode(), msg) 856 norm! r4 857 call assert_equal(['34333333333333333', 'foo'], getline(1, '$'), msg) 858 endfor 859 860 let &mouse = save_mouse 861 let &term = save_term 862 let &ttymouse = save_ttymouse 863 set mousetime& 864 call test_override('no_query_mouse', 0) 865 bwipe! 866endfunc 867 868func Test_xterm_mouse_click_in_fold_columns() 869 new 870 let save_mouse = &mouse 871 let save_term = &term 872 let save_ttymouse = &ttymouse 873 let save_foldcolumn = &foldcolumn 874 set mouse=a term=xterm foldcolumn=3 ttymouse=xterm2 875 876 " Create 2 nested folds. 877 call setline(1, range(1, 7)) 878 2,6fold 879 norm! zR 880 4,5fold 881 call assert_equal([-1, -1, -1, 4, 4, -1, -1], 882 \ map(range(1, 7), 'foldclosed(v:val)')) 883 884 " Click in "+" of inner fold in foldcolumn should open it. 885 redraw 886 let row = 4 887 let col = 2 888 call MouseLeftClick(row, col) 889 call MouseLeftRelease(row, col) 890 call assert_equal([-1, -1, -1, -1, -1, -1, -1], 891 \ map(range(1, 7), 'foldclosed(v:val)')) 892 893 " Click in "-" of outer fold in foldcolumn should close it. 894 redraw 895 let row = 2 896 let col = 1 897 call MouseLeftClick(row, col) 898 call MouseLeftRelease(row, col) 899 call assert_equal([-1, 2, 2, 2, 2, 2, -1], 900 \ map(range(1, 7), 'foldclosed(v:val)')) 901 norm! zR 902 903 " Click in "|" of inner fold in foldcolumn should close it. 904 redraw 905 let row = 5 906 let col = 2 907 call MouseLeftClick(row, col) 908 call MouseLeftRelease(row, col) 909 call assert_equal([-1, -1, -1, 4, 4, -1, -1], 910 \ map(range(1, 7), 'foldclosed(v:val)')) 911 912 let &foldcolumn = save_foldcolumn 913 let &ttymouse = save_ttymouse 914 let &term = save_term 915 let &mouse = save_mouse 916 bwipe! 917endfunc 918 919" Left or right click in Ex command line sets position of the cursor. 920func Test_term_mouse_click_in_cmdline_to_set_pos() 921 let save_mouse = &mouse 922 let save_term = &term 923 let save_ttymouse = &ttymouse 924 call test_override('no_query_mouse', 1) 925 set mouse=a term=xterm 926 let row = &lines 927 928 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec 929 let msg = 'ttymouse=' .. ttymouse_val 930 exe 'set ttymouse=' .. ttymouse_val 931 932 call feedkeys(':"3456789' 933 \ .. MouseLeftClickCode(row, 7) 934 \ .. MouseLeftReleaseCode(row, 7) .. 'L' 935 \ .. MouseRightClickCode(row, 4) 936 \ .. MouseRightReleaseCode(row, 4) .. 'R' 937 \ .. "\<CR>", 'Lx!') 938 call assert_equal('"3R456L789', @:, msg) 939 endfor 940 941 let &mouse = save_mouse 942 let &term = save_term 943 let &ttymouse = save_ttymouse 944 set mousetime& 945 call test_override('no_query_mouse', 0) 946endfunc 947 948" Middle click in command line pastes at position of cursor. 949func Test_term_mouse_middle_click_in_cmdline_to_paste() 950 CheckFeature clipboard_working 951 let save_mouse = &mouse 952 let save_term = &term 953 let save_ttymouse = &ttymouse 954 call test_override('no_query_mouse', 1) 955 set mouse=a term=xterm 956 let row = &lines 957 " Column values does not matter, paste is done at position of cursor. 958 let col = 1 959 let @* = 'paste' 960 961 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec 962 let msg = 'ttymouse=' .. ttymouse_val 963 exe 'set ttymouse=' .. ttymouse_val 964 965 call feedkeys(":\"->" 966 \ .. MouseMiddleReleaseCode(row, col) 967 \ .. MouseMiddleClickCode(row, col) 968 \ .. "<-" 969 \ .. MouseMiddleReleaseCode(row, col) 970 \ .. MouseMiddleClickCode(row, col) 971 \ .. "\<CR>", 'Lx!') 972 call assert_equal('"->paste<-paste', @:, msg) 973 endfor 974 975 let &mouse = save_mouse 976 let &term = save_term 977 let &ttymouse = save_ttymouse 978 let @* = '' 979 call test_override('no_query_mouse', 0) 980endfunc 981 982" Test for displaying the popup menu using the right mouse click 983func Test_mouse_popup_menu() 984 CheckFeature menu 985 new 986 call setline(1, 'popup menu test') 987 let save_mouse = &mouse 988 let save_term = &term 989 let save_ttymouse = &ttymouse 990 let save_mousemodel = &mousemodel 991 call test_override('no_query_mouse', 1) 992 set mouse=a term=xterm mousemodel=popup 993 994 menu PopUp.foo :let g:menustr = 'foo'<CR> 995 menu PopUp.bar :let g:menustr = 'bar'<CR> 996 menu PopUp.baz :let g:menustr = 'baz'<CR> 997 998 for ttymouse_val in s:ttymouse_values 999 exe 'set ttymouse=' .. ttymouse_val 1000 let g:menustr = '' 1001 call feedkeys(MouseRightClickCode(1, 4) 1002 \ .. MouseRightReleaseCode(1, 4) .. "\<Down>\<Down>\<CR>", "x") 1003 call assert_equal('bar', g:menustr) 1004 endfor 1005 1006 unmenu PopUp 1007 let &mouse = save_mouse 1008 let &term = save_term 1009 let &ttymouse = save_ttymouse 1010 let &mousemodel = save_mousemodel 1011 call test_override('no_query_mouse', 0) 1012 close! 1013endfunc 1014 1015" This only checks if the sequence is recognized. 1016func Test_term_rgb_response() 1017 set t_RF=x 1018 set t_RB=y 1019 1020 " response to t_RF, 4 digits 1021 let red = 0x12 1022 let green = 0x34 1023 let blue = 0x56 1024 let seq = printf("\<Esc>]10;rgb:%02x00/%02x00/%02x00\x07", red, green, blue) 1025 call feedkeys(seq, 'Lx!') 1026 call assert_equal(seq, v:termrfgresp) 1027 1028 " response to t_RF, 2 digits 1029 let red = 0x78 1030 let green = 0x9a 1031 let blue = 0xbc 1032 let seq = printf("\<Esc>]10;rgb:%02x/%02x/%02x\x07", red, green, blue) 1033 call feedkeys(seq, 'Lx!') 1034 call assert_equal(seq, v:termrfgresp) 1035 1036 " response to t_RB, 4 digits, dark 1037 set background=light 1038 eval 'background'->test_option_not_set() 1039 let red = 0x29 1040 let green = 0x4a 1041 let blue = 0x6b 1042 let seq = printf("\<Esc>]11;rgb:%02x00/%02x00/%02x00\x07", red, green, blue) 1043 call feedkeys(seq, 'Lx!') 1044 call assert_equal(seq, v:termrbgresp) 1045 call assert_equal('dark', &background) 1046 1047 " response to t_RB, 4 digits, light 1048 set background=dark 1049 call test_option_not_set('background') 1050 let red = 0x81 1051 let green = 0x63 1052 let blue = 0x65 1053 let seq = printf("\<Esc>]11;rgb:%02x00/%02x00/%02x00\x07", red, green, blue) 1054 call feedkeys(seq, 'Lx!') 1055 call assert_equal(seq, v:termrbgresp) 1056 call assert_equal('light', &background) 1057 1058 " response to t_RB, 2 digits, dark 1059 set background=light 1060 call test_option_not_set('background') 1061 let red = 0x47 1062 let green = 0x59 1063 let blue = 0x5b 1064 let seq = printf("\<Esc>]11;rgb:%02x/%02x/%02x\x07", red, green, blue) 1065 call feedkeys(seq, 'Lx!') 1066 call assert_equal(seq, v:termrbgresp) 1067 call assert_equal('dark', &background) 1068 1069 " response to t_RB, 2 digits, light 1070 set background=dark 1071 call test_option_not_set('background') 1072 let red = 0x83 1073 let green = 0xa4 1074 let blue = 0xc2 1075 let seq = printf("\<Esc>]11;rgb:%02x/%02x/%02x\x07", red, green, blue) 1076 call feedkeys(seq, 'Lx!') 1077 call assert_equal(seq, v:termrbgresp) 1078 call assert_equal('light', &background) 1079 1080 set t_RF= t_RB= 1081endfunc 1082 1083" This only checks if the sequence is recognized. 1084" This must be after other tests, because it has side effects to xterm 1085" properties. 1086func Test_xx01_term_style_response() 1087 " Termresponse is only parsed when t_RV is not empty. 1088 set t_RV=x 1089 1090 " send the termresponse to trigger requesting the XT codes 1091 let seq = "\<Esc>[>41;337;0c" 1092 call feedkeys(seq, 'Lx!') 1093 call assert_equal(seq, v:termresponse) 1094 1095 let seq = "\<Esc>P1$r2 q\<Esc>\\" 1096 call feedkeys(seq, 'Lx!') 1097 call assert_equal(seq, v:termstyleresp) 1098 1099 set t_RV= 1100endfunc 1101 1102" This checks the iTerm2 version response. 1103" This must be after other tests, because it has side effects to xterm 1104" properties. 1105func Test_xx02_iTerm2_response() 1106 " Termresponse is only parsed when t_RV is not empty. 1107 set t_RV=x 1108 1109 " Old versions of iTerm2 used a different style term response. 1110 set ttymouse=xterm 1111 call test_option_not_set('ttymouse') 1112 let seq = "\<Esc>[>0;95;c" 1113 call feedkeys(seq, 'Lx!') 1114 call assert_equal(seq, v:termresponse) 1115 call assert_equal('xterm', &ttymouse) 1116 1117 set ttymouse=xterm 1118 call test_option_not_set('ttymouse') 1119 let seq = "\<Esc>[>0;95;0c" 1120 call feedkeys(seq, 'Lx!') 1121 call assert_equal(seq, v:termresponse) 1122 call assert_equal('sgr', &ttymouse) 1123 1124 set t_RV= 1125endfunc 1126 1127" This checks the libvterm version response. 1128" This must be after other tests, because it has side effects to xterm 1129" properties. 1130func Test_xx03_libvterm_response() 1131 " Termresponse is only parsed when t_RV is not empty. 1132 set t_RV=x 1133 1134 set ttymouse=xterm 1135 call test_option_not_set('ttymouse') 1136 let seq = "\<Esc>[>0;100;0c" 1137 call feedkeys(seq, 'Lx!') 1138 call assert_equal(seq, v:termresponse) 1139 call assert_equal('sgr', &ttymouse) 1140 1141 set t_RV= 1142endfunc 1143 1144" This checks the Mac Terminal.app version response. 1145" This must be after other tests, because it has side effects to xterm 1146" properties. 1147func Test_xx04_Mac_Terminal_response() 1148 " Termresponse is only parsed when t_RV is not empty. 1149 set t_RV=x 1150 1151 set ttymouse=xterm 1152 call test_option_not_set('ttymouse') 1153 let seq = "\<Esc>[>1;95;0c" 1154 call feedkeys(seq, 'Lx!') 1155 call assert_equal(seq, v:termresponse) 1156 call assert_equal('sgr', &ttymouse) 1157 1158 " Reset is_not_xterm and is_mac_terminal. 1159 set t_RV= 1160 set term=xterm 1161 set t_RV=x 1162endfunc 1163 1164" This checks the mintty version response. 1165" This must be after other tests, because it has side effects to xterm 1166" properties. 1167func Test_xx05_mintty_response() 1168 " Termresponse is only parsed when t_RV is not empty. 1169 set t_RV=x 1170 1171 set ttymouse=xterm 1172 call test_option_not_set('ttymouse') 1173 let seq = "\<Esc>[>77;20905;0c" 1174 call feedkeys(seq, 'Lx!') 1175 call assert_equal(seq, v:termresponse) 1176 call assert_equal('sgr', &ttymouse) 1177 1178 set t_RV= 1179endfunc 1180 1181" This checks the screen version response. 1182" This must be after other tests, because it has side effects to xterm 1183" properties. 1184func Test_xx06_screen_response() 1185 " Termresponse is only parsed when t_RV is not empty. 1186 set t_RV=x 1187 1188 " Old versions of screen don't support SGR mouse mode. 1189 set ttymouse=xterm 1190 call test_option_not_set('ttymouse') 1191 let seq = "\<Esc>[>83;40500;0c" 1192 call feedkeys(seq, 'Lx!') 1193 call assert_equal(seq, v:termresponse) 1194 call assert_equal('xterm', &ttymouse) 1195 1196 " screen supports SGR mouse mode starting in version 4.7. 1197 set ttymouse=xterm 1198 call test_option_not_set('ttymouse') 1199 let seq = "\<Esc>[>83;40700;0c" 1200 call feedkeys(seq, 'Lx!') 1201 call assert_equal(seq, v:termresponse) 1202 call assert_equal('sgr', &ttymouse) 1203 1204 set t_RV= 1205endfunc 1206 1207" This checks the xterm version response. 1208" This must be after other tests, because it has side effects to xterm 1209" properties. 1210func Test_xx07_xterm_response() 1211 " Termresponse is only parsed when t_RV is not empty. 1212 set t_RV=x 1213 1214 " Do Terminal.app first to check that is_mac_terminal is reset. 1215 set ttymouse=xterm 1216 call test_option_not_set('ttymouse') 1217 let seq = "\<Esc>[>1;95;0c" 1218 call feedkeys(seq, 'Lx!') 1219 call assert_equal(seq, v:termresponse) 1220 call assert_equal('sgr', &ttymouse) 1221 1222 " xterm < 95: "xterm" (actually unmodified) 1223 set t_RV= 1224 set term=xterm 1225 set t_RV=x 1226 set ttymouse=xterm 1227 call test_option_not_set('ttymouse') 1228 let seq = "\<Esc>[>0;94;0c" 1229 call feedkeys(seq, 'Lx!') 1230 call assert_equal(seq, v:termresponse) 1231 call assert_equal('xterm', &ttymouse) 1232 1233 " xterm >= 95 < 277 "xterm2" 1234 set ttymouse=xterm 1235 call test_option_not_set('ttymouse') 1236 let seq = "\<Esc>[>0;267;0c" 1237 call feedkeys(seq, 'Lx!') 1238 call assert_equal(seq, v:termresponse) 1239 call assert_equal('xterm2', &ttymouse) 1240 1241 " xterm >= 277: "sgr" 1242 set ttymouse=xterm 1243 call test_option_not_set('ttymouse') 1244 let seq = "\<Esc>[>0;277;0c" 1245 call feedkeys(seq, 'Lx!') 1246 call assert_equal(seq, v:termresponse) 1247 call assert_equal('sgr', &ttymouse) 1248 1249 set t_RV= 1250endfunc 1251 1252func Test_get_termcode() 1253 try 1254 let k1 = &t_k1 1255 catch /E113/ 1256 throw 'Skipped: Unable to query termcodes' 1257 endtry 1258 set t_k1= 1259 set t_k1& 1260 call assert_equal(k1, &t_k1) 1261 1262 " use external termcap first 1263 set nottybuiltin 1264 set t_k1= 1265 set t_k1& 1266 " when using external termcap may get something else, but it must not be 1267 " empty, since we would fallback to the builtin one. 1268 call assert_notequal('', &t_k1) 1269 1270 if &term =~ 'xterm' 1271 " use internal termcap first 1272 let term_save = &term 1273 let &term = 'builtin_' .. &term 1274 set t_k1= 1275 set t_k1& 1276 call assert_equal(k1, &t_k1) 1277 let &term = term_save 1278 endif 1279 1280 set ttybuiltin 1281endfunc 1282 1283func GetEscCodeCSI27(key, modifier) 1284 let key = printf("%d", char2nr(a:key)) 1285 let mod = printf("%d", a:modifier) 1286 return "\<Esc>[27;" .. mod .. ';' .. key .. '~' 1287endfunc 1288 1289func GetEscCodeCSIu(key, modifier) 1290 let key = printf("%d", char2nr(a:key)) 1291 let mod = printf("%d", a:modifier) 1292 return "\<Esc>[" .. key .. ';' .. mod .. 'u' 1293endfunc 1294 1295" This checks the CSI sequences when in modifyOtherKeys mode. 1296" The mode doesn't need to be enabled, the codes are always detected. 1297func RunTest_modifyOtherKeys(func) 1298 new 1299 set timeoutlen=10 1300 1301 " Shift-X is sent as 'X' with the shift modifier 1302 call feedkeys('a' .. a:func('X', 2) .. "\<Esc>", 'Lx!') 1303 call assert_equal('X', getline(1)) 1304 1305 " Ctrl-i is Tab 1306 call setline(1, '') 1307 call feedkeys('a' .. a:func('i', 5) .. "\<Esc>", 'Lx!') 1308 call assert_equal("\t", getline(1)) 1309 1310 " Ctrl-I is also Tab 1311 call setline(1, '') 1312 call feedkeys('a' .. a:func('I', 5) .. "\<Esc>", 'Lx!') 1313 call assert_equal("\t", getline(1)) 1314 1315 " Alt-x is ø 1316 call setline(1, '') 1317 call feedkeys('a' .. a:func('x', 3) .. "\<Esc>", 'Lx!') 1318 call assert_equal("ø", getline(1)) 1319 1320 " Meta-x is also ø 1321 call setline(1, '') 1322 call feedkeys('a' .. a:func('x', 9) .. "\<Esc>", 'Lx!') 1323 call assert_equal("ø", getline(1)) 1324 1325 " Alt-X is Ø 1326 call setline(1, '') 1327 call feedkeys('a' .. a:func('X', 3) .. "\<Esc>", 'Lx!') 1328 call assert_equal("Ø", getline(1)) 1329 1330 " Meta-X is ø 1331 call setline(1, '') 1332 call feedkeys('a' .. a:func('X', 9) .. "\<Esc>", 'Lx!') 1333 call assert_equal("Ø", getline(1)) 1334 1335 " Ctrl-6 is Ctrl-^ 1336 split aaa 1337 edit bbb 1338 call feedkeys(a:func('6', 5), 'Lx!') 1339 call assert_equal("aaa", bufname()) 1340 bwipe aaa 1341 bwipe bbb 1342 1343 bwipe! 1344 set timeoutlen& 1345endfunc 1346 1347func Test_modifyOtherKeys_basic() 1348 call RunTest_modifyOtherKeys(function('GetEscCodeCSI27')) 1349 call RunTest_modifyOtherKeys(function('GetEscCodeCSIu')) 1350endfunc 1351 1352func Test_modifyOtherKeys_no_mapping() 1353 set timeoutlen=10 1354 1355 let @a = 'aaa' 1356 call feedkeys(":let x = '" .. GetEscCodeCSI27('R', 5) .. GetEscCodeCSI27('R', 5) .. "a'\<CR>", 'Lx!') 1357 call assert_equal("let x = 'aaa'", @:) 1358 1359 new 1360 call feedkeys("a" .. GetEscCodeCSI27('R', 5) .. GetEscCodeCSI27('R', 5) .. "a\<Esc>", 'Lx!') 1361 call assert_equal("aaa", getline(1)) 1362 bwipe! 1363 1364 new 1365 call feedkeys("axx\<CR>yy" .. GetEscCodeCSI27('G', 5) .. GetEscCodeCSI27('K', 5) .. "a\<Esc>", 'Lx!') 1366 call assert_equal("axx", getline(1)) 1367 call assert_equal("yy", getline(2)) 1368 bwipe! 1369 1370 set timeoutlen& 1371endfunc 1372 1373func RunTest_mapping_shift(key, func) 1374 call setline(1, '') 1375 if a:key == '|' 1376 exe 'inoremap \| xyz' 1377 else 1378 exe 'inoremap ' .. a:key .. ' xyz' 1379 endif 1380 call feedkeys('a' .. a:func(a:key, 2) .. "\<Esc>", 'Lx!') 1381 call assert_equal("xyz", getline(1)) 1382 if a:key == '|' 1383 exe 'iunmap \|' 1384 else 1385 exe 'iunmap ' .. a:key 1386 endif 1387endfunc 1388 1389func RunTest_mapping_works_with_shift(func) 1390 new 1391 set timeoutlen=10 1392 1393 call RunTest_mapping_shift('@', a:func) 1394 call RunTest_mapping_shift('A', a:func) 1395 call RunTest_mapping_shift('Z', a:func) 1396 call RunTest_mapping_shift('^', a:func) 1397 call RunTest_mapping_shift('_', a:func) 1398 call RunTest_mapping_shift('{', a:func) 1399 call RunTest_mapping_shift('|', a:func) 1400 call RunTest_mapping_shift('}', a:func) 1401 call RunTest_mapping_shift('~', a:func) 1402 1403 bwipe! 1404 set timeoutlen& 1405endfunc 1406 1407func Test_mapping_works_with_shift_plain() 1408 call RunTest_mapping_works_with_shift(function('GetEscCodeCSI27')) 1409 call RunTest_mapping_works_with_shift(function('GetEscCodeCSIu')) 1410endfunc 1411 1412func RunTest_mapping_mods(map, key, func, code) 1413 call setline(1, '') 1414 exe 'inoremap ' .. a:map .. ' xyz' 1415 call feedkeys('a' .. a:func(a:key, a:code) .. "\<Esc>", 'Lx!') 1416 call assert_equal("xyz", getline(1)) 1417 exe 'iunmap ' .. a:map 1418endfunc 1419 1420func RunTest_mapping_works_with_mods(func, mods, code) 1421 new 1422 set timeoutlen=10 1423 1424 if a:mods !~ 'S' 1425 " Shift by itself has no effect 1426 call RunTest_mapping_mods('<' .. a:mods .. '-@>', '@', a:func, a:code) 1427 endif 1428 call RunTest_mapping_mods('<' .. a:mods .. '-A>', 'A', a:func, a:code) 1429 call RunTest_mapping_mods('<' .. a:mods .. '-Z>', 'Z', a:func, a:code) 1430 if a:mods !~ 'S' 1431 " with Shift code is always upper case 1432 call RunTest_mapping_mods('<' .. a:mods .. '-a>', 'a', a:func, a:code) 1433 call RunTest_mapping_mods('<' .. a:mods .. '-z>', 'z', a:func, a:code) 1434 endif 1435 if a:mods != 'A' 1436 " with Alt code is not in upper case 1437 call RunTest_mapping_mods('<' .. a:mods .. '-a>', 'A', a:func, a:code) 1438 call RunTest_mapping_mods('<' .. a:mods .. '-z>', 'Z', a:func, a:code) 1439 endif 1440 call RunTest_mapping_mods('<' .. a:mods .. '-á>', 'á', a:func, a:code) 1441 if a:mods !~ 'S' 1442 " Shift by itself has no effect 1443 call RunTest_mapping_mods('<' .. a:mods .. '-^>', '^', a:func, a:code) 1444 call RunTest_mapping_mods('<' .. a:mods .. '-_>', '_', a:func, a:code) 1445 call RunTest_mapping_mods('<' .. a:mods .. '-{>', '{', a:func, a:code) 1446 call RunTest_mapping_mods('<' .. a:mods .. '-\|>', '|', a:func, a:code) 1447 call RunTest_mapping_mods('<' .. a:mods .. '-}>', '}', a:func, a:code) 1448 call RunTest_mapping_mods('<' .. a:mods .. '-~>', '~', a:func, a:code) 1449 endif 1450 1451 bwipe! 1452 set timeoutlen& 1453endfunc 1454 1455func Test_mapping_works_with_shift() 1456 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'S', 2) 1457 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'S', 2) 1458endfunc 1459 1460func Test_mapping_works_with_ctrl() 1461 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C', 5) 1462 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C', 5) 1463endfunc 1464 1465func Test_mapping_works_with_shift_ctrl() 1466 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-S', 6) 1467 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-S', 6) 1468endfunc 1469 1470" Below we also test the "u" code with Alt, This works, but libvterm would not 1471" send the Alt key like this but by prefixing an Esc. 1472 1473func Test_mapping_works_with_alt() 1474 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'A', 3) 1475 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'A', 3) 1476endfunc 1477 1478func Test_mapping_works_with_shift_alt() 1479 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'S-A', 4) 1480 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'S-A', 4) 1481endfunc 1482 1483func Test_mapping_works_with_ctrl_alt() 1484 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-A', 7) 1485 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-A', 7) 1486endfunc 1487 1488func Test_mapping_works_with_shift_ctrl_alt() 1489 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-S-A', 8) 1490 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-S-A', 8) 1491endfunc 1492 1493func Test_insert_literal() 1494 set timeoutlen=10 1495 new 1496 " CTRL-V CTRL-X inserts a ^X 1497 call feedkeys('a' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu('X', '5') .. "\<Esc>", 'Lx!') 1498 call assert_equal("\<C-X>", getline(1)) 1499 1500 call setline(1, '') 1501 call feedkeys('a' .. GetEscCodeCSI27('V', '5') .. GetEscCodeCSI27('X', '5') .. "\<Esc>", 'Lx!') 1502 call assert_equal("\<C-X>", getline(1)) 1503 1504 " CTRL-SHIFT-V CTRL-X inserts escape sequence 1505 call setline(1, '') 1506 call feedkeys('a' .. GetEscCodeCSIu('V', '6') .. GetEscCodeCSIu('X', '5') .. "\<Esc>", 'Lx!') 1507 call assert_equal("\<Esc>[88;5u", getline(1)) 1508 1509 call setline(1, '') 1510 call feedkeys('a' .. GetEscCodeCSI27('V', '6') .. GetEscCodeCSI27('X', '5') .. "\<Esc>", 'Lx!') 1511 call assert_equal("\<Esc>[27;5;88~", getline(1)) 1512 1513 bwipe! 1514 set timeoutlen& 1515endfunc 1516 1517func Test_cmdline_literal() 1518 set timeoutlen=10 1519 1520 " CTRL-V CTRL-Y inserts a ^Y 1521 call feedkeys(':' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!') 1522 call assert_equal("\"\<C-Y>", @:) 1523 1524 call feedkeys(':' .. GetEscCodeCSI27('V', '5') .. GetEscCodeCSI27('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!') 1525 call assert_equal("\"\<C-Y>", @:) 1526 1527 " CTRL-SHIFT-V CTRL-Y inserts escape sequence 1528 call feedkeys(':' .. GetEscCodeCSIu('V', '6') .. GetEscCodeCSIu('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!') 1529 call assert_equal("\"\<Esc>[89;5u", @:) 1530 1531 call setline(1, '') 1532 call feedkeys(':' .. GetEscCodeCSI27('V', '6') .. GetEscCodeCSI27('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!') 1533 call assert_equal("\"\<Esc>[27;5;89~", @:) 1534 1535 set timeoutlen& 1536endfunc 1537 1538" vim: shiftwidth=2 sts=2 expandtab 1539