blob: 1f2ea7de59431fb5cbfa039c7d4df57f394bcdb3 [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 +02004CheckNotGui
5CheckUnix
Bram Moolenaar905dd902019-04-07 14:21:47 +02006
Christian Brabandteb380b92025-07-07 20:53:55 +02007source util/mouse.vim
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +02008
Christian Brabandtd7f58542025-01-31 16:13:14 +01009func s:TermGuiColorsTest()
10 CheckNotMSWindows
11 if !CanRunVimInTerminal()
12 throw 'Skipped: cannot make screendumps'
13 endif
14 if !executable('tput')
15 throw "Skipped: tput not executable!"
16 endif
17 if has("gui_running")
18 throw "Skipped: does not work in GUI mode"
19 endif
20 call system('tput -Txterm-direct RGB 2>/dev/null')
21 if v:shell_error
22 throw "Skipped: xterm-direct $TERM has no RGB capability"
23 endif
24endfunc
25
26
Bram Moolenaar92fd5992019-05-02 23:00:22 +020027func Test_term_mouse_left_click()
Bram Moolenaar905dd902019-04-07 14:21:47 +020028 new
29 let save_mouse = &mouse
30 let save_term = &term
31 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +020032 call test_override('no_query_mouse', 1)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +020033 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +000034 call WaitForResponses()
35
Bram Moolenaar905dd902019-04-07 14:21:47 +020036 call setline(1, ['line 1', 'line 2', 'line 3 is a bit longer'])
Bram Moolenaar905dd902019-04-07 14:21:47 +020037
Bram Moolenaar515545e2020-03-22 14:08:59 +010038 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm
Bram Moolenaar49452192019-04-17 16:27:02 +020039 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +020040 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +020041 go
Bram Moolenaar49452192019-04-17 16:27:02 +020042 call assert_equal([0, 1, 1, 0], getpos('.'), msg)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +020043 let row = 2
44 let col = 6
45 call MouseLeftClick(row, col)
46 call MouseLeftRelease(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +020047 call assert_equal([0, 2, 6, 0], getpos('.'), msg)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +020048 endfor
Bram Moolenaar905dd902019-04-07 14:21:47 +020049
50 let &mouse = save_mouse
51 let &term = save_term
52 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +020053 call test_override('no_query_mouse', 0)
Bram Moolenaar905dd902019-04-07 14:21:47 +020054 bwipe!
55endfunc
56
Bram Moolenaar6aa75232019-10-13 21:01:34 +020057func Test_xterm_mouse_right_click_extends_visual()
58 if has('mac')
59 throw "Skipped: test right click in visual mode does not work on macOs (why?)"
60 endif
61 let save_mouse = &mouse
62 let save_term = &term
63 let save_ttymouse = &ttymouse
64 call test_override('no_query_mouse', 1)
65 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +000066 call WaitForResponses()
Bram Moolenaar6aa75232019-10-13 21:01:34 +020067
68 for visual_mode in ["v", "V", "\<C-V>"]
Bram Moolenaar515545e2020-03-22 14:08:59 +010069 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaar6aa75232019-10-13 21:01:34 +020070 let msg = 'visual=' .. visual_mode .. ' ttymouse=' .. ttymouse_val
71 exe 'set ttymouse=' .. ttymouse_val
72
73 call setline(1, repeat([repeat('-', 7)], 7))
74 call MouseLeftClick(4, 4)
75 call MouseLeftRelease(4, 4)
76 exe "norm! " .. visual_mode
77
78 " Right click extends top left of visual area.
79 call MouseRightClick(2, 2)
80 call MouseRightRelease(2, 2)
81
Bram Moolenaarf19f8d12019-12-18 19:36:23 +010082 " Right click extends bottom right of visual area.
Bram Moolenaar6aa75232019-10-13 21:01:34 +020083 call MouseRightClick(6, 6)
84 call MouseRightRelease(6, 6)
85 norm! r1gv
86
87 " Right click shrinks top left of visual area.
88 call MouseRightClick(3, 3)
89 call MouseRightRelease(3, 3)
90
91 " Right click shrinks bottom right of visual area.
92 call MouseRightClick(5, 5)
93 call MouseRightRelease(5, 5)
94 norm! r2
95
96 if visual_mode ==# 'v'
97 call assert_equal(['-------',
98 \ '-111111',
99 \ '1122222',
100 \ '2222222',
101 \ '2222211',
102 \ '111111-',
103 \ '-------'], getline(1, '$'), msg)
104 elseif visual_mode ==# 'V'
105 call assert_equal(['-------',
106 \ '1111111',
107 \ '2222222',
108 \ '2222222',
109 \ '2222222',
110 \ '1111111',
111 \ '-------'], getline(1, '$'), msg)
112 else
113 call assert_equal(['-------',
114 \ '-11111-',
115 \ '-12221-',
116 \ '-12221-',
117 \ '-12221-',
118 \ '-11111-',
119 \ '-------'], getline(1, '$'), msg)
120 endif
121 endfor
122 endfor
123
124 let &mouse = save_mouse
125 let &term = save_term
126 let &ttymouse = save_ttymouse
127 call test_override('no_query_mouse', 0)
128 bwipe!
129endfunc
130
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200131" Test that <C-LeftMouse> jumps to help tag and <C-RightMouse> jumps back.
Bram Moolenaar297bec02020-07-14 22:11:04 +0200132" Also test for g<LeftMouse> and g<RightMouse>.
133func Test_xterm_mouse_tagjump()
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200134 let save_mouse = &mouse
135 let save_term = &term
136 let save_ttymouse = &ttymouse
137 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +0000138 call WaitForResponses()
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200139
Bram Moolenaar515545e2020-03-22 14:08:59 +0100140 for ttymouse_val in g:Ttymouse_values
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200141 let msg = 'ttymouse=' .. ttymouse_val
142 exe 'set ttymouse=' .. ttymouse_val
143 help
144 /usr_02.txt
145 norm! zt
Bram Moolenaar297bec02020-07-14 22:11:04 +0200146
147 " CTRL-left click to jump to a tag
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200148 let row = 1
149 let col = 1
150 call MouseCtrlLeftClick(row, col)
151 call MouseLeftRelease(row, col)
152 call assert_match('usr_02.txt$', bufname('%'), msg)
Bram Moolenaarb4367b72019-10-01 14:19:07 +0200153 call assert_equal('*usr_02.txt*', expand('<cWORD>'), msg)
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200154
Bram Moolenaar297bec02020-07-14 22:11:04 +0200155 " CTRL-right click to pop a tag
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200156 call MouseCtrlRightClick(row, col)
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200157 call MouseRightRelease(row, col)
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200158 call assert_match('help.txt$', bufname('%'), msg)
Bram Moolenaarb4367b72019-10-01 14:19:07 +0200159 call assert_equal('|usr_02.txt|', expand('<cWORD>'), msg)
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200160
Bram Moolenaar297bec02020-07-14 22:11:04 +0200161 " Jump to a tag
162 exe "normal \<C-]>"
163 call assert_match('usr_02.txt$', bufname('%'), msg)
164 call assert_equal('*usr_02.txt*', expand('<cWORD>'), msg)
165
166 " Use CTRL-right click in insert mode to pop the tag
167 new
168 let str = 'iHello' .. MouseCtrlRightClickCode(row, col)
169 \ .. MouseRightReleaseCode(row, col) .. "\<C-C>"
Bram Moolenaar2764d062020-07-18 12:59:19 +0200170 call assert_fails('call feedkeys(str, "Lx!")', 'E37:', msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +0200171 close!
172
173 " CTRL-right click with a count
174 let str = "4" .. MouseCtrlRightClickCode(row, col)
175 \ .. MouseRightReleaseCode(row, col)
Bram Moolenaar2764d062020-07-18 12:59:19 +0200176 call assert_fails('call feedkeys(str, "Lx!")', 'E555:', msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +0200177 call assert_match('help.txt$', bufname('%'), msg)
178 call assert_equal(1, line('.'), msg)
179
180 " g<LeftMouse> to jump to a tag
181 /usr_02.txt
182 norm! zt
183 call test_setmouse(row, col)
184 exe "normal g\<LeftMouse>"
185 call assert_match('usr_02.txt$', bufname('%'), msg)
186 call assert_equal('*usr_02.txt*', expand('<cWORD>'), msg)
187
188 " g<RightMouse> to pop to a tag
189 call test_setmouse(row, col)
190 exe "normal g\<RightMouse>"
191 call assert_match('help.txt$', bufname('%'), msg)
192 call assert_equal('|usr_02.txt|', expand('<cWORD>'), msg)
193
194 %bw!
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200195 endfor
196
197 let &mouse = save_mouse
198 let &term = save_term
199 let &ttymouse = save_ttymouse
200endfunc
201
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200202func Test_term_mouse_middle_click()
Bram Moolenaar52992fe2019-08-12 14:20:33 +0200203 CheckFeature clipboard_working
Bram Moolenaar564344a2019-04-28 13:00:12 +0200204
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200205 new
206 let save_mouse = &mouse
207 let save_term = &term
208 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200209 call test_override('no_query_mouse', 1)
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200210 let save_quotestar = @*
Bram Moolenaar297bec02020-07-14 22:11:04 +0200211 let save_quoteplus = @+
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200212 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +0000213 call WaitForResponses()
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200214
Bram Moolenaar515545e2020-03-22 14:08:59 +0100215 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200216 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200217 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200218 call setline(1, ['123456789', '123456789'])
Bram Moolenaar297bec02020-07-14 22:11:04 +0200219 let @* = 'abc'
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200220
221 " Middle-click in the middle of the line pastes text where clicked.
222 let row = 1
223 let col = 6
224 call MouseMiddleClick(row, col)
225 call MouseMiddleRelease(row, col)
226 call assert_equal(['12345abc6789', '123456789'], getline(1, '$'), msg)
227
228 " Middle-click beyond end of the line pastes text at the end of the line.
229 let col = 20
230 call MouseMiddleClick(row, col)
231 call MouseMiddleRelease(row, col)
232 call assert_equal(['12345abc6789abc', '123456789'], getline(1, '$'), msg)
233
234 " Middle-click beyond the last line pastes in the last line.
235 let row = 5
236 let col = 3
237 call MouseMiddleClick(row, col)
238 call MouseMiddleRelease(row, col)
239 call assert_equal(['12345abc6789abc', '12abc3456789'], getline(1, '$'), msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +0200240
241 " Middle mouse click in operator pending mode beeps
242 call assert_beeps('exe "normal c\<MiddleMouse>"')
243
244 " Clicking middle mouse in visual mode, yanks the selection and pastes the
245 " clipboard contents
246 let save_clipboard = &clipboard
247 set clipboard=
248 let @" = ''
249 call cursor(1, 1)
250 call feedkeys("v3l" ..
251 \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7), 'Lx!')
252 call assert_equal(['12345abc6789abc', '12abc3abc456789'],
253 \ getline(1, '$'), msg)
Bram Moolenaar2764d062020-07-18 12:59:19 +0200254 call assert_equal('1234', @", msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +0200255 let &clipboard = save_clipboard
256
257 " Clicking middle mouse in select mode, replaces the selected text with
258 " the clipboard contents
259 let @+ = 'xyz'
260 call cursor(1, 3)
261 exe "normal gh\<Right>\<Right>\<MiddleMouse>"
262 call assert_equal(['12xyzabc6789abc', '12abc3abc456789'],
263 \ getline(1, '$'), msg)
Bram Moolenaar2764d062020-07-18 12:59:19 +0200264
265 " Prefixing middle click with [ or ] fixes the indent after pasting.
266 %d
267 call setline(1, " one two")
268 call setreg('r', 'red blue', 'l')
269 call test_setmouse(1, 5)
270 exe "normal \"r[\<MiddleMouse>"
271 call assert_equal(' red blue', getline(1), msg)
272 call test_setmouse(2, 5)
273 exe "normal \"r]\<MiddleMouse>"
274 call assert_equal(' red blue', getline(3), msg)
275 %d
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200276 endfor
277
278 let &mouse = save_mouse
279 let &term = save_term
280 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200281 call test_override('no_query_mouse', 0)
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200282 let @* = save_quotestar
zeertzjq0b933c32023-04-28 18:44:50 +0100283 let @+ = save_quoteplus
Bram Moolenaarc1b81602019-04-27 19:11:35 +0200284 bwipe!
285endfunc
286
Bram Moolenaar297bec02020-07-14 22:11:04 +0200287" If clipboard is not working, then clicking the middle mouse button in visual
288" mode, will copy and paste the selected text.
289func Test_term_mouse_middle_click_no_clipboard()
290 if has('clipboard_working')
291 throw 'Skipped: clipboard support works'
Bram Moolenaar297bec02020-07-14 22:11:04 +0200292 endif
293 new
294 let save_mouse = &mouse
295 let save_term = &term
296 let save_ttymouse = &ttymouse
297 call test_override('no_query_mouse', 1)
298 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +0000299 call WaitForResponses()
Bram Moolenaar297bec02020-07-14 22:11:04 +0200300
301 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
302 let msg = 'ttymouse=' .. ttymouse_val
303 exe 'set ttymouse=' .. ttymouse_val
304 call setline(1, ['123456789', '123456789'])
305
306 " Clicking middle mouse in visual mode, yanks the selection and pastes it
307 call cursor(1, 1)
308 call feedkeys("v3l" ..
309 \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7), 'Lx!')
310 call assert_equal(['123456789', '1234561234789'],
311 \ getline(1, '$'), msg)
312 endfor
313
314 call test_override('no_query_mouse', 0)
315 let &ttymouse = save_ttymouse
316 let &term = save_term
317 let &mouse = save_mouse
Christian Brabandt08ea2e12025-01-25 15:01:42 +0100318 bw!
Bram Moolenaar297bec02020-07-14 22:11:04 +0200319endfunc
320
321func Test_term_mouse_middle_click_insert_mode()
322 CheckFeature clipboard_working
323
324 new
325 let save_mouse = &mouse
326 let save_term = &term
327 let save_ttymouse = &ttymouse
328 call test_override('no_query_mouse', 1)
329 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +0000330 call WaitForResponses()
Bram Moolenaar297bec02020-07-14 22:11:04 +0200331
332 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
333 let msg = 'ttymouse=' .. ttymouse_val
334 exe 'set ttymouse=' .. ttymouse_val
335 call setline(1, ['123456789', '123456789'])
336 let @* = 'abc'
337
Dominique Pelle923dce22021-11-21 11:36:04 +0000338 " Middle-click in insert mode doesn't move the cursor but inserts the
339 " contents of a register
Bram Moolenaar297bec02020-07-14 22:11:04 +0200340 call cursor(1, 4)
341 call feedkeys('i' ..
342 \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7) ..
343 \ "\<C-C>", 'Lx!')
344 call assert_equal(['123abc456789', '123456789'],
345 \ getline(1, '$'), msg)
Bram Moolenaar2764d062020-07-18 12:59:19 +0200346 call assert_equal([1, 6], [line('.'), col('.')], msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +0200347
348 " Middle-click in replace mode
349 call cursor(1, 1)
350 call feedkeys('$R' ..
351 \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7) ..
352 \ "\<C-C>", 'Lx!')
353 call assert_equal(['123abc45678abc', '123456789'],
354 \ getline(1, '$'), msg)
Bram Moolenaar2764d062020-07-18 12:59:19 +0200355 call assert_equal([1, 14], [line('.'), col('.')], msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +0200356 endfor
357
358 let &mouse = save_mouse
359 let &term = save_term
360 let &ttymouse = save_ttymouse
361 call test_override('no_query_mouse', 0)
362 close!
363endfunc
364
365" Test for switching window using mouse in insert mode
366func Test_term_mouse_switch_win_insert_mode()
367 5new
368 let save_mouse = &mouse
369 let save_term = &term
370 let save_ttymouse = &ttymouse
371 call test_override('no_query_mouse', 1)
372 set mouse=a term=xterm ttymouse=xterm2
Bram Moolenaarc255b782022-11-26 19:16:48 +0000373 call WaitForResponses()
Bram Moolenaar297bec02020-07-14 22:11:04 +0200374
375 call feedkeys('ivim' ..
376 \ MouseLeftClickCode(8, 6) .. MouseLeftReleaseCode(8, 6) ..
377 \ "\<C-C>", 'Lx!')
378 call assert_equal(2, winnr())
379 wincmd w
380 call assert_equal('n', mode())
381 call assert_equal(['vim'], getline(1, '$'))
382
383 let &mouse = save_mouse
384 let &term = save_term
385 let &ttymouse = save_ttymouse
386 call test_override('no_query_mouse', 0)
Christian Brabandt08ea2e12025-01-25 15:01:42 +0100387 bw!
Bram Moolenaar297bec02020-07-14 22:11:04 +0200388endfunc
389
Dominique Pelle923dce22021-11-21 11:36:04 +0000390" Test for using the mouse to increase the height of the cmdline window
Bram Moolenaar297bec02020-07-14 22:11:04 +0200391func Test_mouse_cmdwin_resize()
392 let save_mouse = &mouse
393 let save_term = &term
394 let save_ttymouse = &ttymouse
395 call test_override('no_query_mouse', 1)
396 set mouse=a term=xterm ttymouse=xterm2
Bram Moolenaarc255b782022-11-26 19:16:48 +0000397 call WaitForResponses()
398
Bram Moolenaar297bec02020-07-14 22:11:04 +0200399 5new
400 redraw!
401
402 let h = 0
403 let row = &lines - &cmdwinheight - 2
404 call feedkeys("q:" ..
405 \ MouseLeftClickCode(row, 1) ..
406 \ MouseLeftDragCode(row - 1, 1) ..
407 \ MouseLeftReleaseCode(row - 2, 1) ..
408 \ "alet h = \<C-R>=winheight(0)\<CR>\<CR>", 'Lx!')
409 call assert_equal(&cmdwinheight + 2, h)
410
411 let &mouse = save_mouse
412 let &term = save_term
413 let &ttymouse = save_ttymouse
414 call test_override('no_query_mouse', 0)
415 close!
416endfunc
417
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200418" TODO: for unclear reasons this test fails if it comes after
419" Test_xterm_mouse_ctrl_click()
420func Test_1xterm_mouse_wheel()
Bram Moolenaar049736f2019-04-07 21:55:07 +0200421 new
422 let save_mouse = &mouse
423 let save_term = &term
Bram Moolenaard58d4f92020-07-01 15:49:29 +0200424 let save_wrap = &wrap
Bram Moolenaar049736f2019-04-07 21:55:07 +0200425 let save_ttymouse = &ttymouse
Bram Moolenaard58d4f92020-07-01 15:49:29 +0200426 set mouse=a term=xterm nowrap
Bram Moolenaarc255b782022-11-26 19:16:48 +0000427 call WaitForResponses()
428
Bram Moolenaard58d4f92020-07-01 15:49:29 +0200429 call setline(1, range(100000000000000, 100000000000100))
Bram Moolenaar049736f2019-04-07 21:55:07 +0200430
Bram Moolenaar515545e2020-03-22 14:08:59 +0100431 for ttymouse_val in g:Ttymouse_values
Bram Moolenaar49452192019-04-17 16:27:02 +0200432 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200433 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200434 go
Bram Moolenaar49452192019-04-17 16:27:02 +0200435 call assert_equal(1, line('w0'), msg)
436 call assert_equal([0, 1, 1, 0], getpos('.'), msg)
Bram Moolenaar049736f2019-04-07 21:55:07 +0200437
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200438 call MouseWheelDown(1, 1)
Bram Moolenaar49452192019-04-17 16:27:02 +0200439 call assert_equal(4, line('w0'), msg)
440 call assert_equal([0, 4, 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(7, line('w0'), msg)
444 call assert_equal([0, 7, 1, 0], getpos('.'), msg)
Bram Moolenaar049736f2019-04-07 21:55:07 +0200445
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200446 call MouseWheelUp(1, 1)
Bram Moolenaar49452192019-04-17 16:27:02 +0200447 call assert_equal(4, 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(1, line('w0'), msg)
452 call assert_equal([0, 7, 1, 0], getpos('.'), msg)
Bram Moolenaard58d4f92020-07-01 15:49:29 +0200453
Christopher Plewright20b795e2022-12-20 20:01:58 +0000454 call MouseWheelRight(1, 1)
455 call assert_equal(7, 1 + virtcol(".") - wincol(), msg)
456 call assert_equal([0, 7, 7, 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(13, 1 + virtcol(".") - wincol(), msg)
460 call assert_equal([0, 7, 13, 0], getpos('.'), msg)
Bram Moolenaard58d4f92020-07-01 15:49:29 +0200461
Christopher Plewright20b795e2022-12-20 20:01:58 +0000462 call MouseWheelLeft(1, 1)
463 call assert_equal(7, 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(1, 1 + virtcol(".") - wincol(), msg)
468 call assert_equal([0, 7, 13, 0], getpos('.'), msg)
469
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200470 endfor
Bram Moolenaar049736f2019-04-07 21:55:07 +0200471
472 let &mouse = save_mouse
473 let &term = save_term
Bram Moolenaard58d4f92020-07-01 15:49:29 +0200474 let &wrap = save_wrap
Bram Moolenaar049736f2019-04-07 21:55:07 +0200475 let &ttymouse = save_ttymouse
476 bwipe!
477endfunc
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200478
Bram Moolenaarb4367b72019-10-01 14:19:07 +0200479" Test that dragging beyond the window (at the bottom and at the top)
Bram Moolenaarf19f8d12019-12-18 19:36:23 +0100480" scrolls window content by the number of lines beyond the window.
Bram Moolenaarb4367b72019-10-01 14:19:07 +0200481func Test_term_mouse_drag_beyond_window()
482 let save_mouse = &mouse
483 let save_term = &term
484 let save_ttymouse = &ttymouse
485 call test_override('no_query_mouse', 1)
486 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +0000487 call WaitForResponses()
488
Bram Moolenaarb4367b72019-10-01 14:19:07 +0200489 let col = 1
490 call setline(1, range(1, 100))
491
492 " Split into 3 windows, and go into the middle window
493 " so we test dragging mouse below and above the window.
494 2split
495 wincmd j
496 2split
497
Bram Moolenaar515545e2020-03-22 14:08:59 +0100498 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaarb4367b72019-10-01 14:19:07 +0200499 let msg = 'ttymouse=' .. ttymouse_val
500 exe 'set ttymouse=' .. ttymouse_val
501
502 " Line #10 at the top.
503 norm! 10zt
504 redraw
505 call assert_equal(10, winsaveview().topline, msg)
506 call assert_equal(2, winheight(0), msg)
507
508 let row = 4
509 call MouseLeftClick(row, col)
510 call assert_equal(10, winsaveview().topline, msg)
511
512 " Drag downwards. We're still in the window so topline should
513 " not change yet.
514 let row += 1
515 call MouseLeftDrag(row, col)
516 call assert_equal(10, winsaveview().topline, msg)
517
518 " We now leave the window at the bottom, so the window content should
519 " scroll by 1 line, then 2 lines (etc) as we drag further away.
520 let row += 1
521 call MouseLeftDrag(row, col)
522 call assert_equal(11, winsaveview().topline, msg)
523
524 let row += 1
525 call MouseLeftDrag(row, col)
526 call assert_equal(13, winsaveview().topline, msg)
527
528 " Now drag upwards.
529 let row -= 1
530 call MouseLeftDrag(row, col)
531 call assert_equal(14, winsaveview().topline, msg)
532
533 " We're now back in the window so the topline should not change.
534 let row -= 1
535 call MouseLeftDrag(row, col)
536 call assert_equal(14, winsaveview().topline, msg)
537
538 let row -= 1
539 call MouseLeftDrag(row, col)
540 call assert_equal(14, winsaveview().topline, msg)
541
542 " We now leave the window at the top so the window content should
543 " scroll by 1 line, then 2, then 3 (etc) in the opposite direction.
544 let row -= 1
545 call MouseLeftDrag(row, col)
546 call assert_equal(13, winsaveview().topline, msg)
547
548 let row -= 1
549 call MouseLeftDrag(row, col)
550 call assert_equal(11, winsaveview().topline, msg)
551
552 let row -= 1
553 call MouseLeftDrag(row, col)
554 call assert_equal(8, winsaveview().topline, msg)
555
556 call MouseLeftRelease(row, col)
557 call assert_equal(8, winsaveview().topline, msg)
558 call assert_equal(2, winheight(0), msg)
559 endfor
560
561 let &mouse = save_mouse
562 let &term = save_term
563 let &ttymouse = save_ttymouse
564 call test_override('no_query_mouse', 0)
565 bwipe!
566endfunc
567
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200568func Test_term_mouse_drag_window_separator()
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200569 let save_mouse = &mouse
570 let save_term = &term
571 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200572 call test_override('no_query_mouse', 1)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200573 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +0000574 call WaitForResponses()
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200575
Bram Moolenaar515545e2020-03-22 14:08:59 +0100576 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaar49452192019-04-17 16:27:02 +0200577 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200578 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200579
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200580 " Split horizontally and test dragging the horizontal window separator.
581 split
582 let rowseparator = winheight(0) + 1
583 let row = rowseparator
584 let col = 1
Bram Moolenaarc8b3dda2019-04-12 21:42:52 +0200585
Bram Moolenaar2b00b9b2019-04-17 17:08:27 +0200586 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
587 if ttymouse_val !=# 'xterm2' || row <= 223
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200588 call MouseLeftClick(row, col)
589 let row -= 1
590 call MouseLeftDrag(row, col)
zeertzjq8e0ccb62022-11-01 18:35:27 +0000591 call assert_equal(rowseparator - 1, winheight(0) + 1, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200592 let row += 1
593 call MouseLeftDrag(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200594 call assert_equal(rowseparator, winheight(0) + 1, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200595 call MouseLeftRelease(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200596 call assert_equal(rowseparator, winheight(0) + 1, msg)
Bram Moolenaarc8b3dda2019-04-12 21:42:52 +0200597 endif
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200598 bwipe!
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200599
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200600 " Split vertically and test dragging the vertical window separator.
601 vsplit
602 let colseparator = winwidth(0) + 1
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200603 let row = 1
604 let col = colseparator
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200605
Bram Moolenaar2b00b9b2019-04-17 17:08:27 +0200606 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
607 if ttymouse_val !=# 'xterm2' || col <= 223
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200608 call MouseLeftClick(row, col)
609 let col -= 1
610 call MouseLeftDrag(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200611 call assert_equal(colseparator - 1, winwidth(0) + 1, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200612 let col += 1
613 call MouseLeftDrag(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200614 call assert_equal(colseparator, winwidth(0) + 1, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200615 call MouseLeftRelease(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200616 call assert_equal(colseparator, winwidth(0) + 1, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200617 endif
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200618 bwipe!
619 endfor
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200620
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200621 let &mouse = save_mouse
622 let &term = save_term
623 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200624 call test_override('no_query_mouse', 0)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200625endfunc
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200626
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200627func Test_term_mouse_drag_statusline()
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200628 let save_mouse = &mouse
629 let save_term = &term
630 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200631 call test_override('no_query_mouse', 1)
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200632 let save_laststatus = &laststatus
633 set mouse=a term=xterm laststatus=2
Bram Moolenaarc255b782022-11-26 19:16:48 +0000634 call WaitForResponses()
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200635
Bram Moolenaar515545e2020-03-22 14:08:59 +0100636 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaar49452192019-04-17 16:27:02 +0200637 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200638 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200639
Bram Moolenaar49452192019-04-17 16:27:02 +0200640 call assert_equal(1, &cmdheight, msg)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200641 let rowstatusline = winheight(0) + 1
642 let row = rowstatusline
643 let col = 1
Bram Moolenaarc8b3dda2019-04-12 21:42:52 +0200644
Bram Moolenaar2b00b9b2019-04-17 17:08:27 +0200645 if ttymouse_val ==# 'xterm2' && row > 223
646 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
Bram Moolenaarc8b3dda2019-04-12 21:42:52 +0200647 continue
648 endif
649
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200650 call MouseLeftClick(row, col)
651 let row -= 1
652 call MouseLeftDrag(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200653 call assert_equal(2, &cmdheight, msg)
654 call assert_equal(rowstatusline - 1, winheight(0) + 1, msg)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200655 let row += 1
656 call MouseLeftDrag(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200657 call assert_equal(1, &cmdheight, msg)
658 call assert_equal(rowstatusline, winheight(0) + 1, msg)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200659 call MouseLeftRelease(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200660 call assert_equal(1, &cmdheight, msg)
661 call assert_equal(rowstatusline, winheight(0) + 1, msg)
Bram Moolenaar3fbd2d72019-04-11 23:56:16 +0200662 endfor
663
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200664 let &mouse = save_mouse
665 let &term = save_term
666 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200667 call test_override('no_query_mouse', 0)
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200668 let &laststatus = save_laststatus
669endfunc
670
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200671func Test_term_mouse_click_tab()
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200672 let save_mouse = &mouse
673 let save_term = &term
674 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200675 call test_override('no_query_mouse', 1)
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200676 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +0000677 call WaitForResponses()
678
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200679 let row = 1
680
Bram Moolenaar515545e2020-03-22 14:08:59 +0100681 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm
Bram Moolenaar49452192019-04-17 16:27:02 +0200682 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200683 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200684 e Xfoo
685 tabnew Xbar
686
687 let a = split(execute(':tabs'), "\n")
688 call assert_equal(['Tab page 1',
689 \ ' Xfoo',
690 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200691 \ '> Xbar'], a, msg)
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200692
693 " Test clicking on tab names in the tabline at the top.
694 let col = 2
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200695 redraw
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200696 call MouseLeftClick(row, col)
697 call MouseLeftRelease(row, col)
698 let a = split(execute(':tabs'), "\n")
699 call assert_equal(['Tab page 1',
700 \ '> Xfoo',
701 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200702 \ ' Xbar'], a, msg)
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200703
704 let col = 9
705 call MouseLeftClick(row, col)
706 call MouseLeftRelease(row, col)
707 let a = split(execute(':tabs'), "\n")
708 call assert_equal(['Tab page 1',
709 \ ' Xfoo',
710 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200711 \ '> Xbar'], a, msg)
Bram Moolenaarca57ab52019-04-13 14:53:16 +0200712
713 %bwipe!
714 endfor
715
716 let &mouse = save_mouse
717 let &term = save_term
718 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200719 call test_override('no_query_mouse', 0)
Bram Moolenaar3fb01a52019-04-09 21:52:02 +0200720endfunc
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200721
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200722func Test_term_mouse_click_X_to_close_tab()
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200723 let save_mouse = &mouse
724 let save_term = &term
725 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200726 call test_override('no_query_mouse', 1)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200727 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +0000728 call WaitForResponses()
729
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200730 let row = 1
731 let col = &columns
732
Bram Moolenaar515545e2020-03-22 14:08:59 +0100733 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm
Bram Moolenaar2b00b9b2019-04-17 17:08:27 +0200734 if ttymouse_val ==# 'xterm2' && col > 223
735 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200736 continue
737 endif
Bram Moolenaar49452192019-04-17 16:27:02 +0200738 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200739 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200740 e Xtab1
741 tabnew Xtab2
742 tabnew Xtab3
743 tabn 2
744
745 let a = split(execute(':tabs'), "\n")
746 call assert_equal(['Tab page 1',
747 \ ' Xtab1',
748 \ 'Tab page 2',
749 \ '> Xtab2',
750 \ 'Tab page 3',
Bram Moolenaar49452192019-04-17 16:27:02 +0200751 \ ' Xtab3'], a, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200752
753 " Click on "X" in tabline to close current tab i.e. Xtab2.
754 redraw
755 call MouseLeftClick(row, col)
756 call MouseLeftRelease(row, col)
757 let a = split(execute(':tabs'), "\n")
758 call assert_equal(['Tab page 1',
759 \ ' Xtab1',
760 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200761 \ '> Xtab3'], a, msg)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200762
763 %bwipe!
764 endfor
765
766 let &mouse = save_mouse
767 let &term = save_term
768 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200769 call test_override('no_query_mouse', 0)
Bram Moolenaar39f76c62019-04-13 22:13:23 +0200770endfunc
Bram Moolenaare3e38282019-04-15 20:55:31 +0200771
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200772func Test_term_mouse_drag_to_move_tab()
Bram Moolenaare3e38282019-04-15 20:55:31 +0200773 let save_mouse = &mouse
774 let save_term = &term
775 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200776 call test_override('no_query_mouse', 1)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200777 " Set 'mousetime' to 1 to avoid recognizing a double-click in the loop
778 set mouse=a term=xterm mousetime=1
Bram Moolenaarc255b782022-11-26 19:16:48 +0000779 call WaitForResponses()
780
Bram Moolenaare3e38282019-04-15 20:55:31 +0200781 let row = 1
782
Bram Moolenaar515545e2020-03-22 14:08:59 +0100783 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaar49452192019-04-17 16:27:02 +0200784 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200785 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaare3e38282019-04-15 20:55:31 +0200786 e Xtab1
787 tabnew Xtab2
788
789 let a = split(execute(':tabs'), "\n")
790 call assert_equal(['Tab page 1',
791 \ ' Xtab1',
792 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200793 \ '> Xtab2'], a, msg)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200794 redraw
795
796 " Click in tab2 and drag it to tab1.
797 " Check getcharmod() to verify that click is not
798 " interpreted as a spurious double-click.
799 call MouseLeftClick(row, 10)
Bram Moolenaar49452192019-04-17 16:27:02 +0200800 call assert_equal(0, getcharmod(), msg)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200801 for col in [9, 8, 7, 6]
802 call MouseLeftDrag(row, col)
803 endfor
804 call MouseLeftRelease(row, col)
805 let a = split(execute(':tabs'), "\n")
806 call assert_equal(['Tab page 1',
807 \ '> Xtab2',
808 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200809 \ ' Xtab1'], a, msg)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200810
zeertzjq8e0ccb62022-11-01 18:35:27 +0000811 " Switch to tab1
812 tabnext
813 let a = split(execute(':tabs'), "\n")
814 call assert_equal(['Tab page 1',
815 \ ' Xtab2',
816 \ 'Tab page 2',
817 \ '> Xtab1'], a, msg)
818
819 " Click in tab2 and drag it to tab1.
820 " This time it is non-current tab.
821 call MouseLeftClick(row, 6)
822 call assert_equal(0, getcharmod(), msg)
823 for col in [7, 8, 9, 10]
824 call MouseLeftDrag(row, col)
825 endfor
826 call MouseLeftRelease(row, col)
827 let a = split(execute(':tabs'), "\n")
828 call assert_equal(['Tab page 1',
829 \ ' Xtab1',
830 \ 'Tab page 2',
831 \ '> Xtab2'], a, msg)
832
Bram Moolenaarf36a2c72019-11-16 18:57:16 +0100833 " Click elsewhere so that click in next iteration is not
834 " interpreted as unwanted double-click.
835 call MouseLeftClick(row, 11)
836 call MouseLeftRelease(row, 11)
837
Bram Moolenaare3e38282019-04-15 20:55:31 +0200838 %bwipe!
839 endfor
840
841 let &mouse = save_mouse
842 let &term = save_term
843 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200844 call test_override('no_query_mouse', 0)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200845 set mousetime&
846endfunc
847
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200848func Test_term_mouse_double_click_to_create_tab()
Bram Moolenaare3e38282019-04-15 20:55:31 +0200849 let save_mouse = &mouse
850 let save_term = &term
851 let save_ttymouse = &ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200852 call test_override('no_query_mouse', 1)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200853 " Set 'mousetime' to a small value, so that double-click works but we don't
854 " have to wait long to avoid a triple-click.
Bram Moolenaarf36a2c72019-11-16 18:57:16 +0100855 set mouse=a term=xterm mousetime=200
Bram Moolenaarc255b782022-11-26 19:16:48 +0000856 call WaitForResponses()
857
Bram Moolenaare3e38282019-04-15 20:55:31 +0200858 let row = 1
859 let col = 10
860
Bram Moolenaar515545e2020-03-22 14:08:59 +0100861 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaar49452192019-04-17 16:27:02 +0200862 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar1ee36d62019-05-01 23:13:56 +0200863 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaare3e38282019-04-15 20:55:31 +0200864 e Xtab1
865 tabnew Xtab2
866
867 let a = split(execute(':tabs'), "\n")
868 call assert_equal(['Tab page 1',
869 \ ' Xtab1',
870 \ 'Tab page 2',
Bram Moolenaar49452192019-04-17 16:27:02 +0200871 \ '> Xtab2'], a, msg)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200872
873 redraw
874 call MouseLeftClick(row, col)
875 " Check getcharmod() to verify that first click is not
876 " interpreted as a spurious double-click.
Bram Moolenaar49452192019-04-17 16:27:02 +0200877 call assert_equal(0, getcharmod(), msg)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200878 call MouseLeftRelease(row, col)
879 call MouseLeftClick(row, col)
Bram Moolenaar49452192019-04-17 16:27:02 +0200880 call assert_equal(32, getcharmod(), msg) " double-click
Bram Moolenaare3e38282019-04-15 20:55:31 +0200881 call MouseLeftRelease(row, col)
882 let a = split(execute(':tabs'), "\n")
883 call assert_equal(['Tab page 1',
884 \ ' Xtab1',
885 \ 'Tab page 2',
886 \ '> [No Name]',
887 \ 'Tab page 3',
Bram Moolenaar49452192019-04-17 16:27:02 +0200888 \ ' Xtab2'], a, msg)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200889
Bram Moolenaarf36a2c72019-11-16 18:57:16 +0100890 " Click elsewhere so that click in next iteration is not
891 " interpreted as unwanted double click.
892 call MouseLeftClick(row, col + 1)
893 call MouseLeftRelease(row, col + 1)
894
Bram Moolenaare3e38282019-04-15 20:55:31 +0200895 %bwipe!
896 endfor
897
898 let &mouse = save_mouse
899 let &term = save_term
900 let &ttymouse = save_ttymouse
Bram Moolenaar92fd5992019-05-02 23:00:22 +0200901 call test_override('no_query_mouse', 0)
Bram Moolenaare3e38282019-04-15 20:55:31 +0200902 set mousetime&
903endfunc
Bram Moolenaar696d6372019-04-17 16:33:46 +0200904
Bram Moolenaarf36a2c72019-11-16 18:57:16 +0100905" Test double/triple/quadruple click in normal mode to visually select.
906func Test_term_mouse_multiple_clicks_to_visually_select()
907 let save_mouse = &mouse
908 let save_term = &term
909 let save_ttymouse = &ttymouse
910 call test_override('no_query_mouse', 1)
Bram Moolenaar94722c52023-01-28 19:19:03 +0000911
Bram Moolenaar2a5c61a2020-12-30 14:59:23 +0100912 " 'mousetime' must be sufficiently large, or else the test is flaky when
913 " using a ssh connection with X forwarding; i.e. ssh -X (issue #7563).
914 set mouse=a term=xterm mousetime=600
Bram Moolenaarc255b782022-11-26 19:16:48 +0000915 call WaitForResponses()
916
Bram Moolenaarf36a2c72019-11-16 18:57:16 +0100917 new
918
Bram Moolenaar515545e2020-03-22 14:08:59 +0100919 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaarf36a2c72019-11-16 18:57:16 +0100920 let msg = 'ttymouse=' .. ttymouse_val
921 exe 'set ttymouse=' .. ttymouse_val
922 call setline(1, ['foo [foo bar] foo', 'foo'])
923
924 " Double-click on word should visually select the word.
925 call MouseLeftClick(1, 2)
926 call assert_equal(0, getcharmod(), msg)
927 call MouseLeftRelease(1, 2)
928 call MouseLeftClick(1, 2)
929 call assert_equal(32, getcharmod(), msg) " double-click
930 call MouseLeftRelease(1, 2)
931 call assert_equal('v', mode(), msg)
932 norm! r1
933 call assert_equal(['111 [foo bar] foo', 'foo'], getline(1, '$'), msg)
934
935 " Double-click on opening square bracket should visually
936 " select the whole [foo bar].
937 call MouseLeftClick(1, 5)
938 call assert_equal(0, getcharmod(), msg)
939 call MouseLeftRelease(1, 5)
940 call MouseLeftClick(1, 5)
941 call assert_equal(32, getcharmod(), msg) " double-click
942 call MouseLeftRelease(1, 5)
943 call assert_equal('v', mode(), msg)
944 norm! r2
945 call assert_equal(['111 222222222 foo', 'foo'], getline(1, '$'), msg)
946
947 " Triple-click should visually select the whole line.
948 call MouseLeftClick(1, 3)
949 call assert_equal(0, getcharmod(), msg)
950 call MouseLeftRelease(1, 3)
951 call MouseLeftClick(1, 3)
952 call assert_equal(32, getcharmod(), msg) " double-click
953 call MouseLeftRelease(1, 3)
954 call MouseLeftClick(1, 3)
955 call assert_equal(64, getcharmod(), msg) " triple-click
956 call MouseLeftRelease(1, 3)
957 call assert_equal('V', mode(), msg)
958 norm! r3
959 call assert_equal(['33333333333333333', 'foo'], getline(1, '$'), msg)
960
961 " Quadruple-click should start visual block select.
962 call MouseLeftClick(1, 2)
963 call assert_equal(0, getcharmod(), msg)
964 call MouseLeftRelease(1, 2)
965 call MouseLeftClick(1, 2)
966 call assert_equal(32, getcharmod(), msg) " double-click
967 call MouseLeftRelease(1, 2)
968 call MouseLeftClick(1, 2)
969 call assert_equal(64, getcharmod(), msg) " triple-click
970 call MouseLeftRelease(1, 2)
971 call MouseLeftClick(1, 2)
972 call assert_equal(96, getcharmod(), msg) " quadruple-click
973 call MouseLeftRelease(1, 2)
974 call assert_equal("\<c-v>", mode(), msg)
975 norm! r4
976 call assert_equal(['34333333333333333', 'foo'], getline(1, '$'), msg)
Bram Moolenaar2764d062020-07-18 12:59:19 +0200977
978 " Double-click on a space character should visually select all the
979 " consecutive space characters.
980 %d
981 call setline(1, ' one two')
982 call MouseLeftClick(1, 2)
983 call MouseLeftRelease(1, 2)
984 call MouseLeftClick(1, 2)
985 call MouseLeftRelease(1, 2)
986 call assert_equal('v', mode(), msg)
987 norm! r1
988 call assert_equal(['1111one two'], getline(1, '$'), msg)
989
990 " Double-click on a word with exclusive selection
991 set selection=exclusive
992 let @" = ''
993 call MouseLeftClick(1, 10)
994 call MouseLeftRelease(1, 10)
995 call MouseLeftClick(1, 10)
996 call MouseLeftRelease(1, 10)
997 norm! y
998 call assert_equal('two', @", msg)
999
1000 " Double click to select a block of text with exclusive selection
1001 %d
1002 call setline(1, 'one (two) three')
1003 call MouseLeftClick(1, 5)
1004 call MouseLeftRelease(1, 5)
1005 call MouseLeftClick(1, 5)
1006 call MouseLeftRelease(1, 5)
1007 norm! y
1008 call assert_equal(5, col("'<"), msg)
1009 call assert_equal(10, col("'>"), msg)
1010
1011 call MouseLeftClick(1, 9)
1012 call MouseLeftRelease(1, 9)
1013 call MouseLeftClick(1, 9)
1014 call MouseLeftRelease(1, 9)
1015 norm! y
1016 call assert_equal(5, col("'<"), msg)
1017 call assert_equal(10, col("'>"), msg)
1018 set selection&
1019
1020 " Click somewhere else so that the clicks above is not combined with the
1021 " clicks in the next iteration.
1022 call MouseRightClick(3, 10)
1023 call MouseRightRelease(3, 10)
Bram Moolenaarf36a2c72019-11-16 18:57:16 +01001024 endfor
1025
1026 let &mouse = save_mouse
1027 let &term = save_term
1028 let &ttymouse = save_ttymouse
1029 set mousetime&
1030 call test_override('no_query_mouse', 0)
1031 bwipe!
1032endfunc
1033
Bram Moolenaar2764d062020-07-18 12:59:19 +02001034" Test for selecting text in visual blockwise mode using Alt-LeftClick
1035func Test_mouse_alt_leftclick()
1036 let save_mouse = &mouse
1037 let save_term = &term
1038 let save_ttymouse = &ttymouse
1039 call test_override('no_query_mouse', 1)
1040 set mouse=a term=xterm mousetime=200
1041 set mousemodel=popup
Bram Moolenaarc255b782022-11-26 19:16:48 +00001042 call WaitForResponses()
1043
Bram Moolenaar2764d062020-07-18 12:59:19 +02001044 new
1045 call setline(1, 'one (two) three')
1046
1047 for ttymouse_val in g:Ttymouse_values
1048 let msg = 'ttymouse=' .. ttymouse_val
1049 exe 'set ttymouse=' .. ttymouse_val
1050
1051 " Left click with the Alt modifier key should extend the selection in
1052 " blockwise visual mode.
1053 let @" = ''
1054 call MouseLeftClick(1, 3)
1055 call MouseLeftRelease(1, 3)
1056 call MouseAltLeftClick(1, 11)
1057 call MouseLeftRelease(1, 11)
1058 call assert_equal("\<C-V>", mode(), msg)
1059 normal! y
1060 call assert_equal('e (two) t', @")
1061 endfor
1062
1063 let &mouse = save_mouse
1064 let &term = save_term
1065 let &ttymouse = save_ttymouse
1066 set mousetime& mousemodel&
1067 call test_override('no_query_mouse', 0)
Christian Brabandt08ea2e12025-01-25 15:01:42 +01001068 bw!
Bram Moolenaar2764d062020-07-18 12:59:19 +02001069endfunc
1070
Bram Moolenaar696d6372019-04-17 16:33:46 +02001071func Test_xterm_mouse_click_in_fold_columns()
1072 new
1073 let save_mouse = &mouse
1074 let save_term = &term
1075 let save_ttymouse = &ttymouse
1076 let save_foldcolumn = &foldcolumn
Bram Moolenaar2b00b9b2019-04-17 17:08:27 +02001077 set mouse=a term=xterm foldcolumn=3 ttymouse=xterm2
Bram Moolenaarc255b782022-11-26 19:16:48 +00001078 call WaitForResponses()
Bram Moolenaar696d6372019-04-17 16:33:46 +02001079
1080 " Create 2 nested folds.
1081 call setline(1, range(1, 7))
1082 2,6fold
1083 norm! zR
1084 4,5fold
1085 call assert_equal([-1, -1, -1, 4, 4, -1, -1],
1086 \ map(range(1, 7), 'foldclosed(v:val)'))
1087
1088 " Click in "+" of inner fold in foldcolumn should open it.
1089 redraw
1090 let row = 4
1091 let col = 2
1092 call MouseLeftClick(row, col)
1093 call MouseLeftRelease(row, col)
1094 call assert_equal([-1, -1, -1, -1, -1, -1, -1],
1095 \ map(range(1, 7), 'foldclosed(v:val)'))
1096
1097 " Click in "-" of outer fold in foldcolumn should close it.
1098 redraw
1099 let row = 2
1100 let col = 1
1101 call MouseLeftClick(row, col)
1102 call MouseLeftRelease(row, col)
1103 call assert_equal([-1, 2, 2, 2, 2, 2, -1],
1104 \ map(range(1, 7), 'foldclosed(v:val)'))
1105 norm! zR
1106
1107 " Click in "|" of inner fold in foldcolumn should close it.
1108 redraw
1109 let row = 5
1110 let col = 2
1111 call MouseLeftClick(row, col)
1112 call MouseLeftRelease(row, col)
1113 call assert_equal([-1, -1, -1, 4, 4, -1, -1],
1114 \ map(range(1, 7), 'foldclosed(v:val)'))
1115
1116 let &foldcolumn = save_foldcolumn
1117 let &ttymouse = save_ttymouse
1118 let &term = save_term
1119 let &mouse = save_mouse
1120 bwipe!
1121endfunc
Bram Moolenaar66761db2019-06-05 22:07:51 +02001122
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01001123" Left or right click in Ex command line sets position of the cursor.
1124func Test_term_mouse_click_in_cmdline_to_set_pos()
1125 let save_mouse = &mouse
1126 let save_term = &term
1127 let save_ttymouse = &ttymouse
1128 call test_override('no_query_mouse', 1)
1129 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +00001130 call WaitForResponses()
1131
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01001132 let row = &lines
1133
Bram Moolenaar515545e2020-03-22 14:08:59 +01001134 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaarab505b12020-03-23 19:28:44 +01001135 " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
1136 if ttymouse_val !=# 'xterm2' || row <= 223
1137 let msg = 'ttymouse=' .. ttymouse_val
1138 exe 'set ttymouse=' .. ttymouse_val
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01001139
Bram Moolenaarab505b12020-03-23 19:28:44 +01001140
1141 call feedkeys(':"3456789'
1142 \ .. MouseLeftClickCode(row, 7)
1143 \ .. MouseLeftReleaseCode(row, 7) .. 'L'
1144 \ .. MouseRightClickCode(row, 4)
1145 \ .. MouseRightReleaseCode(row, 4) .. 'R'
1146 \ .. "\<CR>", 'Lx!')
1147 call assert_equal('"3R456L789', @:, msg)
1148 endif
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01001149 endfor
1150
1151 let &mouse = save_mouse
1152 let &term = save_term
1153 let &ttymouse = save_ttymouse
1154 set mousetime&
1155 call test_override('no_query_mouse', 0)
1156endfunc
1157
1158" Middle click in command line pastes at position of cursor.
1159func Test_term_mouse_middle_click_in_cmdline_to_paste()
1160 CheckFeature clipboard_working
1161 let save_mouse = &mouse
1162 let save_term = &term
1163 let save_ttymouse = &ttymouse
1164 call test_override('no_query_mouse', 1)
1165 set mouse=a term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +00001166 call WaitForResponses()
1167
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01001168 let row = &lines
1169 " Column values does not matter, paste is done at position of cursor.
1170 let col = 1
1171 let @* = 'paste'
1172
Bram Moolenaar515545e2020-03-22 14:08:59 +01001173 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01001174 let msg = 'ttymouse=' .. ttymouse_val
1175 exe 'set ttymouse=' .. ttymouse_val
1176
1177 call feedkeys(":\"->"
1178 \ .. MouseMiddleReleaseCode(row, col)
1179 \ .. MouseMiddleClickCode(row, col)
1180 \ .. "<-"
1181 \ .. MouseMiddleReleaseCode(row, col)
1182 \ .. MouseMiddleClickCode(row, col)
1183 \ .. "\<CR>", 'Lx!')
1184 call assert_equal('"->paste<-paste', @:, msg)
1185 endfor
1186
1187 let &mouse = save_mouse
1188 let &term = save_term
1189 let &ttymouse = save_ttymouse
1190 let @* = ''
1191 call test_override('no_query_mouse', 0)
1192endfunc
1193
Bram Moolenaar297bec02020-07-14 22:11:04 +02001194" Test for making sure S-Middlemouse doesn't do anything
1195func Test_term_mouse_shift_middle_click()
1196 new
1197 let save_mouse = &mouse
1198 let save_term = &term
1199 let save_ttymouse = &ttymouse
1200 call test_override('no_query_mouse', 1)
1201 set mouse=a term=xterm ttymouse=xterm2 mousemodel=
Bram Moolenaarc255b782022-11-26 19:16:48 +00001202 call WaitForResponses()
Bram Moolenaar297bec02020-07-14 22:11:04 +02001203
1204 call test_setmouse(1, 1)
1205 exe "normal \<S-MiddleMouse>"
1206 call assert_equal([''], getline(1, '$'))
1207 call assert_equal(1, winnr())
1208
1209 let &mouse = save_mouse
1210 let &term = save_term
1211 let &ttymouse = save_ttymouse
1212 set mousemodel&
1213 call test_override('no_query_mouse', 0)
1214 close!
1215endfunc
1216
1217" Test for using mouse in visual mode
1218func Test_term_mouse_visual_mode()
1219 new
1220 let save_mouse = &mouse
1221 let save_term = &term
1222 let save_ttymouse = &ttymouse
1223 call test_override('no_query_mouse', 1)
1224 set term=xterm ttymouse=xterm2
Bram Moolenaarc255b782022-11-26 19:16:48 +00001225 call WaitForResponses()
Bram Moolenaar297bec02020-07-14 22:11:04 +02001226
1227 " If visual mode is not present in 'mouse', then left click should not
1228 " do anything in visal mode.
1229 call setline(1, ['one two three four'])
1230 set mouse=nci
1231 call cursor(1, 5)
1232 let @" = ''
1233 call feedkeys("ve"
1234 \ .. MouseLeftClickCode(1, 15) .. MouseLeftReleaseCode(1, 15)
1235 \ .. 'y', 'Lx!')
1236 call assert_equal(5, col('.'))
1237 call assert_equal('two', @")
1238
1239 " Pressing right click in visual mode should change the visual selection
1240 " if 'mousemodel' doesn't contain popup.
1241 " Right click after the visual selection
1242 set mousemodel=
1243 set mouse=a
1244 call test_setmouse(1, 13)
1245 exe "normal 5|ve\<RightMouse>y"
1246 call assert_equal('two three', @")
1247 call assert_equal(5, col('.'))
1248
1249 " Right click before the visual selection
1250 call test_setmouse(1, 9)
1251 exe "normal 15|ve\<RightMouse>y"
1252 call assert_equal('three four', @")
1253 call assert_equal(9, col('.'))
1254
Bram Moolenaar2764d062020-07-18 12:59:19 +02001255 " Right click inside the selection closer to the start of the selection
1256 call test_setmouse(1, 7)
1257 exe "normal 5|vee\<RightMouse>lly"
1258 call assert_equal('three', @")
1259 call assert_equal(9, col('.'))
1260 call assert_equal(9, col("'<"))
1261 call assert_equal(13, col("'>"))
1262
1263 " Right click inside the selection closer to the end of the selection
1264 call test_setmouse(1, 11)
1265 exe "normal 5|vee\<RightMouse>ly"
1266 call assert_equal('two thre', @")
1267 call assert_equal(5, col('.'))
1268 call assert_equal(5, col("'<"))
1269 call assert_equal(12, col("'>"))
1270
dundargocc57b5bc2022-11-02 13:30:51 +00001271 " Multi-line selection. Right click inside the selection.
Bram Moolenaar2764d062020-07-18 12:59:19 +02001272 call setline(1, repeat(['aaaaaa'], 7))
Bram Moolenaar297bec02020-07-14 22:11:04 +02001273 call test_setmouse(3, 1)
1274 exe "normal ggVG\<RightMouse>y"
1275 call assert_equal(3, line("'<"))
Bram Moolenaar2764d062020-07-18 12:59:19 +02001276 call test_setmouse(5, 1)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001277 exe "normal ggVG\<RightMouse>y"
Bram Moolenaar2764d062020-07-18 12:59:19 +02001278 call assert_equal(5, line("'>"))
1279
1280 " Click right in the middle line of the selection
1281 call test_setmouse(4, 3)
1282 exe "normal ggVG$\<RightMouse>y"
1283 call assert_equal(4, line("'<"))
1284 call test_setmouse(4, 4)
1285 exe "normal ggVG$\<RightMouse>y"
Bram Moolenaar297bec02020-07-14 22:11:04 +02001286 call assert_equal(4, line("'>"))
1287
1288 set mousemodel&
1289 let &mouse = save_mouse
1290 let &term = save_term
1291 let &ttymouse = save_ttymouse
1292 call test_override('no_query_mouse', 0)
Christian Brabandt08ea2e12025-01-25 15:01:42 +01001293 bw!
Bram Moolenaar297bec02020-07-14 22:11:04 +02001294endfunc
1295
Bram Moolenaar0eabd4d2020-03-15 16:13:53 +01001296" Test for displaying the popup menu using the right mouse click
Bram Moolenaar297bec02020-07-14 22:11:04 +02001297func Test_term_mouse_popup_menu()
Bram Moolenaar0eabd4d2020-03-15 16:13:53 +01001298 CheckFeature menu
1299 new
1300 call setline(1, 'popup menu test')
1301 let save_mouse = &mouse
1302 let save_term = &term
1303 let save_ttymouse = &ttymouse
1304 let save_mousemodel = &mousemodel
1305 call test_override('no_query_mouse', 1)
1306 set mouse=a term=xterm mousemodel=popup
Bram Moolenaarc255b782022-11-26 19:16:48 +00001307 call WaitForResponses()
Bram Moolenaar0eabd4d2020-03-15 16:13:53 +01001308
1309 menu PopUp.foo :let g:menustr = 'foo'<CR>
1310 menu PopUp.bar :let g:menustr = 'bar'<CR>
1311 menu PopUp.baz :let g:menustr = 'baz'<CR>
1312
Bram Moolenaar515545e2020-03-22 14:08:59 +01001313 for ttymouse_val in g:Ttymouse_values
Bram Moolenaar2764d062020-07-18 12:59:19 +02001314 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar0eabd4d2020-03-15 16:13:53 +01001315 exe 'set ttymouse=' .. ttymouse_val
1316 let g:menustr = ''
1317 call feedkeys(MouseRightClickCode(1, 4)
1318 \ .. MouseRightReleaseCode(1, 4) .. "\<Down>\<Down>\<CR>", "x")
Bram Moolenaar2764d062020-07-18 12:59:19 +02001319 call assert_equal('bar', g:menustr, msg)
Bram Moolenaar0eabd4d2020-03-15 16:13:53 +01001320 endfor
1321
1322 unmenu PopUp
1323 let &mouse = save_mouse
1324 let &term = save_term
1325 let &ttymouse = save_ttymouse
1326 let &mousemodel = save_mousemodel
1327 call test_override('no_query_mouse', 0)
Christian Brabandt08ea2e12025-01-25 15:01:42 +01001328 bw!
Bram Moolenaar0eabd4d2020-03-15 16:13:53 +01001329endfunc
1330
Bram Moolenaar297bec02020-07-14 22:11:04 +02001331" Test for 'mousemodel' set to popup_setpos to move the cursor where the popup
1332" menu is displayed.
1333func Test_term_mouse_popup_menu_setpos()
1334 CheckFeature menu
1335 5new
1336 call setline(1, ['the dish ran away with the spoon',
1337 \ 'the cow jumped over the moon' ])
1338 let save_mouse = &mouse
1339 let save_term = &term
1340 let save_ttymouse = &ttymouse
1341 let save_mousemodel = &mousemodel
1342 call test_override('no_query_mouse', 1)
1343 set mouse=a term=xterm mousemodel=popup_setpos
Bram Moolenaarc255b782022-11-26 19:16:48 +00001344 call WaitForResponses()
Bram Moolenaar297bec02020-07-14 22:11:04 +02001345
1346 nmenu PopUp.foo :let g:menustr = 'foo'<CR>
1347 nmenu PopUp.bar :let g:menustr = 'bar'<CR>
1348 nmenu PopUp.baz :let g:menustr = 'baz'<CR>
1349 vmenu PopUp.foo y:<C-U>let g:menustr = 'foo'<CR>
1350 vmenu PopUp.bar y:<C-U>let g:menustr = 'bar'<CR>
1351 vmenu PopUp.baz y:<C-U>let g:menustr = 'baz'<CR>
1352
1353 for ttymouse_val in g:Ttymouse_values
Bram Moolenaar2764d062020-07-18 12:59:19 +02001354 let msg = 'ttymouse=' .. ttymouse_val
Bram Moolenaar297bec02020-07-14 22:11:04 +02001355 exe 'set ttymouse=' .. ttymouse_val
1356 let g:menustr = ''
1357 call cursor(1, 1)
1358 call feedkeys(MouseRightClickCode(1, 5)
1359 \ .. MouseRightReleaseCode(1, 5) .. "\<Down>\<Down>\<CR>", "x")
Bram Moolenaar2764d062020-07-18 12:59:19 +02001360 call assert_equal('bar', g:menustr, msg)
1361 call assert_equal([1, 5], [line('.'), col('.')], msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001362
1363 " Test for right click in visual mode inside the selection
1364 let @" = ''
1365 call cursor(1, 10)
1366 call feedkeys('vee' .. MouseRightClickCode(1, 12)
1367 \ .. MouseRightReleaseCode(1, 12) .. "\<Down>\<CR>", "x")
Bram Moolenaar2764d062020-07-18 12:59:19 +02001368 call assert_equal([1, 10], [line('.'), col('.')], msg)
1369 call assert_equal('ran away', @", msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001370
Yee Cheng Chin17822c52022-10-13 13:17:40 +01001371 " Test for right click in visual mode right before the selection
Bram Moolenaar297bec02020-07-14 22:11:04 +02001372 let @" = ''
1373 call cursor(1, 10)
Yee Cheng Chin17822c52022-10-13 13:17:40 +01001374 call feedkeys('vee' .. MouseRightClickCode(1, 9)
1375 \ .. MouseRightReleaseCode(1, 9) .. "\<Down>\<CR>", "x")
1376 call assert_equal([1, 9], [line('.'), col('.')], msg)
Bram Moolenaar2764d062020-07-18 12:59:19 +02001377 call assert_equal('', @", msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001378
Yee Cheng Chin17822c52022-10-13 13:17:40 +01001379 " Test for right click in visual mode right after the selection
Bram Moolenaar297bec02020-07-14 22:11:04 +02001380 let @" = ''
1381 call cursor(1, 10)
Yee Cheng Chin17822c52022-10-13 13:17:40 +01001382 call feedkeys('vee' .. MouseRightClickCode(1, 18)
1383 \ .. MouseRightReleaseCode(1, 18) .. "\<Down>\<CR>", "x")
1384 call assert_equal([1, 18], [line('.'), col('.')], msg)
Bram Moolenaar2764d062020-07-18 12:59:19 +02001385 call assert_equal('', @", msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001386
1387 " Test for right click in block-wise visual mode inside the selection
1388 let @" = ''
1389 call cursor(1, 16)
1390 call feedkeys("\<C-V>j3l" .. MouseRightClickCode(2, 17)
1391 \ .. MouseRightReleaseCode(2, 17) .. "\<Down>\<CR>", "x")
Bram Moolenaar2764d062020-07-18 12:59:19 +02001392 call assert_equal([1, 16], [line('.'), col('.')], msg)
1393 call assert_equal("\<C-V>4", getregtype('"'), msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001394
1395 " Test for right click in block-wise visual mode outside the selection
1396 let @" = ''
1397 call cursor(1, 16)
1398 call feedkeys("\<C-V>j3l" .. MouseRightClickCode(2, 2)
1399 \ .. MouseRightReleaseCode(2, 2) .. "\<Down>\<CR>", "x")
Bram Moolenaar2764d062020-07-18 12:59:19 +02001400 call assert_equal([2, 2], [line('.'), col('.')], msg)
1401 call assert_equal('v', getregtype('"'), msg)
1402 call assert_equal('', @", msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001403
Yee Cheng Chin17822c52022-10-13 13:17:40 +01001404 " Test for right click in line-wise visual mode inside the selection
1405 let @" = ''
1406 call cursor(1, 16)
1407 call feedkeys("V" .. MouseRightClickCode(1, 10)
1408 \ .. MouseRightReleaseCode(1, 10) .. "\<Down>\<CR>", "x")
1409 call assert_equal([1, 1], [line('.'), col('.')], msg) " After yanking, the cursor goes to 1,1
1410 call assert_equal("V", getregtype('"'), msg)
zeertzjqdf63f052022-10-19 15:12:54 +01001411 call assert_equal(1, len(getreg('"', 1, v:true)), msg)
Yee Cheng Chin17822c52022-10-13 13:17:40 +01001412
1413 " Test for right click in multi-line line-wise visual mode inside the selection
1414 let @" = ''
1415 call cursor(1, 16)
1416 call feedkeys("Vj" .. MouseRightClickCode(2, 20)
1417 \ .. MouseRightReleaseCode(2, 20) .. "\<Down>\<CR>", "x")
1418 call assert_equal([1, 1], [line('.'), col('.')], msg) " After yanking, the cursor goes to 1,1
1419 call assert_equal("V", getregtype('"'), msg)
zeertzjqdf63f052022-10-19 15:12:54 +01001420 call assert_equal(2, len(getreg('"', 1, v:true)), msg)
Yee Cheng Chin17822c52022-10-13 13:17:40 +01001421
1422 " Test for right click in line-wise visual mode outside the selection
1423 let @" = ''
1424 call cursor(1, 16)
1425 call feedkeys("V" .. MouseRightClickCode(2, 10)
1426 \ .. MouseRightReleaseCode(2, 10) .. "\<Down>\<CR>", "x")
1427 call assert_equal([2, 10], [line('.'), col('.')], msg)
1428 call assert_equal("", @", msg)
1429
Bram Moolenaar297bec02020-07-14 22:11:04 +02001430 " Try clicking on the status line
1431 let @" = ''
1432 call cursor(1, 10)
1433 call feedkeys('vee' .. MouseRightClickCode(6, 2)
1434 \ .. MouseRightReleaseCode(6, 2) .. "\<Down>\<CR>", "x")
Bram Moolenaar2764d062020-07-18 12:59:19 +02001435 call assert_equal([1, 10], [line('.'), col('.')], msg)
1436 call assert_equal('ran away', @", msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001437
1438 " Try clicking outside the window
1439 let @" = ''
zeertzjqdf63f052022-10-19 15:12:54 +01001440 call cursor(2, 2)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001441 call feedkeys('vee' .. MouseRightClickCode(7, 2)
1442 \ .. MouseRightReleaseCode(7, 2) .. "\<Down>\<CR>", "x")
Bram Moolenaar2764d062020-07-18 12:59:19 +02001443 call assert_equal(2, winnr(), msg)
1444 call assert_equal('', @", msg)
Bram Moolenaar297bec02020-07-14 22:11:04 +02001445 wincmd w
1446 endfor
1447
1448 unmenu PopUp
1449 let &mouse = save_mouse
1450 let &term = save_term
1451 let &ttymouse = save_ttymouse
1452 let &mousemodel = save_mousemodel
1453 call test_override('no_query_mouse', 0)
Christian Brabandt08ea2e12025-01-25 15:01:42 +01001454 bw!
Bram Moolenaar297bec02020-07-14 22:11:04 +02001455endfunc
1456
1457" Test for searching for the word under the cursor using Shift-Right or
1458" Shift-Left click.
1459func Test_term_mouse_search()
1460 new
1461 let save_mouse = &mouse
1462 let save_term = &term
1463 let save_ttymouse = &ttymouse
1464 call test_override('no_query_mouse', 1)
1465 set mouse=a term=xterm ttymouse=xterm2
1466 set mousemodel=
Bram Moolenaarc255b782022-11-26 19:16:48 +00001467 call WaitForResponses()
Bram Moolenaar297bec02020-07-14 22:11:04 +02001468
1469 " In normal mode, Shift-Left or Shift-Right click should search for the word
1470 " under the cursor.
1471 call setline(1, ['one two three four', 'four three two one'])
1472 call test_setmouse(1, 4)
1473 exe "normal \<S-LeftMouse>"
1474 call assert_equal([2, 12], [line('.'), col('.')])
1475 call test_setmouse(2, 16)
1476 exe "normal \<S-RightMouse>"
1477 call assert_equal([1, 1], [line('.'), col('.')])
1478
1479 " In visual mode, Shift-Left or Shift-Right click should search for the word
1480 " under the cursor and extend the selection.
1481 call test_setmouse(1, 4)
1482 exe "normal 4|ve\<S-LeftMouse>y"
1483 call assert_equal([2, 12], [line("'>"), col("'>")])
1484 call test_setmouse(2, 16)
1485 exe "normal 2G16|ve\<S-RightMouse>y"
1486 call assert_equal([1, 1], [line("'<"), col("'<")])
1487
1488 set mousemodel&
1489 let &mouse = save_mouse
1490 let &term = save_term
1491 let &ttymouse = save_ttymouse
1492 call test_override('no_query_mouse', 0)
Christian Brabandt08ea2e12025-01-25 15:01:42 +01001493 bw!
Bram Moolenaar297bec02020-07-14 22:11:04 +02001494endfunc
1495
1496" Test for selecting an entry in the quickfix/location list window using the
1497" mouse.
1498func Test_term_mouse_quickfix_window()
1499 let save_mouse = &mouse
1500 let save_term = &term
1501 let save_ttymouse = &ttymouse
1502 call test_override('no_query_mouse', 1)
1503 set mouse=a term=xterm ttymouse=xterm2
1504 set mousemodel=
Bram Moolenaarc255b782022-11-26 19:16:48 +00001505 call WaitForResponses()
Bram Moolenaar297bec02020-07-14 22:11:04 +02001506
1507 cgetexpr "Xfile1:1:L1"
1508 copen 5
1509 call test_setmouse(&lines - 7, 1)
1510 exe "normal \<2-LeftMouse>"
1511 call assert_equal('Xfile1', @%)
1512 %bw!
1513
1514 lgetexpr "Xfile2:1:L1"
1515 lopen 5
1516 call test_setmouse(&lines - 7, 1)
1517 exe "normal \<2-LeftMouse>"
1518 call assert_equal('Xfile2', @%)
1519 %bw!
1520
1521 set mousemodel&
1522 let &mouse = save_mouse
1523 let &term = save_term
1524 let &ttymouse = save_ttymouse
1525 call test_override('no_query_mouse', 0)
1526endfunc
1527
Bram Moolenaar2764d062020-07-18 12:59:19 +02001528" Test for the 'h' flag in the 'mouse' option. Using mouse in the help window.
1529func Test_term_mouse_help_window()
1530 let save_mouse = &mouse
1531 let save_term = &term
1532 let save_ttymouse = &ttymouse
1533 call test_override('no_query_mouse', 1)
1534 set mouse=h term=xterm mousetime=200
Bram Moolenaarc255b782022-11-26 19:16:48 +00001535 call WaitForResponses()
Bram Moolenaar2764d062020-07-18 12:59:19 +02001536
1537 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
1538 let msg = 'ttymouse=' .. ttymouse_val
1539 exe 'set ttymouse=' .. ttymouse_val
1540 help
1541 let @" = ''
1542 call MouseLeftClick(2, 5)
1543 call MouseLeftRelease(2, 5)
1544 call MouseLeftClick(1, 1)
1545 call MouseLeftDrag(1, 10)
1546 call MouseLeftRelease(1, 10)
1547 norm! y
1548 call assert_equal('*help.txt*', @", msg)
1549 helpclose
1550
1551 " Click somewhere else to make sure the left click above is not combined
1552 " with the next left click and treated as a double click
1553 call MouseRightClick(5, 10)
1554 call MouseRightRelease(5, 10)
1555 endfor
1556
1557 let &mouse = save_mouse
1558 let &term = save_term
1559 let &ttymouse = save_ttymouse
1560 set mousetime&
1561 call test_override('no_query_mouse', 0)
1562 %bw!
1563endfunc
1564
1565" Test for the translation of various mouse terminal codes
1566func Test_mouse_termcodes()
1567 let save_mouse = &mouse
1568 let save_term = &term
1569 let save_ttymouse = &ttymouse
1570 call test_override('no_query_mouse', 1)
1571 set mouse=a term=xterm mousetime=200
Bram Moolenaarc255b782022-11-26 19:16:48 +00001572 call WaitForResponses()
Bram Moolenaar2764d062020-07-18 12:59:19 +02001573
1574 new
1575 for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm
1576 let msg = 'ttymouse=' .. ttymouse_val
1577 exe 'set ttymouse=' .. ttymouse_val
1578
1579 let mouse_codes = [
1580 \ ["\<LeftMouse>", "<LeftMouse>"],
1581 \ ["\<MiddleMouse>", "<MiddleMouse>"],
1582 \ ["\<RightMouse>", "<RightMouse>"],
1583 \ ["\<S-LeftMouse>", "<S-LeftMouse>"],
1584 \ ["\<S-MiddleMouse>", "<S-MiddleMouse>"],
1585 \ ["\<S-RightMouse>", "<S-RightMouse>"],
1586 \ ["\<C-LeftMouse>", "<C-LeftMouse>"],
1587 \ ["\<C-MiddleMouse>", "<C-MiddleMouse>"],
1588 \ ["\<C-RightMouse>", "<C-RightMouse>"],
1589 \ ["\<M-LeftMouse>", "<M-LeftMouse>"],
1590 \ ["\<M-MiddleMouse>", "<M-MiddleMouse>"],
1591 \ ["\<M-RightMouse>", "<M-RightMouse>"],
1592 \ ["\<2-LeftMouse>", "<2-LeftMouse>"],
1593 \ ["\<2-MiddleMouse>", "<2-MiddleMouse>"],
1594 \ ["\<2-RightMouse>", "<2-RightMouse>"],
1595 \ ["\<3-LeftMouse>", "<3-LeftMouse>"],
1596 \ ["\<3-MiddleMouse>", "<3-MiddleMouse>"],
1597 \ ["\<3-RightMouse>", "<3-RightMouse>"],
1598 \ ["\<4-LeftMouse>", "<4-LeftMouse>"],
1599 \ ["\<4-MiddleMouse>", "<4-MiddleMouse>"],
1600 \ ["\<4-RightMouse>", "<4-RightMouse>"],
1601 \ ["\<LeftDrag>", "<LeftDrag>"],
1602 \ ["\<MiddleDrag>", "<MiddleDrag>"],
1603 \ ["\<RightDrag>", "<RightDrag>"],
1604 \ ["\<LeftRelease>", "<LeftRelease>"],
1605 \ ["\<MiddleRelease>", "<MiddleRelease>"],
1606 \ ["\<RightRelease>", "<RightRelease>"],
1607 \ ["\<ScrollWheelUp>", "<ScrollWheelUp>"],
1608 \ ["\<S-ScrollWheelUp>", "<S-ScrollWheelUp>"],
1609 \ ["\<C-ScrollWheelUp>", "<C-ScrollWheelUp>"],
1610 \ ["\<ScrollWheelDown>", "<ScrollWheelDown>"],
1611 \ ["\<S-ScrollWheelDown>", "<S-ScrollWheelDown>"],
1612 \ ["\<C-ScrollWheelDown>", "<C-ScrollWheelDown>"],
1613 \ ["\<ScrollWheelLeft>", "<ScrollWheelLeft>"],
1614 \ ["\<S-ScrollWheelLeft>", "<S-ScrollWheelLeft>"],
1615 \ ["\<C-ScrollWheelLeft>", "<C-ScrollWheelLeft>"],
1616 \ ["\<ScrollWheelRight>", "<ScrollWheelRight>"],
1617 \ ["\<S-ScrollWheelRight>", "<S-ScrollWheelRight>"],
1618 \ ["\<C-ScrollWheelRight>", "<C-ScrollWheelRight>"]
1619 \ ]
1620
1621 for [code, outstr] in mouse_codes
1622 exe "normal ggC\<C-K>" . code
1623 call assert_equal(outstr, getline(1), msg)
1624 endfor
1625 endfor
1626
1627 let &mouse = save_mouse
1628 let &term = save_term
1629 let &ttymouse = save_ttymouse
1630 set mousetime&
1631 call test_override('no_query_mouse', 0)
1632 %bw!
1633endfunc
1634
Bram Moolenaar66761db2019-06-05 22:07:51 +02001635" This only checks if the sequence is recognized.
Bram Moolenaar66761db2019-06-05 22:07:51 +02001636func Test_term_rgb_response()
1637 set t_RF=x
1638 set t_RB=y
1639
1640 " response to t_RF, 4 digits
1641 let red = 0x12
1642 let green = 0x34
1643 let blue = 0x56
1644 let seq = printf("\<Esc>]10;rgb:%02x00/%02x00/%02x00\x07", red, green, blue)
1645 call feedkeys(seq, 'Lx!')
1646 call assert_equal(seq, v:termrfgresp)
1647
1648 " response to t_RF, 2 digits
1649 let red = 0x78
1650 let green = 0x9a
1651 let blue = 0xbc
1652 let seq = printf("\<Esc>]10;rgb:%02x/%02x/%02x\x07", red, green, blue)
1653 call feedkeys(seq, 'Lx!')
1654 call assert_equal(seq, v:termrfgresp)
1655
Bram Moolenaar32e19772019-06-05 22:57:04 +02001656 " response to t_RB, 4 digits, dark
1657 set background=light
Bram Moolenaarce90e362019-09-08 18:58:44 +02001658 eval 'background'->test_option_not_set()
Bram Moolenaar32e19772019-06-05 22:57:04 +02001659 let red = 0x29
1660 let green = 0x4a
1661 let blue = 0x6b
1662 let seq = printf("\<Esc>]11;rgb:%02x00/%02x00/%02x00\x07", red, green, blue)
1663 call feedkeys(seq, 'Lx!')
1664 call assert_equal(seq, v:termrbgresp)
1665 call assert_equal('dark', &background)
1666
1667 " response to t_RB, 4 digits, light
1668 set background=dark
1669 call test_option_not_set('background')
1670 let red = 0x81
1671 let green = 0x63
Bram Moolenaar66761db2019-06-05 22:07:51 +02001672 let blue = 0x65
1673 let seq = printf("\<Esc>]11;rgb:%02x00/%02x00/%02x00\x07", red, green, blue)
1674 call feedkeys(seq, 'Lx!')
1675 call assert_equal(seq, v:termrbgresp)
Bram Moolenaar32e19772019-06-05 22:57:04 +02001676 call assert_equal('light', &background)
Bram Moolenaar66761db2019-06-05 22:07:51 +02001677
Bram Moolenaar32e19772019-06-05 22:57:04 +02001678 " response to t_RB, 2 digits, dark
1679 set background=light
1680 call test_option_not_set('background')
1681 let red = 0x47
1682 let green = 0x59
1683 let blue = 0x5b
Bram Moolenaar66761db2019-06-05 22:07:51 +02001684 let seq = printf("\<Esc>]11;rgb:%02x/%02x/%02x\x07", red, green, blue)
1685 call feedkeys(seq, 'Lx!')
1686 call assert_equal(seq, v:termrbgresp)
Bram Moolenaar32e19772019-06-05 22:57:04 +02001687 call assert_equal('dark', &background)
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01001688
Bram Moolenaar32e19772019-06-05 22:57:04 +02001689 " response to t_RB, 2 digits, light
1690 set background=dark
1691 call test_option_not_set('background')
1692 let red = 0x83
1693 let green = 0xa4
1694 let blue = 0xc2
1695 let seq = printf("\<Esc>]11;rgb:%02x/%02x/%02x\x07", red, green, blue)
1696 call feedkeys(seq, 'Lx!')
1697 call assert_equal(seq, v:termrbgresp)
1698 call assert_equal('light', &background)
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01001699
Bram Moolenaar66761db2019-06-05 22:07:51 +02001700 set t_RF= t_RB=
1701endfunc
1702
1703" This only checks if the sequence is recognized.
Bram Moolenaar1a4cbb12019-10-12 13:25:44 +02001704" This must be after other tests, because it has side effects to xterm
1705" properties.
1706func Test_xx01_term_style_response()
Bram Moolenaar66761db2019-06-05 22:07:51 +02001707 " Termresponse is only parsed when t_RV is not empty.
1708 set t_RV=x
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001709 call test_override('term_props', 1)
Bram Moolenaar66761db2019-06-05 22:07:51 +02001710
1711 " send the termresponse to trigger requesting the XT codes
1712 let seq = "\<Esc>[>41;337;0c"
1713 call feedkeys(seq, 'Lx!')
1714 call assert_equal(seq, v:termresponse)
1715
1716 let seq = "\<Esc>P1$r2 q\<Esc>\\"
1717 call feedkeys(seq, 'Lx!')
1718 call assert_equal(seq, v:termstyleresp)
1719
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001720 call assert_equal(#{
1721 \ cursor_style: 'u',
1722 \ cursor_blink_mode: 'u',
1723 \ underline_rgb: 'u',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001724 \ mouse: 's',
1725 \ kitty: 'u',
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001726 \ }, terminalprops())
1727
Bram Moolenaar66761db2019-06-05 22:07:51 +02001728 set t_RV=
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001729 call test_override('term_props', 0)
Bram Moolenaar66761db2019-06-05 22:07:51 +02001730endfunc
Bram Moolenaarde6dbb42019-06-06 11:59:18 +02001731
Bram Moolenaar89577b32019-10-18 21:26:05 +02001732" This checks the iTerm2 version response.
1733" This must be after other tests, because it has side effects to xterm
1734" properties.
1735func Test_xx02_iTerm2_response()
1736 " Termresponse is only parsed when t_RV is not empty.
1737 set t_RV=x
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001738 call test_override('term_props', 1)
Bram Moolenaar89577b32019-10-18 21:26:05 +02001739
1740 " Old versions of iTerm2 used a different style term response.
1741 set ttymouse=xterm
1742 call test_option_not_set('ttymouse')
1743 let seq = "\<Esc>[>0;95;c"
1744 call feedkeys(seq, 'Lx!')
1745 call assert_equal(seq, v:termresponse)
1746 call assert_equal('xterm', &ttymouse)
1747
1748 set ttymouse=xterm
1749 call test_option_not_set('ttymouse')
1750 let seq = "\<Esc>[>0;95;0c"
1751 call feedkeys(seq, 'Lx!')
1752 call assert_equal(seq, v:termresponse)
1753 call assert_equal('sgr', &ttymouse)
1754
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001755 call assert_equal(#{
1756 \ cursor_style: 'n',
1757 \ cursor_blink_mode: 'u',
1758 \ underline_rgb: 'u',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001759 \ mouse: 's',
1760 \ kitty: 'u',
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001761 \ }, terminalprops())
1762
Bram Moolenaar89577b32019-10-18 21:26:05 +02001763 set t_RV=
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001764 call test_override('term_props', 0)
Bram Moolenaar89577b32019-10-18 21:26:05 +02001765endfunc
1766
Bram Moolenaard55f9ef2022-08-26 12:26:07 +01001767func Run_libvterm_konsole_response(code)
Bram Moolenaar1a4cbb12019-10-12 13:25:44 +02001768 set ttymouse=xterm
1769 call test_option_not_set('ttymouse')
Bram Moolenaard55f9ef2022-08-26 12:26:07 +01001770 let seq = "\<Esc>[>0;" .. a:code .. ";0c"
Bram Moolenaar1a4cbb12019-10-12 13:25:44 +02001771 call feedkeys(seq, 'Lx!')
1772 call assert_equal(seq, v:termresponse)
1773 call assert_equal('sgr', &ttymouse)
1774
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001775 call assert_equal(#{
1776 \ cursor_style: 'n',
1777 \ cursor_blink_mode: 'u',
1778 \ underline_rgb: 'u',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001779 \ mouse: 's',
1780 \ kitty: 'u',
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001781 \ }, terminalprops())
Bram Moolenaard55f9ef2022-08-26 12:26:07 +01001782endfunc
1783
1784" This checks the libvterm version response.
1785" This must be after other tests, because it has side effects to xterm
1786" properties.
1787func Test_xx03_libvterm_konsole_response()
1788 " Termresponse is only parsed when t_RV is not empty.
1789 set t_RV=x
1790 call test_override('term_props', 1)
1791
1792 " libvterm
1793 call Run_libvterm_konsole_response(100)
1794 " Konsole
1795 call Run_libvterm_konsole_response(115)
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001796
Bram Moolenaar1a4cbb12019-10-12 13:25:44 +02001797 set t_RV=
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001798 call test_override('term_props', 0)
Bram Moolenaar1a4cbb12019-10-12 13:25:44 +02001799endfunc
1800
Bram Moolenaar89577b32019-10-18 21:26:05 +02001801" This checks the Mac Terminal.app version response.
1802" This must be after other tests, because it has side effects to xterm
1803" properties.
1804func Test_xx04_Mac_Terminal_response()
1805 " Termresponse is only parsed when t_RV is not empty.
1806 set t_RV=x
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001807 call test_override('term_props', 1)
Bram Moolenaar89577b32019-10-18 21:26:05 +02001808
1809 set ttymouse=xterm
Bram Moolenaar8dff4cb2020-06-14 14:34:16 +02001810 " t_8u is not reset
1811 let &t_8u = "\<Esc>[58;2;%lu;%lu;%lum"
Bram Moolenaar89577b32019-10-18 21:26:05 +02001812 call test_option_not_set('ttymouse')
1813 let seq = "\<Esc>[>1;95;0c"
1814 call feedkeys(seq, 'Lx!')
1815 call assert_equal(seq, v:termresponse)
1816 call assert_equal('sgr', &ttymouse)
1817
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001818 call assert_equal(#{
1819 \ cursor_style: 'n',
1820 \ cursor_blink_mode: 'u',
1821 \ underline_rgb: 'y',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001822 \ mouse: 's',
1823 \ kitty: 'u',
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001824 \ }, terminalprops())
Bram Moolenaar8dff4cb2020-06-14 14:34:16 +02001825 call assert_equal("\<Esc>[58;2;%lu;%lu;%lum", &t_8u)
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001826
Bram Moolenaar89577b32019-10-18 21:26:05 +02001827 " Reset is_not_xterm and is_mac_terminal.
1828 set t_RV=
1829 set term=xterm
1830 set t_RV=x
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001831 call test_override('term_props', 0)
Bram Moolenaar89577b32019-10-18 21:26:05 +02001832endfunc
1833
1834" This checks the mintty version response.
1835" This must be after other tests, because it has side effects to xterm
1836" properties.
1837func Test_xx05_mintty_response()
1838 " Termresponse is only parsed when t_RV is not empty.
1839 set t_RV=x
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001840 call test_override('term_props', 1)
Bram Moolenaar89577b32019-10-18 21:26:05 +02001841
1842 set ttymouse=xterm
1843 call test_option_not_set('ttymouse')
1844 let seq = "\<Esc>[>77;20905;0c"
1845 call feedkeys(seq, 'Lx!')
1846 call assert_equal(seq, v:termresponse)
1847 call assert_equal('sgr', &ttymouse)
1848
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001849 call assert_equal(#{
1850 \ cursor_style: 'n',
1851 \ cursor_blink_mode: 'u',
1852 \ underline_rgb: 'y',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001853 \ mouse: 's',
1854 \ kitty: 'u',
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001855 \ }, terminalprops())
1856
Bram Moolenaar89577b32019-10-18 21:26:05 +02001857 set t_RV=
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001858 call test_override('term_props', 0)
Bram Moolenaar89577b32019-10-18 21:26:05 +02001859endfunc
1860
1861" This checks the screen version response.
1862" This must be after other tests, because it has side effects to xterm
1863" properties.
1864func Test_xx06_screen_response()
1865 " Termresponse is only parsed when t_RV is not empty.
1866 set t_RV=x
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001867 call test_override('term_props', 1)
Bram Moolenaar89577b32019-10-18 21:26:05 +02001868
1869 " Old versions of screen don't support SGR mouse mode.
1870 set ttymouse=xterm
1871 call test_option_not_set('ttymouse')
1872 let seq = "\<Esc>[>83;40500;0c"
1873 call feedkeys(seq, 'Lx!')
1874 call assert_equal(seq, v:termresponse)
1875 call assert_equal('xterm', &ttymouse)
1876
1877 " screen supports SGR mouse mode starting in version 4.7.
1878 set ttymouse=xterm
1879 call test_option_not_set('ttymouse')
1880 let seq = "\<Esc>[>83;40700;0c"
1881 call feedkeys(seq, 'Lx!')
1882 call assert_equal(seq, v:termresponse)
1883 call assert_equal('sgr', &ttymouse)
1884
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001885 call assert_equal(#{
1886 \ cursor_style: 'n',
1887 \ cursor_blink_mode: 'n',
1888 \ underline_rgb: 'y',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001889 \ mouse: 's',
1890 \ kitty: 'u',
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001891 \ }, terminalprops())
1892
Bram Moolenaar89577b32019-10-18 21:26:05 +02001893 set t_RV=
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001894 call test_override('term_props', 0)
Bram Moolenaar89577b32019-10-18 21:26:05 +02001895endfunc
1896
Bram Moolenaard0eaf672022-04-20 19:55:37 +01001897func Do_check_t_8u_set_reset(set_by_user)
1898 set ttymouse=xterm
1899 call test_option_not_set('ttymouse')
1900 let default_value = "\<Esc>[58;2;%lu;%lu;%lum"
1901 let &t_8u = default_value
1902 if !a:set_by_user
1903 call test_option_not_set('t_8u')
1904 endif
1905 let seq = "\<Esc>[>0;279;0c"
1906 call feedkeys(seq, 'Lx!')
1907 call assert_equal(seq, v:termresponse)
1908 call assert_equal('sgr', &ttymouse)
1909
1910 call assert_equal(#{
1911 \ cursor_style: 'u',
1912 \ cursor_blink_mode: 'u',
1913 \ underline_rgb: 'u',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001914 \ mouse: 's',
1915 \ kitty: 'u',
Bram Moolenaard0eaf672022-04-20 19:55:37 +01001916 \ }, terminalprops())
1917 call assert_equal(a:set_by_user ? default_value : '', &t_8u)
1918endfunc
1919
Bram Moolenaar03b00472019-10-14 22:22:03 +02001920" This checks the xterm version response.
1921" This must be after other tests, because it has side effects to xterm
1922" properties.
Bram Moolenaar89577b32019-10-18 21:26:05 +02001923func Test_xx07_xterm_response()
Bram Moolenaar03b00472019-10-14 22:22:03 +02001924 " Termresponse is only parsed when t_RV is not empty.
1925 set t_RV=x
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001926 call test_override('term_props', 1)
Bram Moolenaar03b00472019-10-14 22:22:03 +02001927
Bram Moolenaar3cea8a92019-10-17 21:55:24 +02001928 " Do Terminal.app first to check that is_mac_terminal is reset.
1929 set ttymouse=xterm
1930 call test_option_not_set('ttymouse')
1931 let seq = "\<Esc>[>1;95;0c"
1932 call feedkeys(seq, 'Lx!')
1933 call assert_equal(seq, v:termresponse)
1934 call assert_equal('sgr', &ttymouse)
1935
Bram Moolenaar03b00472019-10-14 22:22:03 +02001936 " xterm < 95: "xterm" (actually unmodified)
Bram Moolenaar3cea8a92019-10-17 21:55:24 +02001937 set t_RV=
1938 set term=xterm
Bram Moolenaarc255b782022-11-26 19:16:48 +00001939 call WaitForResponses()
1940
Bram Moolenaar3cea8a92019-10-17 21:55:24 +02001941 set t_RV=x
Bram Moolenaar03b00472019-10-14 22:22:03 +02001942 set ttymouse=xterm
1943 call test_option_not_set('ttymouse')
1944 let seq = "\<Esc>[>0;94;0c"
1945 call feedkeys(seq, 'Lx!')
1946 call assert_equal(seq, v:termresponse)
1947 call assert_equal('xterm', &ttymouse)
1948
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001949 call assert_equal(#{
1950 \ cursor_style: 'n',
1951 \ cursor_blink_mode: 'u',
1952 \ underline_rgb: 'y',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001953 \ mouse: 'u',
1954 \ kitty: 'u',
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001955 \ }, terminalprops())
1956
Bram Moolenaar03b00472019-10-14 22:22:03 +02001957 " xterm >= 95 < 277 "xterm2"
1958 set ttymouse=xterm
1959 call test_option_not_set('ttymouse')
1960 let seq = "\<Esc>[>0;267;0c"
1961 call feedkeys(seq, 'Lx!')
1962 call assert_equal(seq, v:termresponse)
1963 call assert_equal('xterm2', &ttymouse)
1964
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001965 call assert_equal(#{
1966 \ cursor_style: 'n',
1967 \ cursor_blink_mode: 'u',
1968 \ underline_rgb: 'u',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001969 \ mouse: '2',
1970 \ kitty: 'u',
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001971 \ }, terminalprops())
1972
Bram Moolenaar03b00472019-10-14 22:22:03 +02001973 " xterm >= 277: "sgr"
1974 set ttymouse=xterm
1975 call test_option_not_set('ttymouse')
1976 let seq = "\<Esc>[>0;277;0c"
1977 call feedkeys(seq, 'Lx!')
1978 call assert_equal(seq, v:termresponse)
1979 call assert_equal('sgr', &ttymouse)
1980
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001981 call assert_equal(#{
1982 \ cursor_style: 'n',
1983 \ cursor_blink_mode: 'u',
1984 \ underline_rgb: 'u',
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001985 \ mouse: 's',
1986 \ kitty: 'u',
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001987 \ }, terminalprops())
1988
Bram Moolenaard0eaf672022-04-20 19:55:37 +01001989 " xterm >= 279: "sgr" and cursor_style not reset; also check t_8u reset,
1990 " except when it was set by the user
1991 call Do_check_t_8u_set_reset(0)
1992 call Do_check_t_8u_set_reset(1)
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001993
Bram Moolenaar03b00472019-10-14 22:22:03 +02001994 set t_RV=
Bram Moolenaar0c0eddd2020-06-13 15:47:25 +02001995 call test_override('term_props', 0)
Bram Moolenaar03b00472019-10-14 22:22:03 +02001996endfunc
1997
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01001998func Test_xx08_kitty_response()
1999 " Termresponse is only parsed when t_RV is not empty.
2000 set t_RV=x
2001 call test_override('term_props', 1)
2002
2003 set ttymouse=xterm
2004 call test_option_not_set('ttymouse')
2005 let seq = "\<Esc>[>1;4001;12c"
2006 call feedkeys(seq, 'Lx!')
2007 call assert_equal(seq, v:termresponse)
2008 call assert_equal('sgr', &ttymouse)
2009
2010 call assert_equal(#{
2011 \ cursor_style: 'u',
2012 \ cursor_blink_mode: 'u',
2013 \ underline_rgb: 'y',
2014 \ mouse: 's',
2015 \ kitty: 'y',
2016 \ }, terminalprops())
2017
Christian Filliona2834e12024-10-16 17:28:38 +02002018 call feedkeys("\<Esc>[?1u") " simulate the kitty keyboard protocol is enabled
2019 call feedkeys(':' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIuWithoutModifier("\<Esc>") .. "\<C-B>\"\<CR>", 'Lx!')
2020 call assert_equal("\"\<Esc>", @:)
2021 call feedkeys(':' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu("\<Esc>", '129') .. "\<C-B>\"\<CR>", 'Lx!')
2022 call assert_equal("\"\<Esc>", @:)
2023
Bram Moolenaar4bc85f22022-10-21 14:17:24 +01002024 set t_RV=
2025 call test_override('term_props', 0)
2026endfunc
2027
Bram Moolenaar92e5df82021-01-30 15:39:47 +01002028func Test_focus_events()
2029 let save_term = &term
2030 let save_ttymouse = &ttymouse
2031 set term=xterm ttymouse=xterm2
Bram Moolenaarc255b782022-11-26 19:16:48 +00002032 call WaitForResponses()
Bram Moolenaar92e5df82021-01-30 15:39:47 +01002033
2034 au FocusGained * let g:focus_gained += 1
2035 au FocusLost * let g:focus_lost += 1
2036 let g:focus_gained = 0
2037 let g:focus_lost = 0
2038
2039 call feedkeys("\<Esc>[O", "Lx!")
2040 call assert_equal(1, g:focus_lost)
2041 call feedkeys("\<Esc>[I", "Lx!")
2042 call assert_equal(1, g:focus_gained)
2043
2044 " still works when 'ttymouse' is empty
2045 set ttymouse=
2046 call feedkeys("\<Esc>[O", "Lx!")
2047 call assert_equal(2, g:focus_lost)
2048 call feedkeys("\<Esc>[I", "Lx!")
2049 call assert_equal(2, g:focus_gained)
2050
2051 au! FocusGained
2052 au! FocusLost
2053 let &term = save_term
2054 let &ttymouse = save_ttymouse
2055endfunc
2056
Bram Moolenaarde6dbb42019-06-06 11:59:18 +02002057func Test_get_termcode()
Bram Moolenaareb663282019-10-06 12:02:15 +02002058 try
2059 let k1 = &t_k1
2060 catch /E113/
2061 throw 'Skipped: Unable to query termcodes'
2062 endtry
Bram Moolenaarde6dbb42019-06-06 11:59:18 +02002063 set t_k1=
2064 set t_k1&
2065 call assert_equal(k1, &t_k1)
Bram Moolenaar9aeb3362019-06-06 12:36:15 +02002066
2067 " use external termcap first
2068 set nottybuiltin
2069 set t_k1=
2070 set t_k1&
2071 " when using external termcap may get something else, but it must not be
2072 " empty, since we would fallback to the builtin one.
2073 call assert_notequal('', &t_k1)
2074
2075 if &term =~ 'xterm'
2076 " use internal termcap first
2077 let term_save = &term
2078 let &term = 'builtin_' .. &term
2079 set t_k1=
2080 set t_k1&
2081 call assert_equal(k1, &t_k1)
2082 let &term = term_save
2083 endif
2084
2085 set ttybuiltin
Bram Moolenaarde6dbb42019-06-06 11:59:18 +02002086endfunc
Bram Moolenaar18a79a62019-10-12 15:36:11 +02002087
Bram Moolenaarecd34bf2020-08-04 20:17:31 +02002088func Test_list_builtin_terminals()
Bram Moolenaare46a2ed2020-08-04 21:04:57 +02002089 CheckRunVimInTerminal
Bram Moolenaar4654d632022-11-17 22:05:12 +00002090
Bram Moolenaar4d05af02020-11-27 20:55:00 +01002091 call RunVimInTerminal('', #{rows: 14})
2092 call term_sendkeys('', ":set cmdheight=3\<CR>")
2093 call TermWait('', 100)
2094 call term_sendkeys('', ":set term=xxx\<CR>")
2095 call TermWait('', 100)
Bram Moolenaar4654d632022-11-17 22:05:12 +00002096
2097 " Check that the list ends in "builtin_dumb" and "builtin_debug".
2098 let dumb_idx = 0
2099 for n in range(8, 12)
2100 if term_getline('', n) =~ 'builtin_dumb'
2101 let dumb_idx = n
2102 break
2103 endif
2104 endfor
2105 call assert_notequal(0, dumb_idx, 'builtin_dumb not found')
2106
2107 call assert_match('builtin_dumb', term_getline('', dumb_idx))
2108 call assert_match('builtin_debug', term_getline('', dumb_idx + 1))
2109 call assert_match('Not found in termcap', term_getline('', dumb_idx + 2))
2110
Bram Moolenaar4d05af02020-11-27 20:55:00 +01002111 call StopVimInTerminal('')
Bram Moolenaarecd34bf2020-08-04 20:17:31 +02002112endfunc
2113
Bram Moolenaar18a79a62019-10-12 15:36:11 +02002114" This checks the CSI sequences when in modifyOtherKeys mode.
2115" The mode doesn't need to be enabled, the codes are always detected.
2116func RunTest_modifyOtherKeys(func)
2117 new
Bram Moolenaar459fd782019-10-13 16:43:39 +02002118 set timeoutlen=10
Bram Moolenaar18a79a62019-10-12 15:36:11 +02002119
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01002120 " Shift-X is sent as 'X' with the shift modifier
Bram Moolenaar18a79a62019-10-12 15:36:11 +02002121 call feedkeys('a' .. a:func('X', 2) .. "\<Esc>", 'Lx!')
2122 call assert_equal('X', getline(1))
2123
2124 " Ctrl-i is Tab
2125 call setline(1, '')
2126 call feedkeys('a' .. a:func('i', 5) .. "\<Esc>", 'Lx!')
2127 call assert_equal("\t", getline(1))
2128
2129 " Ctrl-I is also Tab
2130 call setline(1, '')
2131 call feedkeys('a' .. a:func('I', 5) .. "\<Esc>", 'Lx!')
2132 call assert_equal("\t", getline(1))
2133
2134 " Alt-x is ø
2135 call setline(1, '')
2136 call feedkeys('a' .. a:func('x', 3) .. "\<Esc>", 'Lx!')
2137 call assert_equal("ø", getline(1))
2138
2139 " Meta-x is also ø
2140 call setline(1, '')
2141 call feedkeys('a' .. a:func('x', 9) .. "\<Esc>", 'Lx!')
2142 call assert_equal("ø", getline(1))
2143
2144 " Alt-X is Ø
2145 call setline(1, '')
2146 call feedkeys('a' .. a:func('X', 3) .. "\<Esc>", 'Lx!')
2147 call assert_equal("Ø", getline(1))
2148
2149 " Meta-X is ø
2150 call setline(1, '')
2151 call feedkeys('a' .. a:func('X', 9) .. "\<Esc>", 'Lx!')
2152 call assert_equal("Ø", getline(1))
2153
Bram Moolenaar828ffd52019-11-21 23:24:00 +01002154 " Ctrl-6 is Ctrl-^
2155 split aaa
2156 edit bbb
2157 call feedkeys(a:func('6', 5), 'Lx!')
2158 call assert_equal("aaa", bufname())
2159 bwipe aaa
2160 bwipe bbb
2161
Bram Moolenaar0684e362020-12-03 19:54:42 +01002162 " Ctrl-V X 33 is 3
2163 call setline(1, '')
2164 call feedkeys("a\<C-V>" .. a:func('X', 2) .. "33\<Esc>", 'Lx!')
2165 call assert_equal("3", getline(1))
2166
2167 " Ctrl-V U 12345 is Unicode 12345
2168 call setline(1, '')
2169 call feedkeys("a\<C-V>" .. a:func('U', 2) .. "12345\<Esc>", 'Lx!')
2170 call assert_equal("\U12345", getline(1))
2171
Bram Moolenaar18a79a62019-10-12 15:36:11 +02002172 bwipe!
2173 set timeoutlen&
2174endfunc
2175
Bram Moolenaar459fd782019-10-13 16:43:39 +02002176func Test_modifyOtherKeys_basic()
Bram Moolenaar18a79a62019-10-12 15:36:11 +02002177 call RunTest_modifyOtherKeys(function('GetEscCodeCSI27'))
Bram Moolenaar18a79a62019-10-12 15:36:11 +02002178 call RunTest_modifyOtherKeys(function('GetEscCodeCSIu'))
2179endfunc
Bram Moolenaard1e2f392019-10-12 18:22:50 +02002180
Bram Moolenaar38571a02019-11-26 14:28:15 +01002181func Test_modifyOtherKeys_no_mapping()
2182 set timeoutlen=10
2183
2184 let @a = 'aaa'
2185 call feedkeys(":let x = '" .. GetEscCodeCSI27('R', 5) .. GetEscCodeCSI27('R', 5) .. "a'\<CR>", 'Lx!')
2186 call assert_equal("let x = 'aaa'", @:)
2187
2188 new
2189 call feedkeys("a" .. GetEscCodeCSI27('R', 5) .. GetEscCodeCSI27('R', 5) .. "a\<Esc>", 'Lx!')
2190 call assert_equal("aaa", getline(1))
2191 bwipe!
2192
2193 new
2194 call feedkeys("axx\<CR>yy" .. GetEscCodeCSI27('G', 5) .. GetEscCodeCSI27('K', 5) .. "a\<Esc>", 'Lx!')
2195 call assert_equal("axx", getline(1))
2196 call assert_equal("yy", getline(2))
2197 bwipe!
2198
2199 set timeoutlen&
2200endfunc
2201
Trygve Aabergeb9c09c12022-10-14 12:08:24 +01002202func Test_CSIu_keys_without_modifiers()
Bram Moolenaarebed1b02022-11-24 14:05:19 +00002203 " make this execute faster
2204 set timeoutlen=10
2205
Bram Moolenaarc255b782022-11-26 19:16:48 +00002206 call WaitForResponses()
2207
Trygve Aabergeb9c09c12022-10-14 12:08:24 +01002208 " Escape sent as `CSI 27 u` should act as normal escape and not undo
2209 call setline(1, 'a')
2210 call feedkeys('a' .. GetEscCodeCSIuWithoutModifier("\e"), 'Lx!')
2211 call assert_equal('n', mode())
2212 call assert_equal('a', getline(1))
2213
2214 " Tab sent as `CSI 9 u` should work
2215 call setline(1, '')
2216 call feedkeys('a' .. GetEscCodeCSIuWithoutModifier("\t") .. "\<Esc>", 'Lx!')
2217 call assert_equal("\t", getline(1))
Bram Moolenaarebed1b02022-11-24 14:05:19 +00002218
2219 set timeoutlen&
Trygve Aabergeb9c09c12022-10-14 12:08:24 +01002220endfunc
2221
Bram Moolenaarc14b57c2021-12-03 13:20:29 +00002222" Check that when DEC mouse codes are recognized a special key is handled.
2223func Test_ignore_dec_mouse()
Dominique Pellef589fd32021-12-05 12:39:21 +00002224 silent !infocmp gnome >/dev/null 2>&1
2225 if v:shell_error != 0
2226 throw 'Skipped: gnome entry missing in the terminfo db'
2227 endif
Bram Moolenaarc14b57c2021-12-03 13:20:29 +00002228
2229 new
2230 let save_mouse = &mouse
2231 let save_term = &term
2232 let save_ttymouse = &ttymouse
2233 call test_override('no_query_mouse', 1)
2234 set mouse=a term=gnome ttymouse=
Bram Moolenaarc255b782022-11-26 19:16:48 +00002235 call WaitForResponses()
Bram Moolenaarc14b57c2021-12-03 13:20:29 +00002236
2237 execute "set <xF1>=\<Esc>[1;*P"
2238 nnoremap <S-F1> agot it<Esc>
2239 call feedkeys("\<Esc>[1;2P", 'Lx!')
2240 call assert_equal('got it', getline(1))
2241
2242 let &mouse = save_mouse
2243 let &term = save_term
2244 let &ttymouse = save_ttymouse
2245 call test_override('no_query_mouse', 0)
2246 bwipe!
2247endfunc
2248
Bram Moolenaard1e2f392019-10-12 18:22:50 +02002249func RunTest_mapping_shift(key, func)
2250 call setline(1, '')
2251 if a:key == '|'
2252 exe 'inoremap \| xyz'
2253 else
2254 exe 'inoremap ' .. a:key .. ' xyz'
2255 endif
2256 call feedkeys('a' .. a:func(a:key, 2) .. "\<Esc>", 'Lx!')
2257 call assert_equal("xyz", getline(1))
2258 if a:key == '|'
2259 exe 'iunmap \|'
2260 else
2261 exe 'iunmap ' .. a:key
2262 endif
2263endfunc
2264
Bram Moolenaar975a8802020-06-06 22:36:24 +02002265func Test_modifyOtherKeys_mapped()
2266 set timeoutlen=10
2267 imap ' <C-W>
2268 imap <C-W><C-A> c-a
2269 call setline(1, '')
2270
2271 " single quote is turned into single byte CTRL-W
2272 " CTRL-A is added with a separate modifier, and needs to be simplified before
2273 " the mapping can match.
2274 call feedkeys("a'" .. GetEscCodeCSI27('A', 5) .. "\<Esc>", 'Lx!')
2275 call assert_equal('c-a', getline(1))
2276
2277 iunmap '
2278 iunmap <C-W><C-A>
Oleg Goncharov56904f92024-07-23 20:34:15 +02002279
2280 " clean buffer
2281 %d _
2282 imap B b
2283 imap BBB blimp
2284 let input = repeat(GetEscCodeCSI27('B', 2), 3)
2285 call feedkeys("a" .. input .. "\<Esc>", 'Lx!')
2286 call assert_equal('blimp', getline(1))
2287 " cleanup
2288 iunmap BBB
2289 iunmap B
Bram Moolenaar975a8802020-06-06 22:36:24 +02002290 set timeoutlen&
2291endfunc
2292
Bram Moolenaar196c3852022-03-04 19:22:36 +00002293func Test_modifyOtherKeys_ambiguous_mapping()
2294 new
2295 set timeoutlen=10
2296 map <C-J> a
2297 map <C-J>x <Nop>
2298 call setline(1, 'x')
2299
2300 " CTRL-J b should have trigger the <C-J> mapping and then insert "b"
2301 call feedkeys(GetEscCodeCSI27('J', 5) .. "b\<Esc>", 'Lx!')
2302 call assert_equal('xb', getline(1))
2303
2304 unmap <C-J>
2305 unmap <C-J>x
Bram Moolenaarf35fd8e2022-03-18 15:41:17 +00002306
2307 " if a special character is following there should be a check for a termcode
2308 nnoremap s aX<Esc>
2309 nnoremap s<BS> aY<Esc>
2310 set t_kb=
2311 call setline(1, 'x')
2312 call feedkeys("s\x08", 'Lx!')
2313 call assert_equal('xY', getline(1))
2314
Bram Moolenaar196c3852022-03-04 19:22:36 +00002315 set timeoutlen&
2316 bwipe!
2317endfunc
2318
Bram Moolenaar749bc952020-10-31 16:33:47 +01002319" Whether Shift-Tab sends "ESC [ Z" or "ESC [ 27 ; 2 ; 9 ~" is unpredictable,
2320" both should work.
2321func Test_modifyOtherKeys_shift_tab()
2322 set timeoutlen=10
2323
2324 call setline(1, '')
2325 call feedkeys("a\<C-K>" .. GetEscCodeCSI27("\t", '2') .. "\<Esc>", 'Lx!')
2326 eval getline(1)->assert_equal('<S-Tab>')
2327
2328 call setline(1, '')
2329 call feedkeys("a\<C-K>\<Esc>[Z\<Esc>", 'Lx!')
2330 eval getline(1)->assert_equal('<S-Tab>')
2331
2332 set timeoutlen&
2333 bwipe!
2334endfunc
2335
Bram Moolenaard1e2f392019-10-12 18:22:50 +02002336func RunTest_mapping_works_with_shift(func)
2337 new
Bram Moolenaar459fd782019-10-13 16:43:39 +02002338 set timeoutlen=10
Bram Moolenaard1e2f392019-10-12 18:22:50 +02002339
2340 call RunTest_mapping_shift('@', a:func)
2341 call RunTest_mapping_shift('A', a:func)
2342 call RunTest_mapping_shift('Z', a:func)
2343 call RunTest_mapping_shift('^', a:func)
2344 call RunTest_mapping_shift('_', a:func)
2345 call RunTest_mapping_shift('{', a:func)
2346 call RunTest_mapping_shift('|', a:func)
2347 call RunTest_mapping_shift('}', a:func)
2348 call RunTest_mapping_shift('~', a:func)
2349
2350 bwipe!
2351 set timeoutlen&
2352endfunc
2353
Bram Moolenaar459fd782019-10-13 16:43:39 +02002354func Test_mapping_works_with_shift_plain()
Bram Moolenaard1e2f392019-10-12 18:22:50 +02002355 call RunTest_mapping_works_with_shift(function('GetEscCodeCSI27'))
2356 call RunTest_mapping_works_with_shift(function('GetEscCodeCSIu'))
2357endfunc
Bram Moolenaar459fd782019-10-13 16:43:39 +02002358
2359func RunTest_mapping_mods(map, key, func, code)
2360 call setline(1, '')
2361 exe 'inoremap ' .. a:map .. ' xyz'
2362 call feedkeys('a' .. a:func(a:key, a:code) .. "\<Esc>", 'Lx!')
2363 call assert_equal("xyz", getline(1))
2364 exe 'iunmap ' .. a:map
2365endfunc
2366
2367func RunTest_mapping_works_with_mods(func, mods, code)
2368 new
2369 set timeoutlen=10
2370
2371 if a:mods !~ 'S'
2372 " Shift by itself has no effect
2373 call RunTest_mapping_mods('<' .. a:mods .. '-@>', '@', a:func, a:code)
2374 endif
2375 call RunTest_mapping_mods('<' .. a:mods .. '-A>', 'A', a:func, a:code)
2376 call RunTest_mapping_mods('<' .. a:mods .. '-Z>', 'Z', a:func, a:code)
2377 if a:mods !~ 'S'
2378 " with Shift code is always upper case
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 endif
2382 if a:mods != 'A'
2383 " with Alt code is not in upper case
2384 call RunTest_mapping_mods('<' .. a:mods .. '-a>', 'A', a:func, a:code)
2385 call RunTest_mapping_mods('<' .. a:mods .. '-z>', 'Z', a:func, a:code)
2386 endif
2387 call RunTest_mapping_mods('<' .. a:mods .. '-á>', 'á', a:func, a:code)
2388 if a:mods !~ 'S'
2389 " Shift by itself has no effect
2390 call RunTest_mapping_mods('<' .. a:mods .. '-^>', '^', a:func, a:code)
2391 call RunTest_mapping_mods('<' .. a:mods .. '-_>', '_', a:func, a:code)
2392 call RunTest_mapping_mods('<' .. a:mods .. '-{>', '{', a:func, a:code)
2393 call RunTest_mapping_mods('<' .. a:mods .. '-\|>', '|', a:func, a:code)
2394 call RunTest_mapping_mods('<' .. a:mods .. '-}>', '}', a:func, a:code)
2395 call RunTest_mapping_mods('<' .. a:mods .. '-~>', '~', a:func, a:code)
2396 endif
2397
2398 bwipe!
2399 set timeoutlen&
2400endfunc
2401
2402func Test_mapping_works_with_shift()
2403 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'S', 2)
2404 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'S', 2)
2405endfunc
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01002406
Bram Moolenaar459fd782019-10-13 16:43:39 +02002407func Test_mapping_works_with_ctrl()
2408 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C', 5)
2409 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C', 5)
Bram Moolenaar4e2114e2020-10-07 16:12:37 +02002410
2411 new
2412 set timeoutlen=10
2413
2414 " CTRL-@ actually produces the code for CTRL-2, which is converted
2415 call RunTest_mapping_mods('<C-@>', '2', function('GetEscCodeCSI27'), 5)
2416 call RunTest_mapping_mods('<C-@>', '2', function('GetEscCodeCSIu'), 5)
2417
2418 " CTRL-^ actually produces the code for CTRL-6, which is converted
2419 call RunTest_mapping_mods('<C-^>', '6', function('GetEscCodeCSI27'), 5)
2420 call RunTest_mapping_mods('<C-^>', '6', function('GetEscCodeCSIu'), 5)
2421
2422 " CTRL-_ actually produces the code for CTRL--, which is converted
2423 call RunTest_mapping_mods('<C-_>', '-', function('GetEscCodeCSI27'), 5)
2424 call RunTest_mapping_mods('<C-_>', '-', function('GetEscCodeCSIu'), 5)
2425
2426 bwipe!
2427 set timeoutlen&
Bram Moolenaar459fd782019-10-13 16:43:39 +02002428endfunc
2429
2430func Test_mapping_works_with_shift_ctrl()
2431 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-S', 6)
2432 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-S', 6)
Bram Moolenaar9a033d72020-10-07 17:29:48 +02002433
2434 new
2435 set timeoutlen=10
2436
2437 " Ctrl-Shift-[ actually produces CTRL-Shift-{ which is mapped as <C-{>
2438 call RunTest_mapping_mods('<C-{>', '{', function('GetEscCodeCSI27'), 6)
2439 call RunTest_mapping_mods('<C-{>', '{', function('GetEscCodeCSIu'), 6)
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 bwipe!
2450 set timeoutlen&
Bram Moolenaar459fd782019-10-13 16:43:39 +02002451endfunc
2452
2453" Below we also test the "u" code with Alt, This works, but libvterm would not
2454" send the Alt key like this but by prefixing an Esc.
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01002455
Bram Moolenaar459fd782019-10-13 16:43:39 +02002456func Test_mapping_works_with_alt()
2457 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'A', 3)
2458 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'A', 3)
2459endfunc
2460
2461func Test_mapping_works_with_shift_alt()
2462 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'S-A', 4)
2463 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'S-A', 4)
2464endfunc
2465
Bram Moolenaardaff0fb2020-09-27 13:16:46 +02002466func Test_mapping_works_with_alt_and_shift()
2467 new
2468 set timeoutlen=10
2469
2470 " mapping <A-?> works even though the code is A-S-?
2471 for c in ['!', '$', '+', ':', '?', '^', '~']
2472 call RunTest_mapping_mods('<A-' .. c .. '>', c, function('GetEscCodeCSI27'), 4)
2473 call RunTest_mapping_mods('<A-' .. c .. '>', c, function('GetEscCodeCSIu'), 4)
2474 endfor
2475
2476 bwipe!
2477 set timeoutlen&
2478endfunc
2479
Bram Moolenaar459fd782019-10-13 16:43:39 +02002480func Test_mapping_works_with_ctrl_alt()
2481 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-A', 7)
2482 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-A', 7)
2483endfunc
2484
2485func Test_mapping_works_with_shift_ctrl_alt()
2486 call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-S-A', 8)
2487 call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-S-A', 8)
2488endfunc
Bram Moolenaarfc4ea2a2019-11-26 19:33:22 +01002489
Bram Moolenaar064fd672022-11-29 18:32:32 +00002490func Test_mapping_works_with_unknown_modifiers()
2491 new
2492 set timeoutlen=10
2493
2494 for Func in [function('GetEscCodeCSI27'), function('GetEscCodeCSIu')]
2495 call RunTest_mapping_mods('<C-z>', 'z', Func, 5)
2496 " Add 16, 32, 64 or 128 for modifiers we currently don't support.
2497 call RunTest_mapping_mods('<C-z>', 'z', Func, 5 + 16)
2498 call RunTest_mapping_mods('<C-z>', 'z', Func, 5 + 32)
2499 call RunTest_mapping_mods('<C-z>', 'z', Func, 5 + 64)
2500 call RunTest_mapping_mods('<C-z>', 'z', Func, 5 + 128)
2501
2502 call RunTest_mapping_mods('<S-X>', 'X', Func, 2)
2503 " Add 16, 32, 64 or 128 for modifiers we currently don't support.
2504 call RunTest_mapping_mods('<S-X>', 'X', Func, 2 + 16)
2505 call RunTest_mapping_mods('<S-X>', 'X', Func, 2 + 32)
2506 call RunTest_mapping_mods('<S-X>', 'X', Func, 2 + 64)
2507 call RunTest_mapping_mods('<S-X>', 'X', Func, 2 + 128)
2508 endfor
2509
2510 bwipe!
2511 set timeoutlen&
2512endfunc
2513
Bram Moolenaar1a173402022-12-02 12:28:47 +00002514func RunTest_mapping_funckey(map, func, key, code)
2515 call setline(1, '')
2516 exe 'inoremap ' .. a:map .. ' xyz'
2517 call feedkeys('a' .. a:func(a:key, a:code) .. "\<Esc>", 'Lx!')
2518 call assert_equal("xyz", getline(1), 'mapping ' .. a:map)
2519 exe 'iunmap ' .. a:map
2520endfunc
2521
2522func Test_mapping_kitty_function_keys()
2523 new
2524 set timeoutlen=10
2525
2526 " Function keys made with CSI and ending in [ABCDEFHPQRS].
2527 " 'E' is keypad BEGIN, not supported
2528 let maps = [
2529 \ ['<Up>', 'A', 0],
2530 \ ['<S-Up>', 'A', 2],
2531 \ ['<C-Up>', 'A', 5],
2532 \ ['<C-S-Up>', 'A', 6],
2533 \
2534 \ ['<Down>', 'B', 0],
2535 \ ['<S-Down>', 'B', 2],
2536 \ ['<C-Down>', 'B', 5],
2537 \ ['<C-S-Down>', 'B', 6],
2538 \
2539 \ ['<Right>', 'C', 0],
2540 \ ['<S-Right>', 'C', 2],
2541 \ ['<C-Right>', 'C', 5],
2542 \ ['<C-S-Right>', 'C', 6],
2543 \
2544 \ ['<Left>', 'D', 0],
2545 \ ['<S-Left>', 'D', 2],
2546 \ ['<C-Left>', 'D', 5],
2547 \ ['<C-S-Left>', 'D', 6],
2548 \
2549 \ ['<End>', 'F', 0],
2550 \ ['<S-End>', 'F', 2],
2551 \ ['<C-End>', 'F', 5],
2552 \ ['<C-S-End>', 'F', 6],
2553 \
2554 \ ['<Home>', 'H', 0],
2555 \ ['<S-Home>', 'H', 2],
2556 \ ['<C-Home>', 'H', 5],
2557 \ ['<C-S-Home>', 'H', 6],
2558 \
2559 \ ['<F1>', 'P', 0],
2560 \ ['<S-F1>', 'P', 2],
2561 \ ['<C-F1>', 'P', 5],
2562 \ ['<C-S-F1>', 'P', 6],
2563 \
2564 \ ['<F2>', 'Q', 0],
2565 \ ['<S-F2>', 'Q', 2],
2566 \ ['<C-F2>', 'Q', 5],
2567 \ ['<C-S-F2>', 'Q', 6],
2568 \
2569 \ ['<F3>', 'R', 0],
2570 \ ['<S-F3>', 'R', 2],
2571 \ ['<C-F3>', 'R', 5],
2572 \ ['<C-S-F3>', 'R', 6],
2573 \
2574 \ ['<F4>', 'S', 0],
2575 \ ['<S-F4>', 'S', 2],
2576 \ ['<C-F4>', 'S', 5],
2577 \ ['<C-S-F4>', 'S', 6],
2578 \ ]
2579
2580 for map in maps
2581 call RunTest_mapping_funckey(map[0], function('GetEscCodeFunckey'), map[1], map[2])
2582 endfor
2583
2584 bwipe!
2585 set timeoutlen&
2586endfunc
2587
Bram Moolenaarfc4ea2a2019-11-26 19:33:22 +01002588func Test_insert_literal()
2589 set timeoutlen=10
Bram Moolenaarc255b782022-11-26 19:16:48 +00002590
2591 call WaitForResponses()
2592
Bram Moolenaarfc4ea2a2019-11-26 19:33:22 +01002593 new
2594 " CTRL-V CTRL-X inserts a ^X
2595 call feedkeys('a' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu('X', '5') .. "\<Esc>", 'Lx!')
2596 call assert_equal("\<C-X>", getline(1))
2597
2598 call setline(1, '')
2599 call feedkeys('a' .. GetEscCodeCSI27('V', '5') .. GetEscCodeCSI27('X', '5') .. "\<Esc>", 'Lx!')
2600 call assert_equal("\<C-X>", getline(1))
2601
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01002602 " CTRL-SHIFT-V CTRL-X inserts escape sequence
Bram Moolenaarfc4ea2a2019-11-26 19:33:22 +01002603 call setline(1, '')
2604 call feedkeys('a' .. GetEscCodeCSIu('V', '6') .. GetEscCodeCSIu('X', '5') .. "\<Esc>", 'Lx!')
2605 call assert_equal("\<Esc>[88;5u", getline(1))
2606
2607 call setline(1, '')
2608 call feedkeys('a' .. GetEscCodeCSI27('V', '6') .. GetEscCodeCSI27('X', '5') .. "\<Esc>", 'Lx!')
2609 call assert_equal("\<Esc>[27;5;88~", getline(1))
2610
2611 bwipe!
2612 set timeoutlen&
2613endfunc
2614
2615func Test_cmdline_literal()
2616 set timeoutlen=10
2617
2618 " CTRL-V CTRL-Y inserts a ^Y
2619 call feedkeys(':' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!')
2620 call assert_equal("\"\<C-Y>", @:)
2621
2622 call feedkeys(':' .. GetEscCodeCSI27('V', '5') .. GetEscCodeCSI27('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!')
2623 call assert_equal("\"\<C-Y>", @:)
2624
Bram Moolenaarf19f8d12019-12-18 19:36:23 +01002625 " CTRL-SHIFT-V CTRL-Y inserts escape sequence
Bram Moolenaarfc4ea2a2019-11-26 19:33:22 +01002626 call feedkeys(':' .. GetEscCodeCSIu('V', '6') .. GetEscCodeCSIu('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!')
2627 call assert_equal("\"\<Esc>[89;5u", @:)
2628
2629 call setline(1, '')
2630 call feedkeys(':' .. GetEscCodeCSI27('V', '6') .. GetEscCodeCSI27('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!')
2631 call assert_equal("\"\<Esc>[27;5;89~", @:)
2632
2633 set timeoutlen&
2634endfunc
Bram Moolenaar0eabd4d2020-03-15 16:13:53 +01002635
Bram Moolenaarbbf84e22022-03-12 13:48:39 +00002636func Test_mapping_esc()
2637 set timeoutlen=10
2638
2639 new
2640 nnoremap <Up> iHello<Esc>
2641 nnoremap <Esc> <Nop>
2642
2643 call feedkeys(substitute(&t_ku, '\*', '', 'g'), 'Lx!')
2644 call assert_equal("Hello", getline(1))
2645
2646 bwipe!
2647 nunmap <Up>
2648 nunmap <Esc>
2649 set timeoutlen&
2650endfunc
2651
Bram Moolenaar0ff5ded2020-05-07 18:43:44 +02002652" Test for translation of special key codes (<xF1>, <xF2>, etc.)
Bram Moolenaar92e5df82021-01-30 15:39:47 +01002653func Test_Keycode_Translation()
Bram Moolenaar0ff5ded2020-05-07 18:43:44 +02002654 let keycodes = [
2655 \ ["<xUp>", "<Up>"],
2656 \ ["<xDown>", "<Down>"],
2657 \ ["<xLeft>", "<Left>"],
2658 \ ["<xRight>", "<Right>"],
2659 \ ["<xHome>", "<Home>"],
2660 \ ["<xEnd>", "<End>"],
2661 \ ["<zHome>", "<Home>"],
2662 \ ["<zEnd>", "<End>"],
2663 \ ["<xF1>", "<F1>"],
2664 \ ["<xF2>", "<F2>"],
2665 \ ["<xF3>", "<F3>"],
2666 \ ["<xF4>", "<F4>"],
2667 \ ["<S-xF1>", "<S-F1>"],
2668 \ ["<S-xF2>", "<S-F2>"],
2669 \ ["<S-xF3>", "<S-F3>"],
2670 \ ["<S-xF4>", "<S-F4>"]]
2671 for [k1, k2] in keycodes
2672 exe "nnoremap " .. k1 .. " 2wx"
2673 call assert_true(maparg(k1, 'n', 0, 1).lhs == k2)
2674 exe "nunmap " .. k1
2675 endfor
2676endfunc
2677
Bram Moolenaar1f448d92021-03-22 19:37:06 +01002678" Test for terminal keycodes that doesn't have termcap entries
2679func Test_special_term_keycodes()
2680 new
2681 " Test for <xHome>, <S-xHome> and <C-xHome>
2682 " send <K_SPECIAL> <KS_EXTRA> keycode
2683 call feedkeys("i\<C-K>\x80\xfd\x3f\n", 'xt')
2684 " send <K_SPECIAL> <KS_MODIFIER> bitmap <K_SPECIAL> <KS_EXTRA> keycode
2685 call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x3f\n", 'xt')
2686 call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x3f\n", 'xt')
2687 " Test for <xEnd>, <S-xEnd> and <C-xEnd>
2688 call feedkeys("i\<C-K>\x80\xfd\x3d\n", 'xt')
2689 call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x3d\n", 'xt')
2690 call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x3d\n", 'xt')
2691 " Test for <zHome>, <S-zHome> and <C-zHome>
2692 call feedkeys("i\<C-K>\x80\xfd\x40\n", 'xt')
2693 call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x40\n", 'xt')
2694 call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x40\n", 'xt')
2695 " Test for <zEnd>, <S-zEnd> and <C-zEnd>
2696 call feedkeys("i\<C-K>\x80\xfd\x3e\n", 'xt')
2697 call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x3e\n", 'xt')
2698 call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x3e\n", 'xt')
2699 " Test for <xUp>, <xDown>, <xLeft> and <xRight>
2700 call feedkeys("i\<C-K>\x80\xfd\x41\n", 'xt')
2701 call feedkeys("i\<C-K>\x80\xfd\x42\n", 'xt')
2702 call feedkeys("i\<C-K>\x80\xfd\x43\n", 'xt')
2703 call feedkeys("i\<C-K>\x80\xfd\x44\n", 'xt')
2704 call assert_equal(['<Home>', '<S-Home>', '<C-Home>',
2705 \ '<End>', '<S-End>', '<C-End>',
2706 \ '<Home>', '<S-Home>', '<C-Home>',
2707 \ '<End>', '<S-End>', '<C-End>',
2708 \ '<Up>', '<Down>', '<Left>', '<Right>', ''], getline(1, '$'))
2709 bw!
2710endfunc
2711
Bram Moolenaar1573e732022-11-16 20:33:21 +00002712func Test_home_key_works()
2713 " The '@' character in K_HOME must only match "1" when followed by ";",
2714 " otherwise this code for Home is not recognized: "<Esc>[1~"
Bram Moolenaar1d8765d2022-11-17 16:43:35 +00002715 " Set termcap values like "xterm" uses them. Except using F2 for xHome,
2716 " because that termcap entry can't be set here.
2717 let save_K1 = exists('&t_K1') ? &t_K1 : ''
2718 let save_kh = exists('&t_kh') ? &t_kh : ''
2719 let save_k2 = exists('&t_k2') ? &t_k2 : ''
2720 let save_k3 = exists('&t_k3') ? &t_k3 : ''
2721 let save_end = exists('&t_@7') ? &t_@7 : ''
2722
Bram Moolenaar1573e732022-11-16 20:33:21 +00002723 let &t_K1 = "\<Esc>[1;*~" " <kHome>
2724 let &t_kh = "\<Esc>[@;*H" " <Home>
Bram Moolenaar1d8765d2022-11-17 16:43:35 +00002725 let &t_k2 = "\<Esc>O*H" " use <F2> for <xHome>
Bram Moolenaar1573e732022-11-16 20:33:21 +00002726 let &t_k3 = "\<Esc>[7;*~" " use <F3> for <zHome>
2727 let &t_@7 = "\<Esc>[@;*F" " <End>
2728
2729 new
2730 call feedkeys("i\<C-K>\<Esc>OH\n\<Esc>", 'tx')
2731 call feedkeys("i\<C-K>\<Esc>[1~\n\<Esc>", 'tx')
2732 call assert_equal([
Bram Moolenaar1d8765d2022-11-17 16:43:35 +00002733 \ '<F2>',
Bram Moolenaar1573e732022-11-16 20:33:21 +00002734 \ '<kHome>',
2735 \ ''], getline(1, '$'))
2736
2737 bwipe!
Bram Moolenaar1573e732022-11-16 20:33:21 +00002738 let &t_K1 = save_K1
Bram Moolenaar1d8765d2022-11-17 16:43:35 +00002739 let &t_kh = save_kh
Bram Moolenaar1573e732022-11-16 20:33:21 +00002740 let &t_k2 = save_k2
2741 let &t_k3 = save_k3
2742 let &t_@7 = save_end
2743endfunc
2744
Bram Moolenaar0f5575d2021-07-30 21:18:03 +02002745func Test_terminal_builtin_without_gui()
2746 CheckNotMSWindows
2747
2748 " builtin_gui should not be output by :set term=xxx
Yee Cheng Chine67eff22025-02-14 18:01:25 +01002749 let output = systemlist("TERM=dumb " .. v:progpath .. " --not-a-term --clean -c ':set t_ti= t_te=' -c 'set term=xxx' -c ':q!'")
Bram Moolenaar0f5575d2021-07-30 21:18:03 +02002750 redraw!
2751 call map(output, {_, val -> trim(val)})
2752 call assert_equal(-1, index(output, 'builtin_gui'))
2753 call assert_notequal(-1, index(output, 'builtin_dumb'))
2754endfunc
2755
Christian Brabandt279dd702025-01-26 10:49:59 +01002756func Test_xterm_direct_enables_termguicolors()
Christian Brabandtd7f58542025-01-31 16:13:14 +01002757 call s:TermGuiColorsTest()
Christian Brabandt279dd702025-01-26 10:49:59 +01002758 " TERM=xterm-direct enables termguicolors
Christian Brabandt279dd702025-01-26 10:49:59 +01002759 let colors = systemlist('tput -Txterm-direct colors')[0]
2760 defer delete('XTerm-direct.txt')
2761
2762 let buf = RunVimInTerminal('--cmd ":set noswapfile" --clean XTerm-direct.txt',
2763 \ {'rows': 10, 'env': {'TERM': 'xterm-direct'}})
2764 call TermWait(buf)
2765 call term_sendkeys(buf, ":$put ='TERM: ' .. &term\<cr>")
2766 " doesn't work. Vim cannot query xterm colors in the embedded terminal?
2767 "call term_sendkeys(buf, ":$put ='Colors: ' .. &t_Co\<cr>")
2768 call term_sendkeys(buf, ":$put ='Termguicolors: ' .. &tgc\<cr>")
2769 call term_sendkeys(buf, ":wq\<cr>")
2770 call TermWait(buf)
2771
2772 let result=readfile('XTerm-direct.txt')
2773 " call assert_equal(['', 'TERM: xterm-direct', 'Colors: ' .. colors, 'Termguicolors: 1'], result)
Christian Brabandtb34a6882025-02-17 20:09:11 +01002774 call assert_equal(['', 'TERM: xterm-direct', 'Termguicolors: 0'], result)
Christian Brabandt279dd702025-01-26 10:49:59 +01002775 " cleanup
2776 bw!
Christian Brabandtd7f58542025-01-31 16:13:14 +01002777 close
2778endfunc
2779
2780func Test_xterm_direct_no_termguicolors()
2781 " unfortunately doesn't work with libvterm
2782 call s:TermGuiColorsTest()
2783
2784 let lines =<< trim END
2785 set notermguicolors noswapfile
2786 set t_Co=16777216
2787 END
2788 call writefile(lines, 'XtermDirect', 'D')
2789 defer delete('XTerm-direct2.txt')
2790
2791 let buf = RunVimInTerminal('-S XtermDirect --clean XTerm-direct2.txt',
2792 \ {'rows': 10, 'env': {'TERM': 'xterm-direct'}})
2793 call TermWait(buf)
2794 call term_sendkeys(buf, ":$put ='TERM: ' .. &term\<cr>")
2795 call term_sendkeys(buf, ":$put ='Termguicolors: ' .. &tgc\<cr>")
2796 call term_sendkeys(buf, ":wq\<cr>")
2797 call TermWait(buf)
2798
2799 let result=readfile('XTerm-direct2.txt')
2800 call assert_equal(['', 'TERM: xterm-direct', 'Termguicolors: 0'], result)
2801 " cleanup
2802 bw!
2803 close
Christian Brabandt279dd702025-01-26 10:49:59 +01002804endfunc
2805
Bram Moolenaar0eabd4d2020-03-15 16:13:53 +01002806" vim: shiftwidth=2 sts=2 expandtab