| " Tests for decoding escape sequences sent by the terminal. |
| |
| " This only works for Unix in a terminal |
| CheckNotGui |
| CheckUnix |
| |
| source util/mouse.vim |
| |
| func s:TermGuiColorsTest() |
| CheckNotMSWindows |
| if !CanRunVimInTerminal() |
| throw 'Skipped: cannot make screendumps' |
| endif |
| if !executable('tput') |
| throw "Skipped: tput not executable!" |
| endif |
| if has("gui_running") |
| throw "Skipped: does not work in GUI mode" |
| endif |
| call system('tput -Txterm-direct RGB 2>/dev/null') |
| if v:shell_error |
| throw "Skipped: xterm-direct $TERM has no RGB capability" |
| endif |
| endfunc |
| |
| |
| func Test_term_mouse_left_click() |
| new |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=xterm |
| call WaitForResponses() |
| |
| call setline(1, ['line 1', 'line 2', 'line 3 is a bit longer']) |
| |
| for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| go |
| call assert_equal([0, 1, 1, 0], getpos('.'), msg) |
| let row = 2 |
| let col = 6 |
| call MouseLeftClick(row, col) |
| call MouseLeftRelease(row, col) |
| call assert_equal([0, 2, 6, 0], getpos('.'), msg) |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| call test_override('no_query_mouse', 0) |
| bwipe! |
| endfunc |
| |
| func Test_xterm_mouse_right_click_extends_visual() |
| if has('mac') |
| throw "Skipped: test right click in visual mode does not work on macOs (why?)" |
| endif |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=xterm |
| call WaitForResponses() |
| |
| for visual_mode in ["v", "V", "\<C-V>"] |
| for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec |
| let msg = 'visual=' .. visual_mode .. ' ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| |
| call setline(1, repeat([repeat('-', 7)], 7)) |
| call MouseLeftClick(4, 4) |
| call MouseLeftRelease(4, 4) |
| exe "norm! " .. visual_mode |
| |
| " Right click extends top left of visual area. |
| call MouseRightClick(2, 2) |
| call MouseRightRelease(2, 2) |
| |
| " Right click extends bottom right of visual area. |
| call MouseRightClick(6, 6) |
| call MouseRightRelease(6, 6) |
| norm! r1gv |
| |
| " Right click shrinks top left of visual area. |
| call MouseRightClick(3, 3) |
| call MouseRightRelease(3, 3) |
| |
| " Right click shrinks bottom right of visual area. |
| call MouseRightClick(5, 5) |
| call MouseRightRelease(5, 5) |
| norm! r2 |
| |
| if visual_mode ==# 'v' |
| call assert_equal(['-------', |
| \ '-111111', |
| \ '1122222', |
| \ '2222222', |
| \ '2222211', |
| \ '111111-', |
| \ '-------'], getline(1, '$'), msg) |
| elseif visual_mode ==# 'V' |
| call assert_equal(['-------', |
| \ '1111111', |
| \ '2222222', |
| \ '2222222', |
| \ '2222222', |
| \ '1111111', |
| \ '-------'], getline(1, '$'), msg) |
| else |
| call assert_equal(['-------', |
| \ '-11111-', |
| \ '-12221-', |
| \ '-12221-', |
| \ '-12221-', |
| \ '-11111-', |
| \ '-------'], getline(1, '$'), msg) |
| endif |
| endfor |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| call test_override('no_query_mouse', 0) |
| bwipe! |
| endfunc |
| |
| " Test that <C-LeftMouse> jumps to help tag and <C-RightMouse> jumps back. |
| " Also test for g<LeftMouse> and g<RightMouse>. |
| func Test_xterm_mouse_tagjump() |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| set mouse=a term=xterm |
| call WaitForResponses() |
| |
| for ttymouse_val in g:Ttymouse_values |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| help |
| /usr_02.txt |
| norm! zt |
| |
| " CTRL-left click to jump to a tag |
| let row = 1 |
| let col = 1 |
| call MouseCtrlLeftClick(row, col) |
| call MouseLeftRelease(row, col) |
| call assert_match('usr_02.txt$', bufname('%'), msg) |
| call assert_equal('*usr_02.txt*', expand('<cWORD>'), msg) |
| |
| " CTRL-right click to pop a tag |
| call MouseCtrlRightClick(row, col) |
| call MouseRightRelease(row, col) |
| call assert_match('help.txt$', bufname('%'), msg) |
| call assert_equal('|usr_02.txt|', expand('<cWORD>'), msg) |
| |
| " Jump to a tag |
| exe "normal \<C-]>" |
| call assert_match('usr_02.txt$', bufname('%'), msg) |
| call assert_equal('*usr_02.txt*', expand('<cWORD>'), msg) |
| |
| " Use CTRL-right click in insert mode to pop the tag |
| new |
| let str = 'iHello' .. MouseCtrlRightClickCode(row, col) |
| \ .. MouseRightReleaseCode(row, col) .. "\<C-C>" |
| call assert_fails('call feedkeys(str, "Lx!")', 'E37:', msg) |
| close! |
| |
| " CTRL-right click with a count |
| let str = "4" .. MouseCtrlRightClickCode(row, col) |
| \ .. MouseRightReleaseCode(row, col) |
| call assert_fails('call feedkeys(str, "Lx!")', 'E555:', msg) |
| call assert_match('help.txt$', bufname('%'), msg) |
| call assert_equal(1, line('.'), msg) |
| |
| " g<LeftMouse> to jump to a tag |
| /usr_02.txt |
| norm! zt |
| call test_setmouse(row, col) |
| exe "normal g\<LeftMouse>" |
| call assert_match('usr_02.txt$', bufname('%'), msg) |
| call assert_equal('*usr_02.txt*', expand('<cWORD>'), msg) |
| |
| " g<RightMouse> to pop to a tag |
| call test_setmouse(row, col) |
| exe "normal g\<RightMouse>" |
| call assert_match('help.txt$', bufname('%'), msg) |
| call assert_equal('|usr_02.txt|', expand('<cWORD>'), msg) |
| |
| %bw! |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| endfunc |
| |
| func Test_term_mouse_middle_click() |
| CheckFeature clipboard_working |
| |
| new |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| let save_quotestar = @* |
| let save_quoteplus = @+ |
| set mouse=a term=xterm |
| call WaitForResponses() |
| |
| for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| call setline(1, ['123456789', '123456789']) |
| let @* = 'abc' |
| |
| " Middle-click in the middle of the line pastes text where clicked. |
| let row = 1 |
| let col = 6 |
| call MouseMiddleClick(row, col) |
| call MouseMiddleRelease(row, col) |
| call assert_equal(['12345abc6789', '123456789'], getline(1, '$'), msg) |
| |
| " Middle-click beyond end of the line pastes text at the end of the line. |
| let col = 20 |
| call MouseMiddleClick(row, col) |
| call MouseMiddleRelease(row, col) |
| call assert_equal(['12345abc6789abc', '123456789'], getline(1, '$'), msg) |
| |
| " Middle-click beyond the last line pastes in the last line. |
| let row = 5 |
| let col = 3 |
| call MouseMiddleClick(row, col) |
| call MouseMiddleRelease(row, col) |
| call assert_equal(['12345abc6789abc', '12abc3456789'], getline(1, '$'), msg) |
| |
| " Middle mouse click in operator pending mode beeps |
| call assert_beeps('exe "normal c\<MiddleMouse>"') |
| |
| " Clicking middle mouse in visual mode, yanks the selection and pastes the |
| " clipboard contents |
| let save_clipboard = &clipboard |
| set clipboard= |
| let @" = '' |
| call cursor(1, 1) |
| call feedkeys("v3l" .. |
| \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7), 'Lx!') |
| call assert_equal(['12345abc6789abc', '12abc3abc456789'], |
| \ getline(1, '$'), msg) |
| call assert_equal('1234', @", msg) |
| let &clipboard = save_clipboard |
| |
| " Clicking middle mouse in select mode, replaces the selected text with |
| " the clipboard contents |
| let @+ = 'xyz' |
| call cursor(1, 3) |
| exe "normal gh\<Right>\<Right>\<MiddleMouse>" |
| call assert_equal(['12xyzabc6789abc', '12abc3abc456789'], |
| \ getline(1, '$'), msg) |
| |
| " Prefixing middle click with [ or ] fixes the indent after pasting. |
| %d |
| call setline(1, " one two") |
| call setreg('r', 'red blue', 'l') |
| call test_setmouse(1, 5) |
| exe "normal \"r[\<MiddleMouse>" |
| call assert_equal(' red blue', getline(1), msg) |
| call test_setmouse(2, 5) |
| exe "normal \"r]\<MiddleMouse>" |
| call assert_equal(' red blue', getline(3), msg) |
| %d |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| call test_override('no_query_mouse', 0) |
| let @* = save_quotestar |
| let @+ = save_quoteplus |
| bwipe! |
| endfunc |
| |
| " If clipboard is not working, then clicking the middle mouse button in visual |
| " mode, will copy and paste the selected text. |
| func Test_term_mouse_middle_click_no_clipboard() |
| if has('clipboard_working') |
| throw 'Skipped: clipboard support works' |
| endif |
| new |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=xterm |
| call WaitForResponses() |
| |
| for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| call setline(1, ['123456789', '123456789']) |
| |
| " Clicking middle mouse in visual mode, yanks the selection and pastes it |
| call cursor(1, 1) |
| call feedkeys("v3l" .. |
| \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7), 'Lx!') |
| call assert_equal(['123456789', '1234561234789'], |
| \ getline(1, '$'), msg) |
| endfor |
| |
| call test_override('no_query_mouse', 0) |
| let &ttymouse = save_ttymouse |
| let &term = save_term |
| let &mouse = save_mouse |
| bw! |
| endfunc |
| |
| func Test_term_mouse_middle_click_insert_mode() |
| CheckFeature clipboard_working |
| |
| new |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=xterm |
| call WaitForResponses() |
| |
| for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| call setline(1, ['123456789', '123456789']) |
| let @* = 'abc' |
| |
| " Middle-click in insert mode doesn't move the cursor but inserts the |
| " contents of a register |
| call cursor(1, 4) |
| call feedkeys('i' .. |
| \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7) .. |
| \ "\<C-C>", 'Lx!') |
| call assert_equal(['123abc456789', '123456789'], |
| \ getline(1, '$'), msg) |
| call assert_equal([1, 6], [line('.'), col('.')], msg) |
| |
| " Middle-click in replace mode |
| call cursor(1, 1) |
| call feedkeys('$R' .. |
| \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7) .. |
| \ "\<C-C>", 'Lx!') |
| call assert_equal(['123abc45678abc', '123456789'], |
| \ getline(1, '$'), msg) |
| call assert_equal([1, 14], [line('.'), col('.')], msg) |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| call test_override('no_query_mouse', 0) |
| close! |
| endfunc |
| |
| " Test for switching window using mouse in insert mode |
| func Test_term_mouse_switch_win_insert_mode() |
| 5new |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=xterm ttymouse=xterm2 |
| call WaitForResponses() |
| |
| call feedkeys('ivim' .. |
| \ MouseLeftClickCode(8, 6) .. MouseLeftReleaseCode(8, 6) .. |
| \ "\<C-C>", 'Lx!') |
| call assert_equal(2, winnr()) |
| wincmd w |
| call assert_equal('n', mode()) |
| call assert_equal(['vim'], getline(1, '$')) |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| call test_override('no_query_mouse', 0) |
| bw! |
| endfunc |
| |
| " Test for using the mouse to increase the height of the cmdline window |
| func Test_mouse_cmdwin_resize() |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=xterm ttymouse=xterm2 |
| call WaitForResponses() |
| |
| 5new |
| redraw! |
| |
| let h = 0 |
| let row = &lines - &cmdwinheight - 2 |
| call feedkeys("q:" .. |
| \ MouseLeftClickCode(row, 1) .. |
| \ MouseLeftDragCode(row - 1, 1) .. |
| \ MouseLeftReleaseCode(row - 2, 1) .. |
| \ "alet h = \<C-R>=winheight(0)\<CR>\<CR>", 'Lx!') |
| call assert_equal(&cmdwinheight + 2, h) |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| call test_override('no_query_mouse', 0) |
| close! |
| endfunc |
| |
| " TODO: for unclear reasons this test fails if it comes after |
| " Test_xterm_mouse_ctrl_click() |
| func Test_1xterm_mouse_wheel() |
| new |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_wrap = &wrap |
| let save_ttymouse = &ttymouse |
| set mouse=a term=xterm nowrap |
| call WaitForResponses() |
| |
| call setline(1, range(100000000000000, 100000000000100)) |
| |
| for ttymouse_val in g:Ttymouse_values |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| go |
| call assert_equal(1, line('w0'), msg) |
| call assert_equal([0, 1, 1, 0], getpos('.'), msg) |
| |
| call MouseWheelDown(1, 1) |
| call assert_equal(4, line('w0'), msg) |
| call assert_equal([0, 4, 1, 0], getpos('.'), msg) |
| |
| call MouseWheelDown(1, 1) |
| call assert_equal(7, line('w0'), msg) |
| call assert_equal([0, 7, 1, 0], getpos('.'), msg) |
| |
| call MouseWheelUp(1, 1) |
| call assert_equal(4, line('w0'), msg) |
| call assert_equal([0, 7, 1, 0], getpos('.'), msg) |
| |
| call MouseWheelUp(1, 1) |
| call assert_equal(1, line('w0'), msg) |
| call assert_equal([0, 7, 1, 0], getpos('.'), msg) |
| |
| call MouseWheelRight(1, 1) |
| call assert_equal(7, 1 + virtcol(".") - wincol(), msg) |
| call assert_equal([0, 7, 7, 0], getpos('.'), msg) |
| |
| call MouseWheelRight(1, 1) |
| call assert_equal(13, 1 + virtcol(".") - wincol(), msg) |
| call assert_equal([0, 7, 13, 0], getpos('.'), msg) |
| |
| call MouseWheelLeft(1, 1) |
| call assert_equal(7, 1 + virtcol(".") - wincol(), msg) |
| call assert_equal([0, 7, 13, 0], getpos('.'), msg) |
| |
| call MouseWheelLeft(1, 1) |
| call assert_equal(1, 1 + virtcol(".") - wincol(), msg) |
| call assert_equal([0, 7, 13, 0], getpos('.'), msg) |
| |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &wrap = save_wrap |
| let &ttymouse = save_ttymouse |
| bwipe! |
| endfunc |
| |
| " Test that dragging beyond the window (at the bottom and at the top) |
| " scrolls window content by the number of lines beyond the window. |
| func Test_term_mouse_drag_beyond_window() |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=xterm |
| call WaitForResponses() |
| |
| let col = 1 |
| call setline(1, range(1, 100)) |
| |
| " Split into 3 windows, and go into the middle window |
| " so we test dragging mouse below and above the window. |
| 2split |
| wincmd j |
| 2split |
| |
| for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| |
| " Line #10 at the top. |
| norm! 10zt |
| redraw |
| call assert_equal(10, winsaveview().topline, msg) |
| call assert_equal(2, winheight(0), msg) |
| |
| let row = 4 |
| call MouseLeftClick(row, col) |
| call assert_equal(10, winsaveview().topline, msg) |
| |
| " Drag downwards. We're still in the window so topline should |
| " not change yet. |
| let row += 1 |
| call MouseLeftDrag(row, col) |
| call assert_equal(10, winsaveview().topline, msg) |
| |
| " We now leave the window at the bottom, so the window content should |
| " scroll by 1 line, then 2 lines (etc) as we drag further away. |
| let row += 1 |
| call MouseLeftDrag(row, col) |
| call assert_equal(11, winsaveview().topline, msg) |
| |
| let row += 1 |
| call MouseLeftDrag(row, col) |
| call assert_equal(13, winsaveview().topline, msg) |
| |
| " Now drag upwards. |
| let row -= 1 |
| call MouseLeftDrag(row, col) |
| call assert_equal(14, winsaveview().topline, msg) |
| |
| " We're now back in the window so the topline should not change. |
| let row -= 1 |
| call MouseLeftDrag(row, col) |
| call assert_equal(14, winsaveview().topline, msg) |
| |
| let row -= 1 |
| call MouseLeftDrag(row, col) |
| call assert_equal(14, winsaveview().topline, msg) |
| |
| " We now leave the window at the top so the window content should |
| " scroll by 1 line, then 2, then 3 (etc) in the opposite direction. |
| let row -= 1 |
| call MouseLeftDrag(row, col) |
| call assert_equal(13, winsaveview().topline, msg) |
| |
| let row -= 1 |
| call MouseLeftDrag(row, col) |
| call assert_equal(11, winsaveview().topline, msg) |
| |
| let row -= 1 |
| call MouseLeftDrag(row, col) |
| call assert_equal(8, winsaveview().topline, msg) |
| |
| call MouseLeftRelease(row, col) |
| call assert_equal(8, winsaveview().topline, msg) |
| call assert_equal(2, winheight(0), msg) |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| call test_override('no_query_mouse', 0) |
| bwipe! |
| endfunc |
| |
| func Test_term_mouse_drag_window_separator() |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=xterm |
| call WaitForResponses() |
| |
| for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| |
| " Split horizontally and test dragging the horizontal window separator. |
| split |
| let rowseparator = winheight(0) + 1 |
| let row = rowseparator |
| let col = 1 |
| |
| " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported. |
| if ttymouse_val !=# 'xterm2' || row <= 223 |
| call MouseLeftClick(row, col) |
| let row -= 1 |
| call MouseLeftDrag(row, col) |
| call assert_equal(rowseparator - 1, winheight(0) + 1, msg) |
| let row += 1 |
| call MouseLeftDrag(row, col) |
| call assert_equal(rowseparator, winheight(0) + 1, msg) |
| call MouseLeftRelease(row, col) |
| call assert_equal(rowseparator, winheight(0) + 1, msg) |
| endif |
| bwipe! |
| |
| " Split vertically and test dragging the vertical window separator. |
| vsplit |
| let colseparator = winwidth(0) + 1 |
| let row = 1 |
| let col = colseparator |
| |
| " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported. |
| if ttymouse_val !=# 'xterm2' || col <= 223 |
| call MouseLeftClick(row, col) |
| let col -= 1 |
| call MouseLeftDrag(row, col) |
| call assert_equal(colseparator - 1, winwidth(0) + 1, msg) |
| let col += 1 |
| call MouseLeftDrag(row, col) |
| call assert_equal(colseparator, winwidth(0) + 1, msg) |
| call MouseLeftRelease(row, col) |
| call assert_equal(colseparator, winwidth(0) + 1, msg) |
| endif |
| bwipe! |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| call test_override('no_query_mouse', 0) |
| endfunc |
| |
| func Test_term_mouse_drag_statusline() |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| let save_laststatus = &laststatus |
| set mouse=a term=xterm laststatus=2 |
| call WaitForResponses() |
| |
| for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| |
| call assert_equal(1, &cmdheight, msg) |
| let rowstatusline = winheight(0) + 1 |
| let row = rowstatusline |
| let col = 1 |
| |
| if ttymouse_val ==# 'xterm2' && row > 223 |
| " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported. |
| continue |
| endif |
| |
| call MouseLeftClick(row, col) |
| let row -= 1 |
| call MouseLeftDrag(row, col) |
| call assert_equal(2, &cmdheight, msg) |
| call assert_equal(rowstatusline - 1, winheight(0) + 1, msg) |
| let row += 1 |
| call MouseLeftDrag(row, col) |
| call assert_equal(1, &cmdheight, msg) |
| call assert_equal(rowstatusline, winheight(0) + 1, msg) |
| call MouseLeftRelease(row, col) |
| call assert_equal(1, &cmdheight, msg) |
| call assert_equal(rowstatusline, winheight(0) + 1, msg) |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| call test_override('no_query_mouse', 0) |
| let &laststatus = save_laststatus |
| endfunc |
| |
| func Test_term_mouse_click_tab() |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=xterm |
| call WaitForResponses() |
| |
| let row = 1 |
| |
| for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| e Xfoo |
| tabnew Xbar |
| |
| let a = split(execute(':tabs'), "\n") |
| call assert_equal(['Tab page 1', |
| \ ' Xfoo', |
| \ 'Tab page 2', |
| \ '> Xbar'], a, msg) |
| |
| " Test clicking on tab names in the tabline at the top. |
| let col = 2 |
| redraw |
| call MouseLeftClick(row, col) |
| call MouseLeftRelease(row, col) |
| let a = split(execute(':tabs'), "\n") |
| call assert_equal(['Tab page 1', |
| \ '> Xfoo', |
| \ 'Tab page 2', |
| \ ' Xbar'], a, msg) |
| |
| let col = 9 |
| call MouseLeftClick(row, col) |
| call MouseLeftRelease(row, col) |
| let a = split(execute(':tabs'), "\n") |
| call assert_equal(['Tab page 1', |
| \ ' Xfoo', |
| \ 'Tab page 2', |
| \ '> Xbar'], a, msg) |
| |
| %bwipe! |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| call test_override('no_query_mouse', 0) |
| endfunc |
| |
| func Test_term_mouse_click_X_to_close_tab() |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=xterm |
| call WaitForResponses() |
| |
| let row = 1 |
| let col = &columns |
| |
| for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm |
| if ttymouse_val ==# 'xterm2' && col > 223 |
| " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported. |
| continue |
| endif |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| e Xtab1 |
| tabnew Xtab2 |
| tabnew Xtab3 |
| tabn 2 |
| |
| let a = split(execute(':tabs'), "\n") |
| call assert_equal(['Tab page 1', |
| \ ' Xtab1', |
| \ 'Tab page 2', |
| \ '> Xtab2', |
| \ 'Tab page 3', |
| \ ' Xtab3'], a, msg) |
| |
| " Click on "X" in tabline to close current tab i.e. Xtab2. |
| redraw |
| call MouseLeftClick(row, col) |
| call MouseLeftRelease(row, col) |
| let a = split(execute(':tabs'), "\n") |
| call assert_equal(['Tab page 1', |
| \ ' Xtab1', |
| \ 'Tab page 2', |
| \ '> Xtab3'], a, msg) |
| |
| %bwipe! |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| call test_override('no_query_mouse', 0) |
| endfunc |
| |
| func Test_term_mouse_drag_to_move_tab() |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| " Set 'mousetime' to 1 to avoid recognizing a double-click in the loop |
| set mouse=a term=xterm mousetime=1 |
| call WaitForResponses() |
| |
| let row = 1 |
| |
| for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| e Xtab1 |
| tabnew Xtab2 |
| |
| let a = split(execute(':tabs'), "\n") |
| call assert_equal(['Tab page 1', |
| \ ' Xtab1', |
| \ 'Tab page 2', |
| \ '> Xtab2'], a, msg) |
| redraw |
| |
| " Click in tab2 and drag it to tab1. |
| " Check getcharmod() to verify that click is not |
| " interpreted as a spurious double-click. |
| call MouseLeftClick(row, 10) |
| call assert_equal(0, getcharmod(), msg) |
| for col in [9, 8, 7, 6] |
| call MouseLeftDrag(row, col) |
| endfor |
| call MouseLeftRelease(row, col) |
| let a = split(execute(':tabs'), "\n") |
| call assert_equal(['Tab page 1', |
| \ '> Xtab2', |
| \ 'Tab page 2', |
| \ ' Xtab1'], a, msg) |
| |
| " Switch to tab1 |
| tabnext |
| let a = split(execute(':tabs'), "\n") |
| call assert_equal(['Tab page 1', |
| \ ' Xtab2', |
| \ 'Tab page 2', |
| \ '> Xtab1'], a, msg) |
| |
| " Click in tab2 and drag it to tab1. |
| " This time it is non-current tab. |
| call MouseLeftClick(row, 6) |
| call assert_equal(0, getcharmod(), msg) |
| for col in [7, 8, 9, 10] |
| call MouseLeftDrag(row, col) |
| endfor |
| call MouseLeftRelease(row, col) |
| let a = split(execute(':tabs'), "\n") |
| call assert_equal(['Tab page 1', |
| \ ' Xtab1', |
| \ 'Tab page 2', |
| \ '> Xtab2'], a, msg) |
| |
| " Click elsewhere so that click in next iteration is not |
| " interpreted as unwanted double-click. |
| call MouseLeftClick(row, 11) |
| call MouseLeftRelease(row, 11) |
| |
| %bwipe! |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| call test_override('no_query_mouse', 0) |
| set mousetime& |
| endfunc |
| |
| func Test_term_mouse_double_click_to_create_tab() |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| " Set 'mousetime' to a small value, so that double-click works but we don't |
| " have to wait long to avoid a triple-click. |
| set mouse=a term=xterm mousetime=200 |
| call WaitForResponses() |
| |
| let row = 1 |
| let col = 10 |
| |
| for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| e Xtab1 |
| tabnew Xtab2 |
| |
| let a = split(execute(':tabs'), "\n") |
| call assert_equal(['Tab page 1', |
| \ ' Xtab1', |
| \ 'Tab page 2', |
| \ '> Xtab2'], a, msg) |
| |
| redraw |
| call MouseLeftClick(row, col) |
| " Check getcharmod() to verify that first click is not |
| " interpreted as a spurious double-click. |
| call assert_equal(0, getcharmod(), msg) |
| call MouseLeftRelease(row, col) |
| call MouseLeftClick(row, col) |
| call assert_equal(32, getcharmod(), msg) " double-click |
| call MouseLeftRelease(row, col) |
| let a = split(execute(':tabs'), "\n") |
| call assert_equal(['Tab page 1', |
| \ ' Xtab1', |
| \ 'Tab page 2', |
| \ '> [No Name]', |
| \ 'Tab page 3', |
| \ ' Xtab2'], a, msg) |
| |
| " Click elsewhere so that click in next iteration is not |
| " interpreted as unwanted double click. |
| call MouseLeftClick(row, col + 1) |
| call MouseLeftRelease(row, col + 1) |
| |
| %bwipe! |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| call test_override('no_query_mouse', 0) |
| set mousetime& |
| endfunc |
| |
| " Test double/triple/quadruple click in normal mode to visually select. |
| func Test_term_mouse_multiple_clicks_to_visually_select() |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| |
| " 'mousetime' must be sufficiently large, or else the test is flaky when |
| " using a ssh connection with X forwarding; i.e. ssh -X (issue #7563). |
| set mouse=a term=xterm mousetime=600 |
| call WaitForResponses() |
| |
| new |
| |
| for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| call setline(1, ['foo [foo bar] foo', 'foo']) |
| |
| " Double-click on word should visually select the word. |
| call MouseLeftClick(1, 2) |
| call assert_equal(0, getcharmod(), msg) |
| call MouseLeftRelease(1, 2) |
| call MouseLeftClick(1, 2) |
| call assert_equal(32, getcharmod(), msg) " double-click |
| call MouseLeftRelease(1, 2) |
| call assert_equal('v', mode(), msg) |
| norm! r1 |
| call assert_equal(['111 [foo bar] foo', 'foo'], getline(1, '$'), msg) |
| |
| " Double-click on opening square bracket should visually |
| " select the whole [foo bar]. |
| call MouseLeftClick(1, 5) |
| call assert_equal(0, getcharmod(), msg) |
| call MouseLeftRelease(1, 5) |
| call MouseLeftClick(1, 5) |
| call assert_equal(32, getcharmod(), msg) " double-click |
| call MouseLeftRelease(1, 5) |
| call assert_equal('v', mode(), msg) |
| norm! r2 |
| call assert_equal(['111 222222222 foo', 'foo'], getline(1, '$'), msg) |
| |
| " Triple-click should visually select the whole line. |
| call MouseLeftClick(1, 3) |
| call assert_equal(0, getcharmod(), msg) |
| call MouseLeftRelease(1, 3) |
| call MouseLeftClick(1, 3) |
| call assert_equal(32, getcharmod(), msg) " double-click |
| call MouseLeftRelease(1, 3) |
| call MouseLeftClick(1, 3) |
| call assert_equal(64, getcharmod(), msg) " triple-click |
| call MouseLeftRelease(1, 3) |
| call assert_equal('V', mode(), msg) |
| norm! r3 |
| call assert_equal(['33333333333333333', 'foo'], getline(1, '$'), msg) |
| |
| " Quadruple-click should start visual block select. |
| call MouseLeftClick(1, 2) |
| call assert_equal(0, getcharmod(), msg) |
| call MouseLeftRelease(1, 2) |
| call MouseLeftClick(1, 2) |
| call assert_equal(32, getcharmod(), msg) " double-click |
| call MouseLeftRelease(1, 2) |
| call MouseLeftClick(1, 2) |
| call assert_equal(64, getcharmod(), msg) " triple-click |
| call MouseLeftRelease(1, 2) |
| call MouseLeftClick(1, 2) |
| call assert_equal(96, getcharmod(), msg) " quadruple-click |
| call MouseLeftRelease(1, 2) |
| call assert_equal("\<c-v>", mode(), msg) |
| norm! r4 |
| call assert_equal(['34333333333333333', 'foo'], getline(1, '$'), msg) |
| |
| " Double-click on a space character should visually select all the |
| " consecutive space characters. |
| %d |
| call setline(1, ' one two') |
| call MouseLeftClick(1, 2) |
| call MouseLeftRelease(1, 2) |
| call MouseLeftClick(1, 2) |
| call MouseLeftRelease(1, 2) |
| call assert_equal('v', mode(), msg) |
| norm! r1 |
| call assert_equal(['1111one two'], getline(1, '$'), msg) |
| |
| " Double-click on a word with exclusive selection |
| set selection=exclusive |
| let @" = '' |
| call MouseLeftClick(1, 10) |
| call MouseLeftRelease(1, 10) |
| call MouseLeftClick(1, 10) |
| call MouseLeftRelease(1, 10) |
| norm! y |
| call assert_equal('two', @", msg) |
| |
| " Double click to select a block of text with exclusive selection |
| %d |
| call setline(1, 'one (two) three') |
| call MouseLeftClick(1, 5) |
| call MouseLeftRelease(1, 5) |
| call MouseLeftClick(1, 5) |
| call MouseLeftRelease(1, 5) |
| norm! y |
| call assert_equal(5, col("'<"), msg) |
| call assert_equal(10, col("'>"), msg) |
| |
| call MouseLeftClick(1, 9) |
| call MouseLeftRelease(1, 9) |
| call MouseLeftClick(1, 9) |
| call MouseLeftRelease(1, 9) |
| norm! y |
| call assert_equal(5, col("'<"), msg) |
| call assert_equal(10, col("'>"), msg) |
| set selection& |
| |
| " Click somewhere else so that the clicks above is not combined with the |
| " clicks in the next iteration. |
| call MouseRightClick(3, 10) |
| call MouseRightRelease(3, 10) |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| set mousetime& |
| call test_override('no_query_mouse', 0) |
| bwipe! |
| endfunc |
| |
| " Test for selecting text in visual blockwise mode using Alt-LeftClick |
| func Test_mouse_alt_leftclick() |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=xterm mousetime=200 |
| set mousemodel=popup |
| call WaitForResponses() |
| |
| new |
| call setline(1, 'one (two) three') |
| |
| for ttymouse_val in g:Ttymouse_values |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| |
| " Left click with the Alt modifier key should extend the selection in |
| " blockwise visual mode. |
| let @" = '' |
| call MouseLeftClick(1, 3) |
| call MouseLeftRelease(1, 3) |
| call MouseAltLeftClick(1, 11) |
| call MouseLeftRelease(1, 11) |
| call assert_equal("\<C-V>", mode(), msg) |
| normal! y |
| call assert_equal('e (two) t', @") |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| set mousetime& mousemodel& |
| call test_override('no_query_mouse', 0) |
| bw! |
| endfunc |
| |
| func Test_xterm_mouse_click_in_fold_columns() |
| new |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| let save_foldcolumn = &foldcolumn |
| set mouse=a term=xterm foldcolumn=3 ttymouse=xterm2 |
| call WaitForResponses() |
| |
| " Create 2 nested folds. |
| call setline(1, range(1, 7)) |
| 2,6fold |
| norm! zR |
| 4,5fold |
| call assert_equal([-1, -1, -1, 4, 4, -1, -1], |
| \ map(range(1, 7), 'foldclosed(v:val)')) |
| |
| " Click in "+" of inner fold in foldcolumn should open it. |
| redraw |
| let row = 4 |
| let col = 2 |
| call MouseLeftClick(row, col) |
| call MouseLeftRelease(row, col) |
| call assert_equal([-1, -1, -1, -1, -1, -1, -1], |
| \ map(range(1, 7), 'foldclosed(v:val)')) |
| |
| " Click in "-" of outer fold in foldcolumn should close it. |
| redraw |
| let row = 2 |
| let col = 1 |
| call MouseLeftClick(row, col) |
| call MouseLeftRelease(row, col) |
| call assert_equal([-1, 2, 2, 2, 2, 2, -1], |
| \ map(range(1, 7), 'foldclosed(v:val)')) |
| norm! zR |
| |
| " Click in "|" of inner fold in foldcolumn should close it. |
| redraw |
| let row = 5 |
| let col = 2 |
| call MouseLeftClick(row, col) |
| call MouseLeftRelease(row, col) |
| call assert_equal([-1, -1, -1, 4, 4, -1, -1], |
| \ map(range(1, 7), 'foldclosed(v:val)')) |
| |
| let &foldcolumn = save_foldcolumn |
| let &ttymouse = save_ttymouse |
| let &term = save_term |
| let &mouse = save_mouse |
| bwipe! |
| endfunc |
| |
| " Left or right click in Ex command line sets position of the cursor. |
| func Test_term_mouse_click_in_cmdline_to_set_pos() |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=xterm |
| call WaitForResponses() |
| |
| let row = &lines |
| |
| for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec |
| " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported. |
| if ttymouse_val !=# 'xterm2' || row <= 223 |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| |
| |
| call feedkeys(':"3456789' |
| \ .. MouseLeftClickCode(row, 7) |
| \ .. MouseLeftReleaseCode(row, 7) .. 'L' |
| \ .. MouseRightClickCode(row, 4) |
| \ .. MouseRightReleaseCode(row, 4) .. 'R' |
| \ .. "\<CR>", 'Lx!') |
| call assert_equal('"3R456L789', @:, msg) |
| endif |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| set mousetime& |
| call test_override('no_query_mouse', 0) |
| endfunc |
| |
| " Middle click in command line pastes at position of cursor. |
| func Test_term_mouse_middle_click_in_cmdline_to_paste() |
| CheckFeature clipboard_working |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=xterm |
| call WaitForResponses() |
| |
| let row = &lines |
| " Column values does not matter, paste is done at position of cursor. |
| let col = 1 |
| let @* = 'paste' |
| |
| for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| |
| call feedkeys(":\"->" |
| \ .. MouseMiddleReleaseCode(row, col) |
| \ .. MouseMiddleClickCode(row, col) |
| \ .. "<-" |
| \ .. MouseMiddleReleaseCode(row, col) |
| \ .. MouseMiddleClickCode(row, col) |
| \ .. "\<CR>", 'Lx!') |
| call assert_equal('"->paste<-paste', @:, msg) |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| let @* = '' |
| call test_override('no_query_mouse', 0) |
| endfunc |
| |
| " Test for making sure S-Middlemouse doesn't do anything |
| func Test_term_mouse_shift_middle_click() |
| new |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=xterm ttymouse=xterm2 mousemodel= |
| call WaitForResponses() |
| |
| call test_setmouse(1, 1) |
| exe "normal \<S-MiddleMouse>" |
| call assert_equal([''], getline(1, '$')) |
| call assert_equal(1, winnr()) |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| set mousemodel& |
| call test_override('no_query_mouse', 0) |
| close! |
| endfunc |
| |
| " Test for using mouse in visual mode |
| func Test_term_mouse_visual_mode() |
| new |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set term=xterm ttymouse=xterm2 |
| call WaitForResponses() |
| |
| " If visual mode is not present in 'mouse', then left click should not |
| " do anything in visal mode. |
| call setline(1, ['one two three four']) |
| set mouse=nci |
| call cursor(1, 5) |
| let @" = '' |
| call feedkeys("ve" |
| \ .. MouseLeftClickCode(1, 15) .. MouseLeftReleaseCode(1, 15) |
| \ .. 'y', 'Lx!') |
| call assert_equal(5, col('.')) |
| call assert_equal('two', @") |
| |
| " Pressing right click in visual mode should change the visual selection |
| " if 'mousemodel' doesn't contain popup. |
| " Right click after the visual selection |
| set mousemodel= |
| set mouse=a |
| call test_setmouse(1, 13) |
| exe "normal 5|ve\<RightMouse>y" |
| call assert_equal('two three', @") |
| call assert_equal(5, col('.')) |
| |
| " Right click before the visual selection |
| call test_setmouse(1, 9) |
| exe "normal 15|ve\<RightMouse>y" |
| call assert_equal('three four', @") |
| call assert_equal(9, col('.')) |
| |
| " Right click inside the selection closer to the start of the selection |
| call test_setmouse(1, 7) |
| exe "normal 5|vee\<RightMouse>lly" |
| call assert_equal('three', @") |
| call assert_equal(9, col('.')) |
| call assert_equal(9, col("'<")) |
| call assert_equal(13, col("'>")) |
| |
| " Right click inside the selection closer to the end of the selection |
| call test_setmouse(1, 11) |
| exe "normal 5|vee\<RightMouse>ly" |
| call assert_equal('two thre', @") |
| call assert_equal(5, col('.')) |
| call assert_equal(5, col("'<")) |
| call assert_equal(12, col("'>")) |
| |
| " Multi-line selection. Right click inside the selection. |
| call setline(1, repeat(['aaaaaa'], 7)) |
| call test_setmouse(3, 1) |
| exe "normal ggVG\<RightMouse>y" |
| call assert_equal(3, line("'<")) |
| call test_setmouse(5, 1) |
| exe "normal ggVG\<RightMouse>y" |
| call assert_equal(5, line("'>")) |
| |
| " Click right in the middle line of the selection |
| call test_setmouse(4, 3) |
| exe "normal ggVG$\<RightMouse>y" |
| call assert_equal(4, line("'<")) |
| call test_setmouse(4, 4) |
| exe "normal ggVG$\<RightMouse>y" |
| call assert_equal(4, line("'>")) |
| |
| set mousemodel& |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| call test_override('no_query_mouse', 0) |
| bw! |
| endfunc |
| |
| " Test for displaying the popup menu using the right mouse click |
| func Test_term_mouse_popup_menu() |
| CheckFeature menu |
| new |
| call setline(1, 'popup menu test') |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| let save_mousemodel = &mousemodel |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=xterm mousemodel=popup |
| call WaitForResponses() |
| |
| menu PopUp.foo :let g:menustr = 'foo'<CR> |
| menu PopUp.bar :let g:menustr = 'bar'<CR> |
| menu PopUp.baz :let g:menustr = 'baz'<CR> |
| |
| for ttymouse_val in g:Ttymouse_values |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| let g:menustr = '' |
| call feedkeys(MouseRightClickCode(1, 4) |
| \ .. MouseRightReleaseCode(1, 4) .. "\<Down>\<Down>\<CR>", "x") |
| call assert_equal('bar', g:menustr, msg) |
| endfor |
| |
| unmenu PopUp |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| let &mousemodel = save_mousemodel |
| call test_override('no_query_mouse', 0) |
| bw! |
| endfunc |
| |
| " Test for 'mousemodel' set to popup_setpos to move the cursor where the popup |
| " menu is displayed. |
| func Test_term_mouse_popup_menu_setpos() |
| CheckFeature menu |
| 5new |
| call setline(1, ['the dish ran away with the spoon', |
| \ 'the cow jumped over the moon' ]) |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| let save_mousemodel = &mousemodel |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=xterm mousemodel=popup_setpos |
| call WaitForResponses() |
| |
| nmenu PopUp.foo :let g:menustr = 'foo'<CR> |
| nmenu PopUp.bar :let g:menustr = 'bar'<CR> |
| nmenu PopUp.baz :let g:menustr = 'baz'<CR> |
| vmenu PopUp.foo y:<C-U>let g:menustr = 'foo'<CR> |
| vmenu PopUp.bar y:<C-U>let g:menustr = 'bar'<CR> |
| vmenu PopUp.baz y:<C-U>let g:menustr = 'baz'<CR> |
| |
| for ttymouse_val in g:Ttymouse_values |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| let g:menustr = '' |
| call cursor(1, 1) |
| call feedkeys(MouseRightClickCode(1, 5) |
| \ .. MouseRightReleaseCode(1, 5) .. "\<Down>\<Down>\<CR>", "x") |
| call assert_equal('bar', g:menustr, msg) |
| call assert_equal([1, 5], [line('.'), col('.')], msg) |
| |
| " Test for right click in visual mode inside the selection |
| let @" = '' |
| call cursor(1, 10) |
| call feedkeys('vee' .. MouseRightClickCode(1, 12) |
| \ .. MouseRightReleaseCode(1, 12) .. "\<Down>\<CR>", "x") |
| call assert_equal([1, 10], [line('.'), col('.')], msg) |
| call assert_equal('ran away', @", msg) |
| |
| " Test for right click in visual mode right before the selection |
| let @" = '' |
| call cursor(1, 10) |
| call feedkeys('vee' .. MouseRightClickCode(1, 9) |
| \ .. MouseRightReleaseCode(1, 9) .. "\<Down>\<CR>", "x") |
| call assert_equal([1, 9], [line('.'), col('.')], msg) |
| call assert_equal('', @", msg) |
| |
| " Test for right click in visual mode right after the selection |
| let @" = '' |
| call cursor(1, 10) |
| call feedkeys('vee' .. MouseRightClickCode(1, 18) |
| \ .. MouseRightReleaseCode(1, 18) .. "\<Down>\<CR>", "x") |
| call assert_equal([1, 18], [line('.'), col('.')], msg) |
| call assert_equal('', @", msg) |
| |
| " Test for right click in block-wise visual mode inside the selection |
| let @" = '' |
| call cursor(1, 16) |
| call feedkeys("\<C-V>j3l" .. MouseRightClickCode(2, 17) |
| \ .. MouseRightReleaseCode(2, 17) .. "\<Down>\<CR>", "x") |
| call assert_equal([1, 16], [line('.'), col('.')], msg) |
| call assert_equal("\<C-V>4", getregtype('"'), msg) |
| |
| " Test for right click in block-wise visual mode outside the selection |
| let @" = '' |
| call cursor(1, 16) |
| call feedkeys("\<C-V>j3l" .. MouseRightClickCode(2, 2) |
| \ .. MouseRightReleaseCode(2, 2) .. "\<Down>\<CR>", "x") |
| call assert_equal([2, 2], [line('.'), col('.')], msg) |
| call assert_equal('v', getregtype('"'), msg) |
| call assert_equal('', @", msg) |
| |
| " Test for right click in line-wise visual mode inside the selection |
| let @" = '' |
| call cursor(1, 16) |
| call feedkeys("V" .. MouseRightClickCode(1, 10) |
| \ .. MouseRightReleaseCode(1, 10) .. "\<Down>\<CR>", "x") |
| call assert_equal([1, 1], [line('.'), col('.')], msg) " After yanking, the cursor goes to 1,1 |
| call assert_equal("V", getregtype('"'), msg) |
| call assert_equal(1, len(getreg('"', 1, v:true)), msg) |
| |
| " Test for right click in multi-line line-wise visual mode inside the selection |
| let @" = '' |
| call cursor(1, 16) |
| call feedkeys("Vj" .. MouseRightClickCode(2, 20) |
| \ .. MouseRightReleaseCode(2, 20) .. "\<Down>\<CR>", "x") |
| call assert_equal([1, 1], [line('.'), col('.')], msg) " After yanking, the cursor goes to 1,1 |
| call assert_equal("V", getregtype('"'), msg) |
| call assert_equal(2, len(getreg('"', 1, v:true)), msg) |
| |
| " Test for right click in line-wise visual mode outside the selection |
| let @" = '' |
| call cursor(1, 16) |
| call feedkeys("V" .. MouseRightClickCode(2, 10) |
| \ .. MouseRightReleaseCode(2, 10) .. "\<Down>\<CR>", "x") |
| call assert_equal([2, 10], [line('.'), col('.')], msg) |
| call assert_equal("", @", msg) |
| |
| " Try clicking on the status line |
| let @" = '' |
| call cursor(1, 10) |
| call feedkeys('vee' .. MouseRightClickCode(6, 2) |
| \ .. MouseRightReleaseCode(6, 2) .. "\<Down>\<CR>", "x") |
| call assert_equal([1, 10], [line('.'), col('.')], msg) |
| call assert_equal('ran away', @", msg) |
| |
| " Try clicking outside the window |
| let @" = '' |
| call cursor(2, 2) |
| call feedkeys('vee' .. MouseRightClickCode(7, 2) |
| \ .. MouseRightReleaseCode(7, 2) .. "\<Down>\<CR>", "x") |
| call assert_equal(2, winnr(), msg) |
| call assert_equal('', @", msg) |
| wincmd w |
| endfor |
| |
| unmenu PopUp |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| let &mousemodel = save_mousemodel |
| call test_override('no_query_mouse', 0) |
| bw! |
| endfunc |
| |
| " Test for searching for the word under the cursor using Shift-Right or |
| " Shift-Left click. |
| func Test_term_mouse_search() |
| new |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=xterm ttymouse=xterm2 |
| set mousemodel= |
| call WaitForResponses() |
| |
| " In normal mode, Shift-Left or Shift-Right click should search for the word |
| " under the cursor. |
| call setline(1, ['one two three four', 'four three two one']) |
| call test_setmouse(1, 4) |
| exe "normal \<S-LeftMouse>" |
| call assert_equal([2, 12], [line('.'), col('.')]) |
| call test_setmouse(2, 16) |
| exe "normal \<S-RightMouse>" |
| call assert_equal([1, 1], [line('.'), col('.')]) |
| |
| " In visual mode, Shift-Left or Shift-Right click should search for the word |
| " under the cursor and extend the selection. |
| call test_setmouse(1, 4) |
| exe "normal 4|ve\<S-LeftMouse>y" |
| call assert_equal([2, 12], [line("'>"), col("'>")]) |
| call test_setmouse(2, 16) |
| exe "normal 2G16|ve\<S-RightMouse>y" |
| call assert_equal([1, 1], [line("'<"), col("'<")]) |
| |
| set mousemodel& |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| call test_override('no_query_mouse', 0) |
| bw! |
| endfunc |
| |
| " Test for selecting an entry in the quickfix/location list window using the |
| " mouse. |
| func Test_term_mouse_quickfix_window() |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=xterm ttymouse=xterm2 |
| set mousemodel= |
| call WaitForResponses() |
| |
| cgetexpr "Xfile1:1:L1" |
| copen 5 |
| call test_setmouse(&lines - 7, 1) |
| exe "normal \<2-LeftMouse>" |
| call assert_equal('Xfile1', @%) |
| %bw! |
| |
| lgetexpr "Xfile2:1:L1" |
| lopen 5 |
| call test_setmouse(&lines - 7, 1) |
| exe "normal \<2-LeftMouse>" |
| call assert_equal('Xfile2', @%) |
| %bw! |
| |
| set mousemodel& |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| call test_override('no_query_mouse', 0) |
| endfunc |
| |
| " Test for the 'h' flag in the 'mouse' option. Using mouse in the help window. |
| func Test_term_mouse_help_window() |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set mouse=h term=xterm mousetime=200 |
| call WaitForResponses() |
| |
| for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| help |
| let @" = '' |
| call MouseLeftClick(2, 5) |
| call MouseLeftRelease(2, 5) |
| call MouseLeftClick(1, 1) |
| call MouseLeftDrag(1, 10) |
| call MouseLeftRelease(1, 10) |
| norm! y |
| call assert_equal('*help.txt*', @", msg) |
| helpclose |
| |
| " Click somewhere else to make sure the left click above is not combined |
| " with the next left click and treated as a double click |
| call MouseRightClick(5, 10) |
| call MouseRightRelease(5, 10) |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| set mousetime& |
| call test_override('no_query_mouse', 0) |
| %bw! |
| endfunc |
| |
| " Test for the translation of various mouse terminal codes |
| func Test_mouse_termcodes() |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=xterm mousetime=200 |
| call WaitForResponses() |
| |
| new |
| for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| |
| let mouse_codes = [ |
| \ ["\<LeftMouse>", "<LeftMouse>"], |
| \ ["\<MiddleMouse>", "<MiddleMouse>"], |
| \ ["\<RightMouse>", "<RightMouse>"], |
| \ ["\<S-LeftMouse>", "<S-LeftMouse>"], |
| \ ["\<S-MiddleMouse>", "<S-MiddleMouse>"], |
| \ ["\<S-RightMouse>", "<S-RightMouse>"], |
| \ ["\<C-LeftMouse>", "<C-LeftMouse>"], |
| \ ["\<C-MiddleMouse>", "<C-MiddleMouse>"], |
| \ ["\<C-RightMouse>", "<C-RightMouse>"], |
| \ ["\<M-LeftMouse>", "<M-LeftMouse>"], |
| \ ["\<M-MiddleMouse>", "<M-MiddleMouse>"], |
| \ ["\<M-RightMouse>", "<M-RightMouse>"], |
| \ ["\<2-LeftMouse>", "<2-LeftMouse>"], |
| \ ["\<2-MiddleMouse>", "<2-MiddleMouse>"], |
| \ ["\<2-RightMouse>", "<2-RightMouse>"], |
| \ ["\<3-LeftMouse>", "<3-LeftMouse>"], |
| \ ["\<3-MiddleMouse>", "<3-MiddleMouse>"], |
| \ ["\<3-RightMouse>", "<3-RightMouse>"], |
| \ ["\<4-LeftMouse>", "<4-LeftMouse>"], |
| \ ["\<4-MiddleMouse>", "<4-MiddleMouse>"], |
| \ ["\<4-RightMouse>", "<4-RightMouse>"], |
| \ ["\<LeftDrag>", "<LeftDrag>"], |
| \ ["\<MiddleDrag>", "<MiddleDrag>"], |
| \ ["\<RightDrag>", "<RightDrag>"], |
| \ ["\<LeftRelease>", "<LeftRelease>"], |
| \ ["\<MiddleRelease>", "<MiddleRelease>"], |
| \ ["\<RightRelease>", "<RightRelease>"], |
| \ ["\<ScrollWheelUp>", "<ScrollWheelUp>"], |
| \ ["\<S-ScrollWheelUp>", "<S-ScrollWheelUp>"], |
| \ ["\<C-ScrollWheelUp>", "<C-ScrollWheelUp>"], |
| \ ["\<ScrollWheelDown>", "<ScrollWheelDown>"], |
| \ ["\<S-ScrollWheelDown>", "<S-ScrollWheelDown>"], |
| \ ["\<C-ScrollWheelDown>", "<C-ScrollWheelDown>"], |
| \ ["\<ScrollWheelLeft>", "<ScrollWheelLeft>"], |
| \ ["\<S-ScrollWheelLeft>", "<S-ScrollWheelLeft>"], |
| \ ["\<C-ScrollWheelLeft>", "<C-ScrollWheelLeft>"], |
| \ ["\<ScrollWheelRight>", "<ScrollWheelRight>"], |
| \ ["\<S-ScrollWheelRight>", "<S-ScrollWheelRight>"], |
| \ ["\<C-ScrollWheelRight>", "<C-ScrollWheelRight>"] |
| \ ] |
| |
| for [code, outstr] in mouse_codes |
| exe "normal ggC\<C-K>" . code |
| call assert_equal(outstr, getline(1), msg) |
| endfor |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| set mousetime& |
| call test_override('no_query_mouse', 0) |
| %bw! |
| endfunc |
| |
| " This only checks if the sequence is recognized. |
| func Test_term_rgb_response() |
| set t_RF=x |
| set t_RB=y |
| |
| " response to t_RF, 4 digits |
| let red = 0x12 |
| let green = 0x34 |
| let blue = 0x56 |
| let seq = printf("\<Esc>]10;rgb:%02x00/%02x00/%02x00\x07", red, green, blue) |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termrfgresp) |
| |
| " response to t_RF, 2 digits |
| let red = 0x78 |
| let green = 0x9a |
| let blue = 0xbc |
| let seq = printf("\<Esc>]10;rgb:%02x/%02x/%02x\x07", red, green, blue) |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termrfgresp) |
| |
| " response to t_RB, 4 digits, dark |
| set background=light |
| eval 'background'->test_option_not_set() |
| let red = 0x29 |
| let green = 0x4a |
| let blue = 0x6b |
| let seq = printf("\<Esc>]11;rgb:%02x00/%02x00/%02x00\x07", red, green, blue) |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termrbgresp) |
| call assert_equal('dark', &background) |
| |
| " response to t_RB, 4 digits, light |
| set background=dark |
| call test_option_not_set('background') |
| let red = 0x81 |
| let green = 0x63 |
| let blue = 0x65 |
| let seq = printf("\<Esc>]11;rgb:%02x00/%02x00/%02x00\x07", red, green, blue) |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termrbgresp) |
| call assert_equal('light', &background) |
| |
| " response to t_RB, 2 digits, dark |
| set background=light |
| call test_option_not_set('background') |
| let red = 0x47 |
| let green = 0x59 |
| let blue = 0x5b |
| let seq = printf("\<Esc>]11;rgb:%02x/%02x/%02x\x07", red, green, blue) |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termrbgresp) |
| call assert_equal('dark', &background) |
| |
| " response to t_RB, 2 digits, light |
| set background=dark |
| call test_option_not_set('background') |
| let red = 0x83 |
| let green = 0xa4 |
| let blue = 0xc2 |
| let seq = printf("\<Esc>]11;rgb:%02x/%02x/%02x\x07", red, green, blue) |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termrbgresp) |
| call assert_equal('light', &background) |
| |
| set t_RF= t_RB= |
| endfunc |
| |
| " This only checks if the sequence is recognized. |
| " This must be after other tests, because it has side effects to xterm |
| " properties. |
| func Test_xx01_term_style_response() |
| " Termresponse is only parsed when t_RV is not empty. |
| set t_RV=x |
| call test_override('term_props', 1) |
| |
| " send the termresponse to trigger requesting the XT codes |
| let seq = "\<Esc>[>41;337;0c" |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termresponse) |
| |
| let seq = "\<Esc>P1$r2 q\<Esc>\\" |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termstyleresp) |
| |
| call assert_equal(#{ |
| \ cursor_style: 'u', |
| \ cursor_blink_mode: 'u', |
| \ underline_rgb: 'u', |
| \ mouse: 's', |
| \ kitty: 'u', |
| \ }, terminalprops()) |
| |
| set t_RV= |
| call test_override('term_props', 0) |
| endfunc |
| |
| " This checks the iTerm2 version response. |
| " This must be after other tests, because it has side effects to xterm |
| " properties. |
| func Test_xx02_iTerm2_response() |
| " Termresponse is only parsed when t_RV is not empty. |
| set t_RV=x |
| call test_override('term_props', 1) |
| |
| " Old versions of iTerm2 used a different style term response. |
| set ttymouse=xterm |
| call test_option_not_set('ttymouse') |
| let seq = "\<Esc>[>0;95;c" |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termresponse) |
| call assert_equal('xterm', &ttymouse) |
| |
| set ttymouse=xterm |
| call test_option_not_set('ttymouse') |
| let seq = "\<Esc>[>0;95;0c" |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termresponse) |
| call assert_equal('sgr', &ttymouse) |
| |
| call assert_equal(#{ |
| \ cursor_style: 'n', |
| \ cursor_blink_mode: 'u', |
| \ underline_rgb: 'u', |
| \ mouse: 's', |
| \ kitty: 'u', |
| \ }, terminalprops()) |
| |
| set t_RV= |
| call test_override('term_props', 0) |
| endfunc |
| |
| func Run_libvterm_konsole_response(code) |
| set ttymouse=xterm |
| call test_option_not_set('ttymouse') |
| let seq = "\<Esc>[>0;" .. a:code .. ";0c" |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termresponse) |
| call assert_equal('sgr', &ttymouse) |
| |
| call assert_equal(#{ |
| \ cursor_style: 'n', |
| \ cursor_blink_mode: 'u', |
| \ underline_rgb: 'u', |
| \ mouse: 's', |
| \ kitty: 'u', |
| \ }, terminalprops()) |
| endfunc |
| |
| " This checks the libvterm version response. |
| " This must be after other tests, because it has side effects to xterm |
| " properties. |
| func Test_xx03_libvterm_konsole_response() |
| " Termresponse is only parsed when t_RV is not empty. |
| set t_RV=x |
| call test_override('term_props', 1) |
| |
| " libvterm |
| call Run_libvterm_konsole_response(100) |
| " Konsole |
| call Run_libvterm_konsole_response(115) |
| |
| set t_RV= |
| call test_override('term_props', 0) |
| endfunc |
| |
| " This checks the Mac Terminal.app version response. |
| " This must be after other tests, because it has side effects to xterm |
| " properties. |
| func Test_xx04_Mac_Terminal_response() |
| " Termresponse is only parsed when t_RV is not empty. |
| set t_RV=x |
| call test_override('term_props', 1) |
| |
| set ttymouse=xterm |
| " t_8u is not reset |
| let &t_8u = "\<Esc>[58;2;%lu;%lu;%lum" |
| call test_option_not_set('ttymouse') |
| let seq = "\<Esc>[>1;95;0c" |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termresponse) |
| call assert_equal('sgr', &ttymouse) |
| |
| call assert_equal(#{ |
| \ cursor_style: 'n', |
| \ cursor_blink_mode: 'u', |
| \ underline_rgb: 'y', |
| \ mouse: 's', |
| \ kitty: 'u', |
| \ }, terminalprops()) |
| call assert_equal("\<Esc>[58;2;%lu;%lu;%lum", &t_8u) |
| |
| " Reset is_not_xterm and is_mac_terminal. |
| set t_RV= |
| set term=xterm |
| set t_RV=x |
| call test_override('term_props', 0) |
| endfunc |
| |
| " This checks the mintty version response. |
| " This must be after other tests, because it has side effects to xterm |
| " properties. |
| func Test_xx05_mintty_response() |
| " Termresponse is only parsed when t_RV is not empty. |
| set t_RV=x |
| call test_override('term_props', 1) |
| |
| set ttymouse=xterm |
| call test_option_not_set('ttymouse') |
| let seq = "\<Esc>[>77;20905;0c" |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termresponse) |
| call assert_equal('sgr', &ttymouse) |
| |
| call assert_equal(#{ |
| \ cursor_style: 'n', |
| \ cursor_blink_mode: 'u', |
| \ underline_rgb: 'y', |
| \ mouse: 's', |
| \ kitty: 'u', |
| \ }, terminalprops()) |
| |
| set t_RV= |
| call test_override('term_props', 0) |
| endfunc |
| |
| " This checks the screen version response. |
| " This must be after other tests, because it has side effects to xterm |
| " properties. |
| func Test_xx06_screen_response() |
| " Termresponse is only parsed when t_RV is not empty. |
| set t_RV=x |
| call test_override('term_props', 1) |
| |
| " Old versions of screen don't support SGR mouse mode. |
| set ttymouse=xterm |
| call test_option_not_set('ttymouse') |
| let seq = "\<Esc>[>83;40500;0c" |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termresponse) |
| call assert_equal('xterm', &ttymouse) |
| |
| " screen supports SGR mouse mode starting in version 4.7. |
| set ttymouse=xterm |
| call test_option_not_set('ttymouse') |
| let seq = "\<Esc>[>83;40700;0c" |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termresponse) |
| call assert_equal('sgr', &ttymouse) |
| |
| call assert_equal(#{ |
| \ cursor_style: 'n', |
| \ cursor_blink_mode: 'n', |
| \ underline_rgb: 'y', |
| \ mouse: 's', |
| \ kitty: 'u', |
| \ }, terminalprops()) |
| |
| set t_RV= |
| call test_override('term_props', 0) |
| endfunc |
| |
| func Do_check_t_8u_set_reset(set_by_user) |
| set ttymouse=xterm |
| call test_option_not_set('ttymouse') |
| let default_value = "\<Esc>[58;2;%lu;%lu;%lum" |
| let &t_8u = default_value |
| if !a:set_by_user |
| call test_option_not_set('t_8u') |
| endif |
| let seq = "\<Esc>[>0;279;0c" |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termresponse) |
| call assert_equal('sgr', &ttymouse) |
| |
| call assert_equal(#{ |
| \ cursor_style: 'u', |
| \ cursor_blink_mode: 'u', |
| \ underline_rgb: 'u', |
| \ mouse: 's', |
| \ kitty: 'u', |
| \ }, terminalprops()) |
| call assert_equal(a:set_by_user ? default_value : '', &t_8u) |
| endfunc |
| |
| " This checks the xterm version response. |
| " This must be after other tests, because it has side effects to xterm |
| " properties. |
| func Test_xx07_xterm_response() |
| " Termresponse is only parsed when t_RV is not empty. |
| set t_RV=x |
| call test_override('term_props', 1) |
| |
| " Do Terminal.app first to check that is_mac_terminal is reset. |
| set ttymouse=xterm |
| call test_option_not_set('ttymouse') |
| let seq = "\<Esc>[>1;95;0c" |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termresponse) |
| call assert_equal('sgr', &ttymouse) |
| |
| " xterm < 95: "xterm" (actually unmodified) |
| set t_RV= |
| set term=xterm |
| call WaitForResponses() |
| |
| set t_RV=x |
| set ttymouse=xterm |
| call test_option_not_set('ttymouse') |
| let seq = "\<Esc>[>0;94;0c" |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termresponse) |
| call assert_equal('xterm', &ttymouse) |
| |
| call assert_equal(#{ |
| \ cursor_style: 'n', |
| \ cursor_blink_mode: 'u', |
| \ underline_rgb: 'y', |
| \ mouse: 'u', |
| \ kitty: 'u', |
| \ }, terminalprops()) |
| |
| " xterm >= 95 < 277 "xterm2" |
| set ttymouse=xterm |
| call test_option_not_set('ttymouse') |
| let seq = "\<Esc>[>0;267;0c" |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termresponse) |
| call assert_equal('xterm2', &ttymouse) |
| |
| call assert_equal(#{ |
| \ cursor_style: 'n', |
| \ cursor_blink_mode: 'u', |
| \ underline_rgb: 'u', |
| \ mouse: '2', |
| \ kitty: 'u', |
| \ }, terminalprops()) |
| |
| " xterm >= 277: "sgr" |
| set ttymouse=xterm |
| call test_option_not_set('ttymouse') |
| let seq = "\<Esc>[>0;277;0c" |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termresponse) |
| call assert_equal('sgr', &ttymouse) |
| |
| call assert_equal(#{ |
| \ cursor_style: 'n', |
| \ cursor_blink_mode: 'u', |
| \ underline_rgb: 'u', |
| \ mouse: 's', |
| \ kitty: 'u', |
| \ }, terminalprops()) |
| |
| " xterm >= 279: "sgr" and cursor_style not reset; also check t_8u reset, |
| " except when it was set by the user |
| call Do_check_t_8u_set_reset(0) |
| call Do_check_t_8u_set_reset(1) |
| |
| set t_RV= |
| call test_override('term_props', 0) |
| endfunc |
| |
| func Test_xx08_kitty_response() |
| " Termresponse is only parsed when t_RV is not empty. |
| set t_RV=x |
| call test_override('term_props', 1) |
| |
| set ttymouse=xterm |
| call test_option_not_set('ttymouse') |
| let seq = "\<Esc>[>1;4001;12c" |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termresponse) |
| call assert_equal('sgr', &ttymouse) |
| |
| call assert_equal(#{ |
| \ cursor_style: 'u', |
| \ cursor_blink_mode: 'u', |
| \ underline_rgb: 'y', |
| \ mouse: 's', |
| \ kitty: 'y', |
| \ }, terminalprops()) |
| |
| call feedkeys("\<Esc>[?1u") " simulate the kitty keyboard protocol is enabled |
| call feedkeys(':' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIuWithoutModifier("\<Esc>") .. "\<C-B>\"\<CR>", 'Lx!') |
| call assert_equal("\"\<Esc>", @:) |
| call feedkeys(':' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu("\<Esc>", '129') .. "\<C-B>\"\<CR>", 'Lx!') |
| call assert_equal("\"\<Esc>", @:) |
| |
| set t_RV= |
| call test_override('term_props', 0) |
| endfunc |
| |
| func Test_focus_events() |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| set term=xterm ttymouse=xterm2 |
| call WaitForResponses() |
| |
| au FocusGained * let g:focus_gained += 1 |
| au FocusLost * let g:focus_lost += 1 |
| let g:focus_gained = 0 |
| let g:focus_lost = 0 |
| |
| call feedkeys("\<Esc>[O", "Lx!") |
| call assert_equal(1, g:focus_lost) |
| call feedkeys("\<Esc>[I", "Lx!") |
| call assert_equal(1, g:focus_gained) |
| |
| " still works when 'ttymouse' is empty |
| set ttymouse= |
| call feedkeys("\<Esc>[O", "Lx!") |
| call assert_equal(2, g:focus_lost) |
| call feedkeys("\<Esc>[I", "Lx!") |
| call assert_equal(2, g:focus_gained) |
| |
| au! FocusGained |
| au! FocusLost |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| endfunc |
| |
| func Test_get_termcode() |
| try |
| let k1 = &t_k1 |
| catch /E113/ |
| throw 'Skipped: Unable to query termcodes' |
| endtry |
| set t_k1= |
| set t_k1& |
| call assert_equal(k1, &t_k1) |
| |
| " use external termcap first |
| set nottybuiltin |
| set t_k1= |
| set t_k1& |
| " when using external termcap may get something else, but it must not be |
| " empty, since we would fallback to the builtin one. |
| call assert_notequal('', &t_k1) |
| |
| if &term =~ 'xterm' |
| " use internal termcap first |
| let term_save = &term |
| let &term = 'builtin_' .. &term |
| set t_k1= |
| set t_k1& |
| call assert_equal(k1, &t_k1) |
| let &term = term_save |
| endif |
| |
| set ttybuiltin |
| endfunc |
| |
| func Test_list_builtin_terminals() |
| CheckRunVimInTerminal |
| |
| call RunVimInTerminal('', #{rows: 14}) |
| call term_sendkeys('', ":set cmdheight=3\<CR>") |
| call TermWait('', 100) |
| call term_sendkeys('', ":set term=xxx\<CR>") |
| call TermWait('', 100) |
| |
| " Check that the list ends in "builtin_dumb" and "builtin_debug". |
| let dumb_idx = 0 |
| for n in range(8, 12) |
| if term_getline('', n) =~ 'builtin_dumb' |
| let dumb_idx = n |
| break |
| endif |
| endfor |
| call assert_notequal(0, dumb_idx, 'builtin_dumb not found') |
| |
| call assert_match('builtin_dumb', term_getline('', dumb_idx)) |
| call assert_match('builtin_debug', term_getline('', dumb_idx + 1)) |
| call assert_match('Not found in termcap', term_getline('', dumb_idx + 2)) |
| |
| call StopVimInTerminal('') |
| endfunc |
| |
| " This checks the CSI sequences when in modifyOtherKeys mode. |
| " The mode doesn't need to be enabled, the codes are always detected. |
| func RunTest_modifyOtherKeys(func) |
| new |
| set timeoutlen=10 |
| |
| " Shift-X is sent as 'X' with the shift modifier |
| call feedkeys('a' .. a:func('X', 2) .. "\<Esc>", 'Lx!') |
| call assert_equal('X', getline(1)) |
| |
| " Ctrl-i is Tab |
| call setline(1, '') |
| call feedkeys('a' .. a:func('i', 5) .. "\<Esc>", 'Lx!') |
| call assert_equal("\t", getline(1)) |
| |
| " Ctrl-I is also Tab |
| call setline(1, '') |
| call feedkeys('a' .. a:func('I', 5) .. "\<Esc>", 'Lx!') |
| call assert_equal("\t", getline(1)) |
| |
| " Alt-x is ø |
| call setline(1, '') |
| call feedkeys('a' .. a:func('x', 3) .. "\<Esc>", 'Lx!') |
| call assert_equal("ø", getline(1)) |
| |
| " Meta-x is also ø |
| call setline(1, '') |
| call feedkeys('a' .. a:func('x', 9) .. "\<Esc>", 'Lx!') |
| call assert_equal("ø", getline(1)) |
| |
| " Alt-X is Ø |
| call setline(1, '') |
| call feedkeys('a' .. a:func('X', 3) .. "\<Esc>", 'Lx!') |
| call assert_equal("Ø", getline(1)) |
| |
| " Meta-X is ø |
| call setline(1, '') |
| call feedkeys('a' .. a:func('X', 9) .. "\<Esc>", 'Lx!') |
| call assert_equal("Ø", getline(1)) |
| |
| " Ctrl-6 is Ctrl-^ |
| split aaa |
| edit bbb |
| call feedkeys(a:func('6', 5), 'Lx!') |
| call assert_equal("aaa", bufname()) |
| bwipe aaa |
| bwipe bbb |
| |
| " Ctrl-V X 33 is 3 |
| call setline(1, '') |
| call feedkeys("a\<C-V>" .. a:func('X', 2) .. "33\<Esc>", 'Lx!') |
| call assert_equal("3", getline(1)) |
| |
| " Ctrl-V U 12345 is Unicode 12345 |
| call setline(1, '') |
| call feedkeys("a\<C-V>" .. a:func('U', 2) .. "12345\<Esc>", 'Lx!') |
| call assert_equal("\U12345", getline(1)) |
| |
| bwipe! |
| set timeoutlen& |
| endfunc |
| |
| func Test_modifyOtherKeys_basic() |
| call RunTest_modifyOtherKeys(function('GetEscCodeCSI27')) |
| call RunTest_modifyOtherKeys(function('GetEscCodeCSIu')) |
| endfunc |
| |
| func Test_modifyOtherKeys_no_mapping() |
| set timeoutlen=10 |
| |
| let @a = 'aaa' |
| call feedkeys(":let x = '" .. GetEscCodeCSI27('R', 5) .. GetEscCodeCSI27('R', 5) .. "a'\<CR>", 'Lx!') |
| call assert_equal("let x = 'aaa'", @:) |
| |
| new |
| call feedkeys("a" .. GetEscCodeCSI27('R', 5) .. GetEscCodeCSI27('R', 5) .. "a\<Esc>", 'Lx!') |
| call assert_equal("aaa", getline(1)) |
| bwipe! |
| |
| new |
| call feedkeys("axx\<CR>yy" .. GetEscCodeCSI27('G', 5) .. GetEscCodeCSI27('K', 5) .. "a\<Esc>", 'Lx!') |
| call assert_equal("axx", getline(1)) |
| call assert_equal("yy", getline(2)) |
| bwipe! |
| |
| set timeoutlen& |
| endfunc |
| |
| func Test_CSIu_keys_without_modifiers() |
| " make this execute faster |
| set timeoutlen=10 |
| |
| call WaitForResponses() |
| |
| " Escape sent as `CSI 27 u` should act as normal escape and not undo |
| call setline(1, 'a') |
| call feedkeys('a' .. GetEscCodeCSIuWithoutModifier("\e"), 'Lx!') |
| call assert_equal('n', mode()) |
| call assert_equal('a', getline(1)) |
| |
| " Tab sent as `CSI 9 u` should work |
| call setline(1, '') |
| call feedkeys('a' .. GetEscCodeCSIuWithoutModifier("\t") .. "\<Esc>", 'Lx!') |
| call assert_equal("\t", getline(1)) |
| |
| set timeoutlen& |
| endfunc |
| |
| " Check that when DEC mouse codes are recognized a special key is handled. |
| func Test_ignore_dec_mouse() |
| silent !infocmp gnome >/dev/null 2>&1 |
| if v:shell_error != 0 |
| throw 'Skipped: gnome entry missing in the terminfo db' |
| endif |
| |
| new |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| call test_override('no_query_mouse', 1) |
| set mouse=a term=gnome ttymouse= |
| call WaitForResponses() |
| |
| execute "set <xF1>=\<Esc>[1;*P" |
| nnoremap <S-F1> agot it<Esc> |
| call feedkeys("\<Esc>[1;2P", 'Lx!') |
| call assert_equal('got it', getline(1)) |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| call test_override('no_query_mouse', 0) |
| bwipe! |
| endfunc |
| |
| func RunTest_mapping_shift(key, func) |
| call setline(1, '') |
| if a:key == '|' |
| exe 'inoremap \| xyz' |
| else |
| exe 'inoremap ' .. a:key .. ' xyz' |
| endif |
| call feedkeys('a' .. a:func(a:key, 2) .. "\<Esc>", 'Lx!') |
| call assert_equal("xyz", getline(1)) |
| if a:key == '|' |
| exe 'iunmap \|' |
| else |
| exe 'iunmap ' .. a:key |
| endif |
| endfunc |
| |
| func Test_modifyOtherKeys_mapped() |
| set timeoutlen=10 |
| imap ' <C-W> |
| imap <C-W><C-A> c-a |
| call setline(1, '') |
| |
| " single quote is turned into single byte CTRL-W |
| " CTRL-A is added with a separate modifier, and needs to be simplified before |
| " the mapping can match. |
| call feedkeys("a'" .. GetEscCodeCSI27('A', 5) .. "\<Esc>", 'Lx!') |
| call assert_equal('c-a', getline(1)) |
| |
| iunmap ' |
| iunmap <C-W><C-A> |
| |
| " clean buffer |
| %d _ |
| imap B b |
| imap BBB blimp |
| let input = repeat(GetEscCodeCSI27('B', 2), 3) |
| call feedkeys("a" .. input .. "\<Esc>", 'Lx!') |
| call assert_equal('blimp', getline(1)) |
| " cleanup |
| iunmap BBB |
| iunmap B |
| set timeoutlen& |
| endfunc |
| |
| func Test_modifyOtherKeys_ambiguous_mapping() |
| new |
| set timeoutlen=10 |
| map <C-J> a |
| map <C-J>x <Nop> |
| call setline(1, 'x') |
| |
| " CTRL-J b should have trigger the <C-J> mapping and then insert "b" |
| call feedkeys(GetEscCodeCSI27('J', 5) .. "b\<Esc>", 'Lx!') |
| call assert_equal('xb', getline(1)) |
| |
| unmap <C-J> |
| unmap <C-J>x |
| |
| " if a special character is following there should be a check for a termcode |
| nnoremap s aX<Esc> |
| nnoremap s<BS> aY<Esc> |
| set t_kb= |
| call setline(1, 'x') |
| call feedkeys("s\x08", 'Lx!') |
| call assert_equal('xY', getline(1)) |
| |
| set timeoutlen& |
| bwipe! |
| endfunc |
| |
| " Whether Shift-Tab sends "ESC [ Z" or "ESC [ 27 ; 2 ; 9 ~" is unpredictable, |
| " both should work. |
| func Test_modifyOtherKeys_shift_tab() |
| set timeoutlen=10 |
| |
| call setline(1, '') |
| call feedkeys("a\<C-K>" .. GetEscCodeCSI27("\t", '2') .. "\<Esc>", 'Lx!') |
| eval getline(1)->assert_equal('<S-Tab>') |
| |
| call setline(1, '') |
| call feedkeys("a\<C-K>\<Esc>[Z\<Esc>", 'Lx!') |
| eval getline(1)->assert_equal('<S-Tab>') |
| |
| set timeoutlen& |
| bwipe! |
| endfunc |
| |
| func RunTest_mapping_works_with_shift(func) |
| new |
| set timeoutlen=10 |
| |
| call RunTest_mapping_shift('@', a:func) |
| call RunTest_mapping_shift('A', a:func) |
| call RunTest_mapping_shift('Z', a:func) |
| call RunTest_mapping_shift('^', a:func) |
| call RunTest_mapping_shift('_', a:func) |
| call RunTest_mapping_shift('{', a:func) |
| call RunTest_mapping_shift('|', a:func) |
| call RunTest_mapping_shift('}', a:func) |
| call RunTest_mapping_shift('~', a:func) |
| |
| bwipe! |
| set timeoutlen& |
| endfunc |
| |
| func Test_mapping_works_with_shift_plain() |
| call RunTest_mapping_works_with_shift(function('GetEscCodeCSI27')) |
| call RunTest_mapping_works_with_shift(function('GetEscCodeCSIu')) |
| endfunc |
| |
| func RunTest_mapping_mods(map, key, func, code) |
| call setline(1, '') |
| exe 'inoremap ' .. a:map .. ' xyz' |
| call feedkeys('a' .. a:func(a:key, a:code) .. "\<Esc>", 'Lx!') |
| call assert_equal("xyz", getline(1)) |
| exe 'iunmap ' .. a:map |
| endfunc |
| |
| func RunTest_mapping_works_with_mods(func, mods, code) |
| new |
| set timeoutlen=10 |
| |
| if a:mods !~ 'S' |
| " Shift by itself has no effect |
| call RunTest_mapping_mods('<' .. a:mods .. '-@>', '@', a:func, a:code) |
| endif |
| call RunTest_mapping_mods('<' .. a:mods .. '-A>', 'A', a:func, a:code) |
| call RunTest_mapping_mods('<' .. a:mods .. '-Z>', 'Z', a:func, a:code) |
| if a:mods !~ 'S' |
| " with Shift code is always upper case |
| call RunTest_mapping_mods('<' .. a:mods .. '-a>', 'a', a:func, a:code) |
| call RunTest_mapping_mods('<' .. a:mods .. '-z>', 'z', a:func, a:code) |
| endif |
| if a:mods != 'A' |
| " with Alt code is not in upper case |
| call RunTest_mapping_mods('<' .. a:mods .. '-a>', 'A', a:func, a:code) |
| call RunTest_mapping_mods('<' .. a:mods .. '-z>', 'Z', a:func, a:code) |
| endif |
| call RunTest_mapping_mods('<' .. a:mods .. '-á>', 'á', a:func, a:code) |
| if a:mods !~ 'S' |
| " Shift by itself has no effect |
| call RunTest_mapping_mods('<' .. a:mods .. '-^>', '^', a:func, a:code) |
| call RunTest_mapping_mods('<' .. a:mods .. '-_>', '_', a:func, a:code) |
| call RunTest_mapping_mods('<' .. a:mods .. '-{>', '{', a:func, a:code) |
| call RunTest_mapping_mods('<' .. a:mods .. '-\|>', '|', a:func, a:code) |
| call RunTest_mapping_mods('<' .. a:mods .. '-}>', '}', a:func, a:code) |
| call RunTest_mapping_mods('<' .. a:mods .. '-~>', '~', a:func, a:code) |
| endif |
| |
| bwipe! |
| set timeoutlen& |
| endfunc |
| |
| func Test_mapping_works_with_shift() |
| call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'S', 2) |
| call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'S', 2) |
| endfunc |
| |
| func Test_mapping_works_with_ctrl() |
| call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C', 5) |
| call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C', 5) |
| |
| new |
| set timeoutlen=10 |
| |
| " CTRL-@ actually produces the code for CTRL-2, which is converted |
| call RunTest_mapping_mods('<C-@>', '2', function('GetEscCodeCSI27'), 5) |
| call RunTest_mapping_mods('<C-@>', '2', function('GetEscCodeCSIu'), 5) |
| |
| " CTRL-^ actually produces the code for CTRL-6, which is converted |
| call RunTest_mapping_mods('<C-^>', '6', function('GetEscCodeCSI27'), 5) |
| call RunTest_mapping_mods('<C-^>', '6', function('GetEscCodeCSIu'), 5) |
| |
| " CTRL-_ actually produces the code for CTRL--, which is converted |
| call RunTest_mapping_mods('<C-_>', '-', function('GetEscCodeCSI27'), 5) |
| call RunTest_mapping_mods('<C-_>', '-', function('GetEscCodeCSIu'), 5) |
| |
| bwipe! |
| set timeoutlen& |
| endfunc |
| |
| func Test_mapping_works_with_shift_ctrl() |
| call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-S', 6) |
| call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-S', 6) |
| |
| new |
| set timeoutlen=10 |
| |
| " Ctrl-Shift-[ actually produces CTRL-Shift-{ which is mapped as <C-{> |
| call RunTest_mapping_mods('<C-{>', '{', function('GetEscCodeCSI27'), 6) |
| call RunTest_mapping_mods('<C-{>', '{', function('GetEscCodeCSIu'), 6) |
| |
| " Ctrl-Shift-] actually produces CTRL-Shift-} which is mapped as <C-}> |
| call RunTest_mapping_mods('<C-{>', '{', function('GetEscCodeCSI27'), 6) |
| call RunTest_mapping_mods('<C-{>', '{', function('GetEscCodeCSIu'), 6) |
| |
| " Ctrl-Shift-\ actually produces CTRL-Shift-| which is mapped as <C-|> |
| call RunTest_mapping_mods('<C-\|>', '|', function('GetEscCodeCSI27'), 6) |
| call RunTest_mapping_mods('<C-\|>', '|', function('GetEscCodeCSIu'), 6) |
| |
| bwipe! |
| set timeoutlen& |
| endfunc |
| |
| " Below we also test the "u" code with Alt, This works, but libvterm would not |
| " send the Alt key like this but by prefixing an Esc. |
| |
| func Test_mapping_works_with_alt() |
| call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'A', 3) |
| call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'A', 3) |
| endfunc |
| |
| func Test_mapping_works_with_shift_alt() |
| call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'S-A', 4) |
| call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'S-A', 4) |
| endfunc |
| |
| func Test_mapping_works_with_alt_and_shift() |
| new |
| set timeoutlen=10 |
| |
| " mapping <A-?> works even though the code is A-S-? |
| for c in ['!', '$', '+', ':', '?', '^', '~'] |
| call RunTest_mapping_mods('<A-' .. c .. '>', c, function('GetEscCodeCSI27'), 4) |
| call RunTest_mapping_mods('<A-' .. c .. '>', c, function('GetEscCodeCSIu'), 4) |
| endfor |
| |
| bwipe! |
| set timeoutlen& |
| endfunc |
| |
| func Test_mapping_works_with_ctrl_alt() |
| call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-A', 7) |
| call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-A', 7) |
| endfunc |
| |
| func Test_mapping_works_with_shift_ctrl_alt() |
| call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-S-A', 8) |
| call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-S-A', 8) |
| endfunc |
| |
| func Test_mapping_works_with_unknown_modifiers() |
| new |
| set timeoutlen=10 |
| |
| for Func in [function('GetEscCodeCSI27'), function('GetEscCodeCSIu')] |
| call RunTest_mapping_mods('<C-z>', 'z', Func, 5) |
| " Add 16, 32, 64 or 128 for modifiers we currently don't support. |
| call RunTest_mapping_mods('<C-z>', 'z', Func, 5 + 16) |
| call RunTest_mapping_mods('<C-z>', 'z', Func, 5 + 32) |
| call RunTest_mapping_mods('<C-z>', 'z', Func, 5 + 64) |
| call RunTest_mapping_mods('<C-z>', 'z', Func, 5 + 128) |
| |
| call RunTest_mapping_mods('<S-X>', 'X', Func, 2) |
| " Add 16, 32, 64 or 128 for modifiers we currently don't support. |
| call RunTest_mapping_mods('<S-X>', 'X', Func, 2 + 16) |
| call RunTest_mapping_mods('<S-X>', 'X', Func, 2 + 32) |
| call RunTest_mapping_mods('<S-X>', 'X', Func, 2 + 64) |
| call RunTest_mapping_mods('<S-X>', 'X', Func, 2 + 128) |
| endfor |
| |
| bwipe! |
| set timeoutlen& |
| endfunc |
| |
| func RunTest_mapping_funckey(map, func, key, code) |
| call setline(1, '') |
| exe 'inoremap ' .. a:map .. ' xyz' |
| call feedkeys('a' .. a:func(a:key, a:code) .. "\<Esc>", 'Lx!') |
| call assert_equal("xyz", getline(1), 'mapping ' .. a:map) |
| exe 'iunmap ' .. a:map |
| endfunc |
| |
| func Test_mapping_kitty_function_keys() |
| new |
| set timeoutlen=10 |
| |
| " Function keys made with CSI and ending in [ABCDEFHPQRS]. |
| " 'E' is keypad BEGIN, not supported |
| let maps = [ |
| \ ['<Up>', 'A', 0], |
| \ ['<S-Up>', 'A', 2], |
| \ ['<C-Up>', 'A', 5], |
| \ ['<C-S-Up>', 'A', 6], |
| \ |
| \ ['<Down>', 'B', 0], |
| \ ['<S-Down>', 'B', 2], |
| \ ['<C-Down>', 'B', 5], |
| \ ['<C-S-Down>', 'B', 6], |
| \ |
| \ ['<Right>', 'C', 0], |
| \ ['<S-Right>', 'C', 2], |
| \ ['<C-Right>', 'C', 5], |
| \ ['<C-S-Right>', 'C', 6], |
| \ |
| \ ['<Left>', 'D', 0], |
| \ ['<S-Left>', 'D', 2], |
| \ ['<C-Left>', 'D', 5], |
| \ ['<C-S-Left>', 'D', 6], |
| \ |
| \ ['<End>', 'F', 0], |
| \ ['<S-End>', 'F', 2], |
| \ ['<C-End>', 'F', 5], |
| \ ['<C-S-End>', 'F', 6], |
| \ |
| \ ['<Home>', 'H', 0], |
| \ ['<S-Home>', 'H', 2], |
| \ ['<C-Home>', 'H', 5], |
| \ ['<C-S-Home>', 'H', 6], |
| \ |
| \ ['<F1>', 'P', 0], |
| \ ['<S-F1>', 'P', 2], |
| \ ['<C-F1>', 'P', 5], |
| \ ['<C-S-F1>', 'P', 6], |
| \ |
| \ ['<F2>', 'Q', 0], |
| \ ['<S-F2>', 'Q', 2], |
| \ ['<C-F2>', 'Q', 5], |
| \ ['<C-S-F2>', 'Q', 6], |
| \ |
| \ ['<F3>', 'R', 0], |
| \ ['<S-F3>', 'R', 2], |
| \ ['<C-F3>', 'R', 5], |
| \ ['<C-S-F3>', 'R', 6], |
| \ |
| \ ['<F4>', 'S', 0], |
| \ ['<S-F4>', 'S', 2], |
| \ ['<C-F4>', 'S', 5], |
| \ ['<C-S-F4>', 'S', 6], |
| \ ] |
| |
| for map in maps |
| call RunTest_mapping_funckey(map[0], function('GetEscCodeFunckey'), map[1], map[2]) |
| endfor |
| |
| bwipe! |
| set timeoutlen& |
| endfunc |
| |
| func Test_insert_literal() |
| set timeoutlen=10 |
| |
| call WaitForResponses() |
| |
| new |
| " CTRL-V CTRL-X inserts a ^X |
| call feedkeys('a' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu('X', '5') .. "\<Esc>", 'Lx!') |
| call assert_equal("\<C-X>", getline(1)) |
| |
| call setline(1, '') |
| call feedkeys('a' .. GetEscCodeCSI27('V', '5') .. GetEscCodeCSI27('X', '5') .. "\<Esc>", 'Lx!') |
| call assert_equal("\<C-X>", getline(1)) |
| |
| " CTRL-SHIFT-V CTRL-X inserts escape sequence |
| call setline(1, '') |
| call feedkeys('a' .. GetEscCodeCSIu('V', '6') .. GetEscCodeCSIu('X', '5') .. "\<Esc>", 'Lx!') |
| call assert_equal("\<Esc>[88;5u", getline(1)) |
| |
| call setline(1, '') |
| call feedkeys('a' .. GetEscCodeCSI27('V', '6') .. GetEscCodeCSI27('X', '5') .. "\<Esc>", 'Lx!') |
| call assert_equal("\<Esc>[27;5;88~", getline(1)) |
| |
| bwipe! |
| set timeoutlen& |
| endfunc |
| |
| func Test_cmdline_literal() |
| set timeoutlen=10 |
| |
| " CTRL-V CTRL-Y inserts a ^Y |
| call feedkeys(':' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!') |
| call assert_equal("\"\<C-Y>", @:) |
| |
| call feedkeys(':' .. GetEscCodeCSI27('V', '5') .. GetEscCodeCSI27('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!') |
| call assert_equal("\"\<C-Y>", @:) |
| |
| " CTRL-SHIFT-V CTRL-Y inserts escape sequence |
| call feedkeys(':' .. GetEscCodeCSIu('V', '6') .. GetEscCodeCSIu('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!') |
| call assert_equal("\"\<Esc>[89;5u", @:) |
| |
| call setline(1, '') |
| call feedkeys(':' .. GetEscCodeCSI27('V', '6') .. GetEscCodeCSI27('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!') |
| call assert_equal("\"\<Esc>[27;5;89~", @:) |
| |
| set timeoutlen& |
| endfunc |
| |
| func Test_mapping_esc() |
| set timeoutlen=10 |
| |
| new |
| nnoremap <Up> iHello<Esc> |
| nnoremap <Esc> <Nop> |
| |
| call feedkeys(substitute(&t_ku, '\*', '', 'g'), 'Lx!') |
| call assert_equal("Hello", getline(1)) |
| |
| bwipe! |
| nunmap <Up> |
| nunmap <Esc> |
| set timeoutlen& |
| endfunc |
| |
| " Test for translation of special key codes (<xF1>, <xF2>, etc.) |
| func Test_Keycode_Translation() |
| let keycodes = [ |
| \ ["<xUp>", "<Up>"], |
| \ ["<xDown>", "<Down>"], |
| \ ["<xLeft>", "<Left>"], |
| \ ["<xRight>", "<Right>"], |
| \ ["<xHome>", "<Home>"], |
| \ ["<xEnd>", "<End>"], |
| \ ["<zHome>", "<Home>"], |
| \ ["<zEnd>", "<End>"], |
| \ ["<xF1>", "<F1>"], |
| \ ["<xF2>", "<F2>"], |
| \ ["<xF3>", "<F3>"], |
| \ ["<xF4>", "<F4>"], |
| \ ["<S-xF1>", "<S-F1>"], |
| \ ["<S-xF2>", "<S-F2>"], |
| \ ["<S-xF3>", "<S-F3>"], |
| \ ["<S-xF4>", "<S-F4>"]] |
| for [k1, k2] in keycodes |
| exe "nnoremap " .. k1 .. " 2wx" |
| call assert_true(maparg(k1, 'n', 0, 1).lhs == k2) |
| exe "nunmap " .. k1 |
| endfor |
| endfunc |
| |
| " Test for terminal keycodes that doesn't have termcap entries |
| func Test_special_term_keycodes() |
| new |
| " Test for <xHome>, <S-xHome> and <C-xHome> |
| " send <K_SPECIAL> <KS_EXTRA> keycode |
| call feedkeys("i\<C-K>\x80\xfd\x3f\n", 'xt') |
| " send <K_SPECIAL> <KS_MODIFIER> bitmap <K_SPECIAL> <KS_EXTRA> keycode |
| call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x3f\n", 'xt') |
| call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x3f\n", 'xt') |
| " Test for <xEnd>, <S-xEnd> and <C-xEnd> |
| call feedkeys("i\<C-K>\x80\xfd\x3d\n", 'xt') |
| call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x3d\n", 'xt') |
| call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x3d\n", 'xt') |
| " Test for <zHome>, <S-zHome> and <C-zHome> |
| call feedkeys("i\<C-K>\x80\xfd\x40\n", 'xt') |
| call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x40\n", 'xt') |
| call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x40\n", 'xt') |
| " Test for <zEnd>, <S-zEnd> and <C-zEnd> |
| call feedkeys("i\<C-K>\x80\xfd\x3e\n", 'xt') |
| call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x3e\n", 'xt') |
| call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x3e\n", 'xt') |
| " Test for <xUp>, <xDown>, <xLeft> and <xRight> |
| call feedkeys("i\<C-K>\x80\xfd\x41\n", 'xt') |
| call feedkeys("i\<C-K>\x80\xfd\x42\n", 'xt') |
| call feedkeys("i\<C-K>\x80\xfd\x43\n", 'xt') |
| call feedkeys("i\<C-K>\x80\xfd\x44\n", 'xt') |
| call assert_equal(['<Home>', '<S-Home>', '<C-Home>', |
| \ '<End>', '<S-End>', '<C-End>', |
| \ '<Home>', '<S-Home>', '<C-Home>', |
| \ '<End>', '<S-End>', '<C-End>', |
| \ '<Up>', '<Down>', '<Left>', '<Right>', ''], getline(1, '$')) |
| bw! |
| endfunc |
| |
| func Test_home_key_works() |
| " The '@' character in K_HOME must only match "1" when followed by ";", |
| " otherwise this code for Home is not recognized: "<Esc>[1~" |
| " Set termcap values like "xterm" uses them. Except using F2 for xHome, |
| " because that termcap entry can't be set here. |
| let save_K1 = exists('&t_K1') ? &t_K1 : '' |
| let save_kh = exists('&t_kh') ? &t_kh : '' |
| let save_k2 = exists('&t_k2') ? &t_k2 : '' |
| let save_k3 = exists('&t_k3') ? &t_k3 : '' |
| let save_end = exists('&t_@7') ? &t_@7 : '' |
| |
| let &t_K1 = "\<Esc>[1;*~" " <kHome> |
| let &t_kh = "\<Esc>[@;*H" " <Home> |
| let &t_k2 = "\<Esc>O*H" " use <F2> for <xHome> |
| let &t_k3 = "\<Esc>[7;*~" " use <F3> for <zHome> |
| let &t_@7 = "\<Esc>[@;*F" " <End> |
| |
| new |
| call feedkeys("i\<C-K>\<Esc>OH\n\<Esc>", 'tx') |
| call feedkeys("i\<C-K>\<Esc>[1~\n\<Esc>", 'tx') |
| call assert_equal([ |
| \ '<F2>', |
| \ '<kHome>', |
| \ ''], getline(1, '$')) |
| |
| bwipe! |
| let &t_K1 = save_K1 |
| let &t_kh = save_kh |
| let &t_k2 = save_k2 |
| let &t_k3 = save_k3 |
| let &t_@7 = save_end |
| endfunc |
| |
| func Test_terminal_builtin_without_gui() |
| CheckNotMSWindows |
| |
| " builtin_gui should not be output by :set term=xxx |
| let output = systemlist("TERM=dumb " .. v:progpath .. " --not-a-term --clean -c ':set t_ti= t_te=' -c 'set term=xxx' -c ':q!'") |
| redraw! |
| call map(output, {_, val -> trim(val)}) |
| call assert_equal(-1, index(output, 'builtin_gui')) |
| call assert_notequal(-1, index(output, 'builtin_dumb')) |
| endfunc |
| |
| func Test_xterm_direct_enables_termguicolors() |
| call s:TermGuiColorsTest() |
| " TERM=xterm-direct enables termguicolors |
| let colors = systemlist('tput -Txterm-direct colors')[0] |
| defer delete('XTerm-direct.txt') |
| |
| let buf = RunVimInTerminal('--cmd ":set noswapfile" --clean XTerm-direct.txt', |
| \ {'rows': 10, 'env': {'TERM': 'xterm-direct'}}) |
| call TermWait(buf) |
| call term_sendkeys(buf, ":$put ='TERM: ' .. &term\<cr>") |
| " doesn't work. Vim cannot query xterm colors in the embedded terminal? |
| "call term_sendkeys(buf, ":$put ='Colors: ' .. &t_Co\<cr>") |
| call term_sendkeys(buf, ":$put ='Termguicolors: ' .. &tgc\<cr>") |
| call term_sendkeys(buf, ":wq\<cr>") |
| call TermWait(buf) |
| |
| let result=readfile('XTerm-direct.txt') |
| " call assert_equal(['', 'TERM: xterm-direct', 'Colors: ' .. colors, 'Termguicolors: 1'], result) |
| call assert_equal(['', 'TERM: xterm-direct', 'Termguicolors: 0'], result) |
| " cleanup |
| bw! |
| close |
| endfunc |
| |
| func Test_xterm_direct_no_termguicolors() |
| " unfortunately doesn't work with libvterm |
| call s:TermGuiColorsTest() |
| |
| let lines =<< trim END |
| set notermguicolors noswapfile |
| set t_Co=16777216 |
| END |
| call writefile(lines, 'XtermDirect', 'D') |
| defer delete('XTerm-direct2.txt') |
| |
| let buf = RunVimInTerminal('-S XtermDirect --clean XTerm-direct2.txt', |
| \ {'rows': 10, 'env': {'TERM': 'xterm-direct'}}) |
| call TermWait(buf) |
| call term_sendkeys(buf, ":$put ='TERM: ' .. &term\<cr>") |
| call term_sendkeys(buf, ":$put ='Termguicolors: ' .. &tgc\<cr>") |
| call term_sendkeys(buf, ":wq\<cr>") |
| call TermWait(buf) |
| |
| let result=readfile('XTerm-direct2.txt') |
| call assert_equal(['', 'TERM: xterm-direct', 'Termguicolors: 0'], result) |
| " cleanup |
| bw! |
| close |
| endfunc |
| |
| " vim: shiftwidth=2 sts=2 expandtab |