| " Tests for decoding escape sequences sent by the terminal. |
| |
| " This only works for Unix in a terminal |
| source check.vim |
| CheckNotGui |
| CheckUnix |
| |
| source shared.vim |
| |
| " xterm2 and sgr always work, urxvt is optional. |
| let s:ttymouse_values = ['xterm2', 'sgr'] |
| if has('mouse_urxvt') |
| call add(s:ttymouse_values, 'urxvt') |
| endif |
| |
| " dec doesn't support all the functionality |
| if has('mouse_dec') |
| let s:ttymouse_dec = ['dec'] |
| else |
| let s:ttymouse_dec = [] |
| endif |
| |
| " netterm only supports left click |
| if has('mouse_netterm') |
| let s:ttymouse_netterm = ['netterm'] |
| else |
| let s:ttymouse_netterm = [] |
| endif |
| |
| " Helper function to emit a terminal escape code. |
| func TerminalEscapeCode(code, row, col, m) |
| if &ttymouse ==# 'xterm2' |
| " need to use byte encoding here. |
| let str = list2str([a:code + 0x20, a:col + 0x20, a:row + 0x20]) |
| if has('iconv') |
| let bytes = str->iconv('utf-8', 'latin1') |
| else |
| " Hopefully the numbers are not too big. |
| let bytes = str |
| endif |
| return "\<Esc>[M" .. bytes |
| elseif &ttymouse ==# 'sgr' |
| return printf("\<Esc>[<%d;%d;%d%s", a:code, a:col, a:row, a:m) |
| elseif &ttymouse ==# 'urxvt' |
| return printf("\<Esc>[%d;%d;%dM", a:code + 0x20, a:col, a:row) |
| endif |
| endfunc |
| |
| func DecEscapeCode(code, down, row, col) |
| return printf("\<Esc>[%d;%d;%d;%d&w", a:code, a:down, a:row, a:col) |
| endfunc |
| |
| func NettermEscapeCode(row, col) |
| return printf("\<Esc>}%d,%d\r", a:row, a:col) |
| endfunc |
| |
| func MouseLeftClickCode(row, col) |
| if &ttymouse ==# 'dec' |
| return DecEscapeCode(2, 4, a:row, a:col) |
| elseif &ttymouse ==# 'netterm' |
| return NettermEscapeCode(a:row, a:col) |
| else |
| return TerminalEscapeCode(0, a:row, a:col, 'M') |
| endif |
| endfunc |
| |
| func MouseLeftClick(row, col) |
| call feedkeys(MouseLeftClickCode(a:row, a:col), 'Lx!') |
| endfunc |
| |
| func MouseMiddleClickCode(row, col) |
| if &ttymouse ==# 'dec' |
| return DecEscapeCode(4, 2, a:row, a:col) |
| else |
| return TerminalEscapeCode(1, a:row, a:col, 'M') |
| endif |
| endfunc |
| |
| func MouseMiddleClick(row, col) |
| call feedkeys(MouseMiddleClickCode(a:row, a:col), 'Lx!') |
| endfunc |
| |
| func MouseRightClickCode(row, col) |
| if &ttymouse ==# 'dec' |
| return DecEscapeCode(6, 1, a:row, a:col) |
| else |
| return TerminalEscapeCode(2, a:row, a:col, 'M') |
| endif |
| endfunc |
| |
| func MouseRightClick(row, col) |
| call feedkeys(MouseRightClickCode(a:row, a:col), 'Lx!') |
| endfunc |
| |
| func MouseCtrlLeftClickCode(row, col) |
| let ctrl = 0x10 |
| return TerminalEscapeCode(0 + ctrl, a:row, a:col, 'M') |
| endfunc |
| |
| func MouseCtrlLeftClick(row, col) |
| call feedkeys(MouseCtrlLeftClickCode(a:row, a:col), 'Lx!') |
| endfunc |
| |
| func MouseCtrlRightClickCode(row, col) |
| let ctrl = 0x10 |
| return TerminalEscapeCode(2 + ctrl, a:row, a:col, 'M') |
| endfunc |
| |
| func MouseCtrlRightClick(row, col) |
| call feedkeys(MouseCtrlRightClickCode(a:row, a:col), 'Lx!') |
| endfunc |
| |
| func MouseLeftReleaseCode(row, col) |
| if &ttymouse ==# 'dec' |
| return DecEscapeCode(3, 0, a:row, a:col) |
| elseif &ttymouse ==# 'netterm' |
| return '' |
| else |
| return TerminalEscapeCode(3, a:row, a:col, 'm') |
| endif |
| endfunc |
| |
| func MouseLeftRelease(row, col) |
| call feedkeys(MouseLeftReleaseCode(a:row, a:col), 'Lx!') |
| endfunc |
| |
| func MouseMiddleReleaseCode(row, col) |
| if &ttymouse ==# 'dec' |
| return DecEscapeCode(5, 0, a:row, a:col) |
| else |
| return TerminalEscapeCode(3, a:row, a:col, 'm') |
| endif |
| endfunc |
| |
| func MouseMiddleRelease(row, col) |
| call feedkeys(MouseMiddleReleaseCode(a:row, a:col), 'Lx!') |
| endfunc |
| |
| func MouseRightReleaseCode(row, col) |
| if &ttymouse ==# 'dec' |
| return DecEscapeCode(7, 0, a:row, a:col) |
| else |
| return TerminalEscapeCode(3, a:row, a:col, 'm') |
| endif |
| endfunc |
| |
| func MouseRightRelease(row, col) |
| call feedkeys(MouseRightReleaseCode(a:row, a:col), 'Lx!') |
| endfunc |
| |
| func MouseLeftDragCode(row, col) |
| if &ttymouse ==# 'dec' |
| return DecEscapeCode(1, 4, a:row, a:col) |
| else |
| return TerminalEscapeCode(0x20, a:row, a:col, 'M') |
| endif |
| endfunc |
| |
| func MouseLeftDrag(row, col) |
| call feedkeys(MouseLeftDragCode(a:row, a:col), 'Lx!') |
| endfunc |
| |
| func MouseWheelUpCode(row, col) |
| return TerminalEscapeCode(0x40, a:row, a:col, 'M') |
| endfunc |
| |
| func MouseWheelUp(row, col) |
| call feedkeys(MouseWheelUpCode(a:row, a:col), 'Lx!') |
| endfunc |
| |
| func MouseWheelDownCode(row, col) |
| return TerminalEscapeCode(0x41, a:row, a:col, 'M') |
| endfunc |
| |
| func MouseWheelDown(row, col) |
| call feedkeys(MouseWheelDownCode(a:row, a:col), 'Lx!') |
| 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 setline(1, ['line 1', 'line 2', 'line 3 is a bit longer']) |
| |
| for ttymouse_val in s:ttymouse_values + s:ttymouse_dec + s: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 |
| |
| for visual_mode in ["v", "V", "\<C-V>"] |
| for ttymouse_val in s:ttymouse_values + s: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. |
| func Test_xterm_mouse_ctrl_click() |
| let save_mouse = &mouse |
| let save_term = &term |
| let save_ttymouse = &ttymouse |
| set mouse=a term=xterm |
| |
| for ttymouse_val in s:ttymouse_values |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| help |
| /usr_02.txt |
| norm! zt |
| 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) |
| |
| call MouseCtrlRightClick(row, col) |
| call MouseRightRelease(row, col) |
| call assert_match('help.txt$', bufname('%'), msg) |
| call assert_equal('|usr_02.txt|', expand('<cWORD>'), msg) |
| |
| helpclose |
| 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 @* = 'abc' |
| set mouse=a term=xterm |
| |
| for ttymouse_val in s:ttymouse_values + s:ttymouse_dec |
| let msg = 'ttymouse=' .. ttymouse_val |
| exe 'set ttymouse=' .. ttymouse_val |
| call setline(1, ['123456789', '123456789']) |
| |
| " 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) |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| call test_override('no_query_mouse', 0) |
| let @* = save_quotestar |
| bwipe! |
| 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_ttymouse = &ttymouse |
| set mouse=a term=xterm |
| call setline(1, range(1, 100)) |
| |
| for ttymouse_val in s: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) |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| 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 |
| 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 s:ttymouse_values + s: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 |
| |
| for ttymouse_val in s:ttymouse_values + s: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 |
| |
| for ttymouse_val in s:ttymouse_values + s: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 |
| let row = 1 |
| |
| for ttymouse_val in s:ttymouse_values + s:ttymouse_dec + s: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 |
| let row = 1 |
| let col = &columns |
| |
| for ttymouse_val in s:ttymouse_values + s:ttymouse_dec + s: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 |
| let row = 1 |
| |
| for ttymouse_val in s:ttymouse_values + s: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) |
| |
| " 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 |
| let row = 1 |
| let col = 10 |
| |
| for ttymouse_val in s:ttymouse_values + s: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) |
| set mouse=a term=xterm mousetime=200 |
| new |
| |
| for ttymouse_val in s:ttymouse_values + s: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) |
| endfor |
| |
| let &mouse = save_mouse |
| let &term = save_term |
| let &ttymouse = save_ttymouse |
| set mousetime& |
| call test_override('no_query_mouse', 0) |
| bwipe! |
| 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 |
| |
| " 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 |
| let row = &lines |
| |
| for ttymouse_val in s:ttymouse_values + s:ttymouse_dec |
| 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) |
| 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 |
| let row = &lines |
| " Column values does not matter, paste is done at position of cursor. |
| let col = 1 |
| let @* = 'paste' |
| |
| for ttymouse_val in s:ttymouse_values + s: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 |
| |
| " 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 |
| |
| " 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) |
| |
| set t_RV= |
| 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 |
| |
| " 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) |
| |
| set t_RV= |
| 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_response() |
| " Termresponse is only parsed when t_RV is not empty. |
| set t_RV=x |
| |
| set ttymouse=xterm |
| call test_option_not_set('ttymouse') |
| let seq = "\<Esc>[>0;100;0c" |
| call feedkeys(seq, 'Lx!') |
| call assert_equal(seq, v:termresponse) |
| call assert_equal('sgr', &ttymouse) |
| |
| set t_RV= |
| 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 |
| |
| 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) |
| |
| " Reset is_not_xterm and is_mac_terminal. |
| set t_RV= |
| set term=xterm |
| set t_RV=x |
| 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 |
| |
| 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) |
| |
| set t_RV= |
| 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 |
| |
| " 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) |
| |
| set t_RV= |
| 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 |
| |
| " 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 |
| 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) |
| |
| " 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) |
| |
| " 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) |
| |
| set t_RV= |
| 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 GetEscCodeCSI27(key, modifier) |
| let key = printf("%d", char2nr(a:key)) |
| let mod = printf("%d", a:modifier) |
| return "\<Esc>[27;" .. mod .. ';' .. key .. '~' |
| endfunc |
| |
| func GetEscCodeCSIu(key, modifier) |
| let key = printf("%d", char2nr(a:key)) |
| let mod = printf("%d", a:modifier) |
| return "\<Esc>[" .. key .. ';' .. mod .. 'u' |
| 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 |
| |
| 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 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 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) |
| 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) |
| 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_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_insert_literal() |
| set timeoutlen=10 |
| 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 |