blob: 8fe1850ebe32d3fd4c2fa872540c0134e775af6e [file] [log] [blame]
Bram Moolenaar905dd902019-04-07 14:21:47 +02001" Tests for decoding escape sequences sent by the terminal.
2
3" This only works for Unix in a terminal
Bram Moolenaar8c5a2782019-08-07 23:07:07 +02004source check.vim
5CheckNotGui
6CheckUnix
Bram Moolenaar905dd902019-04-07 14:21:47 +02007
Bram Moolenaar564344a2019-04-28 13:00:12 +02008source shared.vim
9
Bram Moolenaard0621d82019-05-02 21:12:19 +020010" xterm2 and sgr always work, urxvt is optional.
Bram Moolenaar92fd5992019-05-02 23:00:22 +020011let s:ttymouse_values = ['xterm2', 'sgr']
Bram Moolenaard0621d82019-05-02 21:12:19 +020012if has('mouse_urxvt')
Bram Moolenaar92fd5992019-05-02 23:00:22 +020013 call add(s:ttymouse_values, 'urxvt')
14endif
15
16" dec doesn't support all the functionality
17if has('mouse_dec')
18 let s:ttymouse_dec = ['dec']
19else
20 let s:ttymouse_dec = []
Bram Moolenaard0621d82019-05-02 21:12:19 +020021endif
22
Bram Moolenaard7885432019-05-03 13:44:10 +020023" netterm only supports left click
24if has('mouse_netterm')
25 let s:ttymouse_netterm = ['netterm']
26else
27 let s:ttymouse_netterm = []
28endif
29
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +020030" Helper function to emit a terminal escape code.
Bram Moolenaard0621d82019-05-02 21:12:19 +020031func TerminalEscapeCode(code, row, col, m)
Bram Moolenaar2b00b9b2019-04-17 17:08:27 +020032 if &ttymouse ==# 'xterm2'
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +020033 " need to use byte encoding here.
Bram Moolenaard0621d82019-05-02 21:12:19 +020034 let str = list2str([a:code + 0x20, a:col + 0x20, a:row + 0x20])
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +020035 if has('iconv')
Bram Moolenaarf9f24ce2019-08-31 21:17:39 +020036 let bytes = str->iconv('utf-8', 'latin1')
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +020037 else
38 " Hopefully the numbers are not too big.
39 let bytes = str
40 endif
41 call feedkeys("\<Esc>[M" .. bytes, 'Lx!')
42 elseif &ttymouse ==# 'sgr'
Bram Moolenaard0621d82019-05-02 21:12:19 +020043 call feedkeys(printf("\<Esc>[<%d;%d;%d%s", a:code, a:col, a:row, a:m), 'Lx!')
44 elseif &ttymouse ==# 'urxvt'
45 call feedkeys(printf("\<Esc>[%d;%d;%dM", a:code + 0x20, a:col, a:row), 'Lx!')
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +020046 endif
47endfunc
48
Bram Moolenaar92fd5992019-05-02 23:00:22 +020049func DecEscapeCode(code, down, row, col)
50 call feedkeys(printf("\<Esc>[%d;%d;%d;%d&w", a:code, a:down, a:row, a:col), 'Lx!')
51endfunc
52
Bram Moolenaard7885432019-05-03 13:44:10 +020053func NettermEscapeCode(row, col)
54 call feedkeys(printf("\<Esc>}%d,%d\r", a:row, a:col), 'Lx!')
55endfunc
56
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +020057func MouseLeftClick(row, col)
Bram Moolenaar92fd5992019-05-02 23:00:22 +020058 if &ttymouse ==# 'dec'
59 call DecEscapeCode(2, 4, a:row, a:col)
Bram Moolenaard7885432019-05-03 13:44:10 +020060 elseif &ttymouse ==# 'netterm'
61 call NettermEscapeCode(a:row, a:col)
Bram Moolenaar92fd5992019-05-02 23:00:22 +020062 else
63 call TerminalEscapeCode(0, a:row, a:col, 'M')
64 endif
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +020065endfunc
66
Bram Moolenaarc1b81602019-04-27 19:11:35 +020067func MouseMiddleClick(row, col)
Bram Moolenaar92fd5992019-05-02 23:00:22 +020068 if &ttymouse ==# 'dec'
69 call DecEscapeCode(4, 2, a:row, a:col)
70 else
71 call TerminalEscapeCode(1, a:row, a:col, 'M')
72 endif
Bram Moolenaarc1b81602019-04-27 19:11:35 +020073endfunc
74
Bram Moolenaar1ee36d62019-05-01 23:13:56 +020075func MouseCtrlLeftClick(row, col)
76 let ctrl = 0x10
Bram Moolenaard0621d82019-05-02 21:12:19 +020077 call TerminalEscapeCode(0 + ctrl, a:row, a:col, 'M')
Bram Moolenaar1ee36d62019-05-01 23:13:56 +020078endfunc
79
80func MouseCtrlRightClick(row, col)
81 let ctrl = 0x10
Bram Moolenaard0621d82019-05-02 21:12:19 +020082 call TerminalEscapeCode(2 + ctrl, a:row, a:col, 'M')
Bram Moolenaar1ee36d62019-05-01 23:13:56 +020083endfunc
84
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +020085func MouseLeftRelease(row, col)
Bram Moolenaar92fd5992019-05-02 23:00:22 +020086 if &ttymouse ==# 'dec'
87 call DecEscapeCode(3, 0, a:row, a:col)
Bram Moolenaard7885432019-05-03 13:44:10 +020088 elseif &ttymouse ==# 'netterm'
89 " send nothing
Bram Moolenaar92fd5992019-05-02 23:00:22 +020090 else
91 call TerminalEscapeCode(3, a:row, a:col, 'm')
92 endif
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +020093endfunc
94
Bram Moolenaarc1b81602019-04-27 19:11:35 +020095func MouseMiddleRelease(row, col)
Bram Moolenaar92fd5992019-05-02 23:00:22 +020096 if &ttymouse ==# 'dec'
97 call DecEscapeCode(5, 0, a:row, a:col)
98 else
99 call TerminalEscapeCode(3, a:row, a:col, 'm')
100 endif
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200101endfunc
102
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200103func MouseRightRelease(row, col)
Bram Moolenaard0621d82019-05-02 21:12:19 +0200104 call TerminalEscapeCode(3, a:row, a:col, 'm')
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200105endfunc
106
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200107func MouseLeftDrag(row, col)
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200108 if &ttymouse ==# 'dec'
109 call DecEscapeCode(1, 4, a:row, a:col)
110 else
111 call TerminalEscapeCode(0x20, a:row, a:col, 'M')
112 endif
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200113endfunc
114
115func MouseWheelUp(row, col)
Bram Moolenaard0621d82019-05-02 21:12:19 +0200116 call TerminalEscapeCode(0x40, a:row, a:col, 'M')
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200117endfunc
118
119func MouseWheelDown(row, col)
Bram Moolenaard0621d82019-05-02 21:12:19 +0200120 call TerminalEscapeCode(0x41, a:row, a:col, 'M')
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200121endfunc
122
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200123func Test_term_mouse_left_click()
Bram Moolenaar905dd902019-04-07 14:21:47 +0200124 new
125 let save_mouse = &mouse
126 let save_term = &term
127 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200128 call test_override('no_query_mouse', 1)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200129 set mouse=a term=xterm
Bram Moolenaar905dd902019-04-07 14:21:47 +0200130 call setline(1, ['line 1', 'line 2', 'line 3 is a bit longer'])
Bram Moolenaar905dd902019-04-07 14:21:47 +0200131
Bram Moolenaard7885432019-05-03 13:44:10 +0200132 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec + s:ttymouse_netterm
Bram Moolenaar49452192019-04-17 16:27:02 +0200133 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200134 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200135 go
Bram Moolenaar49452192019-04-17 16:27:02 +0200136 call assert_equal([0, 1, 1, 0], getpos('.'), msg)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200137 let row = 2
138 let col = 6
139 call MouseLeftClick(row, col)
140 call MouseLeftRelease(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200141 call assert_equal([0, 2, 6, 0], getpos('.'), msg)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200142 endfor
Bram Moolenaar905dd902019-04-07 14:21:47 +0200143
144 let &mouse = save_mouse
145 let &term = save_term
146 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200147 call test_override('no_query_mouse', 0)
Bram Moolenaar905dd902019-04-07 14:21:47 +0200148 bwipe!
149endfunc
150
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200151" Test that <C-LeftMouse> jumps to help tag and <C-RightMouse> jumps back.
152func Test_xterm_mouse_ctrl_click()
153 let save_mouse = &mouse
154 let save_term = &term
155 let save_ttymouse = &ttymouse
156 set mouse=a term=xterm
157
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200158 for ttymouse_val in s:ttymouse_values
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200159 let msg = 'ttymouse=' .. ttymouse_val
160 exe 'set ttymouse=' .. ttymouse_val
161 help
162 /usr_02.txt
163 norm! zt
164 let row = 1
165 let col = 1
166 call MouseCtrlLeftClick(row, col)
167 call MouseLeftRelease(row, col)
168 call assert_match('usr_02.txt$', bufname('%'), msg)
Bram Moolenaarb4367b72019-10-01 14:19:07 +0200169 call assert_equal('*usr_02.txt*', expand('<cWORD>'), msg)
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200170
171 call MouseCtrlRightClick(row, col)
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200172 call MouseRightRelease(row, col)
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200173 call assert_match('help.txt$', bufname('%'), msg)
Bram Moolenaarb4367b72019-10-01 14:19:07 +0200174 call assert_equal('|usr_02.txt|', expand('<cWORD>'), msg)
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200175
176 helpclose
177 endfor
178
179 let &mouse = save_mouse
180 let &term = save_term
181 let &ttymouse = save_ttymouse
182endfunc
183
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200184func Test_term_mouse_middle_click()
Bram Moolenaar52992fe2019-08-12 14:20:33 +0200185 CheckFeature clipboard_working
Bram Moolenaar564344a2019-04-28 13:00:12 +0200186
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200187 new
188 let save_mouse = &mouse
189 let save_term = &term
190 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200191 call test_override('no_query_mouse', 1)
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200192 let save_quotestar = @*
193 let @* = 'abc'
194 set mouse=a term=xterm
195
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200196 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200197 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200198 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200199 call setline(1, ['123456789', '123456789'])
200
201 " Middle-click in the middle of the line pastes text where clicked.
202 let row = 1
203 let col = 6
204 call MouseMiddleClick(row, col)
205 call MouseMiddleRelease(row, col)
206 call assert_equal(['12345abc6789', '123456789'], getline(1, '$'), msg)
207
208 " Middle-click beyond end of the line pastes text at the end of the line.
209 let col = 20
210 call MouseMiddleClick(row, col)
211 call MouseMiddleRelease(row, col)
212 call assert_equal(['12345abc6789abc', '123456789'], getline(1, '$'), msg)
213
214 " Middle-click beyond the last line pastes in the last line.
215 let row = 5
216 let col = 3
217 call MouseMiddleClick(row, col)
218 call MouseMiddleRelease(row, col)
219 call assert_equal(['12345abc6789abc', '12abc3456789'], getline(1, '$'), msg)
220 endfor
221
222 let &mouse = save_mouse
223 let &term = save_term
224 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200225 call test_override('no_query_mouse', 0)
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200226 let @* = save_quotestar
227 bwipe!
228endfunc
229
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200230" TODO: for unclear reasons this test fails if it comes after
231" Test_xterm_mouse_ctrl_click()
232func Test_1xterm_mouse_wheel()
Bram Moolenaar049736f2019-04-07 21:55:07 +0200233 new
234 let save_mouse = &mouse
235 let save_term = &term
236 let save_ttymouse = &ttymouse
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200237 set mouse=a term=xterm
Bram Moolenaar049736f2019-04-07 21:55:07 +0200238 call setline(1, range(1, 100))
239
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200240 for ttymouse_val in s:ttymouse_values
Bram Moolenaar49452192019-04-17 16:27:02 +0200241 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200242 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200243 go
Bram Moolenaar49452192019-04-17 16:27:02 +0200244 call assert_equal(1, line('w0'), msg)
245 call assert_equal([0, 1, 1, 0], getpos('.'), msg)
Bram Moolenaar049736f2019-04-07 21:55:07 +0200246
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200247 call MouseWheelDown(1, 1)
Bram Moolenaar49452192019-04-17 16:27:02 +0200248 call assert_equal(4, line('w0'), msg)
249 call assert_equal([0, 4, 1, 0], getpos('.'), msg)
Bram Moolenaar049736f2019-04-07 21:55:07 +0200250
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200251 call MouseWheelDown(1, 1)
Bram Moolenaar49452192019-04-17 16:27:02 +0200252 call assert_equal(7, line('w0'), msg)
253 call assert_equal([0, 7, 1, 0], getpos('.'), msg)
Bram Moolenaar049736f2019-04-07 21:55:07 +0200254
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200255 call MouseWheelUp(1, 1)
Bram Moolenaar49452192019-04-17 16:27:02 +0200256 call assert_equal(4, line('w0'), msg)
257 call assert_equal([0, 7, 1, 0], getpos('.'), msg)
Bram Moolenaar049736f2019-04-07 21:55:07 +0200258
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200259 call MouseWheelUp(1, 1)
Bram Moolenaar49452192019-04-17 16:27:02 +0200260 call assert_equal(1, line('w0'), msg)
261 call assert_equal([0, 7, 1, 0], getpos('.'), msg)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200262 endfor
Bram Moolenaar049736f2019-04-07 21:55:07 +0200263
264 let &mouse = save_mouse
265 let &term = save_term
266 let &ttymouse = save_ttymouse
267 bwipe!
268endfunc
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200269
Bram Moolenaarb4367b72019-10-01 14:19:07 +0200270" Test that dragging beyond the window (at the bottom and at the top)
271" scrolls window content by the number of of lines beyond the window.
272func Test_term_mouse_drag_beyond_window()
273 let save_mouse = &mouse
274 let save_term = &term
275 let save_ttymouse = &ttymouse
276 call test_override('no_query_mouse', 1)
277 set mouse=a term=xterm
278 let col = 1
279 call setline(1, range(1, 100))
280
281 " Split into 3 windows, and go into the middle window
282 " so we test dragging mouse below and above the window.
283 2split
284 wincmd j
285 2split
286
287 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec
288 let msg = 'ttymouse=' .. ttymouse_val
289 exe 'set ttymouse=' .. ttymouse_val
290
291 " Line #10 at the top.
292 norm! 10zt
293 redraw
294 call assert_equal(10, winsaveview().topline, msg)
295 call assert_equal(2, winheight(0), msg)
296
297 let row = 4
298 call MouseLeftClick(row, col)
299 call assert_equal(10, winsaveview().topline, msg)
300
301 " Drag downwards. We're still in the window so topline should
302 " not change yet.
303 let row += 1
304 call MouseLeftDrag(row, col)
305 call assert_equal(10, winsaveview().topline, msg)
306
307 " We now leave the window at the bottom, so the window content should
308 " scroll by 1 line, then 2 lines (etc) as we drag further away.
309 let row += 1
310 call MouseLeftDrag(row, col)
311 call assert_equal(11, winsaveview().topline, msg)
312
313 let row += 1
314 call MouseLeftDrag(row, col)
315 call assert_equal(13, winsaveview().topline, msg)
316
317 " Now drag upwards.
318 let row -= 1
319 call MouseLeftDrag(row, col)
320 call assert_equal(14, winsaveview().topline, msg)
321
322 " We're now back in the window so the topline should not change.
323 let row -= 1
324 call MouseLeftDrag(row, col)
325 call assert_equal(14, winsaveview().topline, msg)
326
327 let row -= 1
328 call MouseLeftDrag(row, col)
329 call assert_equal(14, winsaveview().topline, msg)
330
331 " We now leave the window at the top so the window content should
332 " scroll by 1 line, then 2, then 3 (etc) in the opposite direction.
333 let row -= 1
334 call MouseLeftDrag(row, col)
335 call assert_equal(13, winsaveview().topline, msg)
336
337 let row -= 1
338 call MouseLeftDrag(row, col)
339 call assert_equal(11, winsaveview().topline, msg)
340
341 let row -= 1
342 call MouseLeftDrag(row, col)
343 call assert_equal(8, winsaveview().topline, msg)
344
345 call MouseLeftRelease(row, col)
346 call assert_equal(8, winsaveview().topline, msg)
347 call assert_equal(2, winheight(0), msg)
348 endfor
349
350 let &mouse = save_mouse
351 let &term = save_term
352 let &ttymouse = save_ttymouse
353 call test_override('no_query_mouse', 0)
354 bwipe!
355endfunc
356
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200357func Test_term_mouse_drag_window_separator()
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200358 let save_mouse = &mouse
359 let save_term = &term
360 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200361 call test_override('no_query_mouse', 1)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200362 set mouse=a term=xterm
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200363
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200364 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec
Bram Moolenaar49452192019-04-17 16:27:02 +0200365 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200366 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200367
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200368 " Split horizontally and test dragging the horizontal window separator.
369 split
370 let rowseparator = winheight(0) + 1
371 let row = rowseparator
372 let col = 1
Bram Moolenaarc8b3dda2019-04-12 21:42:52 +0200373
Bram Moolenaar2b00b9b2019-04-17 17:08:27 +0200374 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
375 if ttymouse_val !=# 'xterm2' || row <= 223
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200376 call MouseLeftClick(row, col)
377 let row -= 1
378 call MouseLeftDrag(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200379 call assert_equal(rowseparator - 1, winheight(0) + 1, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200380 let row += 1
381 call MouseLeftDrag(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200382 call assert_equal(rowseparator, winheight(0) + 1, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200383 call MouseLeftRelease(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200384 call assert_equal(rowseparator, winheight(0) + 1, msg)
Bram Moolenaarc8b3dda2019-04-12 21:42:52 +0200385 endif
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200386 bwipe!
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200387
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200388 " Split vertically and test dragging the vertical window separator.
389 vsplit
390 let colseparator = winwidth(0) + 1
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200391 let row = 1
392 let col = colseparator
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200393
Bram Moolenaar2b00b9b2019-04-17 17:08:27 +0200394 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
395 if ttymouse_val !=# 'xterm2' || col <= 223
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200396 call MouseLeftClick(row, col)
397 let col -= 1
398 call MouseLeftDrag(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200399 call assert_equal(colseparator - 1, winwidth(0) + 1, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200400 let col += 1
401 call MouseLeftDrag(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200402 call assert_equal(colseparator, winwidth(0) + 1, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200403 call MouseLeftRelease(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200404 call assert_equal(colseparator, winwidth(0) + 1, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200405 endif
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200406 bwipe!
407 endfor
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200408
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200409 let &mouse = save_mouse
410 let &term = save_term
411 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200412 call test_override('no_query_mouse', 0)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200413endfunc
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200414
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200415func Test_term_mouse_drag_statusline()
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200416 let save_mouse = &mouse
417 let save_term = &term
418 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200419 call test_override('no_query_mouse', 1)
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200420 let save_laststatus = &laststatus
421 set mouse=a term=xterm laststatus=2
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200422
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200423 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec
Bram Moolenaar49452192019-04-17 16:27:02 +0200424 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200425 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200426
Bram Moolenaar49452192019-04-17 16:27:02 +0200427 call assert_equal(1, &cmdheight, msg)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200428 let rowstatusline = winheight(0) + 1
429 let row = rowstatusline
430 let col = 1
Bram Moolenaarc8b3dda2019-04-12 21:42:52 +0200431
Bram Moolenaar2b00b9b2019-04-17 17:08:27 +0200432 if ttymouse_val ==# 'xterm2' && row > 223
433 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
Bram Moolenaarc8b3dda2019-04-12 21:42:52 +0200434 continue
435 endif
436
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200437 call MouseLeftClick(row, col)
438 let row -= 1
439 call MouseLeftDrag(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200440 call assert_equal(2, &cmdheight, msg)
441 call assert_equal(rowstatusline - 1, winheight(0) + 1, msg)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200442 let row += 1
443 call MouseLeftDrag(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200444 call assert_equal(1, &cmdheight, msg)
445 call assert_equal(rowstatusline, winheight(0) + 1, msg)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200446 call MouseLeftRelease(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200447 call assert_equal(1, &cmdheight, msg)
448 call assert_equal(rowstatusline, winheight(0) + 1, msg)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200449 endfor
450
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200451 let &mouse = save_mouse
452 let &term = save_term
453 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200454 call test_override('no_query_mouse', 0)
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200455 let &laststatus = save_laststatus
456endfunc
457
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200458func Test_term_mouse_click_tab()
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200459 let save_mouse = &mouse
460 let save_term = &term
461 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200462 call test_override('no_query_mouse', 1)
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200463 set mouse=a term=xterm
464 let row = 1
465
Bram Moolenaard7885432019-05-03 13:44:10 +0200466 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec + s:ttymouse_netterm
Bram Moolenaar49452192019-04-17 16:27:02 +0200467 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200468 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200469 e Xfoo
470 tabnew Xbar
471
472 let a = split(execute(':tabs'), "\n")
473 call assert_equal(['Tab page 1',
474 \ ' Xfoo',
475 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200476 \ '> Xbar'], a, msg)
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200477
478 " Test clicking on tab names in the tabline at the top.
479 let col = 2
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200480 redraw
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200481 call MouseLeftClick(row, col)
482 call MouseLeftRelease(row, col)
483 let a = split(execute(':tabs'), "\n")
484 call assert_equal(['Tab page 1',
485 \ '> Xfoo',
486 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200487 \ ' Xbar'], a, msg)
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200488
489 let col = 9
490 call MouseLeftClick(row, col)
491 call MouseLeftRelease(row, col)
492 let a = split(execute(':tabs'), "\n")
493 call assert_equal(['Tab page 1',
494 \ ' Xfoo',
495 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200496 \ '> Xbar'], a, msg)
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200497
498 %bwipe!
499 endfor
500
501 let &mouse = save_mouse
502 let &term = save_term
503 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200504 call test_override('no_query_mouse', 0)
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200505endfunc
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200506
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200507func Test_term_mouse_click_X_to_close_tab()
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200508 let save_mouse = &mouse
509 let save_term = &term
510 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200511 call test_override('no_query_mouse', 1)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200512 set mouse=a term=xterm
513 let row = 1
514 let col = &columns
515
Bram Moolenaard7885432019-05-03 13:44:10 +0200516 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec + s:ttymouse_netterm
Bram Moolenaar2b00b9b2019-04-17 17:08:27 +0200517 if ttymouse_val ==# 'xterm2' && col > 223
518 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200519 continue
520 endif
Bram Moolenaar49452192019-04-17 16:27:02 +0200521 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200522 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200523 e Xtab1
524 tabnew Xtab2
525 tabnew Xtab3
526 tabn 2
527
528 let a = split(execute(':tabs'), "\n")
529 call assert_equal(['Tab page 1',
530 \ ' Xtab1',
531 \ 'Tab page 2',
532 \ '> Xtab2',
533 \ 'Tab page 3',
Bram Moolenaar49452192019-04-17 16:27:02 +0200534 \ ' Xtab3'], a, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200535
536 " Click on "X" in tabline to close current tab i.e. Xtab2.
537 redraw
538 call MouseLeftClick(row, col)
539 call MouseLeftRelease(row, col)
540 let a = split(execute(':tabs'), "\n")
541 call assert_equal(['Tab page 1',
542 \ ' Xtab1',
543 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200544 \ '> Xtab3'], a, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200545
546 %bwipe!
547 endfor
548
549 let &mouse = save_mouse
550 let &term = save_term
551 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200552 call test_override('no_query_mouse', 0)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200553endfunc
Bram Moolenaare3e38282019-04-15 20:55:31 +0200554
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200555func Test_term_mouse_drag_to_move_tab()
Bram Moolenaare3e38282019-04-15 20:55:31 +0200556 let save_mouse = &mouse
557 let save_term = &term
558 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200559 call test_override('no_query_mouse', 1)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200560 " Set 'mousetime' to 1 to avoid recognizing a double-click in the loop
561 set mouse=a term=xterm mousetime=1
562 let row = 1
563
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200564 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec
Bram Moolenaar49452192019-04-17 16:27:02 +0200565 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200566 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaare3e38282019-04-15 20:55:31 +0200567 e Xtab1
568 tabnew Xtab2
569
570 let a = split(execute(':tabs'), "\n")
571 call assert_equal(['Tab page 1',
572 \ ' Xtab1',
573 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200574 \ '> Xtab2'], a, msg)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200575 redraw
576
577 " Click in tab2 and drag it to tab1.
578 " Check getcharmod() to verify that click is not
579 " interpreted as a spurious double-click.
580 call MouseLeftClick(row, 10)
Bram Moolenaar49452192019-04-17 16:27:02 +0200581 call assert_equal(0, getcharmod(), msg)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200582 for col in [9, 8, 7, 6]
583 call MouseLeftDrag(row, col)
584 endfor
585 call MouseLeftRelease(row, col)
586 let a = split(execute(':tabs'), "\n")
587 call assert_equal(['Tab page 1',
588 \ '> Xtab2',
589 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200590 \ ' Xtab1'], a, msg)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200591
Bram Moolenaar7f279762019-04-15 21:48:22 +0200592 " brief sleep to avoid causing a double-click
593 sleep 20m
Bram Moolenaare3e38282019-04-15 20:55:31 +0200594 %bwipe!
595 endfor
596
597 let &mouse = save_mouse
598 let &term = save_term
599 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200600 call test_override('no_query_mouse', 0)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200601 set mousetime&
602endfunc
603
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200604func Test_term_mouse_double_click_to_create_tab()
Bram Moolenaare3e38282019-04-15 20:55:31 +0200605 let save_mouse = &mouse
606 let save_term = &term
607 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200608 call test_override('no_query_mouse', 1)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200609 " Set 'mousetime' to a small value, so that double-click works but we don't
610 " have to wait long to avoid a triple-click.
611 set mouse=a term=xterm mousetime=100
612 let row = 1
613 let col = 10
614
Bram Moolenaard0621d82019-05-02 21:12:19 +0200615 let round = 0
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200616 for ttymouse_val in s:ttymouse_values + s:ttymouse_dec
Bram Moolenaar49452192019-04-17 16:27:02 +0200617 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200618 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaare3e38282019-04-15 20:55:31 +0200619 e Xtab1
620 tabnew Xtab2
621
Bram Moolenaard0621d82019-05-02 21:12:19 +0200622 if round > 0
623 " We need to sleep, or else the first MouseLeftClick() will be
624 " interpreted as a spurious triple-click.
625 sleep 100m
626 endif
627 let round += 1
628
Bram Moolenaare3e38282019-04-15 20:55:31 +0200629 let a = split(execute(':tabs'), "\n")
630 call assert_equal(['Tab page 1',
631 \ ' Xtab1',
632 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200633 \ '> Xtab2'], a, msg)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200634
635 redraw
636 call MouseLeftClick(row, col)
637 " Check getcharmod() to verify that first click is not
638 " interpreted as a spurious double-click.
Bram Moolenaar49452192019-04-17 16:27:02 +0200639 call assert_equal(0, getcharmod(), msg)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200640 call MouseLeftRelease(row, col)
641 call MouseLeftClick(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200642 call assert_equal(32, getcharmod(), msg) " double-click
Bram Moolenaare3e38282019-04-15 20:55:31 +0200643 call MouseLeftRelease(row, col)
644 let a = split(execute(':tabs'), "\n")
645 call assert_equal(['Tab page 1',
646 \ ' Xtab1',
647 \ 'Tab page 2',
648 \ '> [No Name]',
649 \ 'Tab page 3',
Bram Moolenaar49452192019-04-17 16:27:02 +0200650 \ ' Xtab2'], a, msg)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200651
Bram Moolenaare3e38282019-04-15 20:55:31 +0200652 %bwipe!
653 endfor
654
655 let &mouse = save_mouse
656 let &term = save_term
657 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200658 call test_override('no_query_mouse', 0)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200659 set mousetime&
660endfunc
Bram Moolenaar696d6372019-04-17 16:33:46 +0200661
662func Test_xterm_mouse_click_in_fold_columns()
663 new
664 let save_mouse = &mouse
665 let save_term = &term
666 let save_ttymouse = &ttymouse
667 let save_foldcolumn = &foldcolumn
Bram Moolenaar2b00b9b2019-04-17 17:08:27 +0200668 set mouse=a term=xterm foldcolumn=3 ttymouse=xterm2
Bram Moolenaar696d6372019-04-17 16:33:46 +0200669
670 " Create 2 nested folds.
671 call setline(1, range(1, 7))
672 2,6fold
673 norm! zR
674 4,5fold
675 call assert_equal([-1, -1, -1, 4, 4, -1, -1],
676 \ map(range(1, 7), 'foldclosed(v:val)'))
677
678 " Click in "+" of inner fold in foldcolumn should open it.
679 redraw
680 let row = 4
681 let col = 2
682 call MouseLeftClick(row, col)
683 call MouseLeftRelease(row, col)
684 call assert_equal([-1, -1, -1, -1, -1, -1, -1],
685 \ map(range(1, 7), 'foldclosed(v:val)'))
686
687 " Click in "-" of outer fold in foldcolumn should close it.
688 redraw
689 let row = 2
690 let col = 1
691 call MouseLeftClick(row, col)
692 call MouseLeftRelease(row, col)
693 call assert_equal([-1, 2, 2, 2, 2, 2, -1],
694 \ map(range(1, 7), 'foldclosed(v:val)'))
695 norm! zR
696
697 " Click in "|" of inner fold in foldcolumn should close it.
698 redraw
699 let row = 5
700 let col = 2
701 call MouseLeftClick(row, col)
702 call MouseLeftRelease(row, col)
703 call assert_equal([-1, -1, -1, 4, 4, -1, -1],
704 \ map(range(1, 7), 'foldclosed(v:val)'))
705
706 let &foldcolumn = save_foldcolumn
707 let &ttymouse = save_ttymouse
708 let &term = save_term
709 let &mouse = save_mouse
710 bwipe!
711endfunc
Bram Moolenaar66761db2019-06-05 22:07:51 +0200712
713" This only checks if the sequence is recognized.
Bram Moolenaar66761db2019-06-05 22:07:51 +0200714func Test_term_rgb_response()
715 set t_RF=x
716 set t_RB=y
717
718 " response to t_RF, 4 digits
719 let red = 0x12
720 let green = 0x34
721 let blue = 0x56
722 let seq = printf("\<Esc>]10;rgb:%02x00/%02x00/%02x00\x07", red, green, blue)
723 call feedkeys(seq, 'Lx!')
724 call assert_equal(seq, v:termrfgresp)
725
726 " response to t_RF, 2 digits
727 let red = 0x78
728 let green = 0x9a
729 let blue = 0xbc
730 let seq = printf("\<Esc>]10;rgb:%02x/%02x/%02x\x07", red, green, blue)
731 call feedkeys(seq, 'Lx!')
732 call assert_equal(seq, v:termrfgresp)
733
Bram Moolenaar32e19772019-06-05 22:57:04 +0200734 " response to t_RB, 4 digits, dark
735 set background=light
Bram Moolenaarce90e362019-09-08 18:58:44 +0200736 eval 'background'->test_option_not_set()
Bram Moolenaar32e19772019-06-05 22:57:04 +0200737 let red = 0x29
738 let green = 0x4a
739 let blue = 0x6b
740 let seq = printf("\<Esc>]11;rgb:%02x00/%02x00/%02x00\x07", red, green, blue)
741 call feedkeys(seq, 'Lx!')
742 call assert_equal(seq, v:termrbgresp)
743 call assert_equal('dark', &background)
744
745 " response to t_RB, 4 digits, light
746 set background=dark
747 call test_option_not_set('background')
748 let red = 0x81
749 let green = 0x63
Bram Moolenaar66761db2019-06-05 22:07:51 +0200750 let blue = 0x65
751 let seq = printf("\<Esc>]11;rgb:%02x00/%02x00/%02x00\x07", red, green, blue)
752 call feedkeys(seq, 'Lx!')
753 call assert_equal(seq, v:termrbgresp)
Bram Moolenaar32e19772019-06-05 22:57:04 +0200754 call assert_equal('light', &background)
Bram Moolenaar66761db2019-06-05 22:07:51 +0200755
Bram Moolenaar32e19772019-06-05 22:57:04 +0200756 " response to t_RB, 2 digits, dark
757 set background=light
758 call test_option_not_set('background')
759 let red = 0x47
760 let green = 0x59
761 let blue = 0x5b
Bram Moolenaar66761db2019-06-05 22:07:51 +0200762 let seq = printf("\<Esc>]11;rgb:%02x/%02x/%02x\x07", red, green, blue)
763 call feedkeys(seq, 'Lx!')
764 call assert_equal(seq, v:termrbgresp)
Bram Moolenaar32e19772019-06-05 22:57:04 +0200765 call assert_equal('dark', &background)
766
767 " response to t_RB, 2 digits, light
768 set background=dark
769 call test_option_not_set('background')
770 let red = 0x83
771 let green = 0xa4
772 let blue = 0xc2
773 let seq = printf("\<Esc>]11;rgb:%02x/%02x/%02x\x07", red, green, blue)
774 call feedkeys(seq, 'Lx!')
775 call assert_equal(seq, v:termrbgresp)
776 call assert_equal('light', &background)
Bram Moolenaar66761db2019-06-05 22:07:51 +0200777
778 set t_RF= t_RB=
779endfunc
780
781" This only checks if the sequence is recognized.
Bram Moolenaar1a4cbb12019-10-12 13:25:44 +0200782" This must be after other tests, because it has side effects to xterm
783" properties.
784func Test_xx01_term_style_response()
Bram Moolenaar66761db2019-06-05 22:07:51 +0200785 " Termresponse is only parsed when t_RV is not empty.
786 set t_RV=x
787
788 " send the termresponse to trigger requesting the XT codes
789 let seq = "\<Esc>[>41;337;0c"
790 call feedkeys(seq, 'Lx!')
791 call assert_equal(seq, v:termresponse)
792
793 let seq = "\<Esc>P1$r2 q\<Esc>\\"
794 call feedkeys(seq, 'Lx!')
795 call assert_equal(seq, v:termstyleresp)
796
797 set t_RV=
798endfunc
Bram Moolenaarde6dbb42019-06-06 11:59:18 +0200799
Bram Moolenaar1a4cbb12019-10-12 13:25:44 +0200800" This checks the libvterm version response.
801" This must be after other tests, because it has side effects to xterm
802" properties.
803" TODO: check other terminals response
804func Test_xx02_libvterm_response()
805 " Termresponse is only parsed when t_RV is not empty.
806 set t_RV=x
807 set ttymouse=xterm
808 call test_option_not_set('ttymouse')
809
810 let seq = "\<Esc>[>0;100;0c"
811 call feedkeys(seq, 'Lx!')
812 call assert_equal(seq, v:termresponse)
813 call assert_equal('sgr', &ttymouse)
814
815 set t_RV=
816endfunc
817
Bram Moolenaarde6dbb42019-06-06 11:59:18 +0200818func Test_get_termcode()
Bram Moolenaareb663282019-10-06 12:02:15 +0200819 try
820 let k1 = &t_k1
821 catch /E113/
822 throw 'Skipped: Unable to query termcodes'
823 endtry
Bram Moolenaarde6dbb42019-06-06 11:59:18 +0200824 set t_k1=
825 set t_k1&
826 call assert_equal(k1, &t_k1)
Bram Moolenaar9aeb3362019-06-06 12:36:15 +0200827
828 " use external termcap first
829 set nottybuiltin
830 set t_k1=
831 set t_k1&
832 " when using external termcap may get something else, but it must not be
833 " empty, since we would fallback to the builtin one.
834 call assert_notequal('', &t_k1)
835
836 if &term =~ 'xterm'
837 " use internal termcap first
838 let term_save = &term
839 let &term = 'builtin_' .. &term
840 set t_k1=
841 set t_k1&
842 call assert_equal(k1, &t_k1)
843 let &term = term_save
844 endif
845
846 set ttybuiltin
Bram Moolenaarde6dbb42019-06-06 11:59:18 +0200847endfunc
Bram Moolenaar18a79a62019-10-12 15:36:11 +0200848
849func GetEscCodeCSI27(key, modifier)
850 let key = printf("%d", char2nr(a:key))
851 let mod = printf("%d", a:modifier)
852 return "\<Esc>[27;" .. mod .. ';' .. key .. '~'
853endfunc
854
855func GetEscCodeCSIu(key, modifier)
856 let key = printf("%d", char2nr(a:key))
857 let mod = printf("%d", a:modifier)
858 return "\<Esc>[" .. key .. ';' .. mod .. 'u'
859endfunc
860
861" This checks the CSI sequences when in modifyOtherKeys mode.
862" The mode doesn't need to be enabled, the codes are always detected.
863func RunTest_modifyOtherKeys(func)
864 new
Bram Moolenaar459fd782019-10-13 16:43:39 +0200865 set timeoutlen=10
Bram Moolenaar18a79a62019-10-12 15:36:11 +0200866
867 " Shift-X is send as 'X' with the shift modifier
868 call feedkeys('a' .. a:func('X', 2) .. "\<Esc>", 'Lx!')
869 call assert_equal('X', getline(1))
870
871 " Ctrl-i is Tab
872 call setline(1, '')
873 call feedkeys('a' .. a:func('i', 5) .. "\<Esc>", 'Lx!')
874 call assert_equal("\t", getline(1))
875
876 " Ctrl-I is also Tab
877 call setline(1, '')
878 call feedkeys('a' .. a:func('I', 5) .. "\<Esc>", 'Lx!')
879 call assert_equal("\t", getline(1))
880
881 " Alt-x is ø
882 call setline(1, '')
883 call feedkeys('a' .. a:func('x', 3) .. "\<Esc>", 'Lx!')
884 call assert_equal("ø", getline(1))
885
886 " Meta-x is also ø
887 call setline(1, '')
888 call feedkeys('a' .. a:func('x', 9) .. "\<Esc>", 'Lx!')
889 call assert_equal("ø", getline(1))
890
891 " Alt-X is Ø
892 call setline(1, '')
893 call feedkeys('a' .. a:func('X', 3) .. "\<Esc>", 'Lx!')
894 call assert_equal("Ø", getline(1))
895
896 " Meta-X is ø
897 call setline(1, '')
898 call feedkeys('a' .. a:func('X', 9) .. "\<Esc>", 'Lx!')
899 call assert_equal("Ø", getline(1))
900
901 bwipe!
902 set timeoutlen&
903endfunc
904
Bram Moolenaar459fd782019-10-13 16:43:39 +0200905func Test_modifyOtherKeys_basic()
Bram Moolenaar18a79a62019-10-12 15:36:11 +0200906 call RunTest_modifyOtherKeys(function('GetEscCodeCSI27'))
Bram Moolenaar18a79a62019-10-12 15:36:11 +0200907 call RunTest_modifyOtherKeys(function('GetEscCodeCSIu'))
908endfunc
Bram Moolenaard1e2f392019-10-12 18:22:50 +0200909
910func RunTest_mapping_shift(key, func)
911 call setline(1, '')
912 if a:key == '|'
913 exe 'inoremap \| xyz'
914 else
915 exe 'inoremap ' .. a:key .. ' xyz'
916 endif
917 call feedkeys('a' .. a:func(a:key, 2) .. "\<Esc>", 'Lx!')
918 call assert_equal("xyz", getline(1))
919 if a:key == '|'
920 exe 'iunmap \|'
921 else
922 exe 'iunmap ' .. a:key
923 endif
924endfunc
925
926func RunTest_mapping_works_with_shift(func)
927 new
Bram Moolenaar459fd782019-10-13 16:43:39 +0200928 set timeoutlen=10
Bram Moolenaard1e2f392019-10-12 18:22:50 +0200929
930 call RunTest_mapping_shift('@', a:func)
931 call RunTest_mapping_shift('A', a:func)
932 call RunTest_mapping_shift('Z', a:func)
933 call RunTest_mapping_shift('^', a:func)
934 call RunTest_mapping_shift('_', a:func)
935 call RunTest_mapping_shift('{', a:func)
936 call RunTest_mapping_shift('|', a:func)
937 call RunTest_mapping_shift('}', a:func)
938 call RunTest_mapping_shift('~', a:func)
939
940 bwipe!
941 set timeoutlen&
942endfunc
943
Bram Moolenaar459fd782019-10-13 16:43:39 +0200944func Test_mapping_works_with_shift_plain()
Bram Moolenaard1e2f392019-10-12 18:22:50 +0200945 call RunTest_mapping_works_with_shift(function('GetEscCodeCSI27'))
946 call RunTest_mapping_works_with_shift(function('GetEscCodeCSIu'))
947endfunc
Bram Moolenaar459fd782019-10-13 16:43:39 +0200948
949func RunTest_mapping_mods(map, key, func, code)
950 call setline(1, '')
951 exe 'inoremap ' .. a:map .. ' xyz'
952 call feedkeys('a' .. a:func(a:key, a:code) .. "\<Esc>", 'Lx!')
953 call assert_equal("xyz", getline(1))
954 exe 'iunmap ' .. a:map
955endfunc
956
957func RunTest_mapping_works_with_mods(func, mods, code)
958 new
959 set timeoutlen=10
960
961 if a:mods !~ 'S'
962 " Shift by itself has no effect
963 call RunTest_mapping_mods('<' .. a:mods .. '-@>', '@', a:func, a:code)
964 endif
965 call RunTest_mapping_mods('<' .. a:mods .. '-A>', 'A', a:func, a:code)
966 call RunTest_mapping_mods('<' .. a:mods .. '-Z>', 'Z', a:func, a:code)
967 if a:mods !~ 'S'
968 " with Shift code is always upper case
969 call RunTest_mapping_mods('<' .. a:mods .. '-a>', 'a', a:func, a:code)
970 call RunTest_mapping_mods('<' .. a:mods .. '-z>', 'z', a:func, a:code)
971 endif
972 if a:mods != 'A'
973 " with Alt code is not in upper case
974 call RunTest_mapping_mods('<' .. a:mods .. '-a>', 'A', a:func, a:code)
975 call RunTest_mapping_mods('<' .. a:mods .. '-z>', 'Z', a:func, a:code)
976 endif
977 call RunTest_mapping_mods('<' .. a:mods .. '-á>', 'á', a:func, a:code)
978 if a:mods !~ 'S'
979 " Shift by itself has no effect
980 call RunTest_mapping_mods('<' .. a:mods .. '-^>', '^', a:func, a:code)
981 call RunTest_mapping_mods('<' .. a:mods .. '-_>', '_', a:func, a:code)
982 call RunTest_mapping_mods('<' .. a:mods .. '-{>', '{', a:func, a:code)
983 call RunTest_mapping_mods('<' .. a:mods .. '-\|>', '|', a:func, a:code)
984 call RunTest_mapping_mods('<' .. a:mods .. '-}>', '}', a:func, a:code)
985 call RunTest_mapping_mods('<' .. a:mods .. '-~>', '~', a:func, a:code)
986 endif
987
988 bwipe!
989 set timeoutlen&
990endfunc
991
992func Test_mapping_works_with_shift()
993 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'S', 2)
994 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'S', 2)
995endfunc
996
997func Test_mapping_works_with_ctrl()
998 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C', 5)
999 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C', 5)
1000endfunc
1001
1002func Test_mapping_works_with_shift_ctrl()
1003 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-S', 6)
1004 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-S', 6)
1005endfunc
1006
1007" Below we also test the "u" code with Alt, This works, but libvterm would not
1008" send the Alt key like this but by prefixing an Esc.
1009
1010func Test_mapping_works_with_alt()
1011 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'A', 3)
1012 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'A', 3)
1013endfunc
1014
1015func Test_mapping_works_with_shift_alt()
1016 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'S-A', 4)
1017 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'S-A', 4)
1018endfunc
1019
1020func Test_mapping_works_with_ctrl_alt()
1021 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-A', 7)
1022 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-A', 7)
1023endfunc
1024
1025func Test_mapping_works_with_shift_ctrl_alt()
1026 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-S-A', 8)
1027 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-S-A', 8)
1028endfunc