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 10source view_util.vim 11source term_util.vim 12 13func Test_term_mouse_left_click() 14 new 15 let save_mouse = &mouse 16 let save_term = &term 17 let save_ttymouse = &ttymouse 18 call test_override('no_query_mouse', 1) 19 set mouse=a term=xterm 20 call setline(1, ['line 1', 'line 2', 'line 3 is a bit longer']) 21 22 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm 23 let msg = 'ttymouse=' .. ttymouse_val 24 exe 'set ttymouse=' .. ttymouse_val 25 go 26 call assert_equal([0, 1, 1, 0], getpos('.'), msg) 27 let row = 2 28 let col = 6 29 call MouseLeftClick(row, col) 30 call MouseLeftRelease(row, col) 31 call assert_equal([0, 2, 6, 0], getpos('.'), msg) 32 endfor 33 34 let &mouse = save_mouse 35 let &term = save_term 36 let &ttymouse = save_ttymouse 37 call test_override('no_query_mouse', 0) 38 bwipe! 39endfunc 40 41func Test_xterm_mouse_right_click_extends_visual() 42 if has('mac') 43 throw "Skipped: test right click in visual mode does not work on macOs (why?)" 44 endif 45 let save_mouse = &mouse 46 let save_term = &term 47 let save_ttymouse = &ttymouse 48 call test_override('no_query_mouse', 1) 49 set mouse=a term=xterm 50 51 for visual_mode in ["v", "V", "\<C-V>"] 52 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec 53 let msg = 'visual=' .. visual_mode .. ' ttymouse=' .. ttymouse_val 54 exe 'set ttymouse=' .. ttymouse_val 55 56 call setline(1, repeat([repeat('-', 7)], 7)) 57 call MouseLeftClick(4, 4) 58 call MouseLeftRelease(4, 4) 59 exe "norm! " .. visual_mode 60 61 " Right click extends top left of visual area. 62 call MouseRightClick(2, 2) 63 call MouseRightRelease(2, 2) 64 65 " Right click extends bottom right of visual area. 66 call MouseRightClick(6, 6) 67 call MouseRightRelease(6, 6) 68 norm! r1gv 69 70 " Right click shrinks top left of visual area. 71 call MouseRightClick(3, 3) 72 call MouseRightRelease(3, 3) 73 74 " Right click shrinks bottom right of visual area. 75 call MouseRightClick(5, 5) 76 call MouseRightRelease(5, 5) 77 norm! r2 78 79 if visual_mode ==# 'v' 80 call assert_equal(['-------', 81 \ '-111111', 82 \ '1122222', 83 \ '2222222', 84 \ '2222211', 85 \ '111111-', 86 \ '-------'], getline(1, '$'), msg) 87 elseif visual_mode ==# 'V' 88 call assert_equal(['-------', 89 \ '1111111', 90 \ '2222222', 91 \ '2222222', 92 \ '2222222', 93 \ '1111111', 94 \ '-------'], getline(1, '$'), msg) 95 else 96 call assert_equal(['-------', 97 \ '-11111-', 98 \ '-12221-', 99 \ '-12221-', 100 \ '-12221-', 101 \ '-11111-', 102 \ '-------'], getline(1, '$'), msg) 103 endif 104 endfor 105 endfor 106 107 let &mouse = save_mouse 108 let &term = save_term 109 let &ttymouse = save_ttymouse 110 call test_override('no_query_mouse', 0) 111 bwipe! 112endfunc 113 114" Test that <C-LeftMouse> jumps to help tag and <C-RightMouse> jumps back. 115" Also test for g<LeftMouse> and g<RightMouse>. 116func Test_xterm_mouse_tagjump() 117 let save_mouse = &mouse 118 let save_term = &term 119 let save_ttymouse = &ttymouse 120 set mouse=a term=xterm 121 122 for ttymouse_val in g:Ttymouse_values 123 let msg = 'ttymouse=' .. ttymouse_val 124 exe 'set ttymouse=' .. ttymouse_val 125 help 126 /usr_02.txt 127 norm! zt 128 129 " CTRL-left click to jump to a tag 130 let row = 1 131 let col = 1 132 call MouseCtrlLeftClick(row, col) 133 call MouseLeftRelease(row, col) 134 call assert_match('usr_02.txt$', bufname('%'), msg) 135 call assert_equal('*usr_02.txt*', expand('<cWORD>'), msg) 136 137 " CTRL-right click to pop a tag 138 call MouseCtrlRightClick(row, col) 139 call MouseRightRelease(row, col) 140 call assert_match('help.txt$', bufname('%'), msg) 141 call assert_equal('|usr_02.txt|', expand('<cWORD>'), msg) 142 143 " Jump to a tag 144 exe "normal \<C-]>" 145 call assert_match('usr_02.txt$', bufname('%'), msg) 146 call assert_equal('*usr_02.txt*', expand('<cWORD>'), msg) 147 148 " Use CTRL-right click in insert mode to pop the tag 149 new 150 let str = 'iHello' .. MouseCtrlRightClickCode(row, col) 151 \ .. MouseRightReleaseCode(row, col) .. "\<C-C>" 152 call assert_fails('call feedkeys(str, "Lx!")', 'E37:', msg) 153 close! 154 155 " CTRL-right click with a count 156 let str = "4" .. MouseCtrlRightClickCode(row, col) 157 \ .. MouseRightReleaseCode(row, col) 158 call assert_fails('call feedkeys(str, "Lx!")', 'E555:', msg) 159 call assert_match('help.txt$', bufname('%'), msg) 160 call assert_equal(1, line('.'), msg) 161 162 " g<LeftMouse> to jump to a tag 163 /usr_02.txt 164 norm! zt 165 call test_setmouse(row, col) 166 exe "normal g\<LeftMouse>" 167 call assert_match('usr_02.txt$', bufname('%'), msg) 168 call assert_equal('*usr_02.txt*', expand('<cWORD>'), msg) 169 170 " g<RightMouse> to pop to a tag 171 call test_setmouse(row, col) 172 exe "normal g\<RightMouse>" 173 call assert_match('help.txt$', bufname('%'), msg) 174 call assert_equal('|usr_02.txt|', expand('<cWORD>'), msg) 175 176 %bw! 177 endfor 178 179 let &mouse = save_mouse 180 let &term = save_term 181 let &ttymouse = save_ttymouse 182endfunc 183 184func Test_term_mouse_middle_click() 185 CheckFeature clipboard_working 186 187 new 188 let save_mouse = &mouse 189 let save_term = &term 190 let save_ttymouse = &ttymouse 191 call test_override('no_query_mouse', 1) 192 let save_quotestar = @* 193 let save_quoteplus = @+ 194 set mouse=a term=xterm 195 196 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec 197 let msg = 'ttymouse=' .. ttymouse_val 198 exe 'set ttymouse=' .. ttymouse_val 199 call setline(1, ['123456789', '123456789']) 200 let @* = 'abc' 201 202 " Middle-click in the middle of the line pastes text where clicked. 203 let row = 1 204 let col = 6 205 call MouseMiddleClick(row, col) 206 call MouseMiddleRelease(row, col) 207 call assert_equal(['12345abc6789', '123456789'], getline(1, '$'), msg) 208 209 " Middle-click beyond end of the line pastes text at the end of the line. 210 let col = 20 211 call MouseMiddleClick(row, col) 212 call MouseMiddleRelease(row, col) 213 call assert_equal(['12345abc6789abc', '123456789'], getline(1, '$'), msg) 214 215 " Middle-click beyond the last line pastes in the last line. 216 let row = 5 217 let col = 3 218 call MouseMiddleClick(row, col) 219 call MouseMiddleRelease(row, col) 220 call assert_equal(['12345abc6789abc', '12abc3456789'], getline(1, '$'), msg) 221 222 " Middle mouse click in operator pending mode beeps 223 call assert_beeps('exe "normal c\<MiddleMouse>"') 224 225 " Clicking middle mouse in visual mode, yanks the selection and pastes the 226 " clipboard contents 227 let save_clipboard = &clipboard 228 set clipboard= 229 let @" = '' 230 call cursor(1, 1) 231 call feedkeys("v3l" .. 232 \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7), 'Lx!') 233 call assert_equal(['12345abc6789abc', '12abc3abc456789'], 234 \ getline(1, '$'), msg) 235 call assert_equal('1234', @", msg) 236 let &clipboard = save_clipboard 237 238 " Clicking middle mouse in select mode, replaces the selected text with 239 " the clipboard contents 240 let @+ = 'xyz' 241 call cursor(1, 3) 242 exe "normal gh\<Right>\<Right>\<MiddleMouse>" 243 call assert_equal(['12xyzabc6789abc', '12abc3abc456789'], 244 \ getline(1, '$'), msg) 245 246 " Prefixing middle click with [ or ] fixes the indent after pasting. 247 %d 248 call setline(1, " one two") 249 call setreg('r', 'red blue', 'l') 250 call test_setmouse(1, 5) 251 exe "normal \"r[\<MiddleMouse>" 252 call assert_equal(' red blue', getline(1), msg) 253 call test_setmouse(2, 5) 254 exe "normal \"r]\<MiddleMouse>" 255 call assert_equal(' red blue', getline(3), msg) 256 %d 257 endfor 258 259 let &mouse = save_mouse 260 let &term = save_term 261 let &ttymouse = save_ttymouse 262 call test_override('no_query_mouse', 0) 263 let @* = save_quotestar 264 let @+ = save_quotestar 265 bwipe! 266endfunc 267 268" If clipboard is not working, then clicking the middle mouse button in visual 269" mode, will copy and paste the selected text. 270func Test_term_mouse_middle_click_no_clipboard() 271 if has('clipboard_working') 272 throw 'Skipped: clipboard support works' 273 endif 274 new 275 let save_mouse = &mouse 276 let save_term = &term 277 let save_ttymouse = &ttymouse 278 call test_override('no_query_mouse', 1) 279 set mouse=a term=xterm 280 281 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec 282 let msg = 'ttymouse=' .. ttymouse_val 283 exe 'set ttymouse=' .. ttymouse_val 284 call setline(1, ['123456789', '123456789']) 285 286 " Clicking middle mouse in visual mode, yanks the selection and pastes it 287 call cursor(1, 1) 288 call feedkeys("v3l" .. 289 \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7), 'Lx!') 290 call assert_equal(['123456789', '1234561234789'], 291 \ getline(1, '$'), msg) 292 endfor 293 294 call test_override('no_query_mouse', 0) 295 let &ttymouse = save_ttymouse 296 let &term = save_term 297 let &mouse = save_mouse 298 close! 299endfunc 300 301func Test_term_mouse_middle_click_insert_mode() 302 CheckFeature clipboard_working 303 304 new 305 let save_mouse = &mouse 306 let save_term = &term 307 let save_ttymouse = &ttymouse 308 call test_override('no_query_mouse', 1) 309 set mouse=a term=xterm 310 311 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec 312 let msg = 'ttymouse=' .. ttymouse_val 313 exe 'set ttymouse=' .. ttymouse_val 314 call setline(1, ['123456789', '123456789']) 315 let @* = 'abc' 316 317 " Middle-click in inesrt mode doesn't move the cursor but inserts the 318 " contents of aregister 319 call cursor(1, 4) 320 call feedkeys('i' .. 321 \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7) .. 322 \ "\<C-C>", 'Lx!') 323 call assert_equal(['123abc456789', '123456789'], 324 \ getline(1, '$'), msg) 325 call assert_equal([1, 6], [line('.'), col('.')], msg) 326 327 " Middle-click in replace mode 328 call cursor(1, 1) 329 call feedkeys('$R' .. 330 \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7) .. 331 \ "\<C-C>", 'Lx!') 332 call assert_equal(['123abc45678abc', '123456789'], 333 \ getline(1, '$'), msg) 334 call assert_equal([1, 14], [line('.'), col('.')], msg) 335 endfor 336 337 let &mouse = save_mouse 338 let &term = save_term 339 let &ttymouse = save_ttymouse 340 call test_override('no_query_mouse', 0) 341 close! 342endfunc 343 344" Test for switching window using mouse in insert mode 345func Test_term_mouse_switch_win_insert_mode() 346 5new 347 let save_mouse = &mouse 348 let save_term = &term 349 let save_ttymouse = &ttymouse 350 call test_override('no_query_mouse', 1) 351 set mouse=a term=xterm ttymouse=xterm2 352 353 call feedkeys('ivim' .. 354 \ MouseLeftClickCode(8, 6) .. MouseLeftReleaseCode(8, 6) .. 355 \ "\<C-C>", 'Lx!') 356 call assert_equal(2, winnr()) 357 wincmd w 358 call assert_equal('n', mode()) 359 call assert_equal(['vim'], getline(1, '$')) 360 361 let &mouse = save_mouse 362 let &term = save_term 363 let &ttymouse = save_ttymouse 364 call test_override('no_query_mouse', 0) 365 close! 366endfunc 367 368" Test for using the mouse to increaes the height of the cmdline window 369func Test_mouse_cmdwin_resize() 370 CheckFeature cmdwin 371 372 let save_mouse = &mouse 373 let save_term = &term 374 let save_ttymouse = &ttymouse 375 call test_override('no_query_mouse', 1) 376 set mouse=a term=xterm ttymouse=xterm2 377 5new 378 redraw! 379 380 let h = 0 381 let row = &lines - &cmdwinheight - 2 382 call feedkeys("q:" .. 383 \ MouseLeftClickCode(row, 1) .. 384 \ MouseLeftDragCode(row - 1, 1) .. 385 \ MouseLeftReleaseCode(row - 2, 1) .. 386 \ "alet h = \<C-R>=winheight(0)\<CR>\<CR>", 'Lx!') 387 call assert_equal(&cmdwinheight + 2, h) 388 389 let &mouse = save_mouse 390 let &term = save_term 391 let &ttymouse = save_ttymouse 392 call test_override('no_query_mouse', 0) 393 close! 394endfunc 395 396" TODO: for unclear reasons this test fails if it comes after 397" Test_xterm_mouse_ctrl_click() 398func Test_1xterm_mouse_wheel() 399 new 400 let save_mouse = &mouse 401 let save_term = &term 402 let save_wrap = &wrap 403 let save_ttymouse = &ttymouse 404 set mouse=a term=xterm nowrap 405 call setline(1, range(100000000000000, 100000000000100)) 406 407 for ttymouse_val in g:Ttymouse_values 408 let msg = 'ttymouse=' .. ttymouse_val 409 exe 'set ttymouse=' .. ttymouse_val 410 go 411 call assert_equal(1, line('w0'), msg) 412 call assert_equal([0, 1, 1, 0], getpos('.'), msg) 413 414 call MouseWheelDown(1, 1) 415 call assert_equal(4, line('w0'), msg) 416 call assert_equal([0, 4, 1, 0], getpos('.'), msg) 417 418 call MouseWheelDown(1, 1) 419 call assert_equal(7, line('w0'), msg) 420 call assert_equal([0, 7, 1, 0], getpos('.'), msg) 421 422 call MouseWheelUp(1, 1) 423 call assert_equal(4, line('w0'), msg) 424 call assert_equal([0, 7, 1, 0], getpos('.'), msg) 425 426 call MouseWheelUp(1, 1) 427 call assert_equal(1, line('w0'), msg) 428 call assert_equal([0, 7, 1, 0], getpos('.'), msg) 429 430 if has('gui') 431 " Horizontal wheel scrolling currently only works when vim is 432 " compiled with gui enabled. 433 call MouseWheelRight(1, 1) 434 call assert_equal(7, 1 + virtcol(".") - wincol(), msg) 435 call assert_equal([0, 7, 7, 0], getpos('.'), msg) 436 437 call MouseWheelRight(1, 1) 438 call assert_equal(13, 1 + virtcol(".") - wincol(), msg) 439 call assert_equal([0, 7, 13, 0], getpos('.'), msg) 440 441 call MouseWheelLeft(1, 1) 442 call assert_equal(7, 1 + virtcol(".") - wincol(), msg) 443 call assert_equal([0, 7, 13, 0], getpos('.'), msg) 444 445 call MouseWheelLeft(1, 1) 446 call assert_equal(1, 1 + virtcol(".") - wincol(), msg) 447 call assert_equal([0, 7, 13, 0], getpos('.'), msg) 448 endif 449 endfor 450 451 let &mouse = save_mouse 452 let &term = save_term 453 let &wrap = save_wrap 454 let &ttymouse = save_ttymouse 455 bwipe! 456endfunc 457 458" Test that dragging beyond the window (at the bottom and at the top) 459" scrolls window content by the number of lines beyond the window. 460func Test_term_mouse_drag_beyond_window() 461 let save_mouse = &mouse 462 let save_term = &term 463 let save_ttymouse = &ttymouse 464 call test_override('no_query_mouse', 1) 465 set mouse=a term=xterm 466 let col = 1 467 call setline(1, range(1, 100)) 468 469 " Split into 3 windows, and go into the middle window 470 " so we test dragging mouse below and above the window. 471 2split 472 wincmd j 473 2split 474 475 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec 476 let msg = 'ttymouse=' .. ttymouse_val 477 exe 'set ttymouse=' .. ttymouse_val 478 479 " Line #10 at the top. 480 norm! 10zt 481 redraw 482 call assert_equal(10, winsaveview().topline, msg) 483 call assert_equal(2, winheight(0), msg) 484 485 let row = 4 486 call MouseLeftClick(row, col) 487 call assert_equal(10, winsaveview().topline, msg) 488 489 " Drag downwards. We're still in the window so topline should 490 " not change yet. 491 let row += 1 492 call MouseLeftDrag(row, col) 493 call assert_equal(10, winsaveview().topline, msg) 494 495 " We now leave the window at the bottom, so the window content should 496 " scroll by 1 line, then 2 lines (etc) as we drag further away. 497 let row += 1 498 call MouseLeftDrag(row, col) 499 call assert_equal(11, winsaveview().topline, msg) 500 501 let row += 1 502 call MouseLeftDrag(row, col) 503 call assert_equal(13, winsaveview().topline, msg) 504 505 " Now drag upwards. 506 let row -= 1 507 call MouseLeftDrag(row, col) 508 call assert_equal(14, winsaveview().topline, msg) 509 510 " We're now back in the window so the topline should not change. 511 let row -= 1 512 call MouseLeftDrag(row, col) 513 call assert_equal(14, winsaveview().topline, msg) 514 515 let row -= 1 516 call MouseLeftDrag(row, col) 517 call assert_equal(14, winsaveview().topline, msg) 518 519 " We now leave the window at the top so the window content should 520 " scroll by 1 line, then 2, then 3 (etc) in the opposite direction. 521 let row -= 1 522 call MouseLeftDrag(row, col) 523 call assert_equal(13, winsaveview().topline, msg) 524 525 let row -= 1 526 call MouseLeftDrag(row, col) 527 call assert_equal(11, winsaveview().topline, msg) 528 529 let row -= 1 530 call MouseLeftDrag(row, col) 531 call assert_equal(8, winsaveview().topline, msg) 532 533 call MouseLeftRelease(row, col) 534 call assert_equal(8, winsaveview().topline, msg) 535 call assert_equal(2, winheight(0), msg) 536 endfor 537 538 let &mouse = save_mouse 539 let &term = save_term 540 let &ttymouse = save_ttymouse 541 call test_override('no_query_mouse', 0) 542 bwipe! 543endfunc 544 545func Test_term_mouse_drag_window_separator() 546 let save_mouse = &mouse 547 let save_term = &term 548 let save_ttymouse = &ttymouse 549 call test_override('no_query_mouse', 1) 550 set mouse=a term=xterm 551 552 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec 553 let msg = 'ttymouse=' .. ttymouse_val 554 exe 'set ttymouse=' .. ttymouse_val 555 556 " Split horizontally and test dragging the horizontal window separator. 557 split 558 let rowseparator = winheight(0) + 1 559 let row = rowseparator 560 let col = 1 561 562 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported. 563 if ttymouse_val !=# 'xterm2' || row <= 223 564 call MouseLeftClick(row, col) 565 let row -= 1 566 call MouseLeftDrag(row, col) 567 call assert_equal(rowseparator - 1, winheight(0) + 1, msg) 568 let row += 1 569 call MouseLeftDrag(row, col) 570 call assert_equal(rowseparator, winheight(0) + 1, msg) 571 call MouseLeftRelease(row, col) 572 call assert_equal(rowseparator, winheight(0) + 1, msg) 573 endif 574 bwipe! 575 576 " Split vertically and test dragging the vertical window separator. 577 vsplit 578 let colseparator = winwidth(0) + 1 579 let row = 1 580 let col = colseparator 581 582 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported. 583 if ttymouse_val !=# 'xterm2' || col <= 223 584 call MouseLeftClick(row, col) 585 let col -= 1 586 call MouseLeftDrag(row, col) 587 call assert_equal(colseparator - 1, winwidth(0) + 1, msg) 588 let col += 1 589 call MouseLeftDrag(row, col) 590 call assert_equal(colseparator, winwidth(0) + 1, msg) 591 call MouseLeftRelease(row, col) 592 call assert_equal(colseparator, winwidth(0) + 1, msg) 593 endif 594 bwipe! 595 endfor 596 597 let &mouse = save_mouse 598 let &term = save_term 599 let &ttymouse = save_ttymouse 600 call test_override('no_query_mouse', 0) 601endfunc 602 603func Test_term_mouse_drag_statusline() 604 let save_mouse = &mouse 605 let save_term = &term 606 let save_ttymouse = &ttymouse 607 call test_override('no_query_mouse', 1) 608 let save_laststatus = &laststatus 609 set mouse=a term=xterm laststatus=2 610 611 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec 612 let msg = 'ttymouse=' .. ttymouse_val 613 exe 'set ttymouse=' .. ttymouse_val 614 615 call assert_equal(1, &cmdheight, msg) 616 let rowstatusline = winheight(0) + 1 617 let row = rowstatusline 618 let col = 1 619 620 if ttymouse_val ==# 'xterm2' && row > 223 621 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported. 622 continue 623 endif 624 625 call MouseLeftClick(row, col) 626 let row -= 1 627 call MouseLeftDrag(row, col) 628 call assert_equal(2, &cmdheight, msg) 629 call assert_equal(rowstatusline - 1, winheight(0) + 1, msg) 630 let row += 1 631 call MouseLeftDrag(row, col) 632 call assert_equal(1, &cmdheight, msg) 633 call assert_equal(rowstatusline, winheight(0) + 1, msg) 634 call MouseLeftRelease(row, col) 635 call assert_equal(1, &cmdheight, msg) 636 call assert_equal(rowstatusline, winheight(0) + 1, msg) 637 endfor 638 639 let &mouse = save_mouse 640 let &term = save_term 641 let &ttymouse = save_ttymouse 642 call test_override('no_query_mouse', 0) 643 let &laststatus = save_laststatus 644endfunc 645 646func Test_term_mouse_click_tab() 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 652 let row = 1 653 654 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm 655 let msg = 'ttymouse=' .. ttymouse_val 656 exe 'set ttymouse=' .. ttymouse_val 657 e Xfoo 658 tabnew Xbar 659 660 let a = split(execute(':tabs'), "\n") 661 call assert_equal(['Tab page 1', 662 \ ' Xfoo', 663 \ 'Tab page 2', 664 \ '> Xbar'], a, msg) 665 666 " Test clicking on tab names in the tabline at the top. 667 let col = 2 668 redraw 669 call MouseLeftClick(row, col) 670 call MouseLeftRelease(row, col) 671 let a = split(execute(':tabs'), "\n") 672 call assert_equal(['Tab page 1', 673 \ '> Xfoo', 674 \ 'Tab page 2', 675 \ ' Xbar'], a, msg) 676 677 let col = 9 678 call MouseLeftClick(row, col) 679 call MouseLeftRelease(row, col) 680 let a = split(execute(':tabs'), "\n") 681 call assert_equal(['Tab page 1', 682 \ ' Xfoo', 683 \ 'Tab page 2', 684 \ '> Xbar'], a, msg) 685 686 %bwipe! 687 endfor 688 689 let &mouse = save_mouse 690 let &term = save_term 691 let &ttymouse = save_ttymouse 692 call test_override('no_query_mouse', 0) 693endfunc 694 695func Test_term_mouse_click_X_to_close_tab() 696 let save_mouse = &mouse 697 let save_term = &term 698 let save_ttymouse = &ttymouse 699 call test_override('no_query_mouse', 1) 700 set mouse=a term=xterm 701 let row = 1 702 let col = &columns 703 704 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm 705 if ttymouse_val ==# 'xterm2' && col > 223 706 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported. 707 continue 708 endif 709 let msg = 'ttymouse=' .. ttymouse_val 710 exe 'set ttymouse=' .. ttymouse_val 711 e Xtab1 712 tabnew Xtab2 713 tabnew Xtab3 714 tabn 2 715 716 let a = split(execute(':tabs'), "\n") 717 call assert_equal(['Tab page 1', 718 \ ' Xtab1', 719 \ 'Tab page 2', 720 \ '> Xtab2', 721 \ 'Tab page 3', 722 \ ' Xtab3'], a, msg) 723 724 " Click on "X" in tabline to close current tab i.e. Xtab2. 725 redraw 726 call MouseLeftClick(row, col) 727 call MouseLeftRelease(row, col) 728 let a = split(execute(':tabs'), "\n") 729 call assert_equal(['Tab page 1', 730 \ ' Xtab1', 731 \ 'Tab page 2', 732 \ '> Xtab3'], a, msg) 733 734 %bwipe! 735 endfor 736 737 let &mouse = save_mouse 738 let &term = save_term 739 let &ttymouse = save_ttymouse 740 call test_override('no_query_mouse', 0) 741endfunc 742 743func Test_term_mouse_drag_to_move_tab() 744 let save_mouse = &mouse 745 let save_term = &term 746 let save_ttymouse = &ttymouse 747 call test_override('no_query_mouse', 1) 748 " Set 'mousetime' to 1 to avoid recognizing a double-click in the loop 749 set mouse=a term=xterm mousetime=1 750 let row = 1 751 752 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec 753 let msg = 'ttymouse=' .. ttymouse_val 754 exe 'set ttymouse=' .. ttymouse_val 755 e Xtab1 756 tabnew Xtab2 757 758 let a = split(execute(':tabs'), "\n") 759 call assert_equal(['Tab page 1', 760 \ ' Xtab1', 761 \ 'Tab page 2', 762 \ '> Xtab2'], a, msg) 763 redraw 764 765 " Click in tab2 and drag it to tab1. 766 " Check getcharmod() to verify that click is not 767 " interpreted as a spurious double-click. 768 call MouseLeftClick(row, 10) 769 call assert_equal(0, getcharmod(), msg) 770 for col in [9, 8, 7, 6] 771 call MouseLeftDrag(row, col) 772 endfor 773 call MouseLeftRelease(row, col) 774 let a = split(execute(':tabs'), "\n") 775 call assert_equal(['Tab page 1', 776 \ '> Xtab2', 777 \ 'Tab page 2', 778 \ ' Xtab1'], a, msg) 779 780 " Click elsewhere so that click in next iteration is not 781 " interpreted as unwanted double-click. 782 call MouseLeftClick(row, 11) 783 call MouseLeftRelease(row, 11) 784 785 %bwipe! 786 endfor 787 788 let &mouse = save_mouse 789 let &term = save_term 790 let &ttymouse = save_ttymouse 791 call test_override('no_query_mouse', 0) 792 set mousetime& 793endfunc 794 795func Test_term_mouse_double_click_to_create_tab() 796 let save_mouse = &mouse 797 let save_term = &term 798 let save_ttymouse = &ttymouse 799 call test_override('no_query_mouse', 1) 800 " Set 'mousetime' to a small value, so that double-click works but we don't 801 " have to wait long to avoid a triple-click. 802 set mouse=a term=xterm mousetime=200 803 let row = 1 804 let col = 10 805 806 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec 807 let msg = 'ttymouse=' .. ttymouse_val 808 exe 'set ttymouse=' .. ttymouse_val 809 e Xtab1 810 tabnew Xtab2 811 812 let a = split(execute(':tabs'), "\n") 813 call assert_equal(['Tab page 1', 814 \ ' Xtab1', 815 \ 'Tab page 2', 816 \ '> Xtab2'], a, msg) 817 818 redraw 819 call MouseLeftClick(row, col) 820 " Check getcharmod() to verify that first click is not 821 " interpreted as a spurious double-click. 822 call assert_equal(0, getcharmod(), msg) 823 call MouseLeftRelease(row, col) 824 call MouseLeftClick(row, col) 825 call assert_equal(32, getcharmod(), msg) " double-click 826 call MouseLeftRelease(row, col) 827 let a = split(execute(':tabs'), "\n") 828 call assert_equal(['Tab page 1', 829 \ ' Xtab1', 830 \ 'Tab page 2', 831 \ '> [No Name]', 832 \ 'Tab page 3', 833 \ ' Xtab2'], a, msg) 834 835 " Click elsewhere so that click in next iteration is not 836 " interpreted as unwanted double click. 837 call MouseLeftClick(row, col + 1) 838 call MouseLeftRelease(row, col + 1) 839 840 %bwipe! 841 endfor 842 843 let &mouse = save_mouse 844 let &term = save_term 845 let &ttymouse = save_ttymouse 846 call test_override('no_query_mouse', 0) 847 set mousetime& 848endfunc 849 850" Test double/triple/quadruple click in normal mode to visually select. 851func Test_term_mouse_multiple_clicks_to_visually_select() 852 let save_mouse = &mouse 853 let save_term = &term 854 let save_ttymouse = &ttymouse 855 call test_override('no_query_mouse', 1) 856 857 " 'mousetime' must be sufficiently large, or else the test is flaky when 858 " using a ssh connection with X forwarding; i.e. ssh -X (issue #7563). 859 set mouse=a term=xterm mousetime=600 860 new 861 862 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec 863 let msg = 'ttymouse=' .. ttymouse_val 864 exe 'set ttymouse=' .. ttymouse_val 865 call setline(1, ['foo [foo bar] foo', 'foo']) 866 867 " Double-click on word should visually select the word. 868 call MouseLeftClick(1, 2) 869 call assert_equal(0, getcharmod(), msg) 870 call MouseLeftRelease(1, 2) 871 call MouseLeftClick(1, 2) 872 call assert_equal(32, getcharmod(), msg) " double-click 873 call MouseLeftRelease(1, 2) 874 call assert_equal('v', mode(), msg) 875 norm! r1 876 call assert_equal(['111 [foo bar] foo', 'foo'], getline(1, '$'), msg) 877 878 " Double-click on opening square bracket should visually 879 " select the whole [foo bar]. 880 call MouseLeftClick(1, 5) 881 call assert_equal(0, getcharmod(), msg) 882 call MouseLeftRelease(1, 5) 883 call MouseLeftClick(1, 5) 884 call assert_equal(32, getcharmod(), msg) " double-click 885 call MouseLeftRelease(1, 5) 886 call assert_equal('v', mode(), msg) 887 norm! r2 888 call assert_equal(['111 222222222 foo', 'foo'], getline(1, '$'), msg) 889 890 " Triple-click should visually select the whole line. 891 call MouseLeftClick(1, 3) 892 call assert_equal(0, getcharmod(), msg) 893 call MouseLeftRelease(1, 3) 894 call MouseLeftClick(1, 3) 895 call assert_equal(32, getcharmod(), msg) " double-click 896 call MouseLeftRelease(1, 3) 897 call MouseLeftClick(1, 3) 898 call assert_equal(64, getcharmod(), msg) " triple-click 899 call MouseLeftRelease(1, 3) 900 call assert_equal('V', mode(), msg) 901 norm! r3 902 call assert_equal(['33333333333333333', 'foo'], getline(1, '$'), msg) 903 904 " Quadruple-click should start visual block select. 905 call MouseLeftClick(1, 2) 906 call assert_equal(0, getcharmod(), msg) 907 call MouseLeftRelease(1, 2) 908 call MouseLeftClick(1, 2) 909 call assert_equal(32, getcharmod(), msg) " double-click 910 call MouseLeftRelease(1, 2) 911 call MouseLeftClick(1, 2) 912 call assert_equal(64, getcharmod(), msg) " triple-click 913 call MouseLeftRelease(1, 2) 914 call MouseLeftClick(1, 2) 915 call assert_equal(96, getcharmod(), msg) " quadruple-click 916 call MouseLeftRelease(1, 2) 917 call assert_equal("\<c-v>", mode(), msg) 918 norm! r4 919 call assert_equal(['34333333333333333', 'foo'], getline(1, '$'), msg) 920 921 " Double-click on a space character should visually select all the 922 " consecutive space characters. 923 %d 924 call setline(1, ' one two') 925 call MouseLeftClick(1, 2) 926 call MouseLeftRelease(1, 2) 927 call MouseLeftClick(1, 2) 928 call MouseLeftRelease(1, 2) 929 call assert_equal('v', mode(), msg) 930 norm! r1 931 call assert_equal(['1111one two'], getline(1, '$'), msg) 932 933 " Double-click on a word with exclusive selection 934 set selection=exclusive 935 let @" = '' 936 call MouseLeftClick(1, 10) 937 call MouseLeftRelease(1, 10) 938 call MouseLeftClick(1, 10) 939 call MouseLeftRelease(1, 10) 940 norm! y 941 call assert_equal('two', @", msg) 942 943 " Double click to select a block of text with exclusive selection 944 %d 945 call setline(1, 'one (two) three') 946 call MouseLeftClick(1, 5) 947 call MouseLeftRelease(1, 5) 948 call MouseLeftClick(1, 5) 949 call MouseLeftRelease(1, 5) 950 norm! y 951 call assert_equal(5, col("'<"), msg) 952 call assert_equal(10, col("'>"), msg) 953 954 call MouseLeftClick(1, 9) 955 call MouseLeftRelease(1, 9) 956 call MouseLeftClick(1, 9) 957 call MouseLeftRelease(1, 9) 958 norm! y 959 call assert_equal(5, col("'<"), msg) 960 call assert_equal(10, col("'>"), msg) 961 set selection& 962 963 " Click somewhere else so that the clicks above is not combined with the 964 " clicks in the next iteration. 965 call MouseRightClick(3, 10) 966 call MouseRightRelease(3, 10) 967 endfor 968 969 let &mouse = save_mouse 970 let &term = save_term 971 let &ttymouse = save_ttymouse 972 set mousetime& 973 call test_override('no_query_mouse', 0) 974 bwipe! 975endfunc 976 977" Test for selecting text in visual blockwise mode using Alt-LeftClick 978func Test_mouse_alt_leftclick() 979 let save_mouse = &mouse 980 let save_term = &term 981 let save_ttymouse = &ttymouse 982 call test_override('no_query_mouse', 1) 983 set mouse=a term=xterm mousetime=200 984 set mousemodel=popup 985 new 986 call setline(1, 'one (two) three') 987 988 for ttymouse_val in g:Ttymouse_values 989 let msg = 'ttymouse=' .. ttymouse_val 990 exe 'set ttymouse=' .. ttymouse_val 991 992 " Left click with the Alt modifier key should extend the selection in 993 " blockwise visual mode. 994 let @" = '' 995 call MouseLeftClick(1, 3) 996 call MouseLeftRelease(1, 3) 997 call MouseAltLeftClick(1, 11) 998 call MouseLeftRelease(1, 11) 999 call assert_equal("\<C-V>", mode(), msg) 1000 normal! y 1001 call assert_equal('e (two) t', @") 1002 endfor 1003 1004 let &mouse = save_mouse 1005 let &term = save_term 1006 let &ttymouse = save_ttymouse 1007 set mousetime& mousemodel& 1008 call test_override('no_query_mouse', 0) 1009 close! 1010endfunc 1011 1012func Test_xterm_mouse_click_in_fold_columns() 1013 new 1014 let save_mouse = &mouse 1015 let save_term = &term 1016 let save_ttymouse = &ttymouse 1017 let save_foldcolumn = &foldcolumn 1018 set mouse=a term=xterm foldcolumn=3 ttymouse=xterm2 1019 1020 " Create 2 nested folds. 1021 call setline(1, range(1, 7)) 1022 2,6fold 1023 norm! zR 1024 4,5fold 1025 call assert_equal([-1, -1, -1, 4, 4, -1, -1], 1026 \ map(range(1, 7), 'foldclosed(v:val)')) 1027 1028 " Click in "+" of inner fold in foldcolumn should open it. 1029 redraw 1030 let row = 4 1031 let col = 2 1032 call MouseLeftClick(row, col) 1033 call MouseLeftRelease(row, col) 1034 call assert_equal([-1, -1, -1, -1, -1, -1, -1], 1035 \ map(range(1, 7), 'foldclosed(v:val)')) 1036 1037 " Click in "-" of outer fold in foldcolumn should close it. 1038 redraw 1039 let row = 2 1040 let col = 1 1041 call MouseLeftClick(row, col) 1042 call MouseLeftRelease(row, col) 1043 call assert_equal([-1, 2, 2, 2, 2, 2, -1], 1044 \ map(range(1, 7), 'foldclosed(v:val)')) 1045 norm! zR 1046 1047 " Click in "|" of inner fold in foldcolumn should close it. 1048 redraw 1049 let row = 5 1050 let col = 2 1051 call MouseLeftClick(row, col) 1052 call MouseLeftRelease(row, col) 1053 call assert_equal([-1, -1, -1, 4, 4, -1, -1], 1054 \ map(range(1, 7), 'foldclosed(v:val)')) 1055 1056 let &foldcolumn = save_foldcolumn 1057 let &ttymouse = save_ttymouse 1058 let &term = save_term 1059 let &mouse = save_mouse 1060 bwipe! 1061endfunc 1062 1063" Left or right click in Ex command line sets position of the cursor. 1064func Test_term_mouse_click_in_cmdline_to_set_pos() 1065 let save_mouse = &mouse 1066 let save_term = &term 1067 let save_ttymouse = &ttymouse 1068 call test_override('no_query_mouse', 1) 1069 set mouse=a term=xterm 1070 let row = &lines 1071 1072 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec 1073 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported. 1074 if ttymouse_val !=# 'xterm2' || row <= 223 1075 let msg = 'ttymouse=' .. ttymouse_val 1076 exe 'set ttymouse=' .. ttymouse_val 1077 1078 1079 call feedkeys(':"3456789' 1080 \ .. MouseLeftClickCode(row, 7) 1081 \ .. MouseLeftReleaseCode(row, 7) .. 'L' 1082 \ .. MouseRightClickCode(row, 4) 1083 \ .. MouseRightReleaseCode(row, 4) .. 'R' 1084 \ .. "\<CR>", 'Lx!') 1085 call assert_equal('"3R456L789', @:, msg) 1086 endif 1087 endfor 1088 1089 let &mouse = save_mouse 1090 let &term = save_term 1091 let &ttymouse = save_ttymouse 1092 set mousetime& 1093 call test_override('no_query_mouse', 0) 1094endfunc 1095 1096" Middle click in command line pastes at position of cursor. 1097func Test_term_mouse_middle_click_in_cmdline_to_paste() 1098 CheckFeature clipboard_working 1099 let save_mouse = &mouse 1100 let save_term = &term 1101 let save_ttymouse = &ttymouse 1102 call test_override('no_query_mouse', 1) 1103 set mouse=a term=xterm 1104 let row = &lines 1105 " Column values does not matter, paste is done at position of cursor. 1106 let col = 1 1107 let @* = 'paste' 1108 1109 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec 1110 let msg = 'ttymouse=' .. ttymouse_val 1111 exe 'set ttymouse=' .. ttymouse_val 1112 1113 call feedkeys(":\"->" 1114 \ .. MouseMiddleReleaseCode(row, col) 1115 \ .. MouseMiddleClickCode(row, col) 1116 \ .. "<-" 1117 \ .. MouseMiddleReleaseCode(row, col) 1118 \ .. MouseMiddleClickCode(row, col) 1119 \ .. "\<CR>", 'Lx!') 1120 call assert_equal('"->paste<-paste', @:, msg) 1121 endfor 1122 1123 let &mouse = save_mouse 1124 let &term = save_term 1125 let &ttymouse = save_ttymouse 1126 let @* = '' 1127 call test_override('no_query_mouse', 0) 1128endfunc 1129 1130" Test for making sure S-Middlemouse doesn't do anything 1131func Test_term_mouse_shift_middle_click() 1132 new 1133 let save_mouse = &mouse 1134 let save_term = &term 1135 let save_ttymouse = &ttymouse 1136 call test_override('no_query_mouse', 1) 1137 set mouse=a term=xterm ttymouse=xterm2 mousemodel= 1138 1139 call test_setmouse(1, 1) 1140 exe "normal \<S-MiddleMouse>" 1141 call assert_equal([''], getline(1, '$')) 1142 call assert_equal(1, winnr()) 1143 1144 let &mouse = save_mouse 1145 let &term = save_term 1146 let &ttymouse = save_ttymouse 1147 set mousemodel& 1148 call test_override('no_query_mouse', 0) 1149 close! 1150endfunc 1151 1152" Test for using mouse in visual mode 1153func Test_term_mouse_visual_mode() 1154 new 1155 let save_mouse = &mouse 1156 let save_term = &term 1157 let save_ttymouse = &ttymouse 1158 call test_override('no_query_mouse', 1) 1159 set term=xterm ttymouse=xterm2 1160 1161 " If visual mode is not present in 'mouse', then left click should not 1162 " do anything in visal mode. 1163 call setline(1, ['one two three four']) 1164 set mouse=nci 1165 call cursor(1, 5) 1166 let @" = '' 1167 call feedkeys("ve" 1168 \ .. MouseLeftClickCode(1, 15) .. MouseLeftReleaseCode(1, 15) 1169 \ .. 'y', 'Lx!') 1170 call assert_equal(5, col('.')) 1171 call assert_equal('two', @") 1172 1173 " Pressing right click in visual mode should change the visual selection 1174 " if 'mousemodel' doesn't contain popup. 1175 " Right click after the visual selection 1176 set mousemodel= 1177 set mouse=a 1178 call test_setmouse(1, 13) 1179 exe "normal 5|ve\<RightMouse>y" 1180 call assert_equal('two three', @") 1181 call assert_equal(5, col('.')) 1182 1183 " Right click before the visual selection 1184 call test_setmouse(1, 9) 1185 exe "normal 15|ve\<RightMouse>y" 1186 call assert_equal('three four', @") 1187 call assert_equal(9, col('.')) 1188 1189 " Right click inside the selection closer to the start of the selection 1190 call test_setmouse(1, 7) 1191 exe "normal 5|vee\<RightMouse>lly" 1192 call assert_equal('three', @") 1193 call assert_equal(9, col('.')) 1194 call assert_equal(9, col("'<")) 1195 call assert_equal(13, col("'>")) 1196 1197 " Right click inside the selection closer to the end of the selection 1198 call test_setmouse(1, 11) 1199 exe "normal 5|vee\<RightMouse>ly" 1200 call assert_equal('two thre', @") 1201 call assert_equal(5, col('.')) 1202 call assert_equal(5, col("'<")) 1203 call assert_equal(12, col("'>")) 1204 1205 " Multi-line selection. Right click inside thse selection. 1206 call setline(1, repeat(['aaaaaa'], 7)) 1207 call test_setmouse(3, 1) 1208 exe "normal ggVG\<RightMouse>y" 1209 call assert_equal(3, line("'<")) 1210 call test_setmouse(5, 1) 1211 exe "normal ggVG\<RightMouse>y" 1212 call assert_equal(5, line("'>")) 1213 1214 " Click right in the middle line of the selection 1215 call test_setmouse(4, 3) 1216 exe "normal ggVG$\<RightMouse>y" 1217 call assert_equal(4, line("'<")) 1218 call test_setmouse(4, 4) 1219 exe "normal ggVG$\<RightMouse>y" 1220 call assert_equal(4, line("'>")) 1221 1222 set mousemodel& 1223 let &mouse = save_mouse 1224 let &term = save_term 1225 let &ttymouse = save_ttymouse 1226 call test_override('no_query_mouse', 0) 1227 close! 1228endfunc 1229 1230" Test for displaying the popup menu using the right mouse click 1231func Test_term_mouse_popup_menu() 1232 CheckFeature menu 1233 new 1234 call setline(1, 'popup menu test') 1235 let save_mouse = &mouse 1236 let save_term = &term 1237 let save_ttymouse = &ttymouse 1238 let save_mousemodel = &mousemodel 1239 call test_override('no_query_mouse', 1) 1240 set mouse=a term=xterm mousemodel=popup 1241 1242 menu PopUp.foo :let g:menustr = 'foo'<CR> 1243 menu PopUp.bar :let g:menustr = 'bar'<CR> 1244 menu PopUp.baz :let g:menustr = 'baz'<CR> 1245 1246 for ttymouse_val in g:Ttymouse_values 1247 let msg = 'ttymouse=' .. ttymouse_val 1248 exe 'set ttymouse=' .. ttymouse_val 1249 let g:menustr = '' 1250 call feedkeys(MouseRightClickCode(1, 4) 1251 \ .. MouseRightReleaseCode(1, 4) .. "\<Down>\<Down>\<CR>", "x") 1252 call assert_equal('bar', g:menustr, msg) 1253 endfor 1254 1255 unmenu PopUp 1256 let &mouse = save_mouse 1257 let &term = save_term 1258 let &ttymouse = save_ttymouse 1259 let &mousemodel = save_mousemodel 1260 call test_override('no_query_mouse', 0) 1261 close! 1262endfunc 1263 1264" Test for 'mousemodel' set to popup_setpos to move the cursor where the popup 1265" menu is displayed. 1266func Test_term_mouse_popup_menu_setpos() 1267 CheckFeature menu 1268 5new 1269 call setline(1, ['the dish ran away with the spoon', 1270 \ 'the cow jumped over the moon' ]) 1271 let save_mouse = &mouse 1272 let save_term = &term 1273 let save_ttymouse = &ttymouse 1274 let save_mousemodel = &mousemodel 1275 call test_override('no_query_mouse', 1) 1276 set mouse=a term=xterm mousemodel=popup_setpos 1277 1278 nmenu PopUp.foo :let g:menustr = 'foo'<CR> 1279 nmenu PopUp.bar :let g:menustr = 'bar'<CR> 1280 nmenu PopUp.baz :let g:menustr = 'baz'<CR> 1281 vmenu PopUp.foo y:<C-U>let g:menustr = 'foo'<CR> 1282 vmenu PopUp.bar y:<C-U>let g:menustr = 'bar'<CR> 1283 vmenu PopUp.baz y:<C-U>let g:menustr = 'baz'<CR> 1284 1285 for ttymouse_val in g:Ttymouse_values 1286 let msg = 'ttymouse=' .. ttymouse_val 1287 exe 'set ttymouse=' .. ttymouse_val 1288 let g:menustr = '' 1289 call cursor(1, 1) 1290 call feedkeys(MouseRightClickCode(1, 5) 1291 \ .. MouseRightReleaseCode(1, 5) .. "\<Down>\<Down>\<CR>", "x") 1292 call assert_equal('bar', g:menustr, msg) 1293 call assert_equal([1, 5], [line('.'), col('.')], msg) 1294 1295 " Test for right click in visual mode inside the selection 1296 let @" = '' 1297 call cursor(1, 10) 1298 call feedkeys('vee' .. MouseRightClickCode(1, 12) 1299 \ .. MouseRightReleaseCode(1, 12) .. "\<Down>\<CR>", "x") 1300 call assert_equal([1, 10], [line('.'), col('.')], msg) 1301 call assert_equal('ran away', @", msg) 1302 1303 " Test for right click in visual mode before the selection 1304 let @" = '' 1305 call cursor(1, 10) 1306 call feedkeys('vee' .. MouseRightClickCode(1, 2) 1307 \ .. MouseRightReleaseCode(1, 2) .. "\<Down>\<CR>", "x") 1308 call assert_equal([1, 2], [line('.'), col('.')], msg) 1309 call assert_equal('', @", msg) 1310 1311 " Test for right click in visual mode after the selection 1312 let @" = '' 1313 call cursor(1, 10) 1314 call feedkeys('vee' .. MouseRightClickCode(1, 20) 1315 \ .. MouseRightReleaseCode(1, 20) .. "\<Down>\<CR>", "x") 1316 call assert_equal([1, 20], [line('.'), col('.')], msg) 1317 call assert_equal('', @", msg) 1318 1319 " Test for right click in block-wise visual mode inside the selection 1320 let @" = '' 1321 call cursor(1, 16) 1322 call feedkeys("\<C-V>j3l" .. MouseRightClickCode(2, 17) 1323 \ .. MouseRightReleaseCode(2, 17) .. "\<Down>\<CR>", "x") 1324 call assert_equal([1, 16], [line('.'), col('.')], msg) 1325 call assert_equal("\<C-V>4", getregtype('"'), msg) 1326 1327 " Test for right click in block-wise visual mode outside the selection 1328 let @" = '' 1329 call cursor(1, 16) 1330 call feedkeys("\<C-V>j3l" .. MouseRightClickCode(2, 2) 1331 \ .. MouseRightReleaseCode(2, 2) .. "\<Down>\<CR>", "x") 1332 call assert_equal([2, 2], [line('.'), col('.')], msg) 1333 call assert_equal('v', getregtype('"'), msg) 1334 call assert_equal('', @", msg) 1335 1336 " Try clicking on the status line 1337 let @" = '' 1338 call cursor(1, 10) 1339 call feedkeys('vee' .. MouseRightClickCode(6, 2) 1340 \ .. MouseRightReleaseCode(6, 2) .. "\<Down>\<CR>", "x") 1341 call assert_equal([1, 10], [line('.'), col('.')], msg) 1342 call assert_equal('ran away', @", msg) 1343 1344 " Try clicking outside the window 1345 let @" = '' 1346 call cursor(7, 2) 1347 call feedkeys('vee' .. MouseRightClickCode(7, 2) 1348 \ .. MouseRightReleaseCode(7, 2) .. "\<Down>\<CR>", "x") 1349 call assert_equal(2, winnr(), msg) 1350 call assert_equal('', @", msg) 1351 wincmd w 1352 endfor 1353 1354 unmenu PopUp 1355 let &mouse = save_mouse 1356 let &term = save_term 1357 let &ttymouse = save_ttymouse 1358 let &mousemodel = save_mousemodel 1359 call test_override('no_query_mouse', 0) 1360 close! 1361endfunc 1362 1363" Test for searching for the word under the cursor using Shift-Right or 1364" Shift-Left click. 1365func Test_term_mouse_search() 1366 new 1367 let save_mouse = &mouse 1368 let save_term = &term 1369 let save_ttymouse = &ttymouse 1370 call test_override('no_query_mouse', 1) 1371 set mouse=a term=xterm ttymouse=xterm2 1372 set mousemodel= 1373 1374 " In normal mode, Shift-Left or Shift-Right click should search for the word 1375 " under the cursor. 1376 call setline(1, ['one two three four', 'four three two one']) 1377 call test_setmouse(1, 4) 1378 exe "normal \<S-LeftMouse>" 1379 call assert_equal([2, 12], [line('.'), col('.')]) 1380 call test_setmouse(2, 16) 1381 exe "normal \<S-RightMouse>" 1382 call assert_equal([1, 1], [line('.'), col('.')]) 1383 1384 " In visual mode, Shift-Left or Shift-Right click should search for the word 1385 " under the cursor and extend the selection. 1386 call test_setmouse(1, 4) 1387 exe "normal 4|ve\<S-LeftMouse>y" 1388 call assert_equal([2, 12], [line("'>"), col("'>")]) 1389 call test_setmouse(2, 16) 1390 exe "normal 2G16|ve\<S-RightMouse>y" 1391 call assert_equal([1, 1], [line("'<"), col("'<")]) 1392 1393 set mousemodel& 1394 let &mouse = save_mouse 1395 let &term = save_term 1396 let &ttymouse = save_ttymouse 1397 call test_override('no_query_mouse', 0) 1398 close! 1399endfunc 1400 1401" Test for selecting an entry in the quickfix/location list window using the 1402" mouse. 1403func Test_term_mouse_quickfix_window() 1404 let save_mouse = &mouse 1405 let save_term = &term 1406 let save_ttymouse = &ttymouse 1407 call test_override('no_query_mouse', 1) 1408 set mouse=a term=xterm ttymouse=xterm2 1409 set mousemodel= 1410 1411 cgetexpr "Xfile1:1:L1" 1412 copen 5 1413 call test_setmouse(&lines - 7, 1) 1414 exe "normal \<2-LeftMouse>" 1415 call assert_equal('Xfile1', @%) 1416 %bw! 1417 1418 lgetexpr "Xfile2:1:L1" 1419 lopen 5 1420 call test_setmouse(&lines - 7, 1) 1421 exe "normal \<2-LeftMouse>" 1422 call assert_equal('Xfile2', @%) 1423 %bw! 1424 1425 set mousemodel& 1426 let &mouse = save_mouse 1427 let &term = save_term 1428 let &ttymouse = save_ttymouse 1429 call test_override('no_query_mouse', 0) 1430endfunc 1431 1432" Test for the 'h' flag in the 'mouse' option. Using mouse in the help window. 1433func Test_term_mouse_help_window() 1434 let save_mouse = &mouse 1435 let save_term = &term 1436 let save_ttymouse = &ttymouse 1437 call test_override('no_query_mouse', 1) 1438 set mouse=h term=xterm mousetime=200 1439 1440 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec 1441 let msg = 'ttymouse=' .. ttymouse_val 1442 exe 'set ttymouse=' .. ttymouse_val 1443 help 1444 let @" = '' 1445 call MouseLeftClick(2, 5) 1446 call MouseLeftRelease(2, 5) 1447 call MouseLeftClick(1, 1) 1448 call MouseLeftDrag(1, 10) 1449 call MouseLeftRelease(1, 10) 1450 norm! y 1451 call assert_equal('*help.txt*', @", msg) 1452 helpclose 1453 1454 " Click somewhere else to make sure the left click above is not combined 1455 " with the next left click and treated as a double click 1456 call MouseRightClick(5, 10) 1457 call MouseRightRelease(5, 10) 1458 endfor 1459 1460 let &mouse = save_mouse 1461 let &term = save_term 1462 let &ttymouse = save_ttymouse 1463 set mousetime& 1464 call test_override('no_query_mouse', 0) 1465 %bw! 1466endfunc 1467 1468" Test for the translation of various mouse terminal codes 1469func Test_mouse_termcodes() 1470 let save_mouse = &mouse 1471 let save_term = &term 1472 let save_ttymouse = &ttymouse 1473 call test_override('no_query_mouse', 1) 1474 set mouse=a term=xterm mousetime=200 1475 1476 new 1477 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm 1478 let msg = 'ttymouse=' .. ttymouse_val 1479 exe 'set ttymouse=' .. ttymouse_val 1480 1481 let mouse_codes = [ 1482 \ ["\<LeftMouse>", "<LeftMouse>"], 1483 \ ["\<MiddleMouse>", "<MiddleMouse>"], 1484 \ ["\<RightMouse>", "<RightMouse>"], 1485 \ ["\<S-LeftMouse>", "<S-LeftMouse>"], 1486 \ ["\<S-MiddleMouse>", "<S-MiddleMouse>"], 1487 \ ["\<S-RightMouse>", "<S-RightMouse>"], 1488 \ ["\<C-LeftMouse>", "<C-LeftMouse>"], 1489 \ ["\<C-MiddleMouse>", "<C-MiddleMouse>"], 1490 \ ["\<C-RightMouse>", "<C-RightMouse>"], 1491 \ ["\<M-LeftMouse>", "<M-LeftMouse>"], 1492 \ ["\<M-MiddleMouse>", "<M-MiddleMouse>"], 1493 \ ["\<M-RightMouse>", "<M-RightMouse>"], 1494 \ ["\<2-LeftMouse>", "<2-LeftMouse>"], 1495 \ ["\<2-MiddleMouse>", "<2-MiddleMouse>"], 1496 \ ["\<2-RightMouse>", "<2-RightMouse>"], 1497 \ ["\<3-LeftMouse>", "<3-LeftMouse>"], 1498 \ ["\<3-MiddleMouse>", "<3-MiddleMouse>"], 1499 \ ["\<3-RightMouse>", "<3-RightMouse>"], 1500 \ ["\<4-LeftMouse>", "<4-LeftMouse>"], 1501 \ ["\<4-MiddleMouse>", "<4-MiddleMouse>"], 1502 \ ["\<4-RightMouse>", "<4-RightMouse>"], 1503 \ ["\<LeftDrag>", "<LeftDrag>"], 1504 \ ["\<MiddleDrag>", "<MiddleDrag>"], 1505 \ ["\<RightDrag>", "<RightDrag>"], 1506 \ ["\<LeftRelease>", "<LeftRelease>"], 1507 \ ["\<MiddleRelease>", "<MiddleRelease>"], 1508 \ ["\<RightRelease>", "<RightRelease>"], 1509 \ ["\<ScrollWheelUp>", "<ScrollWheelUp>"], 1510 \ ["\<S-ScrollWheelUp>", "<S-ScrollWheelUp>"], 1511 \ ["\<C-ScrollWheelUp>", "<C-ScrollWheelUp>"], 1512 \ ["\<ScrollWheelDown>", "<ScrollWheelDown>"], 1513 \ ["\<S-ScrollWheelDown>", "<S-ScrollWheelDown>"], 1514 \ ["\<C-ScrollWheelDown>", "<C-ScrollWheelDown>"], 1515 \ ["\<ScrollWheelLeft>", "<ScrollWheelLeft>"], 1516 \ ["\<S-ScrollWheelLeft>", "<S-ScrollWheelLeft>"], 1517 \ ["\<C-ScrollWheelLeft>", "<C-ScrollWheelLeft>"], 1518 \ ["\<ScrollWheelRight>", "<ScrollWheelRight>"], 1519 \ ["\<S-ScrollWheelRight>", "<S-ScrollWheelRight>"], 1520 \ ["\<C-ScrollWheelRight>", "<C-ScrollWheelRight>"] 1521 \ ] 1522 1523 for [code, outstr] in mouse_codes 1524 exe "normal ggC\<C-K>" . code 1525 call assert_equal(outstr, getline(1), msg) 1526 endfor 1527 endfor 1528 1529 let &mouse = save_mouse 1530 let &term = save_term 1531 let &ttymouse = save_ttymouse 1532 set mousetime& 1533 call test_override('no_query_mouse', 0) 1534 %bw! 1535endfunc 1536 1537" This only checks if the sequence is recognized. 1538func Test_term_rgb_response() 1539 set t_RF=x 1540 set t_RB=y 1541 1542 " response to t_RF, 4 digits 1543 let red = 0x12 1544 let green = 0x34 1545 let blue = 0x56 1546 let seq = printf("\<Esc>]10;rgb:%02x00/%02x00/%02x00\x07", red, green, blue) 1547 call feedkeys(seq, 'Lx!') 1548 call assert_equal(seq, v:termrfgresp) 1549 1550 " response to t_RF, 2 digits 1551 let red = 0x78 1552 let green = 0x9a 1553 let blue = 0xbc 1554 let seq = printf("\<Esc>]10;rgb:%02x/%02x/%02x\x07", red, green, blue) 1555 call feedkeys(seq, 'Lx!') 1556 call assert_equal(seq, v:termrfgresp) 1557 1558 " response to t_RB, 4 digits, dark 1559 set background=light 1560 eval 'background'->test_option_not_set() 1561 let red = 0x29 1562 let green = 0x4a 1563 let blue = 0x6b 1564 let seq = printf("\<Esc>]11;rgb:%02x00/%02x00/%02x00\x07", red, green, blue) 1565 call feedkeys(seq, 'Lx!') 1566 call assert_equal(seq, v:termrbgresp) 1567 call assert_equal('dark', &background) 1568 1569 " response to t_RB, 4 digits, light 1570 set background=dark 1571 call test_option_not_set('background') 1572 let red = 0x81 1573 let green = 0x63 1574 let blue = 0x65 1575 let seq = printf("\<Esc>]11;rgb:%02x00/%02x00/%02x00\x07", red, green, blue) 1576 call feedkeys(seq, 'Lx!') 1577 call assert_equal(seq, v:termrbgresp) 1578 call assert_equal('light', &background) 1579 1580 " response to t_RB, 2 digits, dark 1581 set background=light 1582 call test_option_not_set('background') 1583 let red = 0x47 1584 let green = 0x59 1585 let blue = 0x5b 1586 let seq = printf("\<Esc>]11;rgb:%02x/%02x/%02x\x07", red, green, blue) 1587 call feedkeys(seq, 'Lx!') 1588 call assert_equal(seq, v:termrbgresp) 1589 call assert_equal('dark', &background) 1590 1591 " response to t_RB, 2 digits, light 1592 set background=dark 1593 call test_option_not_set('background') 1594 let red = 0x83 1595 let green = 0xa4 1596 let blue = 0xc2 1597 let seq = printf("\<Esc>]11;rgb:%02x/%02x/%02x\x07", red, green, blue) 1598 call feedkeys(seq, 'Lx!') 1599 call assert_equal(seq, v:termrbgresp) 1600 call assert_equal('light', &background) 1601 1602 set t_RF= t_RB= 1603endfunc 1604 1605" This only checks if the sequence is recognized. 1606" This must be after other tests, because it has side effects to xterm 1607" properties. 1608func Test_xx01_term_style_response() 1609 " Termresponse is only parsed when t_RV is not empty. 1610 set t_RV=x 1611 call test_override('term_props', 1) 1612 1613 " send the termresponse to trigger requesting the XT codes 1614 let seq = "\<Esc>[>41;337;0c" 1615 call feedkeys(seq, 'Lx!') 1616 call assert_equal(seq, v:termresponse) 1617 1618 let seq = "\<Esc>P1$r2 q\<Esc>\\" 1619 call feedkeys(seq, 'Lx!') 1620 call assert_equal(seq, v:termstyleresp) 1621 1622 call assert_equal(#{ 1623 \ cursor_style: 'u', 1624 \ cursor_blink_mode: 'u', 1625 \ underline_rgb: 'u', 1626 \ mouse: 's' 1627 \ }, terminalprops()) 1628 1629 set t_RV= 1630 call test_override('term_props', 0) 1631endfunc 1632 1633" This checks the iTerm2 version response. 1634" This must be after other tests, because it has side effects to xterm 1635" properties. 1636func Test_xx02_iTerm2_response() 1637 " Termresponse is only parsed when t_RV is not empty. 1638 set t_RV=x 1639 call test_override('term_props', 1) 1640 1641 " Old versions of iTerm2 used a different style term response. 1642 set ttymouse=xterm 1643 call test_option_not_set('ttymouse') 1644 let seq = "\<Esc>[>0;95;c" 1645 call feedkeys(seq, 'Lx!') 1646 call assert_equal(seq, v:termresponse) 1647 call assert_equal('xterm', &ttymouse) 1648 1649 set ttymouse=xterm 1650 call test_option_not_set('ttymouse') 1651 let seq = "\<Esc>[>0;95;0c" 1652 call feedkeys(seq, 'Lx!') 1653 call assert_equal(seq, v:termresponse) 1654 call assert_equal('sgr', &ttymouse) 1655 1656 call assert_equal(#{ 1657 \ cursor_style: 'n', 1658 \ cursor_blink_mode: 'u', 1659 \ underline_rgb: 'u', 1660 \ mouse: 's' 1661 \ }, terminalprops()) 1662 1663 set t_RV= 1664 call test_override('term_props', 0) 1665endfunc 1666 1667" This checks the libvterm version response. 1668" This must be after other tests, because it has side effects to xterm 1669" properties. 1670func Test_xx03_libvterm_response() 1671 " Termresponse is only parsed when t_RV is not empty. 1672 set t_RV=x 1673 call test_override('term_props', 1) 1674 1675 set ttymouse=xterm 1676 call test_option_not_set('ttymouse') 1677 let seq = "\<Esc>[>0;100;0c" 1678 call feedkeys(seq, 'Lx!') 1679 call assert_equal(seq, v:termresponse) 1680 call assert_equal('sgr', &ttymouse) 1681 1682 call assert_equal(#{ 1683 \ cursor_style: 'n', 1684 \ cursor_blink_mode: 'u', 1685 \ underline_rgb: 'u', 1686 \ mouse: 's' 1687 \ }, terminalprops()) 1688 1689 set t_RV= 1690 call test_override('term_props', 0) 1691endfunc 1692 1693" This checks the Mac Terminal.app version response. 1694" This must be after other tests, because it has side effects to xterm 1695" properties. 1696func Test_xx04_Mac_Terminal_response() 1697 " Termresponse is only parsed when t_RV is not empty. 1698 set t_RV=x 1699 call test_override('term_props', 1) 1700 1701 set ttymouse=xterm 1702 " t_8u is not reset 1703 let &t_8u = "\<Esc>[58;2;%lu;%lu;%lum" 1704 call test_option_not_set('ttymouse') 1705 let seq = "\<Esc>[>1;95;0c" 1706 call feedkeys(seq, 'Lx!') 1707 call assert_equal(seq, v:termresponse) 1708 call assert_equal('sgr', &ttymouse) 1709 1710 call assert_equal(#{ 1711 \ cursor_style: 'n', 1712 \ cursor_blink_mode: 'u', 1713 \ underline_rgb: 'y', 1714 \ mouse: 's' 1715 \ }, terminalprops()) 1716 call assert_equal("\<Esc>[58;2;%lu;%lu;%lum", &t_8u) 1717 1718 " Reset is_not_xterm and is_mac_terminal. 1719 set t_RV= 1720 set term=xterm 1721 set t_RV=x 1722 call test_override('term_props', 0) 1723endfunc 1724 1725" This checks the mintty version response. 1726" This must be after other tests, because it has side effects to xterm 1727" properties. 1728func Test_xx05_mintty_response() 1729 " Termresponse is only parsed when t_RV is not empty. 1730 set t_RV=x 1731 call test_override('term_props', 1) 1732 1733 set ttymouse=xterm 1734 call test_option_not_set('ttymouse') 1735 let seq = "\<Esc>[>77;20905;0c" 1736 call feedkeys(seq, 'Lx!') 1737 call assert_equal(seq, v:termresponse) 1738 call assert_equal('sgr', &ttymouse) 1739 1740 call assert_equal(#{ 1741 \ cursor_style: 'n', 1742 \ cursor_blink_mode: 'u', 1743 \ underline_rgb: 'y', 1744 \ mouse: 's' 1745 \ }, terminalprops()) 1746 1747 set t_RV= 1748 call test_override('term_props', 0) 1749endfunc 1750 1751" This checks the screen version response. 1752" This must be after other tests, because it has side effects to xterm 1753" properties. 1754func Test_xx06_screen_response() 1755 " Termresponse is only parsed when t_RV is not empty. 1756 set t_RV=x 1757 call test_override('term_props', 1) 1758 1759 " Old versions of screen don't support SGR mouse mode. 1760 set ttymouse=xterm 1761 call test_option_not_set('ttymouse') 1762 let seq = "\<Esc>[>83;40500;0c" 1763 call feedkeys(seq, 'Lx!') 1764 call assert_equal(seq, v:termresponse) 1765 call assert_equal('xterm', &ttymouse) 1766 1767 " screen supports SGR mouse mode starting in version 4.7. 1768 set ttymouse=xterm 1769 call test_option_not_set('ttymouse') 1770 let seq = "\<Esc>[>83;40700;0c" 1771 call feedkeys(seq, 'Lx!') 1772 call assert_equal(seq, v:termresponse) 1773 call assert_equal('sgr', &ttymouse) 1774 1775 call assert_equal(#{ 1776 \ cursor_style: 'n', 1777 \ cursor_blink_mode: 'n', 1778 \ underline_rgb: 'y', 1779 \ mouse: 's' 1780 \ }, terminalprops()) 1781 1782 set t_RV= 1783 call test_override('term_props', 0) 1784endfunc 1785 1786" This checks the xterm version response. 1787" This must be after other tests, because it has side effects to xterm 1788" properties. 1789func Test_xx07_xterm_response() 1790 " Termresponse is only parsed when t_RV is not empty. 1791 set t_RV=x 1792 call test_override('term_props', 1) 1793 1794 " Do Terminal.app first to check that is_mac_terminal is reset. 1795 set ttymouse=xterm 1796 call test_option_not_set('ttymouse') 1797 let seq = "\<Esc>[>1;95;0c" 1798 call feedkeys(seq, 'Lx!') 1799 call assert_equal(seq, v:termresponse) 1800 call assert_equal('sgr', &ttymouse) 1801 1802 " xterm < 95: "xterm" (actually unmodified) 1803 set t_RV= 1804 set term=xterm 1805 set t_RV=x 1806 set ttymouse=xterm 1807 call test_option_not_set('ttymouse') 1808 let seq = "\<Esc>[>0;94;0c" 1809 call feedkeys(seq, 'Lx!') 1810 call assert_equal(seq, v:termresponse) 1811 call assert_equal('xterm', &ttymouse) 1812 1813 call assert_equal(#{ 1814 \ cursor_style: 'n', 1815 \ cursor_blink_mode: 'u', 1816 \ underline_rgb: 'y', 1817 \ mouse: 'u' 1818 \ }, terminalprops()) 1819 1820 " xterm >= 95 < 277 "xterm2" 1821 set ttymouse=xterm 1822 call test_option_not_set('ttymouse') 1823 let seq = "\<Esc>[>0;267;0c" 1824 call feedkeys(seq, 'Lx!') 1825 call assert_equal(seq, v:termresponse) 1826 call assert_equal('xterm2', &ttymouse) 1827 1828 call assert_equal(#{ 1829 \ cursor_style: 'n', 1830 \ cursor_blink_mode: 'u', 1831 \ underline_rgb: 'u', 1832 \ mouse: '2' 1833 \ }, terminalprops()) 1834 1835 " xterm >= 277: "sgr" 1836 set ttymouse=xterm 1837 call test_option_not_set('ttymouse') 1838 let seq = "\<Esc>[>0;277;0c" 1839 call feedkeys(seq, 'Lx!') 1840 call assert_equal(seq, v:termresponse) 1841 call assert_equal('sgr', &ttymouse) 1842 1843 call assert_equal(#{ 1844 \ cursor_style: 'n', 1845 \ cursor_blink_mode: 'u', 1846 \ underline_rgb: 'u', 1847 \ mouse: 's' 1848 \ }, terminalprops()) 1849 1850 " xterm >= 279: "sgr" and cursor_style not reset; also check t_8u reset 1851 set ttymouse=xterm 1852 call test_option_not_set('ttymouse') 1853 let &t_8u = "\<Esc>[58;2;%lu;%lu;%lum" 1854 let seq = "\<Esc>[>0;279;0c" 1855 call feedkeys(seq, 'Lx!') 1856 call assert_equal(seq, v:termresponse) 1857 call assert_equal('sgr', &ttymouse) 1858 1859 call assert_equal(#{ 1860 \ cursor_style: 'u', 1861 \ cursor_blink_mode: 'u', 1862 \ underline_rgb: 'u', 1863 \ mouse: 's' 1864 \ }, terminalprops()) 1865 call assert_equal('', &t_8u) 1866 1867 set t_RV= 1868 call test_override('term_props', 0) 1869endfunc 1870 1871func Test_focus_events() 1872 let save_term = &term 1873 let save_ttymouse = &ttymouse 1874 set term=xterm ttymouse=xterm2 1875 1876 au FocusGained * let g:focus_gained += 1 1877 au FocusLost * let g:focus_lost += 1 1878 let g:focus_gained = 0 1879 let g:focus_lost = 0 1880 1881 call feedkeys("\<Esc>[O", "Lx!") 1882 call assert_equal(1, g:focus_lost) 1883 call feedkeys("\<Esc>[I", "Lx!") 1884 call assert_equal(1, g:focus_gained) 1885 1886 " still works when 'ttymouse' is empty 1887 set ttymouse= 1888 call feedkeys("\<Esc>[O", "Lx!") 1889 call assert_equal(2, g:focus_lost) 1890 call feedkeys("\<Esc>[I", "Lx!") 1891 call assert_equal(2, g:focus_gained) 1892 1893 au! FocusGained 1894 au! FocusLost 1895 let &term = save_term 1896 let &ttymouse = save_ttymouse 1897endfunc 1898 1899func Test_get_termcode() 1900 try 1901 let k1 = &t_k1 1902 catch /E113/ 1903 throw 'Skipped: Unable to query termcodes' 1904 endtry 1905 set t_k1= 1906 set t_k1& 1907 call assert_equal(k1, &t_k1) 1908 1909 " use external termcap first 1910 set nottybuiltin 1911 set t_k1= 1912 set t_k1& 1913 " when using external termcap may get something else, but it must not be 1914 " empty, since we would fallback to the builtin one. 1915 call assert_notequal('', &t_k1) 1916 1917 if &term =~ 'xterm' 1918 " use internal termcap first 1919 let term_save = &term 1920 let &term = 'builtin_' .. &term 1921 set t_k1= 1922 set t_k1& 1923 call assert_equal(k1, &t_k1) 1924 let &term = term_save 1925 endif 1926 1927 set ttybuiltin 1928endfunc 1929 1930func Test_list_builtin_terminals() 1931 CheckRunVimInTerminal 1932 call RunVimInTerminal('', #{rows: 14}) 1933 call term_sendkeys('', ":set cmdheight=3\<CR>") 1934 call TermWait('', 100) 1935 call term_sendkeys('', ":set term=xxx\<CR>") 1936 call TermWait('', 100) 1937 call assert_match('builtin_dumb', term_getline('', 11)) 1938 call assert_match('Not found in termcap', term_getline('', 12)) 1939 call StopVimInTerminal('') 1940endfunc 1941 1942func GetEscCodeCSI27(key, modifier) 1943 let key = printf("%d", char2nr(a:key)) 1944 let mod = printf("%d", a:modifier) 1945 return "\<Esc>[27;" .. mod .. ';' .. key .. '~' 1946endfunc 1947 1948func GetEscCodeCSIu(key, modifier) 1949 let key = printf("%d", char2nr(a:key)) 1950 let mod = printf("%d", a:modifier) 1951 return "\<Esc>[" .. key .. ';' .. mod .. 'u' 1952endfunc 1953 1954" This checks the CSI sequences when in modifyOtherKeys mode. 1955" The mode doesn't need to be enabled, the codes are always detected. 1956func RunTest_modifyOtherKeys(func) 1957 new 1958 set timeoutlen=10 1959 1960 " Shift-X is sent as 'X' with the shift modifier 1961 call feedkeys('a' .. a:func('X', 2) .. "\<Esc>", 'Lx!') 1962 call assert_equal('X', getline(1)) 1963 1964 " Ctrl-i is Tab 1965 call setline(1, '') 1966 call feedkeys('a' .. a:func('i', 5) .. "\<Esc>", 'Lx!') 1967 call assert_equal("\t", getline(1)) 1968 1969 " Ctrl-I is also Tab 1970 call setline(1, '') 1971 call feedkeys('a' .. a:func('I', 5) .. "\<Esc>", 'Lx!') 1972 call assert_equal("\t", getline(1)) 1973 1974 " Alt-x is ø 1975 call setline(1, '') 1976 call feedkeys('a' .. a:func('x', 3) .. "\<Esc>", 'Lx!') 1977 call assert_equal("ø", getline(1)) 1978 1979 " Meta-x is also ø 1980 call setline(1, '') 1981 call feedkeys('a' .. a:func('x', 9) .. "\<Esc>", 'Lx!') 1982 call assert_equal("ø", getline(1)) 1983 1984 " Alt-X is Ø 1985 call setline(1, '') 1986 call feedkeys('a' .. a:func('X', 3) .. "\<Esc>", 'Lx!') 1987 call assert_equal("Ø", getline(1)) 1988 1989 " Meta-X is ø 1990 call setline(1, '') 1991 call feedkeys('a' .. a:func('X', 9) .. "\<Esc>", 'Lx!') 1992 call assert_equal("Ø", getline(1)) 1993 1994 " Ctrl-6 is Ctrl-^ 1995 split aaa 1996 edit bbb 1997 call feedkeys(a:func('6', 5), 'Lx!') 1998 call assert_equal("aaa", bufname()) 1999 bwipe aaa 2000 bwipe bbb 2001 2002 " Ctrl-V X 33 is 3 2003 call setline(1, '') 2004 call feedkeys("a\<C-V>" .. a:func('X', 2) .. "33\<Esc>", 'Lx!') 2005 call assert_equal("3", getline(1)) 2006 2007 " Ctrl-V U 12345 is Unicode 12345 2008 call setline(1, '') 2009 call feedkeys("a\<C-V>" .. a:func('U', 2) .. "12345\<Esc>", 'Lx!') 2010 call assert_equal("\U12345", getline(1)) 2011 2012 bwipe! 2013 set timeoutlen& 2014endfunc 2015 2016func Test_modifyOtherKeys_basic() 2017 call RunTest_modifyOtherKeys(function('GetEscCodeCSI27')) 2018 call RunTest_modifyOtherKeys(function('GetEscCodeCSIu')) 2019endfunc 2020 2021func Test_modifyOtherKeys_no_mapping() 2022 set timeoutlen=10 2023 2024 let @a = 'aaa' 2025 call feedkeys(":let x = '" .. GetEscCodeCSI27('R', 5) .. GetEscCodeCSI27('R', 5) .. "a'\<CR>", 'Lx!') 2026 call assert_equal("let x = 'aaa'", @:) 2027 2028 new 2029 call feedkeys("a" .. GetEscCodeCSI27('R', 5) .. GetEscCodeCSI27('R', 5) .. "a\<Esc>", 'Lx!') 2030 call assert_equal("aaa", getline(1)) 2031 bwipe! 2032 2033 new 2034 call feedkeys("axx\<CR>yy" .. GetEscCodeCSI27('G', 5) .. GetEscCodeCSI27('K', 5) .. "a\<Esc>", 'Lx!') 2035 call assert_equal("axx", getline(1)) 2036 call assert_equal("yy", getline(2)) 2037 bwipe! 2038 2039 set timeoutlen& 2040endfunc 2041 2042func RunTest_mapping_shift(key, func) 2043 call setline(1, '') 2044 if a:key == '|' 2045 exe 'inoremap \| xyz' 2046 else 2047 exe 'inoremap ' .. a:key .. ' xyz' 2048 endif 2049 call feedkeys('a' .. a:func(a:key, 2) .. "\<Esc>", 'Lx!') 2050 call assert_equal("xyz", getline(1)) 2051 if a:key == '|' 2052 exe 'iunmap \|' 2053 else 2054 exe 'iunmap ' .. a:key 2055 endif 2056endfunc 2057 2058func Test_modifyOtherKeys_mapped() 2059 set timeoutlen=10 2060 imap ' <C-W> 2061 imap <C-W><C-A> c-a 2062 call setline(1, '') 2063 2064 " single quote is turned into single byte CTRL-W 2065 " CTRL-A is added with a separate modifier, and needs to be simplified before 2066 " the mapping can match. 2067 call feedkeys("a'" .. GetEscCodeCSI27('A', 5) .. "\<Esc>", 'Lx!') 2068 call assert_equal('c-a', getline(1)) 2069 2070 iunmap ' 2071 iunmap <C-W><C-A> 2072 set timeoutlen& 2073endfunc 2074 2075" Whether Shift-Tab sends "ESC [ Z" or "ESC [ 27 ; 2 ; 9 ~" is unpredictable, 2076" both should work. 2077func Test_modifyOtherKeys_shift_tab() 2078 set timeoutlen=10 2079 2080 call setline(1, '') 2081 call feedkeys("a\<C-K>" .. GetEscCodeCSI27("\t", '2') .. "\<Esc>", 'Lx!') 2082 eval getline(1)->assert_equal('<S-Tab>') 2083 2084 call setline(1, '') 2085 call feedkeys("a\<C-K>\<Esc>[Z\<Esc>", 'Lx!') 2086 eval getline(1)->assert_equal('<S-Tab>') 2087 2088 set timeoutlen& 2089 bwipe! 2090endfunc 2091 2092func RunTest_mapping_works_with_shift(func) 2093 new 2094 set timeoutlen=10 2095 2096 call RunTest_mapping_shift('@', a:func) 2097 call RunTest_mapping_shift('A', a:func) 2098 call RunTest_mapping_shift('Z', a:func) 2099 call RunTest_mapping_shift('^', a:func) 2100 call RunTest_mapping_shift('_', a:func) 2101 call RunTest_mapping_shift('{', a:func) 2102 call RunTest_mapping_shift('|', a:func) 2103 call RunTest_mapping_shift('}', a:func) 2104 call RunTest_mapping_shift('~', a:func) 2105 2106 bwipe! 2107 set timeoutlen& 2108endfunc 2109 2110func Test_mapping_works_with_shift_plain() 2111 call RunTest_mapping_works_with_shift(function('GetEscCodeCSI27')) 2112 call RunTest_mapping_works_with_shift(function('GetEscCodeCSIu')) 2113endfunc 2114 2115func RunTest_mapping_mods(map, key, func, code) 2116 call setline(1, '') 2117 exe 'inoremap ' .. a:map .. ' xyz' 2118 call feedkeys('a' .. a:func(a:key, a:code) .. "\<Esc>", 'Lx!') 2119 call assert_equal("xyz", getline(1)) 2120 exe 'iunmap ' .. a:map 2121endfunc 2122 2123func RunTest_mapping_works_with_mods(func, mods, code) 2124 new 2125 set timeoutlen=10 2126 2127 if a:mods !~ 'S' 2128 " Shift by itself has no effect 2129 call RunTest_mapping_mods('<' .. a:mods .. '-@>', '@', a:func, a:code) 2130 endif 2131 call RunTest_mapping_mods('<' .. a:mods .. '-A>', 'A', a:func, a:code) 2132 call RunTest_mapping_mods('<' .. a:mods .. '-Z>', 'Z', a:func, a:code) 2133 if a:mods !~ 'S' 2134 " with Shift code is always upper case 2135 call RunTest_mapping_mods('<' .. a:mods .. '-a>', 'a', a:func, a:code) 2136 call RunTest_mapping_mods('<' .. a:mods .. '-z>', 'z', a:func, a:code) 2137 endif 2138 if a:mods != 'A' 2139 " with Alt code is not in upper case 2140 call RunTest_mapping_mods('<' .. a:mods .. '-a>', 'A', a:func, a:code) 2141 call RunTest_mapping_mods('<' .. a:mods .. '-z>', 'Z', a:func, a:code) 2142 endif 2143 call RunTest_mapping_mods('<' .. a:mods .. '-á>', 'á', a:func, a:code) 2144 if a:mods !~ 'S' 2145 " Shift by itself has no effect 2146 call RunTest_mapping_mods('<' .. a:mods .. '-^>', '^', a:func, a:code) 2147 call RunTest_mapping_mods('<' .. a:mods .. '-_>', '_', a:func, a:code) 2148 call RunTest_mapping_mods('<' .. a:mods .. '-{>', '{', a:func, a:code) 2149 call RunTest_mapping_mods('<' .. a:mods .. '-\|>', '|', a:func, a:code) 2150 call RunTest_mapping_mods('<' .. a:mods .. '-}>', '}', a:func, a:code) 2151 call RunTest_mapping_mods('<' .. a:mods .. '-~>', '~', a:func, a:code) 2152 endif 2153 2154 bwipe! 2155 set timeoutlen& 2156endfunc 2157 2158func Test_mapping_works_with_shift() 2159 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'S', 2) 2160 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'S', 2) 2161endfunc 2162 2163func Test_mapping_works_with_ctrl() 2164 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C', 5) 2165 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C', 5) 2166 2167 new 2168 set timeoutlen=10 2169 2170 " CTRL-@ actually produces the code for CTRL-2, which is converted 2171 call RunTest_mapping_mods('<C-@>', '2', function('GetEscCodeCSI27'), 5) 2172 call RunTest_mapping_mods('<C-@>', '2', function('GetEscCodeCSIu'), 5) 2173 2174 " CTRL-^ actually produces the code for CTRL-6, which is converted 2175 call RunTest_mapping_mods('<C-^>', '6', function('GetEscCodeCSI27'), 5) 2176 call RunTest_mapping_mods('<C-^>', '6', function('GetEscCodeCSIu'), 5) 2177 2178 " CTRL-_ actually produces the code for CTRL--, which is converted 2179 call RunTest_mapping_mods('<C-_>', '-', function('GetEscCodeCSI27'), 5) 2180 call RunTest_mapping_mods('<C-_>', '-', function('GetEscCodeCSIu'), 5) 2181 2182 bwipe! 2183 set timeoutlen& 2184endfunc 2185 2186func Test_mapping_works_with_shift_ctrl() 2187 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-S', 6) 2188 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-S', 6) 2189 2190 new 2191 set timeoutlen=10 2192 2193 " Ctrl-Shift-[ actually produces CTRL-Shift-{ which is mapped as <C-{> 2194 call RunTest_mapping_mods('<C-{>', '{', function('GetEscCodeCSI27'), 6) 2195 call RunTest_mapping_mods('<C-{>', '{', function('GetEscCodeCSIu'), 6) 2196 2197 " Ctrl-Shift-] actually produces CTRL-Shift-} which is mapped as <C-}> 2198 call RunTest_mapping_mods('<C-{>', '{', function('GetEscCodeCSI27'), 6) 2199 call RunTest_mapping_mods('<C-{>', '{', function('GetEscCodeCSIu'), 6) 2200 2201 " Ctrl-Shift-\ actually produces CTRL-Shift-| which is mapped as <C-|> 2202 call RunTest_mapping_mods('<C-\|>', '|', function('GetEscCodeCSI27'), 6) 2203 call RunTest_mapping_mods('<C-\|>', '|', function('GetEscCodeCSIu'), 6) 2204 2205 bwipe! 2206 set timeoutlen& 2207endfunc 2208 2209" Below we also test the "u" code with Alt, This works, but libvterm would not 2210" send the Alt key like this but by prefixing an Esc. 2211 2212func Test_mapping_works_with_alt() 2213 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'A', 3) 2214 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'A', 3) 2215endfunc 2216 2217func Test_mapping_works_with_shift_alt() 2218 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'S-A', 4) 2219 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'S-A', 4) 2220endfunc 2221 2222func Test_mapping_works_with_alt_and_shift() 2223 new 2224 set timeoutlen=10 2225 2226 " mapping <A-?> works even though the code is A-S-? 2227 for c in ['!', '$', '+', ':', '?', '^', '~'] 2228 call RunTest_mapping_mods('<A-' .. c .. '>', c, function('GetEscCodeCSI27'), 4) 2229 call RunTest_mapping_mods('<A-' .. c .. '>', c, function('GetEscCodeCSIu'), 4) 2230 endfor 2231 2232 bwipe! 2233 set timeoutlen& 2234endfunc 2235 2236func Test_mapping_works_with_ctrl_alt() 2237 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-A', 7) 2238 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-A', 7) 2239endfunc 2240 2241func Test_mapping_works_with_shift_ctrl_alt() 2242 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-S-A', 8) 2243 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-S-A', 8) 2244endfunc 2245 2246func Test_insert_literal() 2247 set timeoutlen=10 2248 new 2249 " CTRL-V CTRL-X inserts a ^X 2250 call feedkeys('a' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu('X', '5') .. "\<Esc>", 'Lx!') 2251 call assert_equal("\<C-X>", getline(1)) 2252 2253 call setline(1, '') 2254 call feedkeys('a' .. GetEscCodeCSI27('V', '5') .. GetEscCodeCSI27('X', '5') .. "\<Esc>", 'Lx!') 2255 call assert_equal("\<C-X>", getline(1)) 2256 2257 " CTRL-SHIFT-V CTRL-X inserts escape sequence 2258 call setline(1, '') 2259 call feedkeys('a' .. GetEscCodeCSIu('V', '6') .. GetEscCodeCSIu('X', '5') .. "\<Esc>", 'Lx!') 2260 call assert_equal("\<Esc>[88;5u", getline(1)) 2261 2262 call setline(1, '') 2263 call feedkeys('a' .. GetEscCodeCSI27('V', '6') .. GetEscCodeCSI27('X', '5') .. "\<Esc>", 'Lx!') 2264 call assert_equal("\<Esc>[27;5;88~", getline(1)) 2265 2266 bwipe! 2267 set timeoutlen& 2268endfunc 2269 2270func Test_cmdline_literal() 2271 set timeoutlen=10 2272 2273 " CTRL-V CTRL-Y inserts a ^Y 2274 call feedkeys(':' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!') 2275 call assert_equal("\"\<C-Y>", @:) 2276 2277 call feedkeys(':' .. GetEscCodeCSI27('V', '5') .. GetEscCodeCSI27('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!') 2278 call assert_equal("\"\<C-Y>", @:) 2279 2280 " CTRL-SHIFT-V CTRL-Y inserts escape sequence 2281 call feedkeys(':' .. GetEscCodeCSIu('V', '6') .. GetEscCodeCSIu('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!') 2282 call assert_equal("\"\<Esc>[89;5u", @:) 2283 2284 call setline(1, '') 2285 call feedkeys(':' .. GetEscCodeCSI27('V', '6') .. GetEscCodeCSI27('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!') 2286 call assert_equal("\"\<Esc>[27;5;89~", @:) 2287 2288 set timeoutlen& 2289endfunc 2290 2291" Test for translation of special key codes (<xF1>, <xF2>, etc.) 2292func Test_Keycode_Translation() 2293 let keycodes = [ 2294 \ ["<xUp>", "<Up>"], 2295 \ ["<xDown>", "<Down>"], 2296 \ ["<xLeft>", "<Left>"], 2297 \ ["<xRight>", "<Right>"], 2298 \ ["<xHome>", "<Home>"], 2299 \ ["<xEnd>", "<End>"], 2300 \ ["<zHome>", "<Home>"], 2301 \ ["<zEnd>", "<End>"], 2302 \ ["<xF1>", "<F1>"], 2303 \ ["<xF2>", "<F2>"], 2304 \ ["<xF3>", "<F3>"], 2305 \ ["<xF4>", "<F4>"], 2306 \ ["<S-xF1>", "<S-F1>"], 2307 \ ["<S-xF2>", "<S-F2>"], 2308 \ ["<S-xF3>", "<S-F3>"], 2309 \ ["<S-xF4>", "<S-F4>"]] 2310 for [k1, k2] in keycodes 2311 exe "nnoremap " .. k1 .. " 2wx" 2312 call assert_true(maparg(k1, 'n', 0, 1).lhs == k2) 2313 exe "nunmap " .. k1 2314 endfor 2315endfunc 2316 2317" Test for terminal keycodes that doesn't have termcap entries 2318func Test_special_term_keycodes() 2319 new 2320 " Test for <xHome>, <S-xHome> and <C-xHome> 2321 " send <K_SPECIAL> <KS_EXTRA> keycode 2322 call feedkeys("i\<C-K>\x80\xfd\x3f\n", 'xt') 2323 " send <K_SPECIAL> <KS_MODIFIER> bitmap <K_SPECIAL> <KS_EXTRA> keycode 2324 call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x3f\n", 'xt') 2325 call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x3f\n", 'xt') 2326 " Test for <xEnd>, <S-xEnd> and <C-xEnd> 2327 call feedkeys("i\<C-K>\x80\xfd\x3d\n", 'xt') 2328 call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x3d\n", 'xt') 2329 call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x3d\n", 'xt') 2330 " Test for <zHome>, <S-zHome> and <C-zHome> 2331 call feedkeys("i\<C-K>\x80\xfd\x40\n", 'xt') 2332 call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x40\n", 'xt') 2333 call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x40\n", 'xt') 2334 " Test for <zEnd>, <S-zEnd> and <C-zEnd> 2335 call feedkeys("i\<C-K>\x80\xfd\x3e\n", 'xt') 2336 call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x3e\n", 'xt') 2337 call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x3e\n", 'xt') 2338 " Test for <xUp>, <xDown>, <xLeft> and <xRight> 2339 call feedkeys("i\<C-K>\x80\xfd\x41\n", 'xt') 2340 call feedkeys("i\<C-K>\x80\xfd\x42\n", 'xt') 2341 call feedkeys("i\<C-K>\x80\xfd\x43\n", 'xt') 2342 call feedkeys("i\<C-K>\x80\xfd\x44\n", 'xt') 2343 call assert_equal(['<Home>', '<S-Home>', '<C-Home>', 2344 \ '<End>', '<S-End>', '<C-End>', 2345 \ '<Home>', '<S-Home>', '<C-Home>', 2346 \ '<End>', '<S-End>', '<C-End>', 2347 \ '<Up>', '<Down>', '<Left>', '<Right>', ''], getline(1, '$')) 2348 bw! 2349endfunc 2350 2351" vim: shiftwidth=2 sts=2 expandtab 2352