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_get_termcode() 1872 try 1873 let k1 = &t_k1 1874 catch /E113/ 1875 throw 'Skipped: Unable to query termcodes' 1876 endtry 1877 set t_k1= 1878 set t_k1& 1879 call assert_equal(k1, &t_k1) 1880 1881 " use external termcap first 1882 set nottybuiltin 1883 set t_k1= 1884 set t_k1& 1885 " when using external termcap may get something else, but it must not be 1886 " empty, since we would fallback to the builtin one. 1887 call assert_notequal('', &t_k1) 1888 1889 if &term =~ 'xterm' 1890 " use internal termcap first 1891 let term_save = &term 1892 let &term = 'builtin_' .. &term 1893 set t_k1= 1894 set t_k1& 1895 call assert_equal(k1, &t_k1) 1896 let &term = term_save 1897 endif 1898 1899 set ttybuiltin 1900endfunc 1901 1902func Test_list_builtin_terminals() 1903 CheckRunVimInTerminal 1904 call RunVimInTerminal('', #{rows: 14}) 1905 call term_sendkeys('', ":set cmdheight=3\<CR>") 1906 call TermWait('', 100) 1907 call term_sendkeys('', ":set term=xxx\<CR>") 1908 call TermWait('', 100) 1909 call assert_match('builtin_dumb', term_getline('', 11)) 1910 call assert_match('Not found in termcap', term_getline('', 12)) 1911 call StopVimInTerminal('') 1912endfunc 1913 1914func GetEscCodeCSI27(key, modifier) 1915 let key = printf("%d", char2nr(a:key)) 1916 let mod = printf("%d", a:modifier) 1917 return "\<Esc>[27;" .. mod .. ';' .. key .. '~' 1918endfunc 1919 1920func GetEscCodeCSIu(key, modifier) 1921 let key = printf("%d", char2nr(a:key)) 1922 let mod = printf("%d", a:modifier) 1923 return "\<Esc>[" .. key .. ';' .. mod .. 'u' 1924endfunc 1925 1926" This checks the CSI sequences when in modifyOtherKeys mode. 1927" The mode doesn't need to be enabled, the codes are always detected. 1928func RunTest_modifyOtherKeys(func) 1929 new 1930 set timeoutlen=10 1931 1932 " Shift-X is sent as 'X' with the shift modifier 1933 call feedkeys('a' .. a:func('X', 2) .. "\<Esc>", 'Lx!') 1934 call assert_equal('X', getline(1)) 1935 1936 " Ctrl-i is Tab 1937 call setline(1, '') 1938 call feedkeys('a' .. a:func('i', 5) .. "\<Esc>", 'Lx!') 1939 call assert_equal("\t", getline(1)) 1940 1941 " Ctrl-I is also Tab 1942 call setline(1, '') 1943 call feedkeys('a' .. a:func('I', 5) .. "\<Esc>", 'Lx!') 1944 call assert_equal("\t", getline(1)) 1945 1946 " Alt-x is ø 1947 call setline(1, '') 1948 call feedkeys('a' .. a:func('x', 3) .. "\<Esc>", 'Lx!') 1949 call assert_equal("ø", getline(1)) 1950 1951 " Meta-x is also ø 1952 call setline(1, '') 1953 call feedkeys('a' .. a:func('x', 9) .. "\<Esc>", 'Lx!') 1954 call assert_equal("ø", getline(1)) 1955 1956 " Alt-X is Ø 1957 call setline(1, '') 1958 call feedkeys('a' .. a:func('X', 3) .. "\<Esc>", 'Lx!') 1959 call assert_equal("Ø", getline(1)) 1960 1961 " Meta-X is ø 1962 call setline(1, '') 1963 call feedkeys('a' .. a:func('X', 9) .. "\<Esc>", 'Lx!') 1964 call assert_equal("Ø", getline(1)) 1965 1966 " Ctrl-6 is Ctrl-^ 1967 split aaa 1968 edit bbb 1969 call feedkeys(a:func('6', 5), 'Lx!') 1970 call assert_equal("aaa", bufname()) 1971 bwipe aaa 1972 bwipe bbb 1973 1974 " Ctrl-V X 33 is 3 1975 call setline(1, '') 1976 call feedkeys("a\<C-V>" .. a:func('X', 2) .. "33\<Esc>", 'Lx!') 1977 call assert_equal("3", getline(1)) 1978 1979 " Ctrl-V U 12345 is Unicode 12345 1980 call setline(1, '') 1981 call feedkeys("a\<C-V>" .. a:func('U', 2) .. "12345\<Esc>", 'Lx!') 1982 call assert_equal("\U12345", getline(1)) 1983 1984 bwipe! 1985 set timeoutlen& 1986endfunc 1987 1988func Test_modifyOtherKeys_basic() 1989 call RunTest_modifyOtherKeys(function('GetEscCodeCSI27')) 1990 call RunTest_modifyOtherKeys(function('GetEscCodeCSIu')) 1991endfunc 1992 1993func Test_modifyOtherKeys_no_mapping() 1994 set timeoutlen=10 1995 1996 let @a = 'aaa' 1997 call feedkeys(":let x = '" .. GetEscCodeCSI27('R', 5) .. GetEscCodeCSI27('R', 5) .. "a'\<CR>", 'Lx!') 1998 call assert_equal("let x = 'aaa'", @:) 1999 2000 new 2001 call feedkeys("a" .. GetEscCodeCSI27('R', 5) .. GetEscCodeCSI27('R', 5) .. "a\<Esc>", 'Lx!') 2002 call assert_equal("aaa", getline(1)) 2003 bwipe! 2004 2005 new 2006 call feedkeys("axx\<CR>yy" .. GetEscCodeCSI27('G', 5) .. GetEscCodeCSI27('K', 5) .. "a\<Esc>", 'Lx!') 2007 call assert_equal("axx", getline(1)) 2008 call assert_equal("yy", getline(2)) 2009 bwipe! 2010 2011 set timeoutlen& 2012endfunc 2013 2014func RunTest_mapping_shift(key, func) 2015 call setline(1, '') 2016 if a:key == '|' 2017 exe 'inoremap \| xyz' 2018 else 2019 exe 'inoremap ' .. a:key .. ' xyz' 2020 endif 2021 call feedkeys('a' .. a:func(a:key, 2) .. "\<Esc>", 'Lx!') 2022 call assert_equal("xyz", getline(1)) 2023 if a:key == '|' 2024 exe 'iunmap \|' 2025 else 2026 exe 'iunmap ' .. a:key 2027 endif 2028endfunc 2029 2030func Test_modifyOtherKeys_mapped() 2031 set timeoutlen=10 2032 imap ' <C-W> 2033 imap <C-W><C-A> c-a 2034 call setline(1, '') 2035 2036 " single quote is turned into single byte CTRL-W 2037 " CTRL-A is added with a separate modifier, and needs to be simplified before 2038 " the mapping can match. 2039 call feedkeys("a'" .. GetEscCodeCSI27('A', 5) .. "\<Esc>", 'Lx!') 2040 call assert_equal('c-a', getline(1)) 2041 2042 iunmap ' 2043 iunmap <C-W><C-A> 2044 set timeoutlen& 2045endfunc 2046 2047" Whether Shift-Tab sends "ESC [ Z" or "ESC [ 27 ; 2 ; 9 ~" is unpredictable, 2048" both should work. 2049func Test_modifyOtherKeys_shift_tab() 2050 set timeoutlen=10 2051 2052 call setline(1, '') 2053 call feedkeys("a\<C-K>" .. GetEscCodeCSI27("\t", '2') .. "\<Esc>", 'Lx!') 2054 eval getline(1)->assert_equal('<S-Tab>') 2055 2056 call setline(1, '') 2057 call feedkeys("a\<C-K>\<Esc>[Z\<Esc>", 'Lx!') 2058 eval getline(1)->assert_equal('<S-Tab>') 2059 2060 set timeoutlen& 2061 bwipe! 2062endfunc 2063 2064func RunTest_mapping_works_with_shift(func) 2065 new 2066 set timeoutlen=10 2067 2068 call RunTest_mapping_shift('@', a:func) 2069 call RunTest_mapping_shift('A', a:func) 2070 call RunTest_mapping_shift('Z', a:func) 2071 call RunTest_mapping_shift('^', a:func) 2072 call RunTest_mapping_shift('_', a:func) 2073 call RunTest_mapping_shift('{', a:func) 2074 call RunTest_mapping_shift('|', a:func) 2075 call RunTest_mapping_shift('}', a:func) 2076 call RunTest_mapping_shift('~', a:func) 2077 2078 bwipe! 2079 set timeoutlen& 2080endfunc 2081 2082func Test_mapping_works_with_shift_plain() 2083 call RunTest_mapping_works_with_shift(function('GetEscCodeCSI27')) 2084 call RunTest_mapping_works_with_shift(function('GetEscCodeCSIu')) 2085endfunc 2086 2087func RunTest_mapping_mods(map, key, func, code) 2088 call setline(1, '') 2089 exe 'inoremap ' .. a:map .. ' xyz' 2090 call feedkeys('a' .. a:func(a:key, a:code) .. "\<Esc>", 'Lx!') 2091 call assert_equal("xyz", getline(1)) 2092 exe 'iunmap ' .. a:map 2093endfunc 2094 2095func RunTest_mapping_works_with_mods(func, mods, code) 2096 new 2097 set timeoutlen=10 2098 2099 if a:mods !~ 'S' 2100 " Shift by itself has no effect 2101 call RunTest_mapping_mods('<' .. a:mods .. '-@>', '@', a:func, a:code) 2102 endif 2103 call RunTest_mapping_mods('<' .. a:mods .. '-A>', 'A', a:func, a:code) 2104 call RunTest_mapping_mods('<' .. a:mods .. '-Z>', 'Z', a:func, a:code) 2105 if a:mods !~ 'S' 2106 " with Shift code is always upper case 2107 call RunTest_mapping_mods('<' .. a:mods .. '-a>', 'a', a:func, a:code) 2108 call RunTest_mapping_mods('<' .. a:mods .. '-z>', 'z', a:func, a:code) 2109 endif 2110 if a:mods != 'A' 2111 " with Alt code is not in upper case 2112 call RunTest_mapping_mods('<' .. a:mods .. '-a>', 'A', a:func, a:code) 2113 call RunTest_mapping_mods('<' .. a:mods .. '-z>', 'Z', a:func, a:code) 2114 endif 2115 call RunTest_mapping_mods('<' .. a:mods .. '-á>', 'á', a:func, a:code) 2116 if a:mods !~ 'S' 2117 " Shift by itself has no effect 2118 call RunTest_mapping_mods('<' .. a:mods .. '-^>', '^', a:func, a:code) 2119 call RunTest_mapping_mods('<' .. a:mods .. '-_>', '_', a:func, a:code) 2120 call RunTest_mapping_mods('<' .. a:mods .. '-{>', '{', a:func, a:code) 2121 call RunTest_mapping_mods('<' .. a:mods .. '-\|>', '|', a:func, a:code) 2122 call RunTest_mapping_mods('<' .. a:mods .. '-}>', '}', a:func, a:code) 2123 call RunTest_mapping_mods('<' .. a:mods .. '-~>', '~', a:func, a:code) 2124 endif 2125 2126 bwipe! 2127 set timeoutlen& 2128endfunc 2129 2130func Test_mapping_works_with_shift() 2131 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'S', 2) 2132 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'S', 2) 2133endfunc 2134 2135func Test_mapping_works_with_ctrl() 2136 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C', 5) 2137 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C', 5) 2138 2139 new 2140 set timeoutlen=10 2141 2142 " CTRL-@ actually produces the code for CTRL-2, which is converted 2143 call RunTest_mapping_mods('<C-@>', '2', function('GetEscCodeCSI27'), 5) 2144 call RunTest_mapping_mods('<C-@>', '2', function('GetEscCodeCSIu'), 5) 2145 2146 " CTRL-^ actually produces the code for CTRL-6, which is converted 2147 call RunTest_mapping_mods('<C-^>', '6', function('GetEscCodeCSI27'), 5) 2148 call RunTest_mapping_mods('<C-^>', '6', function('GetEscCodeCSIu'), 5) 2149 2150 " CTRL-_ actually produces the code for CTRL--, which is converted 2151 call RunTest_mapping_mods('<C-_>', '-', function('GetEscCodeCSI27'), 5) 2152 call RunTest_mapping_mods('<C-_>', '-', function('GetEscCodeCSIu'), 5) 2153 2154 bwipe! 2155 set timeoutlen& 2156endfunc 2157 2158func Test_mapping_works_with_shift_ctrl() 2159 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-S', 6) 2160 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-S', 6) 2161 2162 new 2163 set timeoutlen=10 2164 2165 " Ctrl-Shift-[ actually produces CTRL-Shift-{ which is mapped as <C-{> 2166 call RunTest_mapping_mods('<C-{>', '{', function('GetEscCodeCSI27'), 6) 2167 call RunTest_mapping_mods('<C-{>', '{', function('GetEscCodeCSIu'), 6) 2168 2169 " Ctrl-Shift-] actually produces CTRL-Shift-} which is mapped as <C-}> 2170 call RunTest_mapping_mods('<C-{>', '{', function('GetEscCodeCSI27'), 6) 2171 call RunTest_mapping_mods('<C-{>', '{', function('GetEscCodeCSIu'), 6) 2172 2173 " Ctrl-Shift-\ actually produces CTRL-Shift-| which is mapped as <C-|> 2174 call RunTest_mapping_mods('<C-\|>', '|', function('GetEscCodeCSI27'), 6) 2175 call RunTest_mapping_mods('<C-\|>', '|', function('GetEscCodeCSIu'), 6) 2176 2177 bwipe! 2178 set timeoutlen& 2179endfunc 2180 2181" Below we also test the "u" code with Alt, This works, but libvterm would not 2182" send the Alt key like this but by prefixing an Esc. 2183 2184func Test_mapping_works_with_alt() 2185 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'A', 3) 2186 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'A', 3) 2187endfunc 2188 2189func Test_mapping_works_with_shift_alt() 2190 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'S-A', 4) 2191 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'S-A', 4) 2192endfunc 2193 2194func Test_mapping_works_with_alt_and_shift() 2195 new 2196 set timeoutlen=10 2197 2198 " mapping <A-?> works even though the code is A-S-? 2199 for c in ['!', '$', '+', ':', '?', '^', '~'] 2200 call RunTest_mapping_mods('<A-' .. c .. '>', c, function('GetEscCodeCSI27'), 4) 2201 call RunTest_mapping_mods('<A-' .. c .. '>', c, function('GetEscCodeCSIu'), 4) 2202 endfor 2203 2204 bwipe! 2205 set timeoutlen& 2206endfunc 2207 2208func Test_mapping_works_with_ctrl_alt() 2209 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-A', 7) 2210 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-A', 7) 2211endfunc 2212 2213func Test_mapping_works_with_shift_ctrl_alt() 2214 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-S-A', 8) 2215 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-S-A', 8) 2216endfunc 2217 2218func Test_insert_literal() 2219 set timeoutlen=10 2220 new 2221 " CTRL-V CTRL-X inserts a ^X 2222 call feedkeys('a' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu('X', '5') .. "\<Esc>", 'Lx!') 2223 call assert_equal("\<C-X>", getline(1)) 2224 2225 call setline(1, '') 2226 call feedkeys('a' .. GetEscCodeCSI27('V', '5') .. GetEscCodeCSI27('X', '5') .. "\<Esc>", 'Lx!') 2227 call assert_equal("\<C-X>", getline(1)) 2228 2229 " CTRL-SHIFT-V CTRL-X inserts escape sequence 2230 call setline(1, '') 2231 call feedkeys('a' .. GetEscCodeCSIu('V', '6') .. GetEscCodeCSIu('X', '5') .. "\<Esc>", 'Lx!') 2232 call assert_equal("\<Esc>[88;5u", getline(1)) 2233 2234 call setline(1, '') 2235 call feedkeys('a' .. GetEscCodeCSI27('V', '6') .. GetEscCodeCSI27('X', '5') .. "\<Esc>", 'Lx!') 2236 call assert_equal("\<Esc>[27;5;88~", getline(1)) 2237 2238 bwipe! 2239 set timeoutlen& 2240endfunc 2241 2242func Test_cmdline_literal() 2243 set timeoutlen=10 2244 2245 " CTRL-V CTRL-Y inserts a ^Y 2246 call feedkeys(':' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!') 2247 call assert_equal("\"\<C-Y>", @:) 2248 2249 call feedkeys(':' .. GetEscCodeCSI27('V', '5') .. GetEscCodeCSI27('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!') 2250 call assert_equal("\"\<C-Y>", @:) 2251 2252 " CTRL-SHIFT-V CTRL-Y inserts escape sequence 2253 call feedkeys(':' .. GetEscCodeCSIu('V', '6') .. GetEscCodeCSIu('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!') 2254 call assert_equal("\"\<Esc>[89;5u", @:) 2255 2256 call setline(1, '') 2257 call feedkeys(':' .. GetEscCodeCSI27('V', '6') .. GetEscCodeCSI27('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!') 2258 call assert_equal("\"\<Esc>[27;5;89~", @:) 2259 2260 set timeoutlen& 2261endfunc 2262 2263" Test for translation of special key codes (<xF1>, <xF2>, etc.) 2264func Test_Keycode_Tranlsation() 2265 let keycodes = [ 2266 \ ["<xUp>", "<Up>"], 2267 \ ["<xDown>", "<Down>"], 2268 \ ["<xLeft>", "<Left>"], 2269 \ ["<xRight>", "<Right>"], 2270 \ ["<xHome>", "<Home>"], 2271 \ ["<xEnd>", "<End>"], 2272 \ ["<zHome>", "<Home>"], 2273 \ ["<zEnd>", "<End>"], 2274 \ ["<xF1>", "<F1>"], 2275 \ ["<xF2>", "<F2>"], 2276 \ ["<xF3>", "<F3>"], 2277 \ ["<xF4>", "<F4>"], 2278 \ ["<S-xF1>", "<S-F1>"], 2279 \ ["<S-xF2>", "<S-F2>"], 2280 \ ["<S-xF3>", "<S-F3>"], 2281 \ ["<S-xF4>", "<S-F4>"]] 2282 for [k1, k2] in keycodes 2283 exe "nnoremap " .. k1 .. " 2wx" 2284 call assert_true(maparg(k1, 'n', 0, 1).lhs == k2) 2285 exe "nunmap " .. k1 2286 endfor 2287endfunc 2288 2289" vim: shiftwidth=2 sts=2 expandtab 2290