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