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