1" Tests for decoding escape sequences sent by the terminal.
2
3" This only works for Unix in a terminal
4source check.vim
5CheckNotGui
6CheckUnix
7
8source shared.vim
9source mouse.vim
10
11func Test_term_mouse_left_click()
12  new
13  let save_mouse = &mouse
14  let save_term = &term
15  let save_ttymouse = &ttymouse
16  call test_override('no_query_mouse', 1)
17  set mouse=a term=xterm
18  call setline(1, ['line 1', 'line 2', 'line 3 is a bit longer'])
19
20  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm
21    let msg = 'ttymouse=' .. ttymouse_val
22    exe 'set ttymouse=' .. ttymouse_val
23    go
24    call assert_equal([0, 1, 1, 0], getpos('.'), msg)
25    let row = 2
26    let col = 6
27    call MouseLeftClick(row, col)
28    call MouseLeftRelease(row, col)
29    call assert_equal([0, 2, 6, 0], getpos('.'), msg)
30  endfor
31
32  let &mouse = save_mouse
33  let &term = save_term
34  let &ttymouse = save_ttymouse
35  call test_override('no_query_mouse', 0)
36  bwipe!
37endfunc
38
39func Test_xterm_mouse_right_click_extends_visual()
40  if has('mac')
41    throw "Skipped: test right click in visual mode does not work on macOs (why?)"
42  endif
43  let save_mouse = &mouse
44  let save_term = &term
45  let save_ttymouse = &ttymouse
46  call test_override('no_query_mouse', 1)
47  set mouse=a term=xterm
48
49  for visual_mode in ["v", "V", "\<C-V>"]
50    for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
51      let msg = 'visual=' .. visual_mode .. ' ttymouse=' .. ttymouse_val
52      exe 'set ttymouse=' .. ttymouse_val
53
54      call setline(1, repeat([repeat('-', 7)], 7))
55      call MouseLeftClick(4, 4)
56      call MouseLeftRelease(4, 4)
57      exe  "norm! " .. visual_mode
58
59      " Right click extends top left of visual area.
60      call MouseRightClick(2, 2)
61      call MouseRightRelease(2, 2)
62
63      " Right click extends bottom right of visual area.
64      call MouseRightClick(6, 6)
65      call MouseRightRelease(6, 6)
66      norm! r1gv
67
68      " Right click shrinks top left of visual area.
69      call MouseRightClick(3, 3)
70      call MouseRightRelease(3, 3)
71
72      " Right click shrinks bottom right of visual area.
73      call MouseRightClick(5, 5)
74      call MouseRightRelease(5, 5)
75      norm! r2
76
77      if visual_mode ==# 'v'
78        call assert_equal(['-------',
79              \            '-111111',
80              \            '1122222',
81              \            '2222222',
82              \            '2222211',
83              \            '111111-',
84              \            '-------'], getline(1, '$'), msg)
85      elseif visual_mode ==# 'V'
86        call assert_equal(['-------',
87              \            '1111111',
88              \            '2222222',
89              \            '2222222',
90              \            '2222222',
91              \            '1111111',
92              \            '-------'], getline(1, '$'), msg)
93      else
94        call assert_equal(['-------',
95              \            '-11111-',
96              \            '-12221-',
97              \            '-12221-',
98              \            '-12221-',
99              \            '-11111-',
100              \            '-------'], getline(1, '$'), msg)
101      endif
102    endfor
103  endfor
104
105  let &mouse = save_mouse
106  let &term = save_term
107  let &ttymouse = save_ttymouse
108  call test_override('no_query_mouse', 0)
109  bwipe!
110endfunc
111
112" Test that <C-LeftMouse> jumps to help tag and <C-RightMouse> jumps back.
113" Also test for g<LeftMouse> and g<RightMouse>.
114func Test_xterm_mouse_tagjump()
115  let save_mouse = &mouse
116  let save_term = &term
117  let save_ttymouse = &ttymouse
118  set mouse=a term=xterm
119
120  for ttymouse_val in g:Ttymouse_values
121    let msg = 'ttymouse=' .. ttymouse_val
122    exe 'set ttymouse=' .. ttymouse_val
123    help
124    /usr_02.txt
125    norm! zt
126
127    " CTRL-left click to jump to a tag
128    let row = 1
129    let col = 1
130    call MouseCtrlLeftClick(row, col)
131    call MouseLeftRelease(row, col)
132    call assert_match('usr_02.txt$', bufname('%'), msg)
133    call assert_equal('*usr_02.txt*', expand('<cWORD>'), msg)
134
135    " CTRL-right click to pop a tag
136    call MouseCtrlRightClick(row, col)
137    call MouseRightRelease(row, col)
138    call assert_match('help.txt$', bufname('%'), msg)
139    call assert_equal('|usr_02.txt|', expand('<cWORD>'), msg)
140
141    " Jump to a tag
142    exe "normal \<C-]>"
143    call assert_match('usr_02.txt$', bufname('%'), msg)
144    call assert_equal('*usr_02.txt*', expand('<cWORD>'), msg)
145
146    " Use CTRL-right click in insert mode to pop the tag
147    new
148    let str = 'iHello' .. MouseCtrlRightClickCode(row, col)
149          \ .. MouseRightReleaseCode(row, col) .. "\<C-C>"
150    call assert_fails('call feedkeys(str, "Lx!")', 'E37:')
151    close!
152
153    " CTRL-right click with a count
154    let str = "4" .. MouseCtrlRightClickCode(row, col)
155          \ .. MouseRightReleaseCode(row, col)
156    call assert_fails('call feedkeys(str, "Lx!")', 'E555:')
157    call assert_match('help.txt$', bufname('%'), msg)
158    call assert_equal(1, line('.'), msg)
159
160    " g<LeftMouse> to jump to a tag
161    /usr_02.txt
162    norm! zt
163    call test_setmouse(row, col)
164    exe "normal g\<LeftMouse>"
165    call assert_match('usr_02.txt$', bufname('%'), msg)
166    call assert_equal('*usr_02.txt*', expand('<cWORD>'), msg)
167
168    " g<RightMouse> to pop to a tag
169    call test_setmouse(row, col)
170    exe "normal g\<RightMouse>"
171    call assert_match('help.txt$', bufname('%'), msg)
172    call assert_equal('|usr_02.txt|', expand('<cWORD>'), msg)
173
174    %bw!
175  endfor
176
177  let &mouse = save_mouse
178  let &term = save_term
179  let &ttymouse = save_ttymouse
180endfunc
181
182func Test_term_mouse_middle_click()
183  CheckFeature clipboard_working
184
185  new
186  let save_mouse = &mouse
187  let save_term = &term
188  let save_ttymouse = &ttymouse
189  call test_override('no_query_mouse', 1)
190  let save_quotestar = @*
191  let save_quoteplus = @+
192  set mouse=a term=xterm
193
194  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
195    let msg = 'ttymouse=' .. ttymouse_val
196    exe 'set ttymouse=' .. ttymouse_val
197    call setline(1, ['123456789', '123456789'])
198    let @* = 'abc'
199
200    " Middle-click in the middle of the line pastes text where clicked.
201    let row = 1
202    let col = 6
203    call MouseMiddleClick(row, col)
204    call MouseMiddleRelease(row, col)
205    call assert_equal(['12345abc6789', '123456789'], getline(1, '$'), msg)
206
207    " Middle-click beyond end of the line pastes text at the end of the line.
208    let col = 20
209    call MouseMiddleClick(row, col)
210    call MouseMiddleRelease(row, col)
211    call assert_equal(['12345abc6789abc', '123456789'], getline(1, '$'), msg)
212
213    " Middle-click beyond the last line pastes in the last line.
214    let row = 5
215    let col = 3
216    call MouseMiddleClick(row, col)
217    call MouseMiddleRelease(row, col)
218    call assert_equal(['12345abc6789abc', '12abc3456789'], getline(1, '$'), msg)
219
220    " Middle mouse click in operator pending mode beeps
221    call assert_beeps('exe "normal c\<MiddleMouse>"')
222
223    " Clicking middle mouse in visual mode, yanks the selection and pastes the
224    " clipboard contents
225    let save_clipboard = &clipboard
226    set clipboard=
227    let @" = ''
228    call cursor(1, 1)
229    call feedkeys("v3l" ..
230          \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7), 'Lx!')
231    call assert_equal(['12345abc6789abc', '12abc3abc456789'],
232          \ getline(1, '$'), msg)
233    call assert_equal('1234', @")
234    let &clipboard = save_clipboard
235
236    " Clicking middle mouse in select mode, replaces the selected text with
237    " the clipboard contents
238    let @+ = 'xyz'
239    call cursor(1, 3)
240    exe "normal gh\<Right>\<Right>\<MiddleMouse>"
241    call assert_equal(['12xyzabc6789abc', '12abc3abc456789'],
242          \ getline(1, '$'), msg)
243  endfor
244
245  let &mouse = save_mouse
246  let &term = save_term
247  let &ttymouse = save_ttymouse
248  call test_override('no_query_mouse', 0)
249  let @* = save_quotestar
250  let @+ = save_quotestar
251  bwipe!
252endfunc
253
254" If clipboard is not working, then clicking the middle mouse button in visual
255" mode, will copy and paste the selected text.
256func Test_term_mouse_middle_click_no_clipboard()
257  if has('clipboard_working')
258    throw 'Skipped: clipboard support works'
259    return
260  endif
261  new
262  let save_mouse = &mouse
263  let save_term = &term
264  let save_ttymouse = &ttymouse
265  call test_override('no_query_mouse', 1)
266  set mouse=a term=xterm
267
268  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
269    let msg = 'ttymouse=' .. ttymouse_val
270    exe 'set ttymouse=' .. ttymouse_val
271    call setline(1, ['123456789', '123456789'])
272
273    " Clicking middle mouse in visual mode, yanks the selection and pastes it
274    call cursor(1, 1)
275    call feedkeys("v3l" ..
276          \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7), 'Lx!')
277    call assert_equal(['123456789', '1234561234789'],
278          \ getline(1, '$'), msg)
279  endfor
280
281  call test_override('no_query_mouse', 0)
282  let &ttymouse = save_ttymouse
283  let &term = save_term
284  let &mouse = save_mouse
285  close!
286endfunc
287
288func Test_term_mouse_middle_click_insert_mode()
289  CheckFeature clipboard_working
290
291  new
292  let save_mouse = &mouse
293  let save_term = &term
294  let save_ttymouse = &ttymouse
295  call test_override('no_query_mouse', 1)
296  set mouse=a term=xterm
297
298  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
299    let msg = 'ttymouse=' .. ttymouse_val
300    exe 'set ttymouse=' .. ttymouse_val
301    call setline(1, ['123456789', '123456789'])
302    let @* = 'abc'
303
304    " Middle-click in inesrt mode doesn't move the cursor but inserts the
305    " contents of aregister
306    call cursor(1, 4)
307    call feedkeys('i' ..
308          \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7) ..
309          \ "\<C-C>", 'Lx!')
310    call assert_equal(['123abc456789', '123456789'],
311          \ getline(1, '$'), msg)
312    call assert_equal([1, 6], [line('.'), col('.')])
313
314    " Middle-click in replace mode
315    call cursor(1, 1)
316    call feedkeys('$R' ..
317          \ MouseMiddleClickCode(2, 7) .. MouseMiddleReleaseCode(2, 7) ..
318          \ "\<C-C>", 'Lx!')
319    call assert_equal(['123abc45678abc', '123456789'],
320          \ getline(1, '$'), msg)
321    call assert_equal([1, 14], [line('.'), col('.')])
322  endfor
323
324  let &mouse = save_mouse
325  let &term = save_term
326  let &ttymouse = save_ttymouse
327  call test_override('no_query_mouse', 0)
328  close!
329endfunc
330
331" Test for switching window using mouse in insert mode
332func Test_term_mouse_switch_win_insert_mode()
333  5new
334  let save_mouse = &mouse
335  let save_term = &term
336  let save_ttymouse = &ttymouse
337  call test_override('no_query_mouse', 1)
338  set mouse=a term=xterm ttymouse=xterm2
339
340  call feedkeys('ivim' ..
341        \ MouseLeftClickCode(8, 6) .. MouseLeftReleaseCode(8, 6) ..
342        \ "\<C-C>", 'Lx!')
343  call assert_equal(2, winnr())
344  wincmd w
345  call assert_equal('n', mode())
346  call assert_equal(['vim'], getline(1, '$'))
347
348  let &mouse = save_mouse
349  let &term = save_term
350  let &ttymouse = save_ttymouse
351  call test_override('no_query_mouse', 0)
352  close!
353endfunc
354
355" Test for using the mouse to increaes the height of the cmdline window
356func Test_mouse_cmdwin_resize()
357  let save_mouse = &mouse
358  let save_term = &term
359  let save_ttymouse = &ttymouse
360  call test_override('no_query_mouse', 1)
361  set mouse=a term=xterm ttymouse=xterm2
362  5new
363  redraw!
364
365  let h = 0
366  let row = &lines - &cmdwinheight - 2
367  call feedkeys("q:" ..
368        \ MouseLeftClickCode(row, 1) ..
369        \ MouseLeftDragCode(row - 1, 1) ..
370        \ MouseLeftReleaseCode(row - 2, 1) ..
371        \ "alet h = \<C-R>=winheight(0)\<CR>\<CR>", 'Lx!')
372  call assert_equal(&cmdwinheight + 2, h)
373
374  let &mouse = save_mouse
375  let &term = save_term
376  let &ttymouse = save_ttymouse
377  call test_override('no_query_mouse', 0)
378  close!
379endfunc
380
381" TODO: for unclear reasons this test fails if it comes after
382" Test_xterm_mouse_ctrl_click()
383func Test_1xterm_mouse_wheel()
384  new
385  let save_mouse = &mouse
386  let save_term = &term
387  let save_wrap = &wrap
388  let save_ttymouse = &ttymouse
389  set mouse=a term=xterm nowrap
390  call setline(1, range(100000000000000, 100000000000100))
391
392  for ttymouse_val in g:Ttymouse_values
393    let msg = 'ttymouse=' .. ttymouse_val
394    exe 'set ttymouse=' .. ttymouse_val
395    go
396    call assert_equal(1, line('w0'), msg)
397    call assert_equal([0, 1, 1, 0], getpos('.'), msg)
398
399    call MouseWheelDown(1, 1)
400    call assert_equal(4, line('w0'), msg)
401    call assert_equal([0, 4, 1, 0], getpos('.'), msg)
402
403    call MouseWheelDown(1, 1)
404    call assert_equal(7, line('w0'), msg)
405    call assert_equal([0, 7, 1, 0], getpos('.'), msg)
406
407    call MouseWheelUp(1, 1)
408    call assert_equal(4, line('w0'), msg)
409    call assert_equal([0, 7, 1, 0], getpos('.'), msg)
410
411    call MouseWheelUp(1, 1)
412    call assert_equal(1, line('w0'), msg)
413    call assert_equal([0, 7, 1, 0], getpos('.'), msg)
414
415    if has('gui')
416      " Horizontal wheel scrolling currently only works when vim is
417      " compiled with gui enabled.
418      call MouseWheelRight(1, 1)
419      call assert_equal(7, 1 + virtcol(".") - wincol(), msg)
420      call assert_equal([0, 7, 7, 0], getpos('.'), msg)
421
422      call MouseWheelRight(1, 1)
423      call assert_equal(13, 1 + virtcol(".") - wincol(), msg)
424      call assert_equal([0, 7, 13, 0], getpos('.'), msg)
425
426      call MouseWheelLeft(1, 1)
427      call assert_equal(7, 1 + virtcol(".") - wincol(), msg)
428      call assert_equal([0, 7, 13, 0], getpos('.'), msg)
429
430      call MouseWheelLeft(1, 1)
431      call assert_equal(1, 1 + virtcol(".") - wincol(), msg)
432      call assert_equal([0, 7, 13, 0], getpos('.'), msg)
433    endif
434  endfor
435
436  let &mouse = save_mouse
437  let &term = save_term
438  let &wrap = save_wrap
439  let &ttymouse = save_ttymouse
440  bwipe!
441endfunc
442
443" Test that dragging beyond the window (at the bottom and at the top)
444" scrolls window content by the number of lines beyond the window.
445func Test_term_mouse_drag_beyond_window()
446  let save_mouse = &mouse
447  let save_term = &term
448  let save_ttymouse = &ttymouse
449  call test_override('no_query_mouse', 1)
450  set mouse=a term=xterm
451  let col = 1
452  call setline(1, range(1, 100))
453
454  " Split into 3 windows, and go into the middle window
455  " so we test dragging mouse below and above the window.
456  2split
457  wincmd j
458  2split
459
460  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
461    let msg = 'ttymouse=' .. ttymouse_val
462    exe 'set ttymouse=' .. ttymouse_val
463
464    " Line #10 at the top.
465    norm! 10zt
466    redraw
467    call assert_equal(10, winsaveview().topline, msg)
468    call assert_equal(2, winheight(0), msg)
469
470    let row = 4
471    call MouseLeftClick(row, col)
472    call assert_equal(10, winsaveview().topline, msg)
473
474    " Drag downwards. We're still in the window so topline should
475    " not change yet.
476    let row += 1
477    call MouseLeftDrag(row, col)
478    call assert_equal(10, winsaveview().topline, msg)
479
480    " We now leave the window at the bottom, so the window content should
481    " scroll by 1 line, then 2 lines (etc) as we drag further away.
482    let row += 1
483    call MouseLeftDrag(row, col)
484    call assert_equal(11, winsaveview().topline, msg)
485
486    let row += 1
487    call MouseLeftDrag(row, col)
488    call assert_equal(13, winsaveview().topline, msg)
489
490    " Now drag upwards.
491    let row -= 1
492    call MouseLeftDrag(row, col)
493    call assert_equal(14, winsaveview().topline, msg)
494
495    " We're now back in the window so the topline should not change.
496    let row -= 1
497    call MouseLeftDrag(row, col)
498    call assert_equal(14, winsaveview().topline, msg)
499
500    let row -= 1
501    call MouseLeftDrag(row, col)
502    call assert_equal(14, winsaveview().topline, msg)
503
504    " We now leave the window at the top so the window content should
505    " scroll by 1 line, then 2, then 3 (etc) in the opposite direction.
506    let row -= 1
507    call MouseLeftDrag(row, col)
508    call assert_equal(13, winsaveview().topline, msg)
509
510    let row -= 1
511    call MouseLeftDrag(row, col)
512    call assert_equal(11, winsaveview().topline, msg)
513
514    let row -= 1
515    call MouseLeftDrag(row, col)
516    call assert_equal(8, winsaveview().topline, msg)
517
518    call MouseLeftRelease(row, col)
519    call assert_equal(8, winsaveview().topline, msg)
520    call assert_equal(2, winheight(0), msg)
521  endfor
522
523  let &mouse = save_mouse
524  let &term = save_term
525  let &ttymouse = save_ttymouse
526  call test_override('no_query_mouse', 0)
527  bwipe!
528endfunc
529
530func Test_term_mouse_drag_window_separator()
531  let save_mouse = &mouse
532  let save_term = &term
533  let save_ttymouse = &ttymouse
534  call test_override('no_query_mouse', 1)
535  set mouse=a term=xterm
536
537  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
538    let msg = 'ttymouse=' .. ttymouse_val
539    exe 'set ttymouse=' .. ttymouse_val
540
541    " Split horizontally and test dragging the horizontal window separator.
542    split
543    let rowseparator = winheight(0) + 1
544    let row = rowseparator
545    let col = 1
546
547    " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
548    if ttymouse_val !=# 'xterm2' || row <= 223
549      call MouseLeftClick(row, col)
550      let row -= 1
551      call MouseLeftDrag(row, col)
552      call assert_equal(rowseparator - 1, winheight(0) + 1, msg)
553      let row += 1
554      call MouseLeftDrag(row, col)
555      call assert_equal(rowseparator, winheight(0) + 1, msg)
556      call MouseLeftRelease(row, col)
557      call assert_equal(rowseparator, winheight(0) + 1, msg)
558    endif
559    bwipe!
560
561    " Split vertically and test dragging the vertical window separator.
562    vsplit
563    let colseparator = winwidth(0) + 1
564    let row = 1
565    let col = colseparator
566
567    " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
568    if ttymouse_val !=# 'xterm2' || col <= 223
569      call MouseLeftClick(row, col)
570      let col -= 1
571      call MouseLeftDrag(row, col)
572      call assert_equal(colseparator - 1, winwidth(0) + 1, msg)
573      let col += 1
574      call MouseLeftDrag(row, col)
575      call assert_equal(colseparator, winwidth(0) + 1, msg)
576      call MouseLeftRelease(row, col)
577      call assert_equal(colseparator, winwidth(0) + 1, msg)
578    endif
579    bwipe!
580  endfor
581
582  let &mouse = save_mouse
583  let &term = save_term
584  let &ttymouse = save_ttymouse
585  call test_override('no_query_mouse', 0)
586endfunc
587
588func Test_term_mouse_drag_statusline()
589  let save_mouse = &mouse
590  let save_term = &term
591  let save_ttymouse = &ttymouse
592  call test_override('no_query_mouse', 1)
593  let save_laststatus = &laststatus
594  set mouse=a term=xterm laststatus=2
595
596  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
597    let msg = 'ttymouse=' .. ttymouse_val
598    exe 'set ttymouse=' .. ttymouse_val
599
600    call assert_equal(1, &cmdheight, msg)
601    let rowstatusline = winheight(0) + 1
602    let row = rowstatusline
603    let col = 1
604
605    if ttymouse_val ==# 'xterm2' && row > 223
606      " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
607      continue
608    endif
609
610    call MouseLeftClick(row, col)
611    let row -= 1
612    call MouseLeftDrag(row, col)
613    call assert_equal(2, &cmdheight, msg)
614    call assert_equal(rowstatusline - 1, winheight(0) + 1, msg)
615    let row += 1
616    call MouseLeftDrag(row, col)
617    call assert_equal(1, &cmdheight, msg)
618    call assert_equal(rowstatusline, winheight(0) + 1, msg)
619    call MouseLeftRelease(row, col)
620    call assert_equal(1, &cmdheight, msg)
621    call assert_equal(rowstatusline, winheight(0) + 1, msg)
622  endfor
623
624  let &mouse = save_mouse
625  let &term = save_term
626  let &ttymouse = save_ttymouse
627  call test_override('no_query_mouse', 0)
628  let &laststatus = save_laststatus
629endfunc
630
631func Test_term_mouse_click_tab()
632  let save_mouse = &mouse
633  let save_term = &term
634  let save_ttymouse = &ttymouse
635  call test_override('no_query_mouse', 1)
636  set mouse=a term=xterm
637  let row = 1
638
639  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm
640    let msg = 'ttymouse=' .. ttymouse_val
641    exe 'set ttymouse=' .. ttymouse_val
642    e Xfoo
643    tabnew Xbar
644
645    let a = split(execute(':tabs'), "\n")
646    call assert_equal(['Tab page 1',
647        \              '    Xfoo',
648        \              'Tab page 2',
649        \              '>   Xbar'], a, msg)
650
651    " Test clicking on tab names in the tabline at the top.
652    let col = 2
653    redraw
654    call MouseLeftClick(row, col)
655    call MouseLeftRelease(row, col)
656    let a = split(execute(':tabs'), "\n")
657    call assert_equal(['Tab page 1',
658        \              '>   Xfoo',
659        \              'Tab page 2',
660        \              '    Xbar'], a, msg)
661
662    let col = 9
663    call MouseLeftClick(row, col)
664    call MouseLeftRelease(row, col)
665    let a = split(execute(':tabs'), "\n")
666    call assert_equal(['Tab page 1',
667        \              '    Xfoo',
668        \              'Tab page 2',
669        \              '>   Xbar'], a, msg)
670
671    %bwipe!
672  endfor
673
674  let &mouse = save_mouse
675  let &term = save_term
676  let &ttymouse = save_ttymouse
677  call test_override('no_query_mouse', 0)
678endfunc
679
680func Test_term_mouse_click_X_to_close_tab()
681  let save_mouse = &mouse
682  let save_term = &term
683  let save_ttymouse = &ttymouse
684  call test_override('no_query_mouse', 1)
685  set mouse=a term=xterm
686  let row = 1
687  let col = &columns
688
689  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm
690    if ttymouse_val ==# 'xterm2' && col > 223
691      " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
692      continue
693    endif
694    let msg = 'ttymouse=' .. ttymouse_val
695    exe 'set ttymouse=' .. ttymouse_val
696    e Xtab1
697    tabnew Xtab2
698    tabnew Xtab3
699    tabn 2
700
701    let a = split(execute(':tabs'), "\n")
702    call assert_equal(['Tab page 1',
703        \              '    Xtab1',
704        \              'Tab page 2',
705        \              '>   Xtab2',
706        \              'Tab page 3',
707        \              '    Xtab3'], a, msg)
708
709    " Click on "X" in tabline to close current tab i.e. Xtab2.
710    redraw
711    call MouseLeftClick(row, col)
712    call MouseLeftRelease(row, col)
713    let a = split(execute(':tabs'), "\n")
714    call assert_equal(['Tab page 1',
715        \              '    Xtab1',
716        \              'Tab page 2',
717        \              '>   Xtab3'], a, msg)
718
719    %bwipe!
720  endfor
721
722  let &mouse = save_mouse
723  let &term = save_term
724  let &ttymouse = save_ttymouse
725  call test_override('no_query_mouse', 0)
726endfunc
727
728func Test_term_mouse_drag_to_move_tab()
729  let save_mouse = &mouse
730  let save_term = &term
731  let save_ttymouse = &ttymouse
732  call test_override('no_query_mouse', 1)
733  " Set 'mousetime' to 1 to avoid recognizing a double-click in the loop
734  set mouse=a term=xterm mousetime=1
735  let row = 1
736
737  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
738    let msg = 'ttymouse=' .. ttymouse_val
739    exe 'set ttymouse=' .. ttymouse_val
740    e Xtab1
741    tabnew Xtab2
742
743    let a = split(execute(':tabs'), "\n")
744    call assert_equal(['Tab page 1',
745        \              '    Xtab1',
746        \              'Tab page 2',
747        \              '>   Xtab2'], a, msg)
748    redraw
749
750    " Click in tab2 and drag it to tab1.
751    " Check getcharmod() to verify that click is not
752    " interpreted as a spurious double-click.
753    call MouseLeftClick(row, 10)
754    call assert_equal(0, getcharmod(), msg)
755    for col in [9, 8, 7, 6]
756      call MouseLeftDrag(row, col)
757    endfor
758    call MouseLeftRelease(row, col)
759    let a = split(execute(':tabs'), "\n")
760    call assert_equal(['Tab page 1',
761        \              '>   Xtab2',
762        \              'Tab page 2',
763        \              '    Xtab1'], a, msg)
764
765    " Click elsewhere so that click in next iteration is not
766    " interpreted as unwanted double-click.
767    call MouseLeftClick(row, 11)
768    call MouseLeftRelease(row, 11)
769
770    %bwipe!
771  endfor
772
773  let &mouse = save_mouse
774  let &term = save_term
775  let &ttymouse = save_ttymouse
776  call test_override('no_query_mouse', 0)
777  set mousetime&
778endfunc
779
780func Test_term_mouse_double_click_to_create_tab()
781  let save_mouse = &mouse
782  let save_term = &term
783  let save_ttymouse = &ttymouse
784  call test_override('no_query_mouse', 1)
785  " Set 'mousetime' to a small value, so that double-click works but we don't
786  " have to wait long to avoid a triple-click.
787  set mouse=a term=xterm mousetime=200
788  let row = 1
789  let col = 10
790
791  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
792    let msg = 'ttymouse=' .. ttymouse_val
793    exe 'set ttymouse=' .. ttymouse_val
794    e Xtab1
795    tabnew Xtab2
796
797    let a = split(execute(':tabs'), "\n")
798    call assert_equal(['Tab page 1',
799        \              '    Xtab1',
800        \              'Tab page 2',
801        \              '>   Xtab2'], a, msg)
802
803    redraw
804    call MouseLeftClick(row, col)
805    " Check getcharmod() to verify that first click is not
806    " interpreted as a spurious double-click.
807    call assert_equal(0, getcharmod(), msg)
808    call MouseLeftRelease(row, col)
809    call MouseLeftClick(row, col)
810    call assert_equal(32, getcharmod(), msg) " double-click
811    call MouseLeftRelease(row, col)
812    let a = split(execute(':tabs'), "\n")
813    call assert_equal(['Tab page 1',
814        \              '    Xtab1',
815        \              'Tab page 2',
816        \              '>   [No Name]',
817        \              'Tab page 3',
818        \              '    Xtab2'], a, msg)
819
820    " Click elsewhere so that click in next iteration is not
821    " interpreted as unwanted double click.
822    call MouseLeftClick(row, col + 1)
823    call MouseLeftRelease(row, col + 1)
824
825    %bwipe!
826  endfor
827
828  let &mouse = save_mouse
829  let &term = save_term
830  let &ttymouse = save_ttymouse
831  call test_override('no_query_mouse', 0)
832  set mousetime&
833endfunc
834
835" Test double/triple/quadruple click in normal mode to visually select.
836func Test_term_mouse_multiple_clicks_to_visually_select()
837  let save_mouse = &mouse
838  let save_term = &term
839  let save_ttymouse = &ttymouse
840  call test_override('no_query_mouse', 1)
841  set mouse=a term=xterm mousetime=200
842  new
843
844  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
845    let msg = 'ttymouse=' .. ttymouse_val
846    exe 'set ttymouse=' .. ttymouse_val
847    call setline(1, ['foo [foo bar] foo', 'foo'])
848
849    " Double-click on word should visually select the word.
850    call MouseLeftClick(1, 2)
851    call assert_equal(0, getcharmod(), msg)
852    call MouseLeftRelease(1, 2)
853    call MouseLeftClick(1, 2)
854    call assert_equal(32, getcharmod(), msg) " double-click
855    call MouseLeftRelease(1, 2)
856    call assert_equal('v', mode(), msg)
857    norm! r1
858    call assert_equal(['111 [foo bar] foo', 'foo'], getline(1, '$'), msg)
859
860    " Double-click on opening square bracket should visually
861    " select the whole [foo bar].
862    call MouseLeftClick(1, 5)
863    call assert_equal(0, getcharmod(), msg)
864    call MouseLeftRelease(1, 5)
865    call MouseLeftClick(1, 5)
866    call assert_equal(32, getcharmod(), msg) " double-click
867    call MouseLeftRelease(1, 5)
868    call assert_equal('v', mode(), msg)
869    norm! r2
870    call assert_equal(['111 222222222 foo', 'foo'], getline(1, '$'), msg)
871
872    " Triple-click should visually select the whole line.
873    call MouseLeftClick(1, 3)
874    call assert_equal(0, getcharmod(), msg)
875    call MouseLeftRelease(1, 3)
876    call MouseLeftClick(1, 3)
877    call assert_equal(32, getcharmod(), msg) " double-click
878    call MouseLeftRelease(1, 3)
879    call MouseLeftClick(1, 3)
880    call assert_equal(64, getcharmod(), msg) " triple-click
881    call MouseLeftRelease(1, 3)
882    call assert_equal('V', mode(), msg)
883    norm! r3
884    call assert_equal(['33333333333333333', 'foo'], getline(1, '$'), msg)
885
886    " Quadruple-click should start visual block select.
887    call MouseLeftClick(1, 2)
888    call assert_equal(0, getcharmod(), msg)
889    call MouseLeftRelease(1, 2)
890    call MouseLeftClick(1, 2)
891    call assert_equal(32, getcharmod(), msg) " double-click
892    call MouseLeftRelease(1, 2)
893    call MouseLeftClick(1, 2)
894    call assert_equal(64, getcharmod(), msg) " triple-click
895    call MouseLeftRelease(1, 2)
896    call MouseLeftClick(1, 2)
897    call assert_equal(96, getcharmod(), msg) " quadruple-click
898    call MouseLeftRelease(1, 2)
899    call assert_equal("\<c-v>", mode(), msg)
900    norm! r4
901    call assert_equal(['34333333333333333', 'foo'], getline(1, '$'), msg)
902  endfor
903
904  let &mouse = save_mouse
905  let &term = save_term
906  let &ttymouse = save_ttymouse
907  set mousetime&
908  call test_override('no_query_mouse', 0)
909  bwipe!
910endfunc
911
912func Test_xterm_mouse_click_in_fold_columns()
913  new
914  let save_mouse = &mouse
915  let save_term = &term
916  let save_ttymouse = &ttymouse
917  let save_foldcolumn = &foldcolumn
918  set mouse=a term=xterm foldcolumn=3 ttymouse=xterm2
919
920  " Create 2 nested folds.
921  call setline(1, range(1, 7))
922  2,6fold
923  norm! zR
924  4,5fold
925  call assert_equal([-1, -1, -1, 4, 4, -1, -1],
926        \           map(range(1, 7), 'foldclosed(v:val)'))
927
928  " Click in "+" of inner fold in foldcolumn should open it.
929  redraw
930  let row = 4
931  let col = 2
932  call MouseLeftClick(row, col)
933  call MouseLeftRelease(row, col)
934  call assert_equal([-1, -1, -1, -1, -1, -1, -1],
935        \           map(range(1, 7), 'foldclosed(v:val)'))
936
937  " Click in "-" of outer fold in foldcolumn should close it.
938  redraw
939  let row = 2
940  let col = 1
941  call MouseLeftClick(row, col)
942  call MouseLeftRelease(row, col)
943  call assert_equal([-1, 2, 2, 2, 2, 2, -1],
944        \           map(range(1, 7), 'foldclosed(v:val)'))
945  norm! zR
946
947  " Click in "|" of inner fold in foldcolumn should close it.
948  redraw
949  let row = 5
950  let col = 2
951  call MouseLeftClick(row, col)
952  call MouseLeftRelease(row, col)
953  call assert_equal([-1, -1, -1, 4, 4, -1, -1],
954        \           map(range(1, 7), 'foldclosed(v:val)'))
955
956  let &foldcolumn = save_foldcolumn
957  let &ttymouse = save_ttymouse
958  let &term = save_term
959  let &mouse = save_mouse
960  bwipe!
961endfunc
962
963" Left or right click in Ex command line sets position of the cursor.
964func Test_term_mouse_click_in_cmdline_to_set_pos()
965  let save_mouse = &mouse
966  let save_term = &term
967  let save_ttymouse = &ttymouse
968  call test_override('no_query_mouse', 1)
969  set mouse=a term=xterm
970  let row = &lines
971
972  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
973    " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
974    if ttymouse_val !=# 'xterm2' || row <= 223
975      let msg = 'ttymouse=' .. ttymouse_val
976      exe 'set ttymouse=' .. ttymouse_val
977
978
979      call feedkeys(':"3456789'
980            \       .. MouseLeftClickCode(row, 7)
981            \       .. MouseLeftReleaseCode(row, 7) .. 'L'
982            \       .. MouseRightClickCode(row, 4)
983            \       .. MouseRightReleaseCode(row, 4) .. 'R'
984            \       .. "\<CR>", 'Lx!')
985      call assert_equal('"3R456L789', @:, msg)
986    endif
987  endfor
988
989  let &mouse = save_mouse
990  let &term = save_term
991  let &ttymouse = save_ttymouse
992  set mousetime&
993  call test_override('no_query_mouse', 0)
994endfunc
995
996" Middle click in command line pastes at position of cursor.
997func Test_term_mouse_middle_click_in_cmdline_to_paste()
998  CheckFeature clipboard_working
999  let save_mouse = &mouse
1000  let save_term = &term
1001  let save_ttymouse = &ttymouse
1002  call test_override('no_query_mouse', 1)
1003  set mouse=a term=xterm
1004  let row = &lines
1005  " Column values does not matter, paste is done at position of cursor.
1006  let col = 1
1007  let @* = 'paste'
1008
1009  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
1010    let msg = 'ttymouse=' .. ttymouse_val
1011    exe 'set ttymouse=' .. ttymouse_val
1012
1013    call feedkeys(":\"->"
1014          \       .. MouseMiddleReleaseCode(row, col)
1015          \       .. MouseMiddleClickCode(row, col)
1016          \       .. "<-"
1017          \       .. MouseMiddleReleaseCode(row, col)
1018          \       .. MouseMiddleClickCode(row, col)
1019          \       .. "\<CR>", 'Lx!')
1020    call assert_equal('"->paste<-paste', @:, msg)
1021  endfor
1022
1023  let &mouse = save_mouse
1024  let &term = save_term
1025  let &ttymouse = save_ttymouse
1026  let @* = ''
1027  call test_override('no_query_mouse', 0)
1028endfunc
1029
1030" Test for making sure S-Middlemouse doesn't do anything
1031func Test_term_mouse_shift_middle_click()
1032  new
1033  let save_mouse = &mouse
1034  let save_term = &term
1035  let save_ttymouse = &ttymouse
1036  call test_override('no_query_mouse', 1)
1037  set mouse=a term=xterm ttymouse=xterm2 mousemodel=
1038
1039  call test_setmouse(1, 1)
1040  exe "normal \<S-MiddleMouse>"
1041  call assert_equal([''], getline(1, '$'))
1042  call assert_equal(1, winnr())
1043
1044  let &mouse = save_mouse
1045  let &term = save_term
1046  let &ttymouse = save_ttymouse
1047  set mousemodel&
1048  call test_override('no_query_mouse', 0)
1049  close!
1050endfunc
1051
1052" Test for using mouse in visual mode
1053func Test_term_mouse_visual_mode()
1054  new
1055  let save_mouse = &mouse
1056  let save_term = &term
1057  let save_ttymouse = &ttymouse
1058  call test_override('no_query_mouse', 1)
1059  set term=xterm ttymouse=xterm2
1060
1061  " If visual mode is not present in 'mouse', then left click should not
1062  " do anything in visal mode.
1063  call setline(1, ['one two three four'])
1064  set mouse=nci
1065  call cursor(1, 5)
1066  let @" = ''
1067  call feedkeys("ve"
1068        \ .. MouseLeftClickCode(1, 15) .. MouseLeftReleaseCode(1, 15)
1069        \ .. 'y', 'Lx!')
1070  call assert_equal(5, col('.'))
1071  call assert_equal('two', @")
1072
1073  " Pressing right click in visual mode should change the visual selection
1074  " if 'mousemodel' doesn't contain popup.
1075  " Right click after the visual selection
1076  set mousemodel=
1077  set mouse=a
1078  call test_setmouse(1, 13)
1079  exe "normal 5|ve\<RightMouse>y"
1080  call assert_equal('two three', @")
1081  call assert_equal(5, col('.'))
1082
1083  " Right click before the visual selection
1084  call test_setmouse(1, 9)
1085  exe "normal 15|ve\<RightMouse>y"
1086  call assert_equal('three four', @")
1087  call assert_equal(9, col('.'))
1088
1089  " Multi-line selection. Right click in the middle of thse selection
1090  call setline(1, ["one", "two", "three", "four", "five", "six"])
1091  call test_setmouse(3, 1)
1092  exe "normal ggVG\<RightMouse>y"
1093  call assert_equal(3, line("'<"))
1094  call test_setmouse(4, 1)
1095  exe "normal ggVG\<RightMouse>y"
1096  call assert_equal(4, line("'>"))
1097
1098  set mousemodel&
1099  let &mouse = save_mouse
1100  let &term = save_term
1101  let &ttymouse = save_ttymouse
1102  call test_override('no_query_mouse', 0)
1103  close!
1104endfunc
1105
1106" Test for displaying the popup menu using the right mouse click
1107func Test_term_mouse_popup_menu()
1108  CheckFeature menu
1109  new
1110  call setline(1, 'popup menu test')
1111  let save_mouse = &mouse
1112  let save_term = &term
1113  let save_ttymouse = &ttymouse
1114  let save_mousemodel = &mousemodel
1115  call test_override('no_query_mouse', 1)
1116  set mouse=a term=xterm mousemodel=popup
1117
1118  menu PopUp.foo :let g:menustr = 'foo'<CR>
1119  menu PopUp.bar :let g:menustr = 'bar'<CR>
1120  menu PopUp.baz :let g:menustr = 'baz'<CR>
1121
1122  for ttymouse_val in g:Ttymouse_values
1123    exe 'set ttymouse=' .. ttymouse_val
1124    let g:menustr = ''
1125    call feedkeys(MouseRightClickCode(1, 4)
1126		\ .. MouseRightReleaseCode(1, 4) .. "\<Down>\<Down>\<CR>", "x")
1127    call assert_equal('bar', g:menustr)
1128  endfor
1129
1130  unmenu PopUp
1131  let &mouse = save_mouse
1132  let &term = save_term
1133  let &ttymouse = save_ttymouse
1134  let &mousemodel = save_mousemodel
1135  call test_override('no_query_mouse', 0)
1136  close!
1137endfunc
1138
1139" Test for 'mousemodel' set to popup_setpos to move the cursor where the popup
1140" menu is displayed.
1141func Test_term_mouse_popup_menu_setpos()
1142  CheckFeature menu
1143  5new
1144  call setline(1, ['the dish ran away with the spoon',
1145        \ 'the cow jumped over the moon' ])
1146  let save_mouse = &mouse
1147  let save_term = &term
1148  let save_ttymouse = &ttymouse
1149  let save_mousemodel = &mousemodel
1150  call test_override('no_query_mouse', 1)
1151  set mouse=a term=xterm mousemodel=popup_setpos
1152
1153  nmenu PopUp.foo :let g:menustr = 'foo'<CR>
1154  nmenu PopUp.bar :let g:menustr = 'bar'<CR>
1155  nmenu PopUp.baz :let g:menustr = 'baz'<CR>
1156  vmenu PopUp.foo y:<C-U>let g:menustr = 'foo'<CR>
1157  vmenu PopUp.bar y:<C-U>let g:menustr = 'bar'<CR>
1158  vmenu PopUp.baz y:<C-U>let g:menustr = 'baz'<CR>
1159
1160  for ttymouse_val in g:Ttymouse_values
1161    exe 'set ttymouse=' .. ttymouse_val
1162    let g:menustr = ''
1163    call cursor(1, 1)
1164    call feedkeys(MouseRightClickCode(1, 5)
1165		\ .. MouseRightReleaseCode(1, 5) .. "\<Down>\<Down>\<CR>", "x")
1166    call assert_equal('bar', g:menustr)
1167    call assert_equal([1, 5], [line('.'), col('.')])
1168
1169    " Test for right click in visual mode inside the selection
1170    let @" = ''
1171    call cursor(1, 10)
1172    call feedkeys('vee' .. MouseRightClickCode(1, 12)
1173		\ .. MouseRightReleaseCode(1, 12) .. "\<Down>\<CR>", "x")
1174    call assert_equal([1, 10], [line('.'), col('.')])
1175    call assert_equal('ran away', @")
1176
1177    " Test for right click in visual mode before the selection
1178    let @" = ''
1179    call cursor(1, 10)
1180    call feedkeys('vee' .. MouseRightClickCode(1, 2)
1181		\ .. MouseRightReleaseCode(1, 2) .. "\<Down>\<CR>", "x")
1182    call assert_equal([1, 2], [line('.'), col('.')])
1183    call assert_equal('', @")
1184
1185    " Test for right click in visual mode after the selection
1186    let @" = ''
1187    call cursor(1, 10)
1188    call feedkeys('vee' .. MouseRightClickCode(1, 20)
1189		\ .. MouseRightReleaseCode(1, 20) .. "\<Down>\<CR>", "x")
1190    call assert_equal([1, 20], [line('.'), col('.')])
1191    call assert_equal('', @")
1192
1193    " Test for right click in block-wise visual mode inside the selection
1194    let @" = ''
1195    call cursor(1, 16)
1196    call feedkeys("\<C-V>j3l" .. MouseRightClickCode(2, 17)
1197		\ .. MouseRightReleaseCode(2, 17) .. "\<Down>\<CR>", "x")
1198    call assert_equal([1, 16], [line('.'), col('.')])
1199    call assert_equal("\<C-V>4", getregtype('"'))
1200
1201    " Test for right click in block-wise visual mode outside the selection
1202    let @" = ''
1203    call cursor(1, 16)
1204    call feedkeys("\<C-V>j3l" .. MouseRightClickCode(2, 2)
1205		\ .. MouseRightReleaseCode(2, 2) .. "\<Down>\<CR>", "x")
1206    call assert_equal([2, 2], [line('.'), col('.')])
1207    call assert_equal('v', getregtype('"'))
1208    call assert_equal('', @")
1209
1210    " Try clicking on the status line
1211    let @" = ''
1212    call cursor(1, 10)
1213    call feedkeys('vee' .. MouseRightClickCode(6, 2)
1214		\ .. MouseRightReleaseCode(6, 2) .. "\<Down>\<CR>", "x")
1215    call assert_equal([1, 10], [line('.'), col('.')])
1216    call assert_equal('ran away', @")
1217
1218    " Try clicking outside the window
1219    let @" = ''
1220    call cursor(7, 2)
1221    call feedkeys('vee' .. MouseRightClickCode(7, 2)
1222		\ .. MouseRightReleaseCode(7, 2) .. "\<Down>\<CR>", "x")
1223    call assert_equal(2, winnr())
1224    call assert_equal('', @")
1225    wincmd w
1226  endfor
1227
1228  unmenu PopUp
1229  let &mouse = save_mouse
1230  let &term = save_term
1231  let &ttymouse = save_ttymouse
1232  let &mousemodel = save_mousemodel
1233  call test_override('no_query_mouse', 0)
1234  close!
1235endfunc
1236
1237" Test for searching for the word under the cursor using Shift-Right or
1238" Shift-Left click.
1239func Test_term_mouse_search()
1240  new
1241  let save_mouse = &mouse
1242  let save_term = &term
1243  let save_ttymouse = &ttymouse
1244  call test_override('no_query_mouse', 1)
1245  set mouse=a term=xterm ttymouse=xterm2
1246  set mousemodel=
1247
1248  " In normal mode, Shift-Left or Shift-Right click should search for the word
1249  " under the cursor.
1250  call setline(1, ['one two three four', 'four three two one'])
1251  call test_setmouse(1, 4)
1252  exe "normal \<S-LeftMouse>"
1253  call assert_equal([2, 12], [line('.'), col('.')])
1254  call test_setmouse(2, 16)
1255  exe "normal \<S-RightMouse>"
1256  call assert_equal([1, 1], [line('.'), col('.')])
1257
1258  " In visual mode, Shift-Left or Shift-Right click should search for the word
1259  " under the cursor and extend the selection.
1260  call test_setmouse(1, 4)
1261  exe "normal 4|ve\<S-LeftMouse>y"
1262  call assert_equal([2, 12], [line("'>"), col("'>")])
1263  call test_setmouse(2, 16)
1264  exe "normal 2G16|ve\<S-RightMouse>y"
1265  call assert_equal([1, 1], [line("'<"), col("'<")])
1266
1267  set mousemodel&
1268  let &mouse = save_mouse
1269  let &term = save_term
1270  let &ttymouse = save_ttymouse
1271  call test_override('no_query_mouse', 0)
1272  close!
1273endfunc
1274
1275" Test for selecting an entry in the quickfix/location list window using the
1276" mouse.
1277func Test_term_mouse_quickfix_window()
1278  let save_mouse = &mouse
1279  let save_term = &term
1280  let save_ttymouse = &ttymouse
1281  call test_override('no_query_mouse', 1)
1282  set mouse=a term=xterm ttymouse=xterm2
1283  set mousemodel=
1284
1285  cgetexpr "Xfile1:1:L1"
1286  copen 5
1287  call test_setmouse(&lines - 7, 1)
1288  exe "normal \<2-LeftMouse>"
1289  call assert_equal('Xfile1', @%)
1290  %bw!
1291
1292  lgetexpr "Xfile2:1:L1"
1293  lopen 5
1294  call test_setmouse(&lines - 7, 1)
1295  exe "normal \<2-LeftMouse>"
1296  call assert_equal('Xfile2', @%)
1297  %bw!
1298
1299  set mousemodel&
1300  let &mouse = save_mouse
1301  let &term = save_term
1302  let &ttymouse = save_ttymouse
1303  call test_override('no_query_mouse', 0)
1304endfunc
1305
1306" This only checks if the sequence is recognized.
1307func Test_term_rgb_response()
1308  set t_RF=x
1309  set t_RB=y
1310
1311  " response to t_RF, 4 digits
1312  let red = 0x12
1313  let green = 0x34
1314  let blue = 0x56
1315  let seq = printf("\<Esc>]10;rgb:%02x00/%02x00/%02x00\x07", red, green, blue)
1316  call feedkeys(seq, 'Lx!')
1317  call assert_equal(seq, v:termrfgresp)
1318
1319  " response to t_RF, 2 digits
1320  let red = 0x78
1321  let green = 0x9a
1322  let blue = 0xbc
1323  let seq = printf("\<Esc>]10;rgb:%02x/%02x/%02x\x07", red, green, blue)
1324  call feedkeys(seq, 'Lx!')
1325  call assert_equal(seq, v:termrfgresp)
1326
1327  " response to t_RB, 4 digits, dark
1328  set background=light
1329  eval 'background'->test_option_not_set()
1330  let red = 0x29
1331  let green = 0x4a
1332  let blue = 0x6b
1333  let seq = printf("\<Esc>]11;rgb:%02x00/%02x00/%02x00\x07", red, green, blue)
1334  call feedkeys(seq, 'Lx!')
1335  call assert_equal(seq, v:termrbgresp)
1336  call assert_equal('dark', &background)
1337
1338  " response to t_RB, 4 digits, light
1339  set background=dark
1340  call test_option_not_set('background')
1341  let red = 0x81
1342  let green = 0x63
1343  let blue = 0x65
1344  let seq = printf("\<Esc>]11;rgb:%02x00/%02x00/%02x00\x07", red, green, blue)
1345  call feedkeys(seq, 'Lx!')
1346  call assert_equal(seq, v:termrbgresp)
1347  call assert_equal('light', &background)
1348
1349  " response to t_RB, 2 digits, dark
1350  set background=light
1351  call test_option_not_set('background')
1352  let red = 0x47
1353  let green = 0x59
1354  let blue = 0x5b
1355  let seq = printf("\<Esc>]11;rgb:%02x/%02x/%02x\x07", red, green, blue)
1356  call feedkeys(seq, 'Lx!')
1357  call assert_equal(seq, v:termrbgresp)
1358  call assert_equal('dark', &background)
1359
1360  " response to t_RB, 2 digits, light
1361  set background=dark
1362  call test_option_not_set('background')
1363  let red = 0x83
1364  let green = 0xa4
1365  let blue = 0xc2
1366  let seq = printf("\<Esc>]11;rgb:%02x/%02x/%02x\x07", red, green, blue)
1367  call feedkeys(seq, 'Lx!')
1368  call assert_equal(seq, v:termrbgresp)
1369  call assert_equal('light', &background)
1370
1371  set t_RF= t_RB=
1372endfunc
1373
1374" This only checks if the sequence is recognized.
1375" This must be after other tests, because it has side effects to xterm
1376" properties.
1377func Test_xx01_term_style_response()
1378  " Termresponse is only parsed when t_RV is not empty.
1379  set t_RV=x
1380  call test_override('term_props', 1)
1381
1382  " send the termresponse to trigger requesting the XT codes
1383  let seq = "\<Esc>[>41;337;0c"
1384  call feedkeys(seq, 'Lx!')
1385  call assert_equal(seq, v:termresponse)
1386
1387  let seq = "\<Esc>P1$r2 q\<Esc>\\"
1388  call feedkeys(seq, 'Lx!')
1389  call assert_equal(seq, v:termstyleresp)
1390
1391  call assert_equal(#{
1392        \ cursor_style: 'u',
1393        \ cursor_blink_mode: 'u',
1394        \ underline_rgb: 'u',
1395        \ mouse: 's'
1396        \ }, terminalprops())
1397
1398  set t_RV=
1399  call test_override('term_props', 0)
1400endfunc
1401
1402" This checks the iTerm2 version response.
1403" This must be after other tests, because it has side effects to xterm
1404" properties.
1405func Test_xx02_iTerm2_response()
1406  " Termresponse is only parsed when t_RV is not empty.
1407  set t_RV=x
1408  call test_override('term_props', 1)
1409
1410  " Old versions of iTerm2 used a different style term response.
1411  set ttymouse=xterm
1412  call test_option_not_set('ttymouse')
1413  let seq = "\<Esc>[>0;95;c"
1414  call feedkeys(seq, 'Lx!')
1415  call assert_equal(seq, v:termresponse)
1416  call assert_equal('xterm', &ttymouse)
1417
1418  set ttymouse=xterm
1419  call test_option_not_set('ttymouse')
1420  let seq = "\<Esc>[>0;95;0c"
1421  call feedkeys(seq, 'Lx!')
1422  call assert_equal(seq, v:termresponse)
1423  call assert_equal('sgr', &ttymouse)
1424
1425  call assert_equal(#{
1426        \ cursor_style: 'n',
1427        \ cursor_blink_mode: 'u',
1428        \ underline_rgb: 'u',
1429        \ mouse: 's'
1430        \ }, terminalprops())
1431
1432  set t_RV=
1433  call test_override('term_props', 0)
1434endfunc
1435
1436" This checks the libvterm version response.
1437" This must be after other tests, because it has side effects to xterm
1438" properties.
1439func Test_xx03_libvterm_response()
1440  " Termresponse is only parsed when t_RV is not empty.
1441  set t_RV=x
1442  call test_override('term_props', 1)
1443
1444  set ttymouse=xterm
1445  call test_option_not_set('ttymouse')
1446  let seq = "\<Esc>[>0;100;0c"
1447  call feedkeys(seq, 'Lx!')
1448  call assert_equal(seq, v:termresponse)
1449  call assert_equal('sgr', &ttymouse)
1450
1451  call assert_equal(#{
1452        \ cursor_style: 'n',
1453        \ cursor_blink_mode: 'u',
1454        \ underline_rgb: 'u',
1455        \ mouse: 's'
1456        \ }, terminalprops())
1457
1458  set t_RV=
1459  call test_override('term_props', 0)
1460endfunc
1461
1462" This checks the Mac Terminal.app version response.
1463" This must be after other tests, because it has side effects to xterm
1464" properties.
1465func Test_xx04_Mac_Terminal_response()
1466  " Termresponse is only parsed when t_RV is not empty.
1467  set t_RV=x
1468  call test_override('term_props', 1)
1469
1470  set ttymouse=xterm
1471  " t_8u is not reset
1472  let &t_8u = "\<Esc>[58;2;%lu;%lu;%lum"
1473  call test_option_not_set('ttymouse')
1474  let seq = "\<Esc>[>1;95;0c"
1475  call feedkeys(seq, 'Lx!')
1476  call assert_equal(seq, v:termresponse)
1477  call assert_equal('sgr', &ttymouse)
1478
1479  call assert_equal(#{
1480        \ cursor_style: 'n',
1481        \ cursor_blink_mode: 'u',
1482        \ underline_rgb: 'y',
1483        \ mouse: 's'
1484        \ }, terminalprops())
1485  call assert_equal("\<Esc>[58;2;%lu;%lu;%lum", &t_8u)
1486
1487  " Reset is_not_xterm and is_mac_terminal.
1488  set t_RV=
1489  set term=xterm
1490  set t_RV=x
1491  call test_override('term_props', 0)
1492endfunc
1493
1494" This checks the mintty version response.
1495" This must be after other tests, because it has side effects to xterm
1496" properties.
1497func Test_xx05_mintty_response()
1498  " Termresponse is only parsed when t_RV is not empty.
1499  set t_RV=x
1500  call test_override('term_props', 1)
1501
1502  set ttymouse=xterm
1503  call test_option_not_set('ttymouse')
1504  let seq = "\<Esc>[>77;20905;0c"
1505  call feedkeys(seq, 'Lx!')
1506  call assert_equal(seq, v:termresponse)
1507  call assert_equal('sgr', &ttymouse)
1508
1509  call assert_equal(#{
1510        \ cursor_style: 'n',
1511        \ cursor_blink_mode: 'u',
1512        \ underline_rgb: 'y',
1513        \ mouse: 's'
1514        \ }, terminalprops())
1515
1516  set t_RV=
1517  call test_override('term_props', 0)
1518endfunc
1519
1520" This checks the screen version response.
1521" This must be after other tests, because it has side effects to xterm
1522" properties.
1523func Test_xx06_screen_response()
1524  " Termresponse is only parsed when t_RV is not empty.
1525  set t_RV=x
1526  call test_override('term_props', 1)
1527
1528  " Old versions of screen don't support SGR mouse mode.
1529  set ttymouse=xterm
1530  call test_option_not_set('ttymouse')
1531  let seq = "\<Esc>[>83;40500;0c"
1532  call feedkeys(seq, 'Lx!')
1533  call assert_equal(seq, v:termresponse)
1534  call assert_equal('xterm', &ttymouse)
1535
1536  " screen supports SGR mouse mode starting in version 4.7.
1537  set ttymouse=xterm
1538  call test_option_not_set('ttymouse')
1539  let seq = "\<Esc>[>83;40700;0c"
1540  call feedkeys(seq, 'Lx!')
1541  call assert_equal(seq, v:termresponse)
1542  call assert_equal('sgr', &ttymouse)
1543
1544  call assert_equal(#{
1545        \ cursor_style: 'n',
1546        \ cursor_blink_mode: 'n',
1547        \ underline_rgb: 'y',
1548        \ mouse: 's'
1549        \ }, terminalprops())
1550
1551  set t_RV=
1552  call test_override('term_props', 0)
1553endfunc
1554
1555" This checks the xterm version response.
1556" This must be after other tests, because it has side effects to xterm
1557" properties.
1558func Test_xx07_xterm_response()
1559  " Termresponse is only parsed when t_RV is not empty.
1560  set t_RV=x
1561  call test_override('term_props', 1)
1562
1563  " Do Terminal.app first to check that is_mac_terminal is reset.
1564  set ttymouse=xterm
1565  call test_option_not_set('ttymouse')
1566  let seq = "\<Esc>[>1;95;0c"
1567  call feedkeys(seq, 'Lx!')
1568  call assert_equal(seq, v:termresponse)
1569  call assert_equal('sgr', &ttymouse)
1570
1571  " xterm < 95: "xterm" (actually unmodified)
1572  set t_RV=
1573  set term=xterm
1574  set t_RV=x
1575  set ttymouse=xterm
1576  call test_option_not_set('ttymouse')
1577  let seq = "\<Esc>[>0;94;0c"
1578  call feedkeys(seq, 'Lx!')
1579  call assert_equal(seq, v:termresponse)
1580  call assert_equal('xterm', &ttymouse)
1581
1582  call assert_equal(#{
1583        \ cursor_style: 'n',
1584        \ cursor_blink_mode: 'u',
1585        \ underline_rgb: 'y',
1586        \ mouse: 'u'
1587        \ }, terminalprops())
1588
1589  " xterm >= 95 < 277 "xterm2"
1590  set ttymouse=xterm
1591  call test_option_not_set('ttymouse')
1592  let seq = "\<Esc>[>0;267;0c"
1593  call feedkeys(seq, 'Lx!')
1594  call assert_equal(seq, v:termresponse)
1595  call assert_equal('xterm2', &ttymouse)
1596
1597  call assert_equal(#{
1598        \ cursor_style: 'n',
1599        \ cursor_blink_mode: 'u',
1600        \ underline_rgb: 'u',
1601        \ mouse: '2'
1602        \ }, terminalprops())
1603
1604  " xterm >= 277: "sgr"
1605  set ttymouse=xterm
1606  call test_option_not_set('ttymouse')
1607  let seq = "\<Esc>[>0;277;0c"
1608  call feedkeys(seq, 'Lx!')
1609  call assert_equal(seq, v:termresponse)
1610  call assert_equal('sgr', &ttymouse)
1611
1612  call assert_equal(#{
1613        \ cursor_style: 'n',
1614        \ cursor_blink_mode: 'u',
1615        \ underline_rgb: 'u',
1616        \ mouse: 's'
1617        \ }, terminalprops())
1618
1619  " xterm >= 279: "sgr" and cursor_style not reset; also check t_8u reset
1620  set ttymouse=xterm
1621  call test_option_not_set('ttymouse')
1622  let &t_8u = "\<Esc>[58;2;%lu;%lu;%lum"
1623  let seq = "\<Esc>[>0;279;0c"
1624  call feedkeys(seq, 'Lx!')
1625  call assert_equal(seq, v:termresponse)
1626  call assert_equal('sgr', &ttymouse)
1627
1628  call assert_equal(#{
1629        \ cursor_style: 'u',
1630        \ cursor_blink_mode: 'u',
1631        \ underline_rgb: 'u',
1632        \ mouse: 's'
1633        \ }, terminalprops())
1634  call assert_equal('', &t_8u)
1635
1636  set t_RV=
1637  call test_override('term_props', 0)
1638endfunc
1639
1640func Test_get_termcode()
1641  try
1642    let k1 = &t_k1
1643  catch /E113/
1644    throw 'Skipped: Unable to query termcodes'
1645  endtry
1646  set t_k1=
1647  set t_k1&
1648  call assert_equal(k1, &t_k1)
1649
1650  " use external termcap first
1651  set nottybuiltin
1652  set t_k1=
1653  set t_k1&
1654  " when using external termcap may get something else, but it must not be
1655  " empty, since we would fallback to the builtin one.
1656  call assert_notequal('', &t_k1)
1657
1658  if &term =~ 'xterm'
1659    " use internal termcap first
1660    let term_save = &term
1661    let &term = 'builtin_' .. &term
1662    set t_k1=
1663    set t_k1&
1664    call assert_equal(k1, &t_k1)
1665    let &term = term_save
1666  endif
1667
1668  set ttybuiltin
1669endfunc
1670
1671func GetEscCodeCSI27(key, modifier)
1672  let key = printf("%d", char2nr(a:key))
1673  let mod = printf("%d", a:modifier)
1674  return "\<Esc>[27;" .. mod .. ';' .. key .. '~'
1675endfunc
1676
1677func GetEscCodeCSIu(key, modifier)
1678  let key = printf("%d", char2nr(a:key))
1679  let mod = printf("%d", a:modifier)
1680  return "\<Esc>[" .. key .. ';' .. mod .. 'u'
1681endfunc
1682
1683" This checks the CSI sequences when in modifyOtherKeys mode.
1684" The mode doesn't need to be enabled, the codes are always detected.
1685func RunTest_modifyOtherKeys(func)
1686  new
1687  set timeoutlen=10
1688
1689  " Shift-X is sent as 'X' with the shift modifier
1690  call feedkeys('a' .. a:func('X', 2) .. "\<Esc>", 'Lx!')
1691  call assert_equal('X', getline(1))
1692
1693  " Ctrl-i is Tab
1694  call setline(1, '')
1695  call feedkeys('a' .. a:func('i', 5) .. "\<Esc>", 'Lx!')
1696  call assert_equal("\t", getline(1))
1697
1698  " Ctrl-I is also Tab
1699  call setline(1, '')
1700  call feedkeys('a' .. a:func('I', 5) .. "\<Esc>", 'Lx!')
1701  call assert_equal("\t", getline(1))
1702
1703  " Alt-x is ø
1704  call setline(1, '')
1705  call feedkeys('a' .. a:func('x', 3) .. "\<Esc>", 'Lx!')
1706  call assert_equal("ø", getline(1))
1707
1708  " Meta-x is also ø
1709  call setline(1, '')
1710  call feedkeys('a' .. a:func('x', 9) .. "\<Esc>", 'Lx!')
1711  call assert_equal("ø", getline(1))
1712
1713  " Alt-X is Ø
1714  call setline(1, '')
1715  call feedkeys('a' .. a:func('X', 3) .. "\<Esc>", 'Lx!')
1716  call assert_equal("Ø", getline(1))
1717
1718  " Meta-X is ø
1719  call setline(1, '')
1720  call feedkeys('a' .. a:func('X', 9) .. "\<Esc>", 'Lx!')
1721  call assert_equal("Ø", getline(1))
1722
1723  " Ctrl-6 is Ctrl-^
1724  split aaa
1725  edit bbb
1726  call feedkeys(a:func('6', 5), 'Lx!')
1727  call assert_equal("aaa", bufname())
1728  bwipe aaa
1729  bwipe bbb
1730
1731  bwipe!
1732  set timeoutlen&
1733endfunc
1734
1735func Test_modifyOtherKeys_basic()
1736  call RunTest_modifyOtherKeys(function('GetEscCodeCSI27'))
1737  call RunTest_modifyOtherKeys(function('GetEscCodeCSIu'))
1738endfunc
1739
1740func Test_modifyOtherKeys_no_mapping()
1741  set timeoutlen=10
1742
1743  let @a = 'aaa'
1744  call feedkeys(":let x = '" .. GetEscCodeCSI27('R', 5) .. GetEscCodeCSI27('R', 5) .. "a'\<CR>", 'Lx!')
1745  call assert_equal("let x = 'aaa'", @:)
1746
1747  new
1748  call feedkeys("a" .. GetEscCodeCSI27('R', 5) .. GetEscCodeCSI27('R', 5) .. "a\<Esc>", 'Lx!')
1749  call assert_equal("aaa", getline(1))
1750  bwipe!
1751
1752  new
1753  call feedkeys("axx\<CR>yy" .. GetEscCodeCSI27('G', 5) .. GetEscCodeCSI27('K', 5) .. "a\<Esc>", 'Lx!')
1754  call assert_equal("axx", getline(1))
1755  call assert_equal("yy", getline(2))
1756  bwipe!
1757
1758  set timeoutlen&
1759endfunc
1760
1761func RunTest_mapping_shift(key, func)
1762  call setline(1, '')
1763  if a:key == '|'
1764    exe 'inoremap \| xyz'
1765  else
1766    exe 'inoremap ' .. a:key .. ' xyz'
1767  endif
1768  call feedkeys('a' .. a:func(a:key, 2) .. "\<Esc>", 'Lx!')
1769  call assert_equal("xyz", getline(1))
1770  if a:key == '|'
1771    exe 'iunmap \|'
1772  else
1773    exe 'iunmap ' .. a:key
1774  endif
1775endfunc
1776
1777func Test_modifyOtherKeys_mapped()
1778  set timeoutlen=10
1779  imap ' <C-W>
1780  imap <C-W><C-A> c-a
1781  call setline(1, '')
1782
1783  " single quote is turned into single byte CTRL-W
1784  " CTRL-A is added with a separate modifier, and needs to be simplified before
1785  " the mapping can match.
1786  call feedkeys("a'" .. GetEscCodeCSI27('A', 5) .. "\<Esc>", 'Lx!')
1787  call assert_equal('c-a', getline(1))
1788
1789  iunmap '
1790  iunmap <C-W><C-A>
1791  set timeoutlen&
1792endfunc
1793
1794func RunTest_mapping_works_with_shift(func)
1795  new
1796  set timeoutlen=10
1797
1798  call RunTest_mapping_shift('@', a:func)
1799  call RunTest_mapping_shift('A', a:func)
1800  call RunTest_mapping_shift('Z', a:func)
1801  call RunTest_mapping_shift('^', a:func)
1802  call RunTest_mapping_shift('_', a:func)
1803  call RunTest_mapping_shift('{', a:func)
1804  call RunTest_mapping_shift('|', a:func)
1805  call RunTest_mapping_shift('}', a:func)
1806  call RunTest_mapping_shift('~', a:func)
1807
1808  bwipe!
1809  set timeoutlen&
1810endfunc
1811
1812func Test_mapping_works_with_shift_plain()
1813  call RunTest_mapping_works_with_shift(function('GetEscCodeCSI27'))
1814  call RunTest_mapping_works_with_shift(function('GetEscCodeCSIu'))
1815endfunc
1816
1817func RunTest_mapping_mods(map, key, func, code)
1818  call setline(1, '')
1819  exe 'inoremap ' .. a:map .. ' xyz'
1820  call feedkeys('a' .. a:func(a:key, a:code) .. "\<Esc>", 'Lx!')
1821  call assert_equal("xyz", getline(1))
1822  exe 'iunmap ' .. a:map
1823endfunc
1824
1825func RunTest_mapping_works_with_mods(func, mods, code)
1826  new
1827  set timeoutlen=10
1828
1829  if a:mods !~ 'S'
1830    " Shift by itself has no effect
1831    call RunTest_mapping_mods('<' .. a:mods .. '-@>', '@', a:func, a:code)
1832  endif
1833  call RunTest_mapping_mods('<' .. a:mods .. '-A>', 'A', a:func, a:code)
1834  call RunTest_mapping_mods('<' .. a:mods .. '-Z>', 'Z', a:func, a:code)
1835  if a:mods !~ 'S'
1836    " with Shift code is always upper case
1837    call RunTest_mapping_mods('<' .. a:mods .. '-a>', 'a', a:func, a:code)
1838    call RunTest_mapping_mods('<' .. a:mods .. '-z>', 'z', a:func, a:code)
1839  endif
1840  if a:mods != 'A'
1841    " with Alt code is not in upper case
1842    call RunTest_mapping_mods('<' .. a:mods .. '-a>', 'A', a:func, a:code)
1843    call RunTest_mapping_mods('<' .. a:mods .. '-z>', 'Z', a:func, a:code)
1844  endif
1845  call RunTest_mapping_mods('<' .. a:mods .. '-á>', 'á', a:func, a:code)
1846  if a:mods !~ 'S'
1847    " Shift by itself has no effect
1848    call RunTest_mapping_mods('<' .. a:mods .. '-^>', '^', a:func, a:code)
1849    call RunTest_mapping_mods('<' .. a:mods .. '-_>', '_', a:func, a:code)
1850    call RunTest_mapping_mods('<' .. a:mods .. '-{>', '{', a:func, a:code)
1851    call RunTest_mapping_mods('<' .. a:mods .. '-\|>', '|', a:func, a:code)
1852    call RunTest_mapping_mods('<' .. a:mods .. '-}>', '}', a:func, a:code)
1853    call RunTest_mapping_mods('<' .. a:mods .. '-~>', '~', a:func, a:code)
1854  endif
1855
1856  bwipe!
1857  set timeoutlen&
1858endfunc
1859
1860func Test_mapping_works_with_shift()
1861  call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'S', 2)
1862  call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'S', 2)
1863endfunc
1864
1865func Test_mapping_works_with_ctrl()
1866  call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C', 5)
1867  call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C', 5)
1868endfunc
1869
1870func Test_mapping_works_with_shift_ctrl()
1871  call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-S', 6)
1872  call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-S', 6)
1873endfunc
1874
1875" Below we also test the "u" code with Alt, This works, but libvterm would not
1876" send the Alt key like this but by prefixing an Esc.
1877
1878func Test_mapping_works_with_alt()
1879  call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'A', 3)
1880  call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'A', 3)
1881endfunc
1882
1883func Test_mapping_works_with_shift_alt()
1884  call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'S-A', 4)
1885  call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'S-A', 4)
1886endfunc
1887
1888func Test_mapping_works_with_ctrl_alt()
1889  call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-A', 7)
1890  call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-A', 7)
1891endfunc
1892
1893func Test_mapping_works_with_shift_ctrl_alt()
1894  call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-S-A', 8)
1895  call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-S-A', 8)
1896endfunc
1897
1898func Test_insert_literal()
1899  set timeoutlen=10
1900  new
1901  " CTRL-V CTRL-X inserts a ^X
1902  call feedkeys('a' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu('X', '5') .. "\<Esc>", 'Lx!')
1903  call assert_equal("\<C-X>", getline(1))
1904
1905  call setline(1, '')
1906  call feedkeys('a' .. GetEscCodeCSI27('V', '5') .. GetEscCodeCSI27('X', '5') .. "\<Esc>", 'Lx!')
1907  call assert_equal("\<C-X>", getline(1))
1908
1909  " CTRL-SHIFT-V CTRL-X inserts escape sequence
1910  call setline(1, '')
1911  call feedkeys('a' .. GetEscCodeCSIu('V', '6') .. GetEscCodeCSIu('X', '5') .. "\<Esc>", 'Lx!')
1912  call assert_equal("\<Esc>[88;5u", getline(1))
1913
1914  call setline(1, '')
1915  call feedkeys('a' .. GetEscCodeCSI27('V', '6') .. GetEscCodeCSI27('X', '5') .. "\<Esc>", 'Lx!')
1916  call assert_equal("\<Esc>[27;5;88~", getline(1))
1917
1918  bwipe!
1919  set timeoutlen&
1920endfunc
1921
1922func Test_cmdline_literal()
1923  set timeoutlen=10
1924
1925  " CTRL-V CTRL-Y inserts a ^Y
1926  call feedkeys(':' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!')
1927  call assert_equal("\"\<C-Y>", @:)
1928
1929  call feedkeys(':' .. GetEscCodeCSI27('V', '5') .. GetEscCodeCSI27('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!')
1930  call assert_equal("\"\<C-Y>", @:)
1931
1932  " CTRL-SHIFT-V CTRL-Y inserts escape sequence
1933  call feedkeys(':' .. GetEscCodeCSIu('V', '6') .. GetEscCodeCSIu('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!')
1934  call assert_equal("\"\<Esc>[89;5u", @:)
1935
1936  call setline(1, '')
1937  call feedkeys(':' .. GetEscCodeCSI27('V', '6') .. GetEscCodeCSI27('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!')
1938  call assert_equal("\"\<Esc>[27;5;89~", @:)
1939
1940  set timeoutlen&
1941endfunc
1942
1943" Test for translation of special key codes (<xF1>, <xF2>, etc.)
1944func Test_Keycode_Tranlsation()
1945  let keycodes = [
1946        \ ["<xUp>", "<Up>"],
1947        \ ["<xDown>", "<Down>"],
1948        \ ["<xLeft>", "<Left>"],
1949        \ ["<xRight>", "<Right>"],
1950        \ ["<xHome>", "<Home>"],
1951        \ ["<xEnd>", "<End>"],
1952        \ ["<zHome>", "<Home>"],
1953        \ ["<zEnd>", "<End>"],
1954        \ ["<xF1>", "<F1>"],
1955        \ ["<xF2>", "<F2>"],
1956        \ ["<xF3>", "<F3>"],
1957        \ ["<xF4>", "<F4>"],
1958        \ ["<S-xF1>", "<S-F1>"],
1959        \ ["<S-xF2>", "<S-F2>"],
1960        \ ["<S-xF3>", "<S-F3>"],
1961        \ ["<S-xF4>", "<S-F4>"]]
1962  for [k1, k2] in keycodes
1963    exe "nnoremap " .. k1 .. " 2wx"
1964    call assert_true(maparg(k1, 'n', 0, 1).lhs == k2)
1965    exe "nunmap " .. k1
1966  endfor
1967endfunc
1968
1969" vim: shiftwidth=2 sts=2 expandtab
1970