blob: db98a70b48e4f5eac78c0da2a570b2dd91d6cba9 [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
Bram Moolenaar515545e2020-03-22 14:08:59 +01009source mouse.vim
Bram Moolenaarecd34bf2020-08-04 20:17:31 +020010source view_util.vim
Bram Moolenaare46a2ed2020-08-04 21:04:57 +020011source term_util.vim
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +020012
Christian Brabandtd7f58542025-01-31 16:13:14 +010013func s:TermGuiColorsTest()
14 CheckNotMSWindows
15 if !CanRunVimInTerminal()
16 throw 'Skipped: cannot make screendumps'
17 endif
18 if !executable('tput')
19 throw "Skipped: tput not executable!"
20 endif
21 if has("gui_running")
22 throw "Skipped: does not work in GUI mode"
23 endif
24 call system('tput -Txterm-direct RGB 2>/dev/null')
25 if v:shell_error
26 throw "Skipped: xterm-direct $TERM has no RGB capability"
27 endif
28endfunc
29
30
Bram Moolenaar92fd5992019-05-02 23:00:22 +020031func Test_term_mouse_left_click()
Bram Moolenaar905dd902019-04-07 14:21:47 +020032 new
33 let save_mouse = &mouse
34 let save_term = &term
35 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +020036 call test_override('no_query_mouse', 1)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +020037 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +000038 call WaitForResponses()
39
Bram Moolenaar905dd902019-04-07 14:21:47 +020040 call setline(1, ['line 1', 'line 2', 'line 3 is a bit longer'])
Bram Moolenaar905dd902019-04-07 14:21:47 +020041
Bram Moolenaar515545e2020-03-22 14:08:59 +010042 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm
Bram Moolenaar49452192019-04-17 16:27:02 +020043 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +020044 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +020045 go
Bram Moolenaar49452192019-04-17 16:27:02 +020046 call assert_equal([0, 1, 1, 0], getpos('.'), msg)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +020047 let row = 2
48 let col = 6
49 call MouseLeftClick(row, col)
50 call MouseLeftRelease(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +020051 call assert_equal([0, 2, 6, 0], getpos('.'), msg)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +020052 endfor
Bram Moolenaar905dd902019-04-07 14:21:47 +020053
54 let &mouse = save_mouse
55 let &term = save_term
56 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +020057 call test_override('no_query_mouse', 0)
Bram Moolenaar905dd902019-04-07 14:21:47 +020058 bwipe!
59endfunc
60
Bram Moolenaar6aa75232019-10-13 21:01:34 +020061func Test_xterm_mouse_right_click_extends_visual()
62 if has('mac')
63 throw "Skipped: test right click in visual mode does not work on macOs (why?)"
64 endif
65 let save_mouse = &mouse
66 let save_term = &term
67 let save_ttymouse = &ttymouse
68 call test_override('no_query_mouse', 1)
69 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +000070 call WaitForResponses()
Bram Moolenaar6aa75232019-10-13 21:01:34 +020071
72 for visual_mode in ["v", "V", "\<C-V>"]
Bram Moolenaar515545e2020-03-22 14:08:59 +010073 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaar6aa75232019-10-13 21:01:34 +020074 let msg = 'visual=' .. visual_mode .. ' ttymouse=' .. ttymouse_val
75 exe 'set ttymouse=' .. ttymouse_val
76
77 call setline(1, repeat([repeat('-', 7)], 7))
78 call MouseLeftClick(4, 4)
79 call MouseLeftRelease(4, 4)
80 exe "norm! " .. visual_mode
81
82 " Right click extends top left of visual area.
83 call MouseRightClick(2, 2)
84 call MouseRightRelease(2, 2)
85
Bram Moolenaarf19f8d12019-12-18 19:36:23 +010086 " Right click extends bottom right of visual area.
Bram Moolenaar6aa75232019-10-13 21:01:34 +020087 call MouseRightClick(6, 6)
88 call MouseRightRelease(6, 6)
89 norm! r1gv
90
91 " Right click shrinks top left of visual area.
92 call MouseRightClick(3, 3)
93 call MouseRightRelease(3, 3)
94
95 " Right click shrinks bottom right of visual area.
96 call MouseRightClick(5, 5)
97 call MouseRightRelease(5, 5)
98 norm! r2
99
100 if visual_mode ==# 'v'
101 call assert_equal(['-------',
102 \ '-111111',
103 \ '1122222',
104 \ '2222222',
105 \ '2222211',
106 \ '111111-',
107 \ '-------'], getline(1, '$'), msg)
108 elseif visual_mode ==# 'V'
109 call assert_equal(['-------',
110 \ '1111111',
111 \ '2222222',
112 \ '2222222',
113 \ '2222222',
114 \ '1111111',
115 \ '-------'], getline(1, '$'), msg)
116 else
117 call assert_equal(['-------',
118 \ '-11111-',
119 \ '-12221-',
120 \ '-12221-',
121 \ '-12221-',
122 \ '-11111-',
123 \ '-------'], getline(1, '$'), msg)
124 endif
125 endfor
126 endfor
127
128 let &mouse = save_mouse
129 let &term = save_term
130 let &ttymouse = save_ttymouse
131 call test_override('no_query_mouse', 0)
132 bwipe!
133endfunc
134
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200135" Test that <C-LeftMouse> jumps to help tag and <C-RightMouse> jumps back.
Bram Moolenaar297bec02020-07-14 22:11:04 +0200136" Also test for g<LeftMouse> and g<RightMouse>.
137func Test_xterm_mouse_tagjump()
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200138 let save_mouse = &mouse
139 let save_term = &term
140 let save_ttymouse = &ttymouse
141 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +0000142 call WaitForResponses()
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200143
Bram Moolenaar515545e2020-03-22 14:08:59 +0100144 for ttymouse_val in g:Ttymouse_values
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200145 let msg = 'ttymouse=' .. ttymouse_val
146 exe 'set ttymouse=' .. ttymouse_val
147 help
148 /usr_02.txt
149 norm! zt
Bram Moolenaar297bec02020-07-14 22:11:04 +0200150
151 " CTRL-left click to jump to a tag
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200152 let row = 1
153 let col = 1
154 call MouseCtrlLeftClick(row, col)
155 call MouseLeftRelease(row, col)
156 call assert_match('usr_02.txt$', bufname('%'), msg)
Bram Moolenaarb4367b72019-10-01 14:19:07 +0200157 call assert_equal('*usr_02.txt*', expand('<cWORD>'), msg)
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200158
Bram Moolenaar297bec02020-07-14 22:11:04 +0200159 " CTRL-right click to pop a tag
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200160 call MouseCtrlRightClick(row, col)
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200161 call MouseRightRelease(row, col)
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200162 call assert_match('help.txt$', bufname('%'), msg)
Bram Moolenaarb4367b72019-10-01 14:19:07 +0200163 call assert_equal('|usr_02.txt|', expand('<cWORD>'), msg)
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200164
Bram Moolenaar297bec02020-07-14 22:11:04 +0200165 " Jump to a tag
166 exe "normal \<C-]>"
167 call assert_match('usr_02.txt$', bufname('%'), msg)
168 call assert_equal('*usr_02.txt*', expand('<cWORD>'), msg)
169
170 " Use CTRL-right click in insert mode to pop the tag
171 new
172 let str = 'iHello' .. MouseCtrlRightClickCode(row, col)
173 \ .. MouseRightReleaseCode(row, col) .. "\<C-C>"
Bram Moolenaar2764d062020-07-18 12:59:19 +0200174 call assert_fails('call feedkeys(str, "Lx!")', 'E37:', msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +0200175 close!
176
177 " CTRL-right click with a count
178 let str = "4" .. MouseCtrlRightClickCode(row, col)
179 \ .. MouseRightReleaseCode(row, col)
Bram Moolenaar2764d062020-07-18 12:59:19 +0200180 call assert_fails('call feedkeys(str, "Lx!")', 'E555:', msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +0200181 call assert_match('help.txt$', bufname('%'), msg)
182 call assert_equal(1, line('.'), msg)
183
184 " g<LeftMouse> to jump to a tag
185 /usr_02.txt
186 norm! zt
187 call test_setmouse(row, col)
188 exe "normal g\<LeftMouse>"
189 call assert_match('usr_02.txt$', bufname('%'), msg)
190 call assert_equal('*usr_02.txt*', expand('<cWORD>'), msg)
191
192 " g<RightMouse> to pop to a tag
193 call test_setmouse(row, col)
194 exe "normal g\<RightMouse>"
195 call assert_match('help.txt$', bufname('%'), msg)
196 call assert_equal('|usr_02.txt|', expand('<cWORD>'), msg)
197
198 %bw!
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200199 endfor
200
201 let &mouse = save_mouse
202 let &term = save_term
203 let &ttymouse = save_ttymouse
204endfunc
205
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200206func Test_term_mouse_middle_click()
Bram Moolenaar52992fe2019-08-12 14:20:33 +0200207 CheckFeature clipboard_working
Bram Moolenaar564344a2019-04-28 13:00:12 +0200208
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200209 new
210 let save_mouse = &mouse
211 let save_term = &term
212 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200213 call test_override('no_query_mouse', 1)
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200214 let save_quotestar = @*
Bram Moolenaar297bec02020-07-14 22:11:04 +0200215 let save_quoteplus = @+
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200216 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +0000217 call WaitForResponses()
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200218
Bram Moolenaar515545e2020-03-22 14:08:59 +0100219 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200220 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200221 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200222 call setline(1, ['123456789', '123456789'])
Bram Moolenaar297bec02020-07-14 22:11:04 +0200223 let @* = 'abc'
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200224
225 " Middle-click in the middle of the line pastes text where clicked.
226 let row = 1
227 let col = 6
228 call MouseMiddleClick(row, col)
229 call MouseMiddleRelease(row, col)
230 call assert_equal(['12345abc6789', '123456789'], getline(1, '$'), msg)
231
232 " Middle-click beyond end of the line pastes text at the end of the line.
233 let col = 20
234 call MouseMiddleClick(row, col)
235 call MouseMiddleRelease(row, col)
236 call assert_equal(['12345abc6789abc', '123456789'], getline(1, '$'), msg)
237
238 " Middle-click beyond the last line pastes in the last line.
239 let row = 5
240 let col = 3
241 call MouseMiddleClick(row, col)
242 call MouseMiddleRelease(row, col)
243 call assert_equal(['12345abc6789abc', '12abc3456789'], getline(1, '$'), msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +0200244
245 " Middle mouse click in operator pending mode beeps
246 call assert_beeps('exe "normal c\<MiddleMouse>"')
247
248 " Clicking middle mouse in visual mode, yanks the selection and pastes the
249 " clipboard contents
250 let save_clipboard = &clipboard
251 set clipboard=
252 let @" = ''
253 call cursor(1, 1)
254 call feedkeys("v3l" ..
255 \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7), 'Lx!')
256 call assert_equal(['12345abc6789abc', '12abc3abc456789'],
257 \ getline(1, '$'), msg)
Bram Moolenaar2764d062020-07-18 12:59:19 +0200258 call assert_equal('1234', @", msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +0200259 let &clipboard = save_clipboard
260
261 " Clicking middle mouse in select mode, replaces the selected text with
262 " the clipboard contents
263 let @+ = 'xyz'
264 call cursor(1, 3)
265 exe "normal gh\<Right>\<Right>\<MiddleMouse>"
266 call assert_equal(['12xyzabc6789abc', '12abc3abc456789'],
267 \ getline(1, '$'), msg)
Bram Moolenaar2764d062020-07-18 12:59:19 +0200268
269 " Prefixing middle click with [ or ] fixes the indent after pasting.
270 %d
271 call setline(1, " one two")
272 call setreg('r', 'red blue', 'l')
273 call test_setmouse(1, 5)
274 exe "normal \"r[\<MiddleMouse>"
275 call assert_equal(' red blue', getline(1), msg)
276 call test_setmouse(2, 5)
277 exe "normal \"r]\<MiddleMouse>"
278 call assert_equal(' red blue', getline(3), msg)
279 %d
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200280 endfor
281
282 let &mouse = save_mouse
283 let &term = save_term
284 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200285 call test_override('no_query_mouse', 0)
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200286 let @* = save_quotestar
zeertzjq0b933c32023-04-28 18:44:50 +0100287 let @+ = save_quoteplus
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200288 bwipe!
289endfunc
290
Bram Moolenaar297bec02020-07-14 22:11:04 +0200291" If clipboard is not working, then clicking the middle mouse button in visual
292" mode, will copy and paste the selected text.
293func Test_term_mouse_middle_click_no_clipboard()
294 if has('clipboard_working')
295 throw 'Skipped: clipboard support works'
Bram Moolenaar297bec02020-07-14 22:11:04 +0200296 endif
297 new
298 let save_mouse = &mouse
299 let save_term = &term
300 let save_ttymouse = &ttymouse
301 call test_override('no_query_mouse', 1)
302 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +0000303 call WaitForResponses()
Bram Moolenaar297bec02020-07-14 22:11:04 +0200304
305 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
306 let msg = 'ttymouse=' .. ttymouse_val
307 exe 'set ttymouse=' .. ttymouse_val
308 call setline(1, ['123456789', '123456789'])
309
310 " Clicking middle mouse in visual mode, yanks the selection and pastes it
311 call cursor(1, 1)
312 call feedkeys("v3l" ..
313 \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7), 'Lx!')
314 call assert_equal(['123456789', '1234561234789'],
315 \ getline(1, '$'), msg)
316 endfor
317
318 call test_override('no_query_mouse', 0)
319 let &ttymouse = save_ttymouse
320 let &term = save_term
321 let &mouse = save_mouse
Christian Brabandt08ea2e12025-01-25 15:01:42 +0100322 bw!
Bram Moolenaar297bec02020-07-14 22:11:04 +0200323endfunc
324
325func Test_term_mouse_middle_click_insert_mode()
326 CheckFeature clipboard_working
327
328 new
329 let save_mouse = &mouse
330 let save_term = &term
331 let save_ttymouse = &ttymouse
332 call test_override('no_query_mouse', 1)
333 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +0000334 call WaitForResponses()
Bram Moolenaar297bec02020-07-14 22:11:04 +0200335
336 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
337 let msg = 'ttymouse=' .. ttymouse_val
338 exe 'set ttymouse=' .. ttymouse_val
339 call setline(1, ['123456789', '123456789'])
340 let @* = 'abc'
341
Dominique Pelle923dce22021-11-21 11:36:04 +0000342 " Middle-click in insert mode doesn't move the cursor but inserts the
343 " contents of a register
Bram Moolenaar297bec02020-07-14 22:11:04 +0200344 call cursor(1, 4)
345 call feedkeys('i' ..
346 \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7) ..
347 \ "\<C-C>", 'Lx!')
348 call assert_equal(['123abc456789', '123456789'],
349 \ getline(1, '$'), msg)
Bram Moolenaar2764d062020-07-18 12:59:19 +0200350 call assert_equal([1, 6], [line('.'), col('.')], msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +0200351
352 " Middle-click in replace mode
353 call cursor(1, 1)
354 call feedkeys('$R' ..
355 \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7) ..
356 \ "\<C-C>", 'Lx!')
357 call assert_equal(['123abc45678abc', '123456789'],
358 \ getline(1, '$'), msg)
Bram Moolenaar2764d062020-07-18 12:59:19 +0200359 call assert_equal([1, 14], [line('.'), col('.')], msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +0200360 endfor
361
362 let &mouse = save_mouse
363 let &term = save_term
364 let &ttymouse = save_ttymouse
365 call test_override('no_query_mouse', 0)
366 close!
367endfunc
368
369" Test for switching window using mouse in insert mode
370func Test_term_mouse_switch_win_insert_mode()
371 5new
372 let save_mouse = &mouse
373 let save_term = &term
374 let save_ttymouse = &ttymouse
375 call test_override('no_query_mouse', 1)
376 set mouse=a term=xterm ttymouse=xterm2
Bram Moolenaarc255b782022-11-26 19:16:48 +0000377 call WaitForResponses()
Bram Moolenaar297bec02020-07-14 22:11:04 +0200378
379 call feedkeys('ivim' ..
380 \ MouseLeftClickCode(8, 6) .. MouseLeftReleaseCode(8, 6) ..
381 \ "\<C-C>", 'Lx!')
382 call assert_equal(2, winnr())
383 wincmd w
384 call assert_equal('n', mode())
385 call assert_equal(['vim'], getline(1, '$'))
386
387 let &mouse = save_mouse
388 let &term = save_term
389 let &ttymouse = save_ttymouse
390 call test_override('no_query_mouse', 0)
Christian Brabandt08ea2e12025-01-25 15:01:42 +0100391 bw!
Bram Moolenaar297bec02020-07-14 22:11:04 +0200392endfunc
393
Dominique Pelle923dce22021-11-21 11:36:04 +0000394" Test for using the mouse to increase the height of the cmdline window
Bram Moolenaar297bec02020-07-14 22:11:04 +0200395func Test_mouse_cmdwin_resize()
396 let save_mouse = &mouse
397 let save_term = &term
398 let save_ttymouse = &ttymouse
399 call test_override('no_query_mouse', 1)
400 set mouse=a term=xterm ttymouse=xterm2
Bram Moolenaarc255b782022-11-26 19:16:48 +0000401 call WaitForResponses()
402
Bram Moolenaar297bec02020-07-14 22:11:04 +0200403 5new
404 redraw!
405
406 let h = 0
407 let row = &lines - &cmdwinheight - 2
408 call feedkeys("q:" ..
409 \ MouseLeftClickCode(row, 1) ..
410 \ MouseLeftDragCode(row - 1, 1) ..
411 \ MouseLeftReleaseCode(row - 2, 1) ..
412 \ "alet h = \<C-R>=winheight(0)\<CR>\<CR>", 'Lx!')
413 call assert_equal(&cmdwinheight + 2, h)
414
415 let &mouse = save_mouse
416 let &term = save_term
417 let &ttymouse = save_ttymouse
418 call test_override('no_query_mouse', 0)
419 close!
420endfunc
421
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200422" TODO: for unclear reasons this test fails if it comes after
423" Test_xterm_mouse_ctrl_click()
424func Test_1xterm_mouse_wheel()
Bram Moolenaar049736f2019-04-07 21:55:07 +0200425 new
426 let save_mouse = &mouse
427 let save_term = &term
Bram Moolenaard58d4f92020-07-01 15:49:29 +0200428 let save_wrap = &wrap
Bram Moolenaar049736f2019-04-07 21:55:07 +0200429 let save_ttymouse = &ttymouse
Bram Moolenaard58d4f92020-07-01 15:49:29 +0200430 set mouse=a term=xterm nowrap
Bram Moolenaarc255b782022-11-26 19:16:48 +0000431 call WaitForResponses()
432
Bram Moolenaard58d4f92020-07-01 15:49:29 +0200433 call setline(1, range(100000000000000, 100000000000100))
Bram Moolenaar049736f2019-04-07 21:55:07 +0200434
Bram Moolenaar515545e2020-03-22 14:08:59 +0100435 for ttymouse_val in g:Ttymouse_values
Bram Moolenaar49452192019-04-17 16:27:02 +0200436 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200437 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200438 go
Bram Moolenaar49452192019-04-17 16:27:02 +0200439 call assert_equal(1, line('w0'), msg)
440 call assert_equal([0, 1, 1, 0], getpos('.'), msg)
Bram Moolenaar049736f2019-04-07 21:55:07 +0200441
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200442 call MouseWheelDown(1, 1)
Bram Moolenaar49452192019-04-17 16:27:02 +0200443 call assert_equal(4, line('w0'), msg)
444 call assert_equal([0, 4, 1, 0], getpos('.'), msg)
Bram Moolenaar049736f2019-04-07 21:55:07 +0200445
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200446 call MouseWheelDown(1, 1)
Bram Moolenaar49452192019-04-17 16:27:02 +0200447 call assert_equal(7, line('w0'), msg)
448 call assert_equal([0, 7, 1, 0], getpos('.'), msg)
Bram Moolenaar049736f2019-04-07 21:55:07 +0200449
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200450 call MouseWheelUp(1, 1)
Bram Moolenaar49452192019-04-17 16:27:02 +0200451 call assert_equal(4, line('w0'), msg)
452 call assert_equal([0, 7, 1, 0], getpos('.'), msg)
Bram Moolenaar049736f2019-04-07 21:55:07 +0200453
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200454 call MouseWheelUp(1, 1)
Bram Moolenaar49452192019-04-17 16:27:02 +0200455 call assert_equal(1, line('w0'), msg)
456 call assert_equal([0, 7, 1, 0], getpos('.'), msg)
Bram Moolenaard58d4f92020-07-01 15:49:29 +0200457
Christopher Plewright20b795e2022-12-20 20:01:58 +0000458 call MouseWheelRight(1, 1)
459 call assert_equal(7, 1 + virtcol(".") - wincol(), msg)
460 call assert_equal([0, 7, 7, 0], getpos('.'), msg)
Bram Moolenaard58d4f92020-07-01 15:49:29 +0200461
Christopher Plewright20b795e2022-12-20 20:01:58 +0000462 call MouseWheelRight(1, 1)
463 call assert_equal(13, 1 + virtcol(".") - wincol(), msg)
464 call assert_equal([0, 7, 13, 0], getpos('.'), msg)
Bram Moolenaard58d4f92020-07-01 15:49:29 +0200465
Christopher Plewright20b795e2022-12-20 20:01:58 +0000466 call MouseWheelLeft(1, 1)
467 call assert_equal(7, 1 + virtcol(".") - wincol(), msg)
468 call assert_equal([0, 7, 13, 0], getpos('.'), msg)
Bram Moolenaard58d4f92020-07-01 15:49:29 +0200469
Christopher Plewright20b795e2022-12-20 20:01:58 +0000470 call MouseWheelLeft(1, 1)
471 call assert_equal(1, 1 + virtcol(".") - wincol(), msg)
472 call assert_equal([0, 7, 13, 0], getpos('.'), msg)
473
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200474 endfor
Bram Moolenaar049736f2019-04-07 21:55:07 +0200475
476 let &mouse = save_mouse
477 let &term = save_term
Bram Moolenaard58d4f92020-07-01 15:49:29 +0200478 let &wrap = save_wrap
Bram Moolenaar049736f2019-04-07 21:55:07 +0200479 let &ttymouse = save_ttymouse
480 bwipe!
481endfunc
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200482
Bram Moolenaarb4367b72019-10-01 14:19:07 +0200483" Test that dragging beyond the window (at the bottom and at the top)
Bram Moolenaarf19f8d12019-12-18 19:36:23 +0100484" scrolls window content by the number of lines beyond the window.
Bram Moolenaarb4367b72019-10-01 14:19:07 +0200485func Test_term_mouse_drag_beyond_window()
486 let save_mouse = &mouse
487 let save_term = &term
488 let save_ttymouse = &ttymouse
489 call test_override('no_query_mouse', 1)
490 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +0000491 call WaitForResponses()
492
Bram Moolenaarb4367b72019-10-01 14:19:07 +0200493 let col = 1
494 call setline(1, range(1, 100))
495
496 " Split into 3 windows, and go into the middle window
497 " so we test dragging mouse below and above the window.
498 2split
499 wincmd j
500 2split
501
Bram Moolenaar515545e2020-03-22 14:08:59 +0100502 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaarb4367b72019-10-01 14:19:07 +0200503 let msg = 'ttymouse=' .. ttymouse_val
504 exe 'set ttymouse=' .. ttymouse_val
505
506 " Line #10 at the top.
507 norm! 10zt
508 redraw
509 call assert_equal(10, winsaveview().topline, msg)
510 call assert_equal(2, winheight(0), msg)
511
512 let row = 4
513 call MouseLeftClick(row, col)
514 call assert_equal(10, winsaveview().topline, msg)
515
516 " Drag downwards. We're still in the window so topline should
517 " not change yet.
518 let row += 1
519 call MouseLeftDrag(row, col)
520 call assert_equal(10, winsaveview().topline, msg)
521
522 " We now leave the window at the bottom, so the window content should
523 " scroll by 1 line, then 2 lines (etc) as we drag further away.
524 let row += 1
525 call MouseLeftDrag(row, col)
526 call assert_equal(11, winsaveview().topline, msg)
527
528 let row += 1
529 call MouseLeftDrag(row, col)
530 call assert_equal(13, winsaveview().topline, msg)
531
532 " Now drag upwards.
533 let row -= 1
534 call MouseLeftDrag(row, col)
535 call assert_equal(14, winsaveview().topline, msg)
536
537 " We're now back in the window so the topline should not change.
538 let row -= 1
539 call MouseLeftDrag(row, col)
540 call assert_equal(14, winsaveview().topline, msg)
541
542 let row -= 1
543 call MouseLeftDrag(row, col)
544 call assert_equal(14, winsaveview().topline, msg)
545
546 " We now leave the window at the top so the window content should
547 " scroll by 1 line, then 2, then 3 (etc) in the opposite direction.
548 let row -= 1
549 call MouseLeftDrag(row, col)
550 call assert_equal(13, winsaveview().topline, msg)
551
552 let row -= 1
553 call MouseLeftDrag(row, col)
554 call assert_equal(11, winsaveview().topline, msg)
555
556 let row -= 1
557 call MouseLeftDrag(row, col)
558 call assert_equal(8, winsaveview().topline, msg)
559
560 call MouseLeftRelease(row, col)
561 call assert_equal(8, winsaveview().topline, msg)
562 call assert_equal(2, winheight(0), msg)
563 endfor
564
565 let &mouse = save_mouse
566 let &term = save_term
567 let &ttymouse = save_ttymouse
568 call test_override('no_query_mouse', 0)
569 bwipe!
570endfunc
571
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200572func Test_term_mouse_drag_window_separator()
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200573 let save_mouse = &mouse
574 let save_term = &term
575 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200576 call test_override('no_query_mouse', 1)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200577 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +0000578 call WaitForResponses()
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200579
Bram Moolenaar515545e2020-03-22 14:08:59 +0100580 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaar49452192019-04-17 16:27:02 +0200581 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200582 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200583
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200584 " Split horizontally and test dragging the horizontal window separator.
585 split
586 let rowseparator = winheight(0) + 1
587 let row = rowseparator
588 let col = 1
Bram Moolenaarc8b3dda2019-04-12 21:42:52 +0200589
Bram Moolenaar2b00b9b2019-04-17 17:08:27 +0200590 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
591 if ttymouse_val !=# 'xterm2' || row <= 223
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200592 call MouseLeftClick(row, col)
593 let row -= 1
594 call MouseLeftDrag(row, col)
zeertzjq8e0ccb62022-11-01 18:35:27 +0000595 call assert_equal(rowseparator - 1, winheight(0) + 1, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200596 let row += 1
597 call MouseLeftDrag(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200598 call assert_equal(rowseparator, winheight(0) + 1, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200599 call MouseLeftRelease(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200600 call assert_equal(rowseparator, winheight(0) + 1, msg)
Bram Moolenaarc8b3dda2019-04-12 21:42:52 +0200601 endif
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200602 bwipe!
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200603
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200604 " Split vertically and test dragging the vertical window separator.
605 vsplit
606 let colseparator = winwidth(0) + 1
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200607 let row = 1
608 let col = colseparator
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200609
Bram Moolenaar2b00b9b2019-04-17 17:08:27 +0200610 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
611 if ttymouse_val !=# 'xterm2' || col <= 223
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200612 call MouseLeftClick(row, col)
613 let col -= 1
614 call MouseLeftDrag(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200615 call assert_equal(colseparator - 1, winwidth(0) + 1, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200616 let col += 1
617 call MouseLeftDrag(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200618 call assert_equal(colseparator, winwidth(0) + 1, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200619 call MouseLeftRelease(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200620 call assert_equal(colseparator, winwidth(0) + 1, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200621 endif
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200622 bwipe!
623 endfor
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200624
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200625 let &mouse = save_mouse
626 let &term = save_term
627 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200628 call test_override('no_query_mouse', 0)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200629endfunc
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200630
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200631func Test_term_mouse_drag_statusline()
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200632 let save_mouse = &mouse
633 let save_term = &term
634 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200635 call test_override('no_query_mouse', 1)
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200636 let save_laststatus = &laststatus
637 set mouse=a term=xterm laststatus=2
Bram Moolenaarc255b782022-11-26 19:16:48 +0000638 call WaitForResponses()
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200639
Bram Moolenaar515545e2020-03-22 14:08:59 +0100640 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaar49452192019-04-17 16:27:02 +0200641 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200642 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200643
Bram Moolenaar49452192019-04-17 16:27:02 +0200644 call assert_equal(1, &cmdheight, msg)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200645 let rowstatusline = winheight(0) + 1
646 let row = rowstatusline
647 let col = 1
Bram Moolenaarc8b3dda2019-04-12 21:42:52 +0200648
Bram Moolenaar2b00b9b2019-04-17 17:08:27 +0200649 if ttymouse_val ==# 'xterm2' && row > 223
650 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
Bram Moolenaarc8b3dda2019-04-12 21:42:52 +0200651 continue
652 endif
653
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200654 call MouseLeftClick(row, col)
655 let row -= 1
656 call MouseLeftDrag(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200657 call assert_equal(2, &cmdheight, msg)
658 call assert_equal(rowstatusline - 1, winheight(0) + 1, msg)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200659 let row += 1
660 call MouseLeftDrag(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200661 call assert_equal(1, &cmdheight, msg)
662 call assert_equal(rowstatusline, winheight(0) + 1, msg)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200663 call MouseLeftRelease(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200664 call assert_equal(1, &cmdheight, msg)
665 call assert_equal(rowstatusline, winheight(0) + 1, msg)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200666 endfor
667
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200668 let &mouse = save_mouse
669 let &term = save_term
670 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200671 call test_override('no_query_mouse', 0)
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200672 let &laststatus = save_laststatus
673endfunc
674
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200675func Test_term_mouse_click_tab()
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200676 let save_mouse = &mouse
677 let save_term = &term
678 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200679 call test_override('no_query_mouse', 1)
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200680 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +0000681 call WaitForResponses()
682
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200683 let row = 1
684
Bram Moolenaar515545e2020-03-22 14:08:59 +0100685 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm
Bram Moolenaar49452192019-04-17 16:27:02 +0200686 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200687 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200688 e Xfoo
689 tabnew Xbar
690
691 let a = split(execute(':tabs'), "\n")
692 call assert_equal(['Tab page 1',
693 \ ' Xfoo',
694 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200695 \ '> Xbar'], a, msg)
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200696
697 " Test clicking on tab names in the tabline at the top.
698 let col = 2
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200699 redraw
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200700 call MouseLeftClick(row, col)
701 call MouseLeftRelease(row, col)
702 let a = split(execute(':tabs'), "\n")
703 call assert_equal(['Tab page 1',
704 \ '> Xfoo',
705 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200706 \ ' Xbar'], a, msg)
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200707
708 let col = 9
709 call MouseLeftClick(row, col)
710 call MouseLeftRelease(row, col)
711 let a = split(execute(':tabs'), "\n")
712 call assert_equal(['Tab page 1',
713 \ ' Xfoo',
714 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200715 \ '> Xbar'], a, msg)
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200716
717 %bwipe!
718 endfor
719
720 let &mouse = save_mouse
721 let &term = save_term
722 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200723 call test_override('no_query_mouse', 0)
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200724endfunc
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200725
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200726func Test_term_mouse_click_X_to_close_tab()
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200727 let save_mouse = &mouse
728 let save_term = &term
729 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200730 call test_override('no_query_mouse', 1)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200731 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +0000732 call WaitForResponses()
733
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200734 let row = 1
735 let col = &columns
736
Bram Moolenaar515545e2020-03-22 14:08:59 +0100737 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm
Bram Moolenaar2b00b9b2019-04-17 17:08:27 +0200738 if ttymouse_val ==# 'xterm2' && col > 223
739 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200740 continue
741 endif
Bram Moolenaar49452192019-04-17 16:27:02 +0200742 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200743 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200744 e Xtab1
745 tabnew Xtab2
746 tabnew Xtab3
747 tabn 2
748
749 let a = split(execute(':tabs'), "\n")
750 call assert_equal(['Tab page 1',
751 \ ' Xtab1',
752 \ 'Tab page 2',
753 \ '> Xtab2',
754 \ 'Tab page 3',
Bram Moolenaar49452192019-04-17 16:27:02 +0200755 \ ' Xtab3'], a, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200756
757 " Click on "X" in tabline to close current tab i.e. Xtab2.
758 redraw
759 call MouseLeftClick(row, col)
760 call MouseLeftRelease(row, col)
761 let a = split(execute(':tabs'), "\n")
762 call assert_equal(['Tab page 1',
763 \ ' Xtab1',
764 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200765 \ '> Xtab3'], a, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200766
767 %bwipe!
768 endfor
769
770 let &mouse = save_mouse
771 let &term = save_term
772 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200773 call test_override('no_query_mouse', 0)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200774endfunc
Bram Moolenaare3e38282019-04-15 20:55:31 +0200775
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200776func Test_term_mouse_drag_to_move_tab()
Bram Moolenaare3e38282019-04-15 20:55:31 +0200777 let save_mouse = &mouse
778 let save_term = &term
779 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200780 call test_override('no_query_mouse', 1)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200781 " Set 'mousetime' to 1 to avoid recognizing a double-click in the loop
782 set mouse=a term=xterm mousetime=1
Bram Moolenaarc255b782022-11-26 19:16:48 +0000783 call WaitForResponses()
784
Bram Moolenaare3e38282019-04-15 20:55:31 +0200785 let row = 1
786
Bram Moolenaar515545e2020-03-22 14:08:59 +0100787 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaar49452192019-04-17 16:27:02 +0200788 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200789 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaare3e38282019-04-15 20:55:31 +0200790 e Xtab1
791 tabnew Xtab2
792
793 let a = split(execute(':tabs'), "\n")
794 call assert_equal(['Tab page 1',
795 \ ' Xtab1',
796 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200797 \ '> Xtab2'], a, msg)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200798 redraw
799
800 " Click in tab2 and drag it to tab1.
801 " Check getcharmod() to verify that click is not
802 " interpreted as a spurious double-click.
803 call MouseLeftClick(row, 10)
Bram Moolenaar49452192019-04-17 16:27:02 +0200804 call assert_equal(0, getcharmod(), msg)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200805 for col in [9, 8, 7, 6]
806 call MouseLeftDrag(row, col)
807 endfor
808 call MouseLeftRelease(row, col)
809 let a = split(execute(':tabs'), "\n")
810 call assert_equal(['Tab page 1',
811 \ '> Xtab2',
812 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200813 \ ' Xtab1'], a, msg)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200814
zeertzjq8e0ccb62022-11-01 18:35:27 +0000815 " Switch to tab1
816 tabnext
817 let a = split(execute(':tabs'), "\n")
818 call assert_equal(['Tab page 1',
819 \ ' Xtab2',
820 \ 'Tab page 2',
821 \ '> Xtab1'], a, msg)
822
823 " Click in tab2 and drag it to tab1.
824 " This time it is non-current tab.
825 call MouseLeftClick(row, 6)
826 call assert_equal(0, getcharmod(), msg)
827 for col in [7, 8, 9, 10]
828 call MouseLeftDrag(row, col)
829 endfor
830 call MouseLeftRelease(row, col)
831 let a = split(execute(':tabs'), "\n")
832 call assert_equal(['Tab page 1',
833 \ ' Xtab1',
834 \ 'Tab page 2',
835 \ '> Xtab2'], a, msg)
836
Bram Moolenaarf36a2c72019-11-16 18:57:16 +0100837 " Click elsewhere so that click in next iteration is not
838 " interpreted as unwanted double-click.
839 call MouseLeftClick(row, 11)
840 call MouseLeftRelease(row, 11)
841
Bram Moolenaare3e38282019-04-15 20:55:31 +0200842 %bwipe!
843 endfor
844
845 let &mouse = save_mouse
846 let &term = save_term
847 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200848 call test_override('no_query_mouse', 0)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200849 set mousetime&
850endfunc
851
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200852func Test_term_mouse_double_click_to_create_tab()
Bram Moolenaare3e38282019-04-15 20:55:31 +0200853 let save_mouse = &mouse
854 let save_term = &term
855 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200856 call test_override('no_query_mouse', 1)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200857 " Set 'mousetime' to a small value, so that double-click works but we don't
858 " have to wait long to avoid a triple-click.
Bram Moolenaarf36a2c72019-11-16 18:57:16 +0100859 set mouse=a term=xterm mousetime=200
Bram Moolenaarc255b782022-11-26 19:16:48 +0000860 call WaitForResponses()
861
Bram Moolenaare3e38282019-04-15 20:55:31 +0200862 let row = 1
863 let col = 10
864
Bram Moolenaar515545e2020-03-22 14:08:59 +0100865 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaar49452192019-04-17 16:27:02 +0200866 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200867 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaare3e38282019-04-15 20:55:31 +0200868 e Xtab1
869 tabnew Xtab2
870
871 let a = split(execute(':tabs'), "\n")
872 call assert_equal(['Tab page 1',
873 \ ' Xtab1',
874 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200875 \ '> Xtab2'], a, msg)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200876
877 redraw
878 call MouseLeftClick(row, col)
879 " Check getcharmod() to verify that first click is not
880 " interpreted as a spurious double-click.
Bram Moolenaar49452192019-04-17 16:27:02 +0200881 call assert_equal(0, getcharmod(), msg)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200882 call MouseLeftRelease(row, col)
883 call MouseLeftClick(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200884 call assert_equal(32, getcharmod(), msg) " double-click
Bram Moolenaare3e38282019-04-15 20:55:31 +0200885 call MouseLeftRelease(row, col)
886 let a = split(execute(':tabs'), "\n")
887 call assert_equal(['Tab page 1',
888 \ ' Xtab1',
889 \ 'Tab page 2',
890 \ '> [No Name]',
891 \ 'Tab page 3',
Bram Moolenaar49452192019-04-17 16:27:02 +0200892 \ ' Xtab2'], a, msg)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200893
Bram Moolenaarf36a2c72019-11-16 18:57:16 +0100894 " Click elsewhere so that click in next iteration is not
895 " interpreted as unwanted double click.
896 call MouseLeftClick(row, col + 1)
897 call MouseLeftRelease(row, col + 1)
898
Bram Moolenaare3e38282019-04-15 20:55:31 +0200899 %bwipe!
900 endfor
901
902 let &mouse = save_mouse
903 let &term = save_term
904 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200905 call test_override('no_query_mouse', 0)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200906 set mousetime&
907endfunc
Bram Moolenaar696d6372019-04-17 16:33:46 +0200908
Bram Moolenaarf36a2c72019-11-16 18:57:16 +0100909" Test double/triple/quadruple click in normal mode to visually select.
910func Test_term_mouse_multiple_clicks_to_visually_select()
911 let save_mouse = &mouse
912 let save_term = &term
913 let save_ttymouse = &ttymouse
914 call test_override('no_query_mouse', 1)
Bram Moolenaar94722c52023-01-28 19:19:03 +0000915
Bram Moolenaar2a5c61a2020-12-30 14:59:23 +0100916 " 'mousetime' must be sufficiently large, or else the test is flaky when
917 " using a ssh connection with X forwarding; i.e. ssh -X (issue #7563).
918 set mouse=a term=xterm mousetime=600
Bram Moolenaarc255b782022-11-26 19:16:48 +0000919 call WaitForResponses()
920
Bram Moolenaarf36a2c72019-11-16 18:57:16 +0100921 new
922
Bram Moolenaar515545e2020-03-22 14:08:59 +0100923 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaarf36a2c72019-11-16 18:57:16 +0100924 let msg = 'ttymouse=' .. ttymouse_val
925 exe 'set ttymouse=' .. ttymouse_val
926 call setline(1, ['foo [foo bar] foo', 'foo'])
927
928 " Double-click on word should visually select the word.
929 call MouseLeftClick(1, 2)
930 call assert_equal(0, getcharmod(), msg)
931 call MouseLeftRelease(1, 2)
932 call MouseLeftClick(1, 2)
933 call assert_equal(32, getcharmod(), msg) " double-click
934 call MouseLeftRelease(1, 2)
935 call assert_equal('v', mode(), msg)
936 norm! r1
937 call assert_equal(['111 [foo bar] foo', 'foo'], getline(1, '$'), msg)
938
939 " Double-click on opening square bracket should visually
940 " select the whole [foo bar].
941 call MouseLeftClick(1, 5)
942 call assert_equal(0, getcharmod(), msg)
943 call MouseLeftRelease(1, 5)
944 call MouseLeftClick(1, 5)
945 call assert_equal(32, getcharmod(), msg) " double-click
946 call MouseLeftRelease(1, 5)
947 call assert_equal('v', mode(), msg)
948 norm! r2
949 call assert_equal(['111 222222222 foo', 'foo'], getline(1, '$'), msg)
950
951 " Triple-click should visually select the whole line.
952 call MouseLeftClick(1, 3)
953 call assert_equal(0, getcharmod(), msg)
954 call MouseLeftRelease(1, 3)
955 call MouseLeftClick(1, 3)
956 call assert_equal(32, getcharmod(), msg) " double-click
957 call MouseLeftRelease(1, 3)
958 call MouseLeftClick(1, 3)
959 call assert_equal(64, getcharmod(), msg) " triple-click
960 call MouseLeftRelease(1, 3)
961 call assert_equal('V', mode(), msg)
962 norm! r3
963 call assert_equal(['33333333333333333', 'foo'], getline(1, '$'), msg)
964
965 " Quadruple-click should start visual block select.
966 call MouseLeftClick(1, 2)
967 call assert_equal(0, getcharmod(), msg)
968 call MouseLeftRelease(1, 2)
969 call MouseLeftClick(1, 2)
970 call assert_equal(32, getcharmod(), msg) " double-click
971 call MouseLeftRelease(1, 2)
972 call MouseLeftClick(1, 2)
973 call assert_equal(64, getcharmod(), msg) " triple-click
974 call MouseLeftRelease(1, 2)
975 call MouseLeftClick(1, 2)
976 call assert_equal(96, getcharmod(), msg) " quadruple-click
977 call MouseLeftRelease(1, 2)
978 call assert_equal("\<c-v>", mode(), msg)
979 norm! r4
980 call assert_equal(['34333333333333333', 'foo'], getline(1, '$'), msg)
Bram Moolenaar2764d062020-07-18 12:59:19 +0200981
982 " Double-click on a space character should visually select all the
983 " consecutive space characters.
984 %d
985 call setline(1, ' one two')
986 call MouseLeftClick(1, 2)
987 call MouseLeftRelease(1, 2)
988 call MouseLeftClick(1, 2)
989 call MouseLeftRelease(1, 2)
990 call assert_equal('v', mode(), msg)
991 norm! r1
992 call assert_equal(['1111one two'], getline(1, '$'), msg)
993
994 " Double-click on a word with exclusive selection
995 set selection=exclusive
996 let @" = ''
997 call MouseLeftClick(1, 10)
998 call MouseLeftRelease(1, 10)
999 call MouseLeftClick(1, 10)
1000 call MouseLeftRelease(1, 10)
1001 norm! y
1002 call assert_equal('two', @", msg)
1003
1004 " Double click to select a block of text with exclusive selection
1005 %d
1006 call setline(1, 'one (two) three')
1007 call MouseLeftClick(1, 5)
1008 call MouseLeftRelease(1, 5)
1009 call MouseLeftClick(1, 5)
1010 call MouseLeftRelease(1, 5)
1011 norm! y
1012 call assert_equal(5, col("'<"), msg)
1013 call assert_equal(10, col("'>"), msg)
1014
1015 call MouseLeftClick(1, 9)
1016 call MouseLeftRelease(1, 9)
1017 call MouseLeftClick(1, 9)
1018 call MouseLeftRelease(1, 9)
1019 norm! y
1020 call assert_equal(5, col("'<"), msg)
1021 call assert_equal(10, col("'>"), msg)
1022 set selection&
1023
1024 " Click somewhere else so that the clicks above is not combined with the
1025 " clicks in the next iteration.
1026 call MouseRightClick(3, 10)
1027 call MouseRightRelease(3, 10)
Bram Moolenaarf36a2c72019-11-16 18:57:16 +01001028 endfor
1029
1030 let &mouse = save_mouse
1031 let &term = save_term
1032 let &ttymouse = save_ttymouse
1033 set mousetime&
1034 call test_override('no_query_mouse', 0)
1035 bwipe!
1036endfunc
1037
Bram Moolenaar2764d062020-07-18 12:59:19 +02001038" Test for selecting text in visual blockwise mode using Alt-LeftClick
1039func Test_mouse_alt_leftclick()
1040 let save_mouse = &mouse
1041 let save_term = &term
1042 let save_ttymouse = &ttymouse
1043 call test_override('no_query_mouse', 1)
1044 set mouse=a term=xterm mousetime=200
1045 set mousemodel=popup
Bram Moolenaarc255b782022-11-26 19:16:48 +00001046 call WaitForResponses()
1047
Bram Moolenaar2764d062020-07-18 12:59:19 +02001048 new
1049 call setline(1, 'one (two) three')
1050
1051 for ttymouse_val in g:Ttymouse_values
1052 let msg = 'ttymouse=' .. ttymouse_val
1053 exe 'set ttymouse=' .. ttymouse_val
1054
1055 " Left click with the Alt modifier key should extend the selection in
1056 " blockwise visual mode.
1057 let @" = ''
1058 call MouseLeftClick(1, 3)
1059 call MouseLeftRelease(1, 3)
1060 call MouseAltLeftClick(1, 11)
1061 call MouseLeftRelease(1, 11)
1062 call assert_equal("\<C-V>", mode(), msg)
1063 normal! y
1064 call assert_equal('e (two) t', @")
1065 endfor
1066
1067 let &mouse = save_mouse
1068 let &term = save_term
1069 let &ttymouse = save_ttymouse
1070 set mousetime& mousemodel&
1071 call test_override('no_query_mouse', 0)
Christian Brabandt08ea2e12025-01-25 15:01:42 +01001072 bw!
Bram Moolenaar2764d062020-07-18 12:59:19 +02001073endfunc
1074
Bram Moolenaar696d6372019-04-17 16:33:46 +02001075func Test_xterm_mouse_click_in_fold_columns()
1076 new
1077 let save_mouse = &mouse
1078 let save_term = &term
1079 let save_ttymouse = &ttymouse
1080 let save_foldcolumn = &foldcolumn
Bram Moolenaar2b00b9b2019-04-17 17:08:27 +02001081 set mouse=a term=xterm foldcolumn=3 ttymouse=xterm2
Bram Moolenaarc255b782022-11-26 19:16:48 +00001082 call WaitForResponses()
Bram Moolenaar696d6372019-04-17 16:33:46 +02001083
1084 " Create 2 nested folds.
1085 call setline(1, range(1, 7))
1086 2,6fold
1087 norm! zR
1088 4,5fold
1089 call assert_equal([-1, -1, -1, 4, 4, -1, -1],
1090 \ map(range(1, 7), 'foldclosed(v:val)'))
1091
1092 " Click in "+" of inner fold in foldcolumn should open it.
1093 redraw
1094 let row = 4
1095 let col = 2
1096 call MouseLeftClick(row, col)
1097 call MouseLeftRelease(row, col)
1098 call assert_equal([-1, -1, -1, -1, -1, -1, -1],
1099 \ map(range(1, 7), 'foldclosed(v:val)'))
1100
1101 " Click in "-" of outer fold in foldcolumn should close it.
1102 redraw
1103 let row = 2
1104 let col = 1
1105 call MouseLeftClick(row, col)
1106 call MouseLeftRelease(row, col)
1107 call assert_equal([-1, 2, 2, 2, 2, 2, -1],
1108 \ map(range(1, 7), 'foldclosed(v:val)'))
1109 norm! zR
1110
1111 " Click in "|" of inner fold in foldcolumn should close it.
1112 redraw
1113 let row = 5
1114 let col = 2
1115 call MouseLeftClick(row, col)
1116 call MouseLeftRelease(row, col)
1117 call assert_equal([-1, -1, -1, 4, 4, -1, -1],
1118 \ map(range(1, 7), 'foldclosed(v:val)'))
1119
1120 let &foldcolumn = save_foldcolumn
1121 let &ttymouse = save_ttymouse
1122 let &term = save_term
1123 let &mouse = save_mouse
1124 bwipe!
1125endfunc
Bram Moolenaar66761db2019-06-05 22:07:51 +02001126
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01001127" Left or right click in Ex command line sets position of the cursor.
1128func Test_term_mouse_click_in_cmdline_to_set_pos()
1129 let save_mouse = &mouse
1130 let save_term = &term
1131 let save_ttymouse = &ttymouse
1132 call test_override('no_query_mouse', 1)
1133 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +00001134 call WaitForResponses()
1135
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01001136 let row = &lines
1137
Bram Moolenaar515545e2020-03-22 14:08:59 +01001138 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaarab505b12020-03-23 19:28:44 +01001139 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
1140 if ttymouse_val !=# 'xterm2' || row <= 223
1141 let msg = 'ttymouse=' .. ttymouse_val
1142 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01001143
Bram Moolenaarab505b12020-03-23 19:28:44 +01001144
1145 call feedkeys(':"3456789'
1146 \ .. MouseLeftClickCode(row, 7)
1147 \ .. MouseLeftReleaseCode(row, 7) .. 'L'
1148 \ .. MouseRightClickCode(row, 4)
1149 \ .. MouseRightReleaseCode(row, 4) .. 'R'
1150 \ .. "\<CR>", 'Lx!')
1151 call assert_equal('"3R456L789', @:, msg)
1152 endif
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01001153 endfor
1154
1155 let &mouse = save_mouse
1156 let &term = save_term
1157 let &ttymouse = save_ttymouse
1158 set mousetime&
1159 call test_override('no_query_mouse', 0)
1160endfunc
1161
1162" Middle click in command line pastes at position of cursor.
1163func Test_term_mouse_middle_click_in_cmdline_to_paste()
1164 CheckFeature clipboard_working
1165 let save_mouse = &mouse
1166 let save_term = &term
1167 let save_ttymouse = &ttymouse
1168 call test_override('no_query_mouse', 1)
1169 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +00001170 call WaitForResponses()
1171
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01001172 let row = &lines
1173 " Column values does not matter, paste is done at position of cursor.
1174 let col = 1
1175 let @* = 'paste'
1176
Bram Moolenaar515545e2020-03-22 14:08:59 +01001177 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01001178 let msg = 'ttymouse=' .. ttymouse_val
1179 exe 'set ttymouse=' .. ttymouse_val
1180
1181 call feedkeys(":\"->"
1182 \ .. MouseMiddleReleaseCode(row, col)
1183 \ .. MouseMiddleClickCode(row, col)
1184 \ .. "<-"
1185 \ .. MouseMiddleReleaseCode(row, col)
1186 \ .. MouseMiddleClickCode(row, col)
1187 \ .. "\<CR>", 'Lx!')
1188 call assert_equal('"->paste<-paste', @:, msg)
1189 endfor
1190
1191 let &mouse = save_mouse
1192 let &term = save_term
1193 let &ttymouse = save_ttymouse
1194 let @* = ''
1195 call test_override('no_query_mouse', 0)
1196endfunc
1197
Bram Moolenaar297bec02020-07-14 22:11:04 +02001198" Test for making sure S-Middlemouse doesn't do anything
1199func Test_term_mouse_shift_middle_click()
1200 new
1201 let save_mouse = &mouse
1202 let save_term = &term
1203 let save_ttymouse = &ttymouse
1204 call test_override('no_query_mouse', 1)
1205 set mouse=a term=xterm ttymouse=xterm2 mousemodel=
Bram Moolenaarc255b782022-11-26 19:16:48 +00001206 call WaitForResponses()
Bram Moolenaar297bec02020-07-14 22:11:04 +02001207
1208 call test_setmouse(1, 1)
1209 exe "normal \<S-MiddleMouse>"
1210 call assert_equal([''], getline(1, '$'))
1211 call assert_equal(1, winnr())
1212
1213 let &mouse = save_mouse
1214 let &term = save_term
1215 let &ttymouse = save_ttymouse
1216 set mousemodel&
1217 call test_override('no_query_mouse', 0)
1218 close!
1219endfunc
1220
1221" Test for using mouse in visual mode
1222func Test_term_mouse_visual_mode()
1223 new
1224 let save_mouse = &mouse
1225 let save_term = &term
1226 let save_ttymouse = &ttymouse
1227 call test_override('no_query_mouse', 1)
1228 set term=xterm ttymouse=xterm2
Bram Moolenaarc255b782022-11-26 19:16:48 +00001229 call WaitForResponses()
Bram Moolenaar297bec02020-07-14 22:11:04 +02001230
1231 " If visual mode is not present in 'mouse', then left click should not
1232 " do anything in visal mode.
1233 call setline(1, ['one two three four'])
1234 set mouse=nci
1235 call cursor(1, 5)
1236 let @" = ''
1237 call feedkeys("ve"
1238 \ .. MouseLeftClickCode(1, 15) .. MouseLeftReleaseCode(1, 15)
1239 \ .. 'y', 'Lx!')
1240 call assert_equal(5, col('.'))
1241 call assert_equal('two', @")
1242
1243 " Pressing right click in visual mode should change the visual selection
1244 " if 'mousemodel' doesn't contain popup.
1245 " Right click after the visual selection
1246 set mousemodel=
1247 set mouse=a
1248 call test_setmouse(1, 13)
1249 exe "normal 5|ve\<RightMouse>y"
1250 call assert_equal('two three', @")
1251 call assert_equal(5, col('.'))
1252
1253 " Right click before the visual selection
1254 call test_setmouse(1, 9)
1255 exe "normal 15|ve\<RightMouse>y"
1256 call assert_equal('three four', @")
1257 call assert_equal(9, col('.'))
1258
Bram Moolenaar2764d062020-07-18 12:59:19 +02001259 " Right click inside the selection closer to the start of the selection
1260 call test_setmouse(1, 7)
1261 exe "normal 5|vee\<RightMouse>lly"
1262 call assert_equal('three', @")
1263 call assert_equal(9, col('.'))
1264 call assert_equal(9, col("'<"))
1265 call assert_equal(13, col("'>"))
1266
1267 " Right click inside the selection closer to the end of the selection
1268 call test_setmouse(1, 11)
1269 exe "normal 5|vee\<RightMouse>ly"
1270 call assert_equal('two thre', @")
1271 call assert_equal(5, col('.'))
1272 call assert_equal(5, col("'<"))
1273 call assert_equal(12, col("'>"))
1274
dundargocc57b5bc2022-11-02 13:30:51 +00001275 " Multi-line selection. Right click inside the selection.
Bram Moolenaar2764d062020-07-18 12:59:19 +02001276 call setline(1, repeat(['aaaaaa'], 7))
Bram Moolenaar297bec02020-07-14 22:11:04 +02001277 call test_setmouse(3, 1)
1278 exe "normal ggVG\<RightMouse>y"
1279 call assert_equal(3, line("'<"))
Bram Moolenaar2764d062020-07-18 12:59:19 +02001280 call test_setmouse(5, 1)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001281 exe "normal ggVG\<RightMouse>y"
Bram Moolenaar2764d062020-07-18 12:59:19 +02001282 call assert_equal(5, line("'>"))
1283
1284 " Click right in the middle line of the selection
1285 call test_setmouse(4, 3)
1286 exe "normal ggVG$\<RightMouse>y"
1287 call assert_equal(4, line("'<"))
1288 call test_setmouse(4, 4)
1289 exe "normal ggVG$\<RightMouse>y"
Bram Moolenaar297bec02020-07-14 22:11:04 +02001290 call assert_equal(4, line("'>"))
1291
1292 set mousemodel&
1293 let &mouse = save_mouse
1294 let &term = save_term
1295 let &ttymouse = save_ttymouse
1296 call test_override('no_query_mouse', 0)
Christian Brabandt08ea2e12025-01-25 15:01:42 +01001297 bw!
Bram Moolenaar297bec02020-07-14 22:11:04 +02001298endfunc
1299
Bram Moolenaar0eabd4d2020-03-15 16:13:53 +01001300" Test for displaying the popup menu using the right mouse click
Bram Moolenaar297bec02020-07-14 22:11:04 +02001301func Test_term_mouse_popup_menu()
Bram Moolenaar0eabd4d2020-03-15 16:13:53 +01001302 CheckFeature menu
1303 new
1304 call setline(1, 'popup menu test')
1305 let save_mouse = &mouse
1306 let save_term = &term
1307 let save_ttymouse = &ttymouse
1308 let save_mousemodel = &mousemodel
1309 call test_override('no_query_mouse', 1)
1310 set mouse=a term=xterm mousemodel=popup
Bram Moolenaarc255b782022-11-26 19:16:48 +00001311 call WaitForResponses()
Bram Moolenaar0eabd4d2020-03-15 16:13:53 +01001312
1313 menu PopUp.foo :let g:menustr = 'foo'<CR>
1314 menu PopUp.bar :let g:menustr = 'bar'<CR>
1315 menu PopUp.baz :let g:menustr = 'baz'<CR>
1316
Bram Moolenaar515545e2020-03-22 14:08:59 +01001317 for ttymouse_val in g:Ttymouse_values
Bram Moolenaar2764d062020-07-18 12:59:19 +02001318 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar0eabd4d2020-03-15 16:13:53 +01001319 exe 'set ttymouse=' .. ttymouse_val
1320 let g:menustr = ''
1321 call feedkeys(MouseRightClickCode(1, 4)
1322 \ .. MouseRightReleaseCode(1, 4) .. "\<Down>\<Down>\<CR>", "x")
Bram Moolenaar2764d062020-07-18 12:59:19 +02001323 call assert_equal('bar', g:menustr, msg)
Bram Moolenaar0eabd4d2020-03-15 16:13:53 +01001324 endfor
1325
1326 unmenu PopUp
1327 let &mouse = save_mouse
1328 let &term = save_term
1329 let &ttymouse = save_ttymouse
1330 let &mousemodel = save_mousemodel
1331 call test_override('no_query_mouse', 0)
Christian Brabandt08ea2e12025-01-25 15:01:42 +01001332 bw!
Bram Moolenaar0eabd4d2020-03-15 16:13:53 +01001333endfunc
1334
Bram Moolenaar297bec02020-07-14 22:11:04 +02001335" Test for 'mousemodel' set to popup_setpos to move the cursor where the popup
1336" menu is displayed.
1337func Test_term_mouse_popup_menu_setpos()
1338 CheckFeature menu
1339 5new
1340 call setline(1, ['the dish ran away with the spoon',
1341 \ 'the cow jumped over the moon' ])
1342 let save_mouse = &mouse
1343 let save_term = &term
1344 let save_ttymouse = &ttymouse
1345 let save_mousemodel = &mousemodel
1346 call test_override('no_query_mouse', 1)
1347 set mouse=a term=xterm mousemodel=popup_setpos
Bram Moolenaarc255b782022-11-26 19:16:48 +00001348 call WaitForResponses()
Bram Moolenaar297bec02020-07-14 22:11:04 +02001349
1350 nmenu PopUp.foo :let g:menustr = 'foo'<CR>
1351 nmenu PopUp.bar :let g:menustr = 'bar'<CR>
1352 nmenu PopUp.baz :let g:menustr = 'baz'<CR>
1353 vmenu PopUp.foo y:<C-U>let g:menustr = 'foo'<CR>
1354 vmenu PopUp.bar y:<C-U>let g:menustr = 'bar'<CR>
1355 vmenu PopUp.baz y:<C-U>let g:menustr = 'baz'<CR>
1356
1357 for ttymouse_val in g:Ttymouse_values
Bram Moolenaar2764d062020-07-18 12:59:19 +02001358 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar297bec02020-07-14 22:11:04 +02001359 exe 'set ttymouse=' .. ttymouse_val
1360 let g:menustr = ''
1361 call cursor(1, 1)
1362 call feedkeys(MouseRightClickCode(1, 5)
1363 \ .. MouseRightReleaseCode(1, 5) .. "\<Down>\<Down>\<CR>", "x")
Bram Moolenaar2764d062020-07-18 12:59:19 +02001364 call assert_equal('bar', g:menustr, msg)
1365 call assert_equal([1, 5], [line('.'), col('.')], msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001366
1367 " Test for right click in visual mode inside the selection
1368 let @" = ''
1369 call cursor(1, 10)
1370 call feedkeys('vee' .. MouseRightClickCode(1, 12)
1371 \ .. MouseRightReleaseCode(1, 12) .. "\<Down>\<CR>", "x")
Bram Moolenaar2764d062020-07-18 12:59:19 +02001372 call assert_equal([1, 10], [line('.'), col('.')], msg)
1373 call assert_equal('ran away', @", msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001374
Yee Cheng Chin17822c52022-10-13 13:17:40 +01001375 " Test for right click in visual mode right before the selection
Bram Moolenaar297bec02020-07-14 22:11:04 +02001376 let @" = ''
1377 call cursor(1, 10)
Yee Cheng Chin17822c52022-10-13 13:17:40 +01001378 call feedkeys('vee' .. MouseRightClickCode(1, 9)
1379 \ .. MouseRightReleaseCode(1, 9) .. "\<Down>\<CR>", "x")
1380 call assert_equal([1, 9], [line('.'), col('.')], msg)
Bram Moolenaar2764d062020-07-18 12:59:19 +02001381 call assert_equal('', @", msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001382
Yee Cheng Chin17822c52022-10-13 13:17:40 +01001383 " Test for right click in visual mode right after the selection
Bram Moolenaar297bec02020-07-14 22:11:04 +02001384 let @" = ''
1385 call cursor(1, 10)
Yee Cheng Chin17822c52022-10-13 13:17:40 +01001386 call feedkeys('vee' .. MouseRightClickCode(1, 18)
1387 \ .. MouseRightReleaseCode(1, 18) .. "\<Down>\<CR>", "x")
1388 call assert_equal([1, 18], [line('.'), col('.')], msg)
Bram Moolenaar2764d062020-07-18 12:59:19 +02001389 call assert_equal('', @", msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001390
1391 " Test for right click in block-wise visual mode inside the selection
1392 let @" = ''
1393 call cursor(1, 16)
1394 call feedkeys("\<C-V>j3l" .. MouseRightClickCode(2, 17)
1395 \ .. MouseRightReleaseCode(2, 17) .. "\<Down>\<CR>", "x")
Bram Moolenaar2764d062020-07-18 12:59:19 +02001396 call assert_equal([1, 16], [line('.'), col('.')], msg)
1397 call assert_equal("\<C-V>4", getregtype('"'), msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001398
1399 " Test for right click in block-wise visual mode outside the selection
1400 let @" = ''
1401 call cursor(1, 16)
1402 call feedkeys("\<C-V>j3l" .. MouseRightClickCode(2, 2)
1403 \ .. MouseRightReleaseCode(2, 2) .. "\<Down>\<CR>", "x")
Bram Moolenaar2764d062020-07-18 12:59:19 +02001404 call assert_equal([2, 2], [line('.'), col('.')], msg)
1405 call assert_equal('v', getregtype('"'), msg)
1406 call assert_equal('', @", msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001407
Yee Cheng Chin17822c52022-10-13 13:17:40 +01001408 " Test for right click in line-wise visual mode inside the selection
1409 let @" = ''
1410 call cursor(1, 16)
1411 call feedkeys("V" .. MouseRightClickCode(1, 10)
1412 \ .. MouseRightReleaseCode(1, 10) .. "\<Down>\<CR>", "x")
1413 call assert_equal([1, 1], [line('.'), col('.')], msg) " After yanking, the cursor goes to 1,1
1414 call assert_equal("V", getregtype('"'), msg)
zeertzjqdf63f052022-10-19 15:12:54 +01001415 call assert_equal(1, len(getreg('"', 1, v:true)), msg)
Yee Cheng Chin17822c52022-10-13 13:17:40 +01001416
1417 " Test for right click in multi-line line-wise visual mode inside the selection
1418 let @" = ''
1419 call cursor(1, 16)
1420 call feedkeys("Vj" .. MouseRightClickCode(2, 20)
1421 \ .. MouseRightReleaseCode(2, 20) .. "\<Down>\<CR>", "x")
1422 call assert_equal([1, 1], [line('.'), col('.')], msg) " After yanking, the cursor goes to 1,1
1423 call assert_equal("V", getregtype('"'), msg)
zeertzjqdf63f052022-10-19 15:12:54 +01001424 call assert_equal(2, len(getreg('"', 1, v:true)), msg)
Yee Cheng Chin17822c52022-10-13 13:17:40 +01001425
1426 " Test for right click in line-wise visual mode outside the selection
1427 let @" = ''
1428 call cursor(1, 16)
1429 call feedkeys("V" .. MouseRightClickCode(2, 10)
1430 \ .. MouseRightReleaseCode(2, 10) .. "\<Down>\<CR>", "x")
1431 call assert_equal([2, 10], [line('.'), col('.')], msg)
1432 call assert_equal("", @", msg)
1433
Bram Moolenaar297bec02020-07-14 22:11:04 +02001434 " Try clicking on the status line
1435 let @" = ''
1436 call cursor(1, 10)
1437 call feedkeys('vee' .. MouseRightClickCode(6, 2)
1438 \ .. MouseRightReleaseCode(6, 2) .. "\<Down>\<CR>", "x")
Bram Moolenaar2764d062020-07-18 12:59:19 +02001439 call assert_equal([1, 10], [line('.'), col('.')], msg)
1440 call assert_equal('ran away', @", msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001441
1442 " Try clicking outside the window
1443 let @" = ''
zeertzjqdf63f052022-10-19 15:12:54 +01001444 call cursor(2, 2)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001445 call feedkeys('vee' .. MouseRightClickCode(7, 2)
1446 \ .. MouseRightReleaseCode(7, 2) .. "\<Down>\<CR>", "x")
Bram Moolenaar2764d062020-07-18 12:59:19 +02001447 call assert_equal(2, winnr(), msg)
1448 call assert_equal('', @", msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001449 wincmd w
1450 endfor
1451
1452 unmenu PopUp
1453 let &mouse = save_mouse
1454 let &term = save_term
1455 let &ttymouse = save_ttymouse
1456 let &mousemodel = save_mousemodel
1457 call test_override('no_query_mouse', 0)
Christian Brabandt08ea2e12025-01-25 15:01:42 +01001458 bw!
Bram Moolenaar297bec02020-07-14 22:11:04 +02001459endfunc
1460
1461" Test for searching for the word under the cursor using Shift-Right or
1462" Shift-Left click.
1463func Test_term_mouse_search()
1464 new
1465 let save_mouse = &mouse
1466 let save_term = &term
1467 let save_ttymouse = &ttymouse
1468 call test_override('no_query_mouse', 1)
1469 set mouse=a term=xterm ttymouse=xterm2
1470 set mousemodel=
Bram Moolenaarc255b782022-11-26 19:16:48 +00001471 call WaitForResponses()
Bram Moolenaar297bec02020-07-14 22:11:04 +02001472
1473 " In normal mode, Shift-Left or Shift-Right click should search for the word
1474 " under the cursor.
1475 call setline(1, ['one two three four', 'four three two one'])
1476 call test_setmouse(1, 4)
1477 exe "normal \<S-LeftMouse>"
1478 call assert_equal([2, 12], [line('.'), col('.')])
1479 call test_setmouse(2, 16)
1480 exe "normal \<S-RightMouse>"
1481 call assert_equal([1, 1], [line('.'), col('.')])
1482
1483 " In visual mode, Shift-Left or Shift-Right click should search for the word
1484 " under the cursor and extend the selection.
1485 call test_setmouse(1, 4)
1486 exe "normal 4|ve\<S-LeftMouse>y"
1487 call assert_equal([2, 12], [line("'>"), col("'>")])
1488 call test_setmouse(2, 16)
1489 exe "normal 2G16|ve\<S-RightMouse>y"
1490 call assert_equal([1, 1], [line("'<"), col("'<")])
1491
1492 set mousemodel&
1493 let &mouse = save_mouse
1494 let &term = save_term
1495 let &ttymouse = save_ttymouse
1496 call test_override('no_query_mouse', 0)
Christian Brabandt08ea2e12025-01-25 15:01:42 +01001497 bw!
Bram Moolenaar297bec02020-07-14 22:11:04 +02001498endfunc
1499
1500" Test for selecting an entry in the quickfix/location list window using the
1501" mouse.
1502func Test_term_mouse_quickfix_window()
1503 let save_mouse = &mouse
1504 let save_term = &term
1505 let save_ttymouse = &ttymouse
1506 call test_override('no_query_mouse', 1)
1507 set mouse=a term=xterm ttymouse=xterm2
1508 set mousemodel=
Bram Moolenaarc255b782022-11-26 19:16:48 +00001509 call WaitForResponses()
Bram Moolenaar297bec02020-07-14 22:11:04 +02001510
1511 cgetexpr "Xfile1:1:L1"
1512 copen 5
1513 call test_setmouse(&lines - 7, 1)
1514 exe "normal \<2-LeftMouse>"
1515 call assert_equal('Xfile1', @%)
1516 %bw!
1517
1518 lgetexpr "Xfile2:1:L1"
1519 lopen 5
1520 call test_setmouse(&lines - 7, 1)
1521 exe "normal \<2-LeftMouse>"
1522 call assert_equal('Xfile2', @%)
1523 %bw!
1524
1525 set mousemodel&
1526 let &mouse = save_mouse
1527 let &term = save_term
1528 let &ttymouse = save_ttymouse
1529 call test_override('no_query_mouse', 0)
1530endfunc
1531
Bram Moolenaar2764d062020-07-18 12:59:19 +02001532" Test for the 'h' flag in the 'mouse' option. Using mouse in the help window.
1533func Test_term_mouse_help_window()
1534 let save_mouse = &mouse
1535 let save_term = &term
1536 let save_ttymouse = &ttymouse
1537 call test_override('no_query_mouse', 1)
1538 set mouse=h term=xterm mousetime=200
Bram Moolenaarc255b782022-11-26 19:16:48 +00001539 call WaitForResponses()
Bram Moolenaar2764d062020-07-18 12:59:19 +02001540
1541 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
1542 let msg = 'ttymouse=' .. ttymouse_val
1543 exe 'set ttymouse=' .. ttymouse_val
1544 help
1545 let @" = ''
1546 call MouseLeftClick(2, 5)
1547 call MouseLeftRelease(2, 5)
1548 call MouseLeftClick(1, 1)
1549 call MouseLeftDrag(1, 10)
1550 call MouseLeftRelease(1, 10)
1551 norm! y
1552 call assert_equal('*help.txt*', @", msg)
1553 helpclose
1554
1555 " Click somewhere else to make sure the left click above is not combined
1556 " with the next left click and treated as a double click
1557 call MouseRightClick(5, 10)
1558 call MouseRightRelease(5, 10)
1559 endfor
1560
1561 let &mouse = save_mouse
1562 let &term = save_term
1563 let &ttymouse = save_ttymouse
1564 set mousetime&
1565 call test_override('no_query_mouse', 0)
1566 %bw!
1567endfunc
1568
1569" Test for the translation of various mouse terminal codes
1570func Test_mouse_termcodes()
1571 let save_mouse = &mouse
1572 let save_term = &term
1573 let save_ttymouse = &ttymouse
1574 call test_override('no_query_mouse', 1)
1575 set mouse=a term=xterm mousetime=200
Bram Moolenaarc255b782022-11-26 19:16:48 +00001576 call WaitForResponses()
Bram Moolenaar2764d062020-07-18 12:59:19 +02001577
1578 new
1579 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm
1580 let msg = 'ttymouse=' .. ttymouse_val
1581 exe 'set ttymouse=' .. ttymouse_val
1582
1583 let mouse_codes = [
1584 \ ["\<LeftMouse>", "<LeftMouse>"],
1585 \ ["\<MiddleMouse>", "<MiddleMouse>"],
1586 \ ["\<RightMouse>", "<RightMouse>"],
1587 \ ["\<S-LeftMouse>", "<S-LeftMouse>"],
1588 \ ["\<S-MiddleMouse>", "<S-MiddleMouse>"],
1589 \ ["\<S-RightMouse>", "<S-RightMouse>"],
1590 \ ["\<C-LeftMouse>", "<C-LeftMouse>"],
1591 \ ["\<C-MiddleMouse>", "<C-MiddleMouse>"],
1592 \ ["\<C-RightMouse>", "<C-RightMouse>"],
1593 \ ["\<M-LeftMouse>", "<M-LeftMouse>"],
1594 \ ["\<M-MiddleMouse>", "<M-MiddleMouse>"],
1595 \ ["\<M-RightMouse>", "<M-RightMouse>"],
1596 \ ["\<2-LeftMouse>", "<2-LeftMouse>"],
1597 \ ["\<2-MiddleMouse>", "<2-MiddleMouse>"],
1598 \ ["\<2-RightMouse>", "<2-RightMouse>"],
1599 \ ["\<3-LeftMouse>", "<3-LeftMouse>"],
1600 \ ["\<3-MiddleMouse>", "<3-MiddleMouse>"],
1601 \ ["\<3-RightMouse>", "<3-RightMouse>"],
1602 \ ["\<4-LeftMouse>", "<4-LeftMouse>"],
1603 \ ["\<4-MiddleMouse>", "<4-MiddleMouse>"],
1604 \ ["\<4-RightMouse>", "<4-RightMouse>"],
1605 \ ["\<LeftDrag>", "<LeftDrag>"],
1606 \ ["\<MiddleDrag>", "<MiddleDrag>"],
1607 \ ["\<RightDrag>", "<RightDrag>"],
1608 \ ["\<LeftRelease>", "<LeftRelease>"],
1609 \ ["\<MiddleRelease>", "<MiddleRelease>"],
1610 \ ["\<RightRelease>", "<RightRelease>"],
1611 \ ["\<ScrollWheelUp>", "<ScrollWheelUp>"],
1612 \ ["\<S-ScrollWheelUp>", "<S-ScrollWheelUp>"],
1613 \ ["\<C-ScrollWheelUp>", "<C-ScrollWheelUp>"],
1614 \ ["\<ScrollWheelDown>", "<ScrollWheelDown>"],
1615 \ ["\<S-ScrollWheelDown>", "<S-ScrollWheelDown>"],
1616 \ ["\<C-ScrollWheelDown>", "<C-ScrollWheelDown>"],
1617 \ ["\<ScrollWheelLeft>", "<ScrollWheelLeft>"],
1618 \ ["\<S-ScrollWheelLeft>", "<S-ScrollWheelLeft>"],
1619 \ ["\<C-ScrollWheelLeft>", "<C-ScrollWheelLeft>"],
1620 \ ["\<ScrollWheelRight>", "<ScrollWheelRight>"],
1621 \ ["\<S-ScrollWheelRight>", "<S-ScrollWheelRight>"],
1622 \ ["\<C-ScrollWheelRight>", "<C-ScrollWheelRight>"]
1623 \ ]
1624
1625 for [code, outstr] in mouse_codes
1626 exe "normal ggC\<C-K>" . code
1627 call assert_equal(outstr, getline(1), msg)
1628 endfor
1629 endfor
1630
1631 let &mouse = save_mouse
1632 let &term = save_term
1633 let &ttymouse = save_ttymouse
1634 set mousetime&
1635 call test_override('no_query_mouse', 0)
1636 %bw!
1637endfunc
1638
Bram Moolenaar66761db2019-06-05 22:07:51 +02001639" This only checks if the sequence is recognized.
Bram Moolenaar66761db2019-06-05 22:07:51 +02001640func Test_term_rgb_response()
1641 set t_RF=x
1642 set t_RB=y
1643
1644 " response to t_RF, 4 digits
1645 let red = 0x12
1646 let green = 0x34
1647 let blue = 0x56
1648 let seq = printf("\<Esc>]10;rgb:%02x00/%02x00/%02x00\x07", red, green, blue)
1649 call feedkeys(seq, 'Lx!')
1650 call assert_equal(seq, v:termrfgresp)
1651
1652 " response to t_RF, 2 digits
1653 let red = 0x78
1654 let green = 0x9a
1655 let blue = 0xbc
1656 let seq = printf("\<Esc>]10;rgb:%02x/%02x/%02x\x07", red, green, blue)
1657 call feedkeys(seq, 'Lx!')
1658 call assert_equal(seq, v:termrfgresp)
1659
Bram Moolenaar32e19772019-06-05 22:57:04 +02001660 " response to t_RB, 4 digits, dark
1661 set background=light
Bram Moolenaarce90e362019-09-08 18:58:44 +02001662 eval 'background'->test_option_not_set()
Bram Moolenaar32e19772019-06-05 22:57:04 +02001663 let red = 0x29
1664 let green = 0x4a
1665 let blue = 0x6b
1666 let seq = printf("\<Esc>]11;rgb:%02x00/%02x00/%02x00\x07", red, green, blue)
1667 call feedkeys(seq, 'Lx!')
1668 call assert_equal(seq, v:termrbgresp)
1669 call assert_equal('dark', &background)
1670
1671 " response to t_RB, 4 digits, light
1672 set background=dark
1673 call test_option_not_set('background')
1674 let red = 0x81
1675 let green = 0x63
Bram Moolenaar66761db2019-06-05 22:07:51 +02001676 let blue = 0x65
1677 let seq = printf("\<Esc>]11;rgb:%02x00/%02x00/%02x00\x07", red, green, blue)
1678 call feedkeys(seq, 'Lx!')
1679 call assert_equal(seq, v:termrbgresp)
Bram Moolenaar32e19772019-06-05 22:57:04 +02001680 call assert_equal('light', &background)
Bram Moolenaar66761db2019-06-05 22:07:51 +02001681
Bram Moolenaar32e19772019-06-05 22:57:04 +02001682 " response to t_RB, 2 digits, dark
1683 set background=light
1684 call test_option_not_set('background')
1685 let red = 0x47
1686 let green = 0x59
1687 let blue = 0x5b
Bram Moolenaar66761db2019-06-05 22:07:51 +02001688 let seq = printf("\<Esc>]11;rgb:%02x/%02x/%02x\x07", red, green, blue)
1689 call feedkeys(seq, 'Lx!')
1690 call assert_equal(seq, v:termrbgresp)
Bram Moolenaar32e19772019-06-05 22:57:04 +02001691 call assert_equal('dark', &background)
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01001692
Bram Moolenaar32e19772019-06-05 22:57:04 +02001693 " response to t_RB, 2 digits, light
1694 set background=dark
1695 call test_option_not_set('background')
1696 let red = 0x83
1697 let green = 0xa4
1698 let blue = 0xc2
1699 let seq = printf("\<Esc>]11;rgb:%02x/%02x/%02x\x07", red, green, blue)
1700 call feedkeys(seq, 'Lx!')
1701 call assert_equal(seq, v:termrbgresp)
1702 call assert_equal('light', &background)
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01001703
Bram Moolenaar66761db2019-06-05 22:07:51 +02001704 set t_RF= t_RB=
1705endfunc
1706
1707" This only checks if the sequence is recognized.
Bram Moolenaar1a4cbb12019-10-12 13:25:44 +02001708" This must be after other tests, because it has side effects to xterm
1709" properties.
1710func Test_xx01_term_style_response()
Bram Moolenaar66761db2019-06-05 22:07:51 +02001711 " Termresponse is only parsed when t_RV is not empty.
1712 set t_RV=x
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001713 call test_override('term_props', 1)
Bram Moolenaar66761db2019-06-05 22:07:51 +02001714
1715 " send the termresponse to trigger requesting the XT codes
1716 let seq = "\<Esc>[>41;337;0c"
1717 call feedkeys(seq, 'Lx!')
1718 call assert_equal(seq, v:termresponse)
1719
1720 let seq = "\<Esc>P1$r2 q\<Esc>\\"
1721 call feedkeys(seq, 'Lx!')
1722 call assert_equal(seq, v:termstyleresp)
1723
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001724 call assert_equal(#{
1725 \ cursor_style: 'u',
1726 \ cursor_blink_mode: 'u',
1727 \ underline_rgb: 'u',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001728 \ mouse: 's',
1729 \ kitty: 'u',
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001730 \ }, terminalprops())
1731
Bram Moolenaar66761db2019-06-05 22:07:51 +02001732 set t_RV=
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001733 call test_override('term_props', 0)
Bram Moolenaar66761db2019-06-05 22:07:51 +02001734endfunc
Bram Moolenaarde6dbb42019-06-06 11:59:18 +02001735
Bram Moolenaar89577b32019-10-18 21:26:05 +02001736" This checks the iTerm2 version response.
1737" This must be after other tests, because it has side effects to xterm
1738" properties.
1739func Test_xx02_iTerm2_response()
1740 " Termresponse is only parsed when t_RV is not empty.
1741 set t_RV=x
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001742 call test_override('term_props', 1)
Bram Moolenaar89577b32019-10-18 21:26:05 +02001743
1744 " Old versions of iTerm2 used a different style term response.
1745 set ttymouse=xterm
1746 call test_option_not_set('ttymouse')
1747 let seq = "\<Esc>[>0;95;c"
1748 call feedkeys(seq, 'Lx!')
1749 call assert_equal(seq, v:termresponse)
1750 call assert_equal('xterm', &ttymouse)
1751
1752 set ttymouse=xterm
1753 call test_option_not_set('ttymouse')
1754 let seq = "\<Esc>[>0;95;0c"
1755 call feedkeys(seq, 'Lx!')
1756 call assert_equal(seq, v:termresponse)
1757 call assert_equal('sgr', &ttymouse)
1758
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001759 call assert_equal(#{
1760 \ cursor_style: 'n',
1761 \ cursor_blink_mode: 'u',
1762 \ underline_rgb: 'u',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001763 \ mouse: 's',
1764 \ kitty: 'u',
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001765 \ }, terminalprops())
1766
Bram Moolenaar89577b32019-10-18 21:26:05 +02001767 set t_RV=
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001768 call test_override('term_props', 0)
Bram Moolenaar89577b32019-10-18 21:26:05 +02001769endfunc
1770
Bram Moolenaard55f9ef2022-08-26 12:26:07 +01001771func Run_libvterm_konsole_response(code)
Bram Moolenaar1a4cbb12019-10-12 13:25:44 +02001772 set ttymouse=xterm
1773 call test_option_not_set('ttymouse')
Bram Moolenaard55f9ef2022-08-26 12:26:07 +01001774 let seq = "\<Esc>[>0;" .. a:code .. ";0c"
Bram Moolenaar1a4cbb12019-10-12 13:25:44 +02001775 call feedkeys(seq, 'Lx!')
1776 call assert_equal(seq, v:termresponse)
1777 call assert_equal('sgr', &ttymouse)
1778
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001779 call assert_equal(#{
1780 \ cursor_style: 'n',
1781 \ cursor_blink_mode: 'u',
1782 \ underline_rgb: 'u',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001783 \ mouse: 's',
1784 \ kitty: 'u',
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001785 \ }, terminalprops())
Bram Moolenaard55f9ef2022-08-26 12:26:07 +01001786endfunc
1787
1788" This checks the libvterm version response.
1789" This must be after other tests, because it has side effects to xterm
1790" properties.
1791func Test_xx03_libvterm_konsole_response()
1792 " Termresponse is only parsed when t_RV is not empty.
1793 set t_RV=x
1794 call test_override('term_props', 1)
1795
1796 " libvterm
1797 call Run_libvterm_konsole_response(100)
1798 " Konsole
1799 call Run_libvterm_konsole_response(115)
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001800
Bram Moolenaar1a4cbb12019-10-12 13:25:44 +02001801 set t_RV=
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001802 call test_override('term_props', 0)
Bram Moolenaar1a4cbb12019-10-12 13:25:44 +02001803endfunc
1804
Bram Moolenaar89577b32019-10-18 21:26:05 +02001805" This checks the Mac Terminal.app version response.
1806" This must be after other tests, because it has side effects to xterm
1807" properties.
1808func Test_xx04_Mac_Terminal_response()
1809 " Termresponse is only parsed when t_RV is not empty.
1810 set t_RV=x
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001811 call test_override('term_props', 1)
Bram Moolenaar89577b32019-10-18 21:26:05 +02001812
1813 set ttymouse=xterm
Bram Moolenaar8dff4cb2020-06-14 14:34:16 +02001814 " t_8u is not reset
1815 let &t_8u = "\<Esc>[58;2;%lu;%lu;%lum"
Bram Moolenaar89577b32019-10-18 21:26:05 +02001816 call test_option_not_set('ttymouse')
1817 let seq = "\<Esc>[>1;95;0c"
1818 call feedkeys(seq, 'Lx!')
1819 call assert_equal(seq, v:termresponse)
1820 call assert_equal('sgr', &ttymouse)
1821
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001822 call assert_equal(#{
1823 \ cursor_style: 'n',
1824 \ cursor_blink_mode: 'u',
1825 \ underline_rgb: 'y',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001826 \ mouse: 's',
1827 \ kitty: 'u',
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001828 \ }, terminalprops())
Bram Moolenaar8dff4cb2020-06-14 14:34:16 +02001829 call assert_equal("\<Esc>[58;2;%lu;%lu;%lum", &t_8u)
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001830
Bram Moolenaar89577b32019-10-18 21:26:05 +02001831 " Reset is_not_xterm and is_mac_terminal.
1832 set t_RV=
1833 set term=xterm
1834 set t_RV=x
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001835 call test_override('term_props', 0)
Bram Moolenaar89577b32019-10-18 21:26:05 +02001836endfunc
1837
1838" This checks the mintty version response.
1839" This must be after other tests, because it has side effects to xterm
1840" properties.
1841func Test_xx05_mintty_response()
1842 " Termresponse is only parsed when t_RV is not empty.
1843 set t_RV=x
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001844 call test_override('term_props', 1)
Bram Moolenaar89577b32019-10-18 21:26:05 +02001845
1846 set ttymouse=xterm
1847 call test_option_not_set('ttymouse')
1848 let seq = "\<Esc>[>77;20905;0c"
1849 call feedkeys(seq, 'Lx!')
1850 call assert_equal(seq, v:termresponse)
1851 call assert_equal('sgr', &ttymouse)
1852
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001853 call assert_equal(#{
1854 \ cursor_style: 'n',
1855 \ cursor_blink_mode: 'u',
1856 \ underline_rgb: 'y',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001857 \ mouse: 's',
1858 \ kitty: 'u',
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001859 \ }, terminalprops())
1860
Bram Moolenaar89577b32019-10-18 21:26:05 +02001861 set t_RV=
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001862 call test_override('term_props', 0)
Bram Moolenaar89577b32019-10-18 21:26:05 +02001863endfunc
1864
1865" This checks the screen version response.
1866" This must be after other tests, because it has side effects to xterm
1867" properties.
1868func Test_xx06_screen_response()
1869 " Termresponse is only parsed when t_RV is not empty.
1870 set t_RV=x
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001871 call test_override('term_props', 1)
Bram Moolenaar89577b32019-10-18 21:26:05 +02001872
1873 " Old versions of screen don't support SGR mouse mode.
1874 set ttymouse=xterm
1875 call test_option_not_set('ttymouse')
1876 let seq = "\<Esc>[>83;40500;0c"
1877 call feedkeys(seq, 'Lx!')
1878 call assert_equal(seq, v:termresponse)
1879 call assert_equal('xterm', &ttymouse)
1880
1881 " screen supports SGR mouse mode starting in version 4.7.
1882 set ttymouse=xterm
1883 call test_option_not_set('ttymouse')
1884 let seq = "\<Esc>[>83;40700;0c"
1885 call feedkeys(seq, 'Lx!')
1886 call assert_equal(seq, v:termresponse)
1887 call assert_equal('sgr', &ttymouse)
1888
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001889 call assert_equal(#{
1890 \ cursor_style: 'n',
1891 \ cursor_blink_mode: 'n',
1892 \ underline_rgb: 'y',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001893 \ mouse: 's',
1894 \ kitty: 'u',
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001895 \ }, terminalprops())
1896
Bram Moolenaar89577b32019-10-18 21:26:05 +02001897 set t_RV=
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001898 call test_override('term_props', 0)
Bram Moolenaar89577b32019-10-18 21:26:05 +02001899endfunc
1900
Bram Moolenaard0eaf672022-04-20 19:55:37 +01001901func Do_check_t_8u_set_reset(set_by_user)
1902 set ttymouse=xterm
1903 call test_option_not_set('ttymouse')
1904 let default_value = "\<Esc>[58;2;%lu;%lu;%lum"
1905 let &t_8u = default_value
1906 if !a:set_by_user
1907 call test_option_not_set('t_8u')
1908 endif
1909 let seq = "\<Esc>[>0;279;0c"
1910 call feedkeys(seq, 'Lx!')
1911 call assert_equal(seq, v:termresponse)
1912 call assert_equal('sgr', &ttymouse)
1913
1914 call assert_equal(#{
1915 \ cursor_style: 'u',
1916 \ cursor_blink_mode: 'u',
1917 \ underline_rgb: 'u',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001918 \ mouse: 's',
1919 \ kitty: 'u',
Bram Moolenaard0eaf672022-04-20 19:55:37 +01001920 \ }, terminalprops())
1921 call assert_equal(a:set_by_user ? default_value : '', &t_8u)
1922endfunc
1923
Bram Moolenaar03b00472019-10-14 22:22:03 +02001924" This checks the xterm version response.
1925" This must be after other tests, because it has side effects to xterm
1926" properties.
Bram Moolenaar89577b32019-10-18 21:26:05 +02001927func Test_xx07_xterm_response()
Bram Moolenaar03b00472019-10-14 22:22:03 +02001928 " Termresponse is only parsed when t_RV is not empty.
1929 set t_RV=x
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001930 call test_override('term_props', 1)
Bram Moolenaar03b00472019-10-14 22:22:03 +02001931
Bram Moolenaar3cea8a92019-10-17 21:55:24 +02001932 " Do Terminal.app first to check that is_mac_terminal is reset.
1933 set ttymouse=xterm
1934 call test_option_not_set('ttymouse')
1935 let seq = "\<Esc>[>1;95;0c"
1936 call feedkeys(seq, 'Lx!')
1937 call assert_equal(seq, v:termresponse)
1938 call assert_equal('sgr', &ttymouse)
1939
Bram Moolenaar03b00472019-10-14 22:22:03 +02001940 " xterm < 95: "xterm" (actually unmodified)
Bram Moolenaar3cea8a92019-10-17 21:55:24 +02001941 set t_RV=
1942 set term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +00001943 call WaitForResponses()
1944
Bram Moolenaar3cea8a92019-10-17 21:55:24 +02001945 set t_RV=x
Bram Moolenaar03b00472019-10-14 22:22:03 +02001946 set ttymouse=xterm
1947 call test_option_not_set('ttymouse')
1948 let seq = "\<Esc>[>0;94;0c"
1949 call feedkeys(seq, 'Lx!')
1950 call assert_equal(seq, v:termresponse)
1951 call assert_equal('xterm', &ttymouse)
1952
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001953 call assert_equal(#{
1954 \ cursor_style: 'n',
1955 \ cursor_blink_mode: 'u',
1956 \ underline_rgb: 'y',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001957 \ mouse: 'u',
1958 \ kitty: 'u',
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001959 \ }, terminalprops())
1960
Bram Moolenaar03b00472019-10-14 22:22:03 +02001961 " xterm >= 95 < 277 "xterm2"
1962 set ttymouse=xterm
1963 call test_option_not_set('ttymouse')
1964 let seq = "\<Esc>[>0;267;0c"
1965 call feedkeys(seq, 'Lx!')
1966 call assert_equal(seq, v:termresponse)
1967 call assert_equal('xterm2', &ttymouse)
1968
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001969 call assert_equal(#{
1970 \ cursor_style: 'n',
1971 \ cursor_blink_mode: 'u',
1972 \ underline_rgb: 'u',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001973 \ mouse: '2',
1974 \ kitty: 'u',
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001975 \ }, terminalprops())
1976
Bram Moolenaar03b00472019-10-14 22:22:03 +02001977 " xterm >= 277: "sgr"
1978 set ttymouse=xterm
1979 call test_option_not_set('ttymouse')
1980 let seq = "\<Esc>[>0;277;0c"
1981 call feedkeys(seq, 'Lx!')
1982 call assert_equal(seq, v:termresponse)
1983 call assert_equal('sgr', &ttymouse)
1984
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001985 call assert_equal(#{
1986 \ cursor_style: 'n',
1987 \ cursor_blink_mode: 'u',
1988 \ underline_rgb: 'u',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001989 \ mouse: 's',
1990 \ kitty: 'u',
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001991 \ }, terminalprops())
1992
Bram Moolenaard0eaf672022-04-20 19:55:37 +01001993 " xterm >= 279: "sgr" and cursor_style not reset; also check t_8u reset,
1994 " except when it was set by the user
1995 call Do_check_t_8u_set_reset(0)
1996 call Do_check_t_8u_set_reset(1)
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001997
Bram Moolenaar03b00472019-10-14 22:22:03 +02001998 set t_RV=
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001999 call test_override('term_props', 0)
Bram Moolenaar03b00472019-10-14 22:22:03 +02002000endfunc
2001
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01002002func Test_xx08_kitty_response()
2003 " Termresponse is only parsed when t_RV is not empty.
2004 set t_RV=x
2005 call test_override('term_props', 1)
2006
2007 set ttymouse=xterm
2008 call test_option_not_set('ttymouse')
2009 let seq = "\<Esc>[>1;4001;12c"
2010 call feedkeys(seq, 'Lx!')
2011 call assert_equal(seq, v:termresponse)
2012 call assert_equal('sgr', &ttymouse)
2013
2014 call assert_equal(#{
2015 \ cursor_style: 'u',
2016 \ cursor_blink_mode: 'u',
2017 \ underline_rgb: 'y',
2018 \ mouse: 's',
2019 \ kitty: 'y',
2020 \ }, terminalprops())
2021
Christian Filliona2834e12024-10-16 17:28:38 +02002022 call feedkeys("\<Esc>[?1u") " simulate the kitty keyboard protocol is enabled
2023 call feedkeys(':' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIuWithoutModifier("\<Esc>") .. "\<C-B>\"\<CR>", 'Lx!')
2024 call assert_equal("\"\<Esc>", @:)
2025 call feedkeys(':' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu("\<Esc>", '129') .. "\<C-B>\"\<CR>", 'Lx!')
2026 call assert_equal("\"\<Esc>", @:)
2027
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01002028 set t_RV=
2029 call test_override('term_props', 0)
2030endfunc
2031
Bram Moolenaar92e5df82021-01-30 15:39:47 +01002032func Test_focus_events()
2033 let save_term = &term
2034 let save_ttymouse = &ttymouse
2035 set term=xterm ttymouse=xterm2
Bram Moolenaarc255b782022-11-26 19:16:48 +00002036 call WaitForResponses()
Bram Moolenaar92e5df82021-01-30 15:39:47 +01002037
2038 au FocusGained * let g:focus_gained += 1
2039 au FocusLost * let g:focus_lost += 1
2040 let g:focus_gained = 0
2041 let g:focus_lost = 0
2042
2043 call feedkeys("\<Esc>[O", "Lx!")
2044 call assert_equal(1, g:focus_lost)
2045 call feedkeys("\<Esc>[I", "Lx!")
2046 call assert_equal(1, g:focus_gained)
2047
2048 " still works when 'ttymouse' is empty
2049 set ttymouse=
2050 call feedkeys("\<Esc>[O", "Lx!")
2051 call assert_equal(2, g:focus_lost)
2052 call feedkeys("\<Esc>[I", "Lx!")
2053 call assert_equal(2, g:focus_gained)
2054
2055 au! FocusGained
2056 au! FocusLost
2057 let &term = save_term
2058 let &ttymouse = save_ttymouse
2059endfunc
2060
Bram Moolenaarde6dbb42019-06-06 11:59:18 +02002061func Test_get_termcode()
Bram Moolenaareb663282019-10-06 12:02:15 +02002062 try
2063 let k1 = &t_k1
2064 catch /E113/
2065 throw 'Skipped: Unable to query termcodes'
2066 endtry
Bram Moolenaarde6dbb42019-06-06 11:59:18 +02002067 set t_k1=
2068 set t_k1&
2069 call assert_equal(k1, &t_k1)
Bram Moolenaar9aeb3362019-06-06 12:36:15 +02002070
2071 " use external termcap first
2072 set nottybuiltin
2073 set t_k1=
2074 set t_k1&
2075 " when using external termcap may get something else, but it must not be
2076 " empty, since we would fallback to the builtin one.
2077 call assert_notequal('', &t_k1)
2078
2079 if &term =~ 'xterm'
2080 " use internal termcap first
2081 let term_save = &term
2082 let &term = 'builtin_' .. &term
2083 set t_k1=
2084 set t_k1&
2085 call assert_equal(k1, &t_k1)
2086 let &term = term_save
2087 endif
2088
2089 set ttybuiltin
Bram Moolenaarde6dbb42019-06-06 11:59:18 +02002090endfunc
Bram Moolenaar18a79a62019-10-12 15:36:11 +02002091
Bram Moolenaarecd34bf2020-08-04 20:17:31 +02002092func Test_list_builtin_terminals()
Bram Moolenaare46a2ed2020-08-04 21:04:57 +02002093 CheckRunVimInTerminal
Bram Moolenaar4654d632022-11-17 22:05:12 +00002094
Bram Moolenaar4d05af02020-11-27 20:55:00 +01002095 call RunVimInTerminal('', #{rows: 14})
2096 call term_sendkeys('', ":set cmdheight=3\<CR>")
2097 call TermWait('', 100)
2098 call term_sendkeys('', ":set term=xxx\<CR>")
2099 call TermWait('', 100)
Bram Moolenaar4654d632022-11-17 22:05:12 +00002100
2101 " Check that the list ends in "builtin_dumb" and "builtin_debug".
2102 let dumb_idx = 0
2103 for n in range(8, 12)
2104 if term_getline('', n) =~ 'builtin_dumb'
2105 let dumb_idx = n
2106 break
2107 endif
2108 endfor
2109 call assert_notequal(0, dumb_idx, 'builtin_dumb not found')
2110
2111 call assert_match('builtin_dumb', term_getline('', dumb_idx))
2112 call assert_match('builtin_debug', term_getline('', dumb_idx + 1))
2113 call assert_match('Not found in termcap', term_getline('', dumb_idx + 2))
2114
Bram Moolenaar4d05af02020-11-27 20:55:00 +01002115 call StopVimInTerminal('')
Bram Moolenaarecd34bf2020-08-04 20:17:31 +02002116endfunc
2117
Bram Moolenaar18a79a62019-10-12 15:36:11 +02002118" This checks the CSI sequences when in modifyOtherKeys mode.
2119" The mode doesn't need to be enabled, the codes are always detected.
2120func RunTest_modifyOtherKeys(func)
2121 new
Bram Moolenaar459fd782019-10-13 16:43:39 +02002122 set timeoutlen=10
Bram Moolenaar18a79a62019-10-12 15:36:11 +02002123
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01002124 " Shift-X is sent as 'X' with the shift modifier
Bram Moolenaar18a79a62019-10-12 15:36:11 +02002125 call feedkeys('a' .. a:func('X', 2) .. "\<Esc>", 'Lx!')
2126 call assert_equal('X', getline(1))
2127
2128 " Ctrl-i is Tab
2129 call setline(1, '')
2130 call feedkeys('a' .. a:func('i', 5) .. "\<Esc>", 'Lx!')
2131 call assert_equal("\t", getline(1))
2132
2133 " Ctrl-I is also Tab
2134 call setline(1, '')
2135 call feedkeys('a' .. a:func('I', 5) .. "\<Esc>", 'Lx!')
2136 call assert_equal("\t", getline(1))
2137
2138 " Alt-x is ø
2139 call setline(1, '')
2140 call feedkeys('a' .. a:func('x', 3) .. "\<Esc>", 'Lx!')
2141 call assert_equal("ø", getline(1))
2142
2143 " Meta-x is also ø
2144 call setline(1, '')
2145 call feedkeys('a' .. a:func('x', 9) .. "\<Esc>", 'Lx!')
2146 call assert_equal("ø", getline(1))
2147
2148 " Alt-X is Ø
2149 call setline(1, '')
2150 call feedkeys('a' .. a:func('X', 3) .. "\<Esc>", 'Lx!')
2151 call assert_equal("Ø", getline(1))
2152
2153 " Meta-X is ø
2154 call setline(1, '')
2155 call feedkeys('a' .. a:func('X', 9) .. "\<Esc>", 'Lx!')
2156 call assert_equal("Ø", getline(1))
2157
Bram Moolenaar828ffd52019-11-21 23:24:00 +01002158 " Ctrl-6 is Ctrl-^
2159 split aaa
2160 edit bbb
2161 call feedkeys(a:func('6', 5), 'Lx!')
2162 call assert_equal("aaa", bufname())
2163 bwipe aaa
2164 bwipe bbb
2165
Bram Moolenaar0684e362020-12-03 19:54:42 +01002166 " Ctrl-V X 33 is 3
2167 call setline(1, '')
2168 call feedkeys("a\<C-V>" .. a:func('X', 2) .. "33\<Esc>", 'Lx!')
2169 call assert_equal("3", getline(1))
2170
2171 " Ctrl-V U 12345 is Unicode 12345
2172 call setline(1, '')
2173 call feedkeys("a\<C-V>" .. a:func('U', 2) .. "12345\<Esc>", 'Lx!')
2174 call assert_equal("\U12345", getline(1))
2175
Bram Moolenaar18a79a62019-10-12 15:36:11 +02002176 bwipe!
2177 set timeoutlen&
2178endfunc
2179
Bram Moolenaar459fd782019-10-13 16:43:39 +02002180func Test_modifyOtherKeys_basic()
Bram Moolenaar18a79a62019-10-12 15:36:11 +02002181 call RunTest_modifyOtherKeys(function('GetEscCodeCSI27'))
Bram Moolenaar18a79a62019-10-12 15:36:11 +02002182 call RunTest_modifyOtherKeys(function('GetEscCodeCSIu'))
2183endfunc
Bram Moolenaard1e2f392019-10-12 18:22:50 +02002184
Bram Moolenaar38571a02019-11-26 14:28:15 +01002185func Test_modifyOtherKeys_no_mapping()
2186 set timeoutlen=10
2187
2188 let @a = 'aaa'
2189 call feedkeys(":let x = '" .. GetEscCodeCSI27('R', 5) .. GetEscCodeCSI27('R', 5) .. "a'\<CR>", 'Lx!')
2190 call assert_equal("let x = 'aaa'", @:)
2191
2192 new
2193 call feedkeys("a" .. GetEscCodeCSI27('R', 5) .. GetEscCodeCSI27('R', 5) .. "a\<Esc>", 'Lx!')
2194 call assert_equal("aaa", getline(1))
2195 bwipe!
2196
2197 new
2198 call feedkeys("axx\<CR>yy" .. GetEscCodeCSI27('G', 5) .. GetEscCodeCSI27('K', 5) .. "a\<Esc>", 'Lx!')
2199 call assert_equal("axx", getline(1))
2200 call assert_equal("yy", getline(2))
2201 bwipe!
2202
2203 set timeoutlen&
2204endfunc
2205
Trygve Aabergeb9c09c12022-10-14 12:08:24 +01002206func Test_CSIu_keys_without_modifiers()
Bram Moolenaarebed1b02022-11-24 14:05:19 +00002207 " make this execute faster
2208 set timeoutlen=10
2209
Bram Moolenaarc255b782022-11-26 19:16:48 +00002210 call WaitForResponses()
2211
Trygve Aabergeb9c09c12022-10-14 12:08:24 +01002212 " Escape sent as `CSI 27 u` should act as normal escape and not undo
2213 call setline(1, 'a')
2214 call feedkeys('a' .. GetEscCodeCSIuWithoutModifier("\e"), 'Lx!')
2215 call assert_equal('n', mode())
2216 call assert_equal('a', getline(1))
2217
2218 " Tab sent as `CSI 9 u` should work
2219 call setline(1, '')
2220 call feedkeys('a' .. GetEscCodeCSIuWithoutModifier("\t") .. "\<Esc>", 'Lx!')
2221 call assert_equal("\t", getline(1))
Bram Moolenaarebed1b02022-11-24 14:05:19 +00002222
2223 set timeoutlen&
Trygve Aabergeb9c09c12022-10-14 12:08:24 +01002224endfunc
2225
Bram Moolenaarc14b57c2021-12-03 13:20:29 +00002226" Check that when DEC mouse codes are recognized a special key is handled.
2227func Test_ignore_dec_mouse()
Dominique Pellef589fd32021-12-05 12:39:21 +00002228 silent !infocmp gnome >/dev/null 2>&1
2229 if v:shell_error != 0
2230 throw 'Skipped: gnome entry missing in the terminfo db'
2231 endif
Bram Moolenaarc14b57c2021-12-03 13:20:29 +00002232
2233 new
2234 let save_mouse = &mouse
2235 let save_term = &term
2236 let save_ttymouse = &ttymouse
2237 call test_override('no_query_mouse', 1)
2238 set mouse=a term=gnome ttymouse=
Bram Moolenaarc255b782022-11-26 19:16:48 +00002239 call WaitForResponses()
Bram Moolenaarc14b57c2021-12-03 13:20:29 +00002240
2241 execute "set <xF1>=\<Esc>[1;*P"
2242 nnoremap <S-F1> agot it<Esc>
2243 call feedkeys("\<Esc>[1;2P", 'Lx!')
2244 call assert_equal('got it', getline(1))
2245
2246 let &mouse = save_mouse
2247 let &term = save_term
2248 let &ttymouse = save_ttymouse
2249 call test_override('no_query_mouse', 0)
2250 bwipe!
2251endfunc
2252
Bram Moolenaard1e2f392019-10-12 18:22:50 +02002253func RunTest_mapping_shift(key, func)
2254 call setline(1, '')
2255 if a:key == '|'
2256 exe 'inoremap \| xyz'
2257 else
2258 exe 'inoremap ' .. a:key .. ' xyz'
2259 endif
2260 call feedkeys('a' .. a:func(a:key, 2) .. "\<Esc>", 'Lx!')
2261 call assert_equal("xyz", getline(1))
2262 if a:key == '|'
2263 exe 'iunmap \|'
2264 else
2265 exe 'iunmap ' .. a:key
2266 endif
2267endfunc
2268
Bram Moolenaar975a8802020-06-06 22:36:24 +02002269func Test_modifyOtherKeys_mapped()
2270 set timeoutlen=10
2271 imap ' <C-W>
2272 imap <C-W><C-A> c-a
2273 call setline(1, '')
2274
2275 " single quote is turned into single byte CTRL-W
2276 " CTRL-A is added with a separate modifier, and needs to be simplified before
2277 " the mapping can match.
2278 call feedkeys("a'" .. GetEscCodeCSI27('A', 5) .. "\<Esc>", 'Lx!')
2279 call assert_equal('c-a', getline(1))
2280
2281 iunmap '
2282 iunmap <C-W><C-A>
Oleg Goncharov56904f92024-07-23 20:34:15 +02002283
2284 " clean buffer
2285 %d _
2286 imap B b
2287 imap BBB blimp
2288 let input = repeat(GetEscCodeCSI27('B', 2), 3)
2289 call feedkeys("a" .. input .. "\<Esc>", 'Lx!')
2290 call assert_equal('blimp', getline(1))
2291 " cleanup
2292 iunmap BBB
2293 iunmap B
Bram Moolenaar975a8802020-06-06 22:36:24 +02002294 set timeoutlen&
2295endfunc
2296
Bram Moolenaar196c3852022-03-04 19:22:36 +00002297func Test_modifyOtherKeys_ambiguous_mapping()
2298 new
2299 set timeoutlen=10
2300 map <C-J> a
2301 map <C-J>x <Nop>
2302 call setline(1, 'x')
2303
2304 " CTRL-J b should have trigger the <C-J> mapping and then insert "b"
2305 call feedkeys(GetEscCodeCSI27('J', 5) .. "b\<Esc>", 'Lx!')
2306 call assert_equal('xb', getline(1))
2307
2308 unmap <C-J>
2309 unmap <C-J>x
Bram Moolenaarf35fd8e2022-03-18 15:41:17 +00002310
2311 " if a special character is following there should be a check for a termcode
2312 nnoremap s aX<Esc>
2313 nnoremap s<BS> aY<Esc>
2314 set t_kb=
2315 call setline(1, 'x')
2316 call feedkeys("s\x08", 'Lx!')
2317 call assert_equal('xY', getline(1))
2318
Bram Moolenaar196c3852022-03-04 19:22:36 +00002319 set timeoutlen&
2320 bwipe!
2321endfunc
2322
Bram Moolenaar749bc952020-10-31 16:33:47 +01002323" Whether Shift-Tab sends "ESC [ Z" or "ESC [ 27 ; 2 ; 9 ~" is unpredictable,
2324" both should work.
2325func Test_modifyOtherKeys_shift_tab()
2326 set timeoutlen=10
2327
2328 call setline(1, '')
2329 call feedkeys("a\<C-K>" .. GetEscCodeCSI27("\t", '2') .. "\<Esc>", 'Lx!')
2330 eval getline(1)->assert_equal('<S-Tab>')
2331
2332 call setline(1, '')
2333 call feedkeys("a\<C-K>\<Esc>[Z\<Esc>", 'Lx!')
2334 eval getline(1)->assert_equal('<S-Tab>')
2335
2336 set timeoutlen&
2337 bwipe!
2338endfunc
2339
Bram Moolenaard1e2f392019-10-12 18:22:50 +02002340func RunTest_mapping_works_with_shift(func)
2341 new
Bram Moolenaar459fd782019-10-13 16:43:39 +02002342 set timeoutlen=10
Bram Moolenaard1e2f392019-10-12 18:22:50 +02002343
2344 call RunTest_mapping_shift('@', a:func)
2345 call RunTest_mapping_shift('A', a:func)
2346 call RunTest_mapping_shift('Z', a:func)
2347 call RunTest_mapping_shift('^', a:func)
2348 call RunTest_mapping_shift('_', a:func)
2349 call RunTest_mapping_shift('{', a:func)
2350 call RunTest_mapping_shift('|', a:func)
2351 call RunTest_mapping_shift('}', a:func)
2352 call RunTest_mapping_shift('~', a:func)
2353
2354 bwipe!
2355 set timeoutlen&
2356endfunc
2357
Bram Moolenaar459fd782019-10-13 16:43:39 +02002358func Test_mapping_works_with_shift_plain()
Bram Moolenaard1e2f392019-10-12 18:22:50 +02002359 call RunTest_mapping_works_with_shift(function('GetEscCodeCSI27'))
2360 call RunTest_mapping_works_with_shift(function('GetEscCodeCSIu'))
2361endfunc
Bram Moolenaar459fd782019-10-13 16:43:39 +02002362
2363func RunTest_mapping_mods(map, key, func, code)
2364 call setline(1, '')
2365 exe 'inoremap ' .. a:map .. ' xyz'
2366 call feedkeys('a' .. a:func(a:key, a:code) .. "\<Esc>", 'Lx!')
2367 call assert_equal("xyz", getline(1))
2368 exe 'iunmap ' .. a:map
2369endfunc
2370
2371func RunTest_mapping_works_with_mods(func, mods, code)
2372 new
2373 set timeoutlen=10
2374
2375 if a:mods !~ 'S'
2376 " Shift by itself has no effect
2377 call RunTest_mapping_mods('<' .. a:mods .. '-@>', '@', a:func, a:code)
2378 endif
2379 call RunTest_mapping_mods('<' .. a:mods .. '-A>', 'A', a:func, a:code)
2380 call RunTest_mapping_mods('<' .. a:mods .. '-Z>', 'Z', a:func, a:code)
2381 if a:mods !~ 'S'
2382 " with Shift code is always upper case
2383 call RunTest_mapping_mods('<' .. a:mods .. '-a>', 'a', a:func, a:code)
2384 call RunTest_mapping_mods('<' .. a:mods .. '-z>', 'z', a:func, a:code)
2385 endif
2386 if a:mods != 'A'
2387 " with Alt code is not in upper case
2388 call RunTest_mapping_mods('<' .. a:mods .. '-a>', 'A', a:func, a:code)
2389 call RunTest_mapping_mods('<' .. a:mods .. '-z>', 'Z', a:func, a:code)
2390 endif
2391 call RunTest_mapping_mods('<' .. a:mods .. '-á>', 'á', a:func, a:code)
2392 if a:mods !~ 'S'
2393 " Shift by itself has no effect
2394 call RunTest_mapping_mods('<' .. a:mods .. '-^>', '^', a:func, a:code)
2395 call RunTest_mapping_mods('<' .. a:mods .. '-_>', '_', a:func, a:code)
2396 call RunTest_mapping_mods('<' .. a:mods .. '-{>', '{', a:func, a:code)
2397 call RunTest_mapping_mods('<' .. a:mods .. '-\|>', '|', a:func, a:code)
2398 call RunTest_mapping_mods('<' .. a:mods .. '-}>', '}', a:func, a:code)
2399 call RunTest_mapping_mods('<' .. a:mods .. '-~>', '~', a:func, a:code)
2400 endif
2401
2402 bwipe!
2403 set timeoutlen&
2404endfunc
2405
2406func Test_mapping_works_with_shift()
2407 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'S', 2)
2408 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'S', 2)
2409endfunc
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01002410
Bram Moolenaar459fd782019-10-13 16:43:39 +02002411func Test_mapping_works_with_ctrl()
2412 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C', 5)
2413 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C', 5)
Bram Moolenaar4e2114e2020-10-07 16:12:37 +02002414
2415 new
2416 set timeoutlen=10
2417
2418 " CTRL-@ actually produces the code for CTRL-2, which is converted
2419 call RunTest_mapping_mods('<C-@>', '2', function('GetEscCodeCSI27'), 5)
2420 call RunTest_mapping_mods('<C-@>', '2', function('GetEscCodeCSIu'), 5)
2421
2422 " CTRL-^ actually produces the code for CTRL-6, which is converted
2423 call RunTest_mapping_mods('<C-^>', '6', function('GetEscCodeCSI27'), 5)
2424 call RunTest_mapping_mods('<C-^>', '6', function('GetEscCodeCSIu'), 5)
2425
2426 " CTRL-_ actually produces the code for CTRL--, which is converted
2427 call RunTest_mapping_mods('<C-_>', '-', function('GetEscCodeCSI27'), 5)
2428 call RunTest_mapping_mods('<C-_>', '-', function('GetEscCodeCSIu'), 5)
2429
2430 bwipe!
2431 set timeoutlen&
Bram Moolenaar459fd782019-10-13 16:43:39 +02002432endfunc
2433
2434func Test_mapping_works_with_shift_ctrl()
2435 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-S', 6)
2436 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-S', 6)
Bram Moolenaar9a033d72020-10-07 17:29:48 +02002437
2438 new
2439 set timeoutlen=10
2440
2441 " Ctrl-Shift-[ actually produces CTRL-Shift-{ which is mapped as <C-{>
2442 call RunTest_mapping_mods('<C-{>', '{', function('GetEscCodeCSI27'), 6)
2443 call RunTest_mapping_mods('<C-{>', '{', function('GetEscCodeCSIu'), 6)
2444
2445 " Ctrl-Shift-] actually produces CTRL-Shift-} which is mapped as <C-}>
2446 call RunTest_mapping_mods('<C-{>', '{', function('GetEscCodeCSI27'), 6)
2447 call RunTest_mapping_mods('<C-{>', '{', function('GetEscCodeCSIu'), 6)
2448
2449 " Ctrl-Shift-\ actually produces CTRL-Shift-| which is mapped as <C-|>
2450 call RunTest_mapping_mods('<C-\|>', '|', function('GetEscCodeCSI27'), 6)
2451 call RunTest_mapping_mods('<C-\|>', '|', function('GetEscCodeCSIu'), 6)
2452
2453 bwipe!
2454 set timeoutlen&
Bram Moolenaar459fd782019-10-13 16:43:39 +02002455endfunc
2456
2457" Below we also test the "u" code with Alt, This works, but libvterm would not
2458" send the Alt key like this but by prefixing an Esc.
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01002459
Bram Moolenaar459fd782019-10-13 16:43:39 +02002460func Test_mapping_works_with_alt()
2461 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'A', 3)
2462 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'A', 3)
2463endfunc
2464
2465func Test_mapping_works_with_shift_alt()
2466 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'S-A', 4)
2467 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'S-A', 4)
2468endfunc
2469
Bram Moolenaardaff0fb2020-09-27 13:16:46 +02002470func Test_mapping_works_with_alt_and_shift()
2471 new
2472 set timeoutlen=10
2473
2474 " mapping <A-?> works even though the code is A-S-?
2475 for c in ['!', '$', '+', ':', '?', '^', '~']
2476 call RunTest_mapping_mods('<A-' .. c .. '>', c, function('GetEscCodeCSI27'), 4)
2477 call RunTest_mapping_mods('<A-' .. c .. '>', c, function('GetEscCodeCSIu'), 4)
2478 endfor
2479
2480 bwipe!
2481 set timeoutlen&
2482endfunc
2483
Bram Moolenaar459fd782019-10-13 16:43:39 +02002484func Test_mapping_works_with_ctrl_alt()
2485 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-A', 7)
2486 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-A', 7)
2487endfunc
2488
2489func Test_mapping_works_with_shift_ctrl_alt()
2490 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-S-A', 8)
2491 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-S-A', 8)
2492endfunc
Bram Moolenaarfc4ea2a2019-11-26 19:33:22 +01002493
Bram Moolenaar064fd672022-11-29 18:32:32 +00002494func Test_mapping_works_with_unknown_modifiers()
2495 new
2496 set timeoutlen=10
2497
2498 for Func in [function('GetEscCodeCSI27'), function('GetEscCodeCSIu')]
2499 call RunTest_mapping_mods('<C-z>', 'z', Func, 5)
2500 " Add 16, 32, 64 or 128 for modifiers we currently don't support.
2501 call RunTest_mapping_mods('<C-z>', 'z', Func, 5 + 16)
2502 call RunTest_mapping_mods('<C-z>', 'z', Func, 5 + 32)
2503 call RunTest_mapping_mods('<C-z>', 'z', Func, 5 + 64)
2504 call RunTest_mapping_mods('<C-z>', 'z', Func, 5 + 128)
2505
2506 call RunTest_mapping_mods('<S-X>', 'X', Func, 2)
2507 " Add 16, 32, 64 or 128 for modifiers we currently don't support.
2508 call RunTest_mapping_mods('<S-X>', 'X', Func, 2 + 16)
2509 call RunTest_mapping_mods('<S-X>', 'X', Func, 2 + 32)
2510 call RunTest_mapping_mods('<S-X>', 'X', Func, 2 + 64)
2511 call RunTest_mapping_mods('<S-X>', 'X', Func, 2 + 128)
2512 endfor
2513
2514 bwipe!
2515 set timeoutlen&
2516endfunc
2517
Bram Moolenaar1a173402022-12-02 12:28:47 +00002518func RunTest_mapping_funckey(map, func, key, code)
2519 call setline(1, '')
2520 exe 'inoremap ' .. a:map .. ' xyz'
2521 call feedkeys('a' .. a:func(a:key, a:code) .. "\<Esc>", 'Lx!')
2522 call assert_equal("xyz", getline(1), 'mapping ' .. a:map)
2523 exe 'iunmap ' .. a:map
2524endfunc
2525
2526func Test_mapping_kitty_function_keys()
2527 new
2528 set timeoutlen=10
2529
2530 " Function keys made with CSI and ending in [ABCDEFHPQRS].
2531 " 'E' is keypad BEGIN, not supported
2532 let maps = [
2533 \ ['<Up>', 'A', 0],
2534 \ ['<S-Up>', 'A', 2],
2535 \ ['<C-Up>', 'A', 5],
2536 \ ['<C-S-Up>', 'A', 6],
2537 \
2538 \ ['<Down>', 'B', 0],
2539 \ ['<S-Down>', 'B', 2],
2540 \ ['<C-Down>', 'B', 5],
2541 \ ['<C-S-Down>', 'B', 6],
2542 \
2543 \ ['<Right>', 'C', 0],
2544 \ ['<S-Right>', 'C', 2],
2545 \ ['<C-Right>', 'C', 5],
2546 \ ['<C-S-Right>', 'C', 6],
2547 \
2548 \ ['<Left>', 'D', 0],
2549 \ ['<S-Left>', 'D', 2],
2550 \ ['<C-Left>', 'D', 5],
2551 \ ['<C-S-Left>', 'D', 6],
2552 \
2553 \ ['<End>', 'F', 0],
2554 \ ['<S-End>', 'F', 2],
2555 \ ['<C-End>', 'F', 5],
2556 \ ['<C-S-End>', 'F', 6],
2557 \
2558 \ ['<Home>', 'H', 0],
2559 \ ['<S-Home>', 'H', 2],
2560 \ ['<C-Home>', 'H', 5],
2561 \ ['<C-S-Home>', 'H', 6],
2562 \
2563 \ ['<F1>', 'P', 0],
2564 \ ['<S-F1>', 'P', 2],
2565 \ ['<C-F1>', 'P', 5],
2566 \ ['<C-S-F1>', 'P', 6],
2567 \
2568 \ ['<F2>', 'Q', 0],
2569 \ ['<S-F2>', 'Q', 2],
2570 \ ['<C-F2>', 'Q', 5],
2571 \ ['<C-S-F2>', 'Q', 6],
2572 \
2573 \ ['<F3>', 'R', 0],
2574 \ ['<S-F3>', 'R', 2],
2575 \ ['<C-F3>', 'R', 5],
2576 \ ['<C-S-F3>', 'R', 6],
2577 \
2578 \ ['<F4>', 'S', 0],
2579 \ ['<S-F4>', 'S', 2],
2580 \ ['<C-F4>', 'S', 5],
2581 \ ['<C-S-F4>', 'S', 6],
2582 \ ]
2583
2584 for map in maps
2585 call RunTest_mapping_funckey(map[0], function('GetEscCodeFunckey'), map[1], map[2])
2586 endfor
2587
2588 bwipe!
2589 set timeoutlen&
2590endfunc
2591
Bram Moolenaarfc4ea2a2019-11-26 19:33:22 +01002592func Test_insert_literal()
2593 set timeoutlen=10
Bram Moolenaarc255b782022-11-26 19:16:48 +00002594
2595 call WaitForResponses()
2596
Bram Moolenaarfc4ea2a2019-11-26 19:33:22 +01002597 new
2598 " CTRL-V CTRL-X inserts a ^X
2599 call feedkeys('a' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu('X', '5') .. "\<Esc>", 'Lx!')
2600 call assert_equal("\<C-X>", getline(1))
2601
2602 call setline(1, '')
2603 call feedkeys('a' .. GetEscCodeCSI27('V', '5') .. GetEscCodeCSI27('X', '5') .. "\<Esc>", 'Lx!')
2604 call assert_equal("\<C-X>", getline(1))
2605
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01002606 " CTRL-SHIFT-V CTRL-X inserts escape sequence
Bram Moolenaarfc4ea2a2019-11-26 19:33:22 +01002607 call setline(1, '')
2608 call feedkeys('a' .. GetEscCodeCSIu('V', '6') .. GetEscCodeCSIu('X', '5') .. "\<Esc>", 'Lx!')
2609 call assert_equal("\<Esc>[88;5u", getline(1))
2610
2611 call setline(1, '')
2612 call feedkeys('a' .. GetEscCodeCSI27('V', '6') .. GetEscCodeCSI27('X', '5') .. "\<Esc>", 'Lx!')
2613 call assert_equal("\<Esc>[27;5;88~", getline(1))
2614
2615 bwipe!
2616 set timeoutlen&
2617endfunc
2618
2619func Test_cmdline_literal()
2620 set timeoutlen=10
2621
2622 " CTRL-V CTRL-Y inserts a ^Y
2623 call feedkeys(':' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!')
2624 call assert_equal("\"\<C-Y>", @:)
2625
2626 call feedkeys(':' .. GetEscCodeCSI27('V', '5') .. GetEscCodeCSI27('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!')
2627 call assert_equal("\"\<C-Y>", @:)
2628
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01002629 " CTRL-SHIFT-V CTRL-Y inserts escape sequence
Bram Moolenaarfc4ea2a2019-11-26 19:33:22 +01002630 call feedkeys(':' .. GetEscCodeCSIu('V', '6') .. GetEscCodeCSIu('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!')
2631 call assert_equal("\"\<Esc>[89;5u", @:)
2632
2633 call setline(1, '')
2634 call feedkeys(':' .. GetEscCodeCSI27('V', '6') .. GetEscCodeCSI27('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!')
2635 call assert_equal("\"\<Esc>[27;5;89~", @:)
2636
2637 set timeoutlen&
2638endfunc
Bram Moolenaar0eabd4d2020-03-15 16:13:53 +01002639
Bram Moolenaarbbf84e22022-03-12 13:48:39 +00002640func Test_mapping_esc()
2641 set timeoutlen=10
2642
2643 new
2644 nnoremap <Up> iHello<Esc>
2645 nnoremap <Esc> <Nop>
2646
2647 call feedkeys(substitute(&t_ku, '\*', '', 'g'), 'Lx!')
2648 call assert_equal("Hello", getline(1))
2649
2650 bwipe!
2651 nunmap <Up>
2652 nunmap <Esc>
2653 set timeoutlen&
2654endfunc
2655
Bram Moolenaar0ff5ded2020-05-07 18:43:44 +02002656" Test for translation of special key codes (<xF1>, <xF2>, etc.)
Bram Moolenaar92e5df82021-01-30 15:39:47 +01002657func Test_Keycode_Translation()
Bram Moolenaar0ff5ded2020-05-07 18:43:44 +02002658 let keycodes = [
2659 \ ["<xUp>", "<Up>"],
2660 \ ["<xDown>", "<Down>"],
2661 \ ["<xLeft>", "<Left>"],
2662 \ ["<xRight>", "<Right>"],
2663 \ ["<xHome>", "<Home>"],
2664 \ ["<xEnd>", "<End>"],
2665 \ ["<zHome>", "<Home>"],
2666 \ ["<zEnd>", "<End>"],
2667 \ ["<xF1>", "<F1>"],
2668 \ ["<xF2>", "<F2>"],
2669 \ ["<xF3>", "<F3>"],
2670 \ ["<xF4>", "<F4>"],
2671 \ ["<S-xF1>", "<S-F1>"],
2672 \ ["<S-xF2>", "<S-F2>"],
2673 \ ["<S-xF3>", "<S-F3>"],
2674 \ ["<S-xF4>", "<S-F4>"]]
2675 for [k1, k2] in keycodes
2676 exe "nnoremap " .. k1 .. " 2wx"
2677 call assert_true(maparg(k1, 'n', 0, 1).lhs == k2)
2678 exe "nunmap " .. k1
2679 endfor
2680endfunc
2681
Bram Moolenaar1f448d92021-03-22 19:37:06 +01002682" Test for terminal keycodes that doesn't have termcap entries
2683func Test_special_term_keycodes()
2684 new
2685 " Test for <xHome>, <S-xHome> and <C-xHome>
2686 " send <K_SPECIAL> <KS_EXTRA> keycode
2687 call feedkeys("i\<C-K>\x80\xfd\x3f\n", 'xt')
2688 " send <K_SPECIAL> <KS_MODIFIER> bitmap <K_SPECIAL> <KS_EXTRA> keycode
2689 call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x3f\n", 'xt')
2690 call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x3f\n", 'xt')
2691 " Test for <xEnd>, <S-xEnd> and <C-xEnd>
2692 call feedkeys("i\<C-K>\x80\xfd\x3d\n", 'xt')
2693 call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x3d\n", 'xt')
2694 call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x3d\n", 'xt')
2695 " Test for <zHome>, <S-zHome> and <C-zHome>
2696 call feedkeys("i\<C-K>\x80\xfd\x40\n", 'xt')
2697 call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x40\n", 'xt')
2698 call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x40\n", 'xt')
2699 " Test for <zEnd>, <S-zEnd> and <C-zEnd>
2700 call feedkeys("i\<C-K>\x80\xfd\x3e\n", 'xt')
2701 call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x3e\n", 'xt')
2702 call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x3e\n", 'xt')
2703 " Test for <xUp>, <xDown>, <xLeft> and <xRight>
2704 call feedkeys("i\<C-K>\x80\xfd\x41\n", 'xt')
2705 call feedkeys("i\<C-K>\x80\xfd\x42\n", 'xt')
2706 call feedkeys("i\<C-K>\x80\xfd\x43\n", 'xt')
2707 call feedkeys("i\<C-K>\x80\xfd\x44\n", 'xt')
2708 call assert_equal(['<Home>', '<S-Home>', '<C-Home>',
2709 \ '<End>', '<S-End>', '<C-End>',
2710 \ '<Home>', '<S-Home>', '<C-Home>',
2711 \ '<End>', '<S-End>', '<C-End>',
2712 \ '<Up>', '<Down>', '<Left>', '<Right>', ''], getline(1, '$'))
2713 bw!
2714endfunc
2715
Bram Moolenaar1573e732022-11-16 20:33:21 +00002716func Test_home_key_works()
2717 " The '@' character in K_HOME must only match "1" when followed by ";",
2718 " otherwise this code for Home is not recognized: "<Esc>[1~"
Bram Moolenaar1d8765d2022-11-17 16:43:35 +00002719 " Set termcap values like "xterm" uses them. Except using F2 for xHome,
2720 " because that termcap entry can't be set here.
2721 let save_K1 = exists('&t_K1') ? &t_K1 : ''
2722 let save_kh = exists('&t_kh') ? &t_kh : ''
2723 let save_k2 = exists('&t_k2') ? &t_k2 : ''
2724 let save_k3 = exists('&t_k3') ? &t_k3 : ''
2725 let save_end = exists('&t_@7') ? &t_@7 : ''
2726
Bram Moolenaar1573e732022-11-16 20:33:21 +00002727 let &t_K1 = "\<Esc>[1;*~" " <kHome>
2728 let &t_kh = "\<Esc>[@;*H" " <Home>
Bram Moolenaar1d8765d2022-11-17 16:43:35 +00002729 let &t_k2 = "\<Esc>O*H" " use <F2> for <xHome>
Bram Moolenaar1573e732022-11-16 20:33:21 +00002730 let &t_k3 = "\<Esc>[7;*~" " use <F3> for <zHome>
2731 let &t_@7 = "\<Esc>[@;*F" " <End>
2732
2733 new
2734 call feedkeys("i\<C-K>\<Esc>OH\n\<Esc>", 'tx')
2735 call feedkeys("i\<C-K>\<Esc>[1~\n\<Esc>", 'tx')
2736 call assert_equal([
Bram Moolenaar1d8765d2022-11-17 16:43:35 +00002737 \ '<F2>',
Bram Moolenaar1573e732022-11-16 20:33:21 +00002738 \ '<kHome>',
2739 \ ''], getline(1, '$'))
2740
2741 bwipe!
Bram Moolenaar1573e732022-11-16 20:33:21 +00002742 let &t_K1 = save_K1
Bram Moolenaar1d8765d2022-11-17 16:43:35 +00002743 let &t_kh = save_kh
Bram Moolenaar1573e732022-11-16 20:33:21 +00002744 let &t_k2 = save_k2
2745 let &t_k3 = save_k3
2746 let &t_@7 = save_end
2747endfunc
2748
Bram Moolenaar0f5575d2021-07-30 21:18:03 +02002749func Test_terminal_builtin_without_gui()
2750 CheckNotMSWindows
2751
2752 " builtin_gui should not be output by :set term=xxx
2753 let output = systemlist("TERM=dumb " .. v:progpath .. " --clean -c ':set t_ti= t_te=' -c 'set term=xxx' -c ':q!'")
2754 redraw!
2755 call map(output, {_, val -> trim(val)})
2756 call assert_equal(-1, index(output, 'builtin_gui'))
2757 call assert_notequal(-1, index(output, 'builtin_dumb'))
2758endfunc
2759
Christian Brabandt279dd702025-01-26 10:49:59 +01002760func Test_xterm_direct_enables_termguicolors()
Christian Brabandtd7f58542025-01-31 16:13:14 +01002761 call s:TermGuiColorsTest()
Christian Brabandt279dd702025-01-26 10:49:59 +01002762 " TERM=xterm-direct enables termguicolors
Christian Brabandt279dd702025-01-26 10:49:59 +01002763 let colors = systemlist('tput -Txterm-direct colors')[0]
2764 defer delete('XTerm-direct.txt')
2765
2766 let buf = RunVimInTerminal('--cmd ":set noswapfile" --clean XTerm-direct.txt',
2767 \ {'rows': 10, 'env': {'TERM': 'xterm-direct'}})
2768 call TermWait(buf)
2769 call term_sendkeys(buf, ":$put ='TERM: ' .. &term\<cr>")
2770 " doesn't work. Vim cannot query xterm colors in the embedded terminal?
2771 "call term_sendkeys(buf, ":$put ='Colors: ' .. &t_Co\<cr>")
2772 call term_sendkeys(buf, ":$put ='Termguicolors: ' .. &tgc\<cr>")
2773 call term_sendkeys(buf, ":wq\<cr>")
2774 call TermWait(buf)
2775
2776 let result=readfile('XTerm-direct.txt')
2777 " call assert_equal(['', 'TERM: xterm-direct', 'Colors: ' .. colors, 'Termguicolors: 1'], result)
2778 call assert_equal(['', 'TERM: xterm-direct', 'Termguicolors: 1'], result)
2779 " cleanup
2780 bw!
Christian Brabandtd7f58542025-01-31 16:13:14 +01002781 close
2782endfunc
2783
2784func Test_xterm_direct_no_termguicolors()
2785 " unfortunately doesn't work with libvterm
2786 call s:TermGuiColorsTest()
2787
2788 let lines =<< trim END
2789 set notermguicolors noswapfile
2790 set t_Co=16777216
2791 END
2792 call writefile(lines, 'XtermDirect', 'D')
2793 defer delete('XTerm-direct2.txt')
2794
2795 let buf = RunVimInTerminal('-S XtermDirect --clean XTerm-direct2.txt',
2796 \ {'rows': 10, 'env': {'TERM': 'xterm-direct'}})
2797 call TermWait(buf)
2798 call term_sendkeys(buf, ":$put ='TERM: ' .. &term\<cr>")
2799 call term_sendkeys(buf, ":$put ='Termguicolors: ' .. &tgc\<cr>")
2800 call term_sendkeys(buf, ":wq\<cr>")
2801 call TermWait(buf)
2802
2803 let result=readfile('XTerm-direct2.txt')
2804 call assert_equal(['', 'TERM: xterm-direct', 'Termguicolors: 0'], result)
2805 " cleanup
2806 bw!
2807 close
Christian Brabandt279dd702025-01-26 10:49:59 +01002808endfunc
2809
Bram Moolenaar0eabd4d2020-03-15 16:13:53 +01002810" vim: shiftwidth=2 sts=2 expandtab