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