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.
113func Test_xterm_mouse_ctrl_click()
114  let save_mouse = &mouse
115  let save_term = &term
116  let save_ttymouse = &ttymouse
117  set mouse=a term=xterm
118
119  for ttymouse_val in g:Ttymouse_values
120    let msg = 'ttymouse=' .. ttymouse_val
121    exe 'set ttymouse=' .. ttymouse_val
122    help
123    /usr_02.txt
124    norm! zt
125    let row = 1
126    let col = 1
127    call MouseCtrlLeftClick(row, col)
128    call MouseLeftRelease(row, col)
129    call assert_match('usr_02.txt$', bufname('%'), msg)
130    call assert_equal('*usr_02.txt*', expand('<cWORD>'), msg)
131
132    call MouseCtrlRightClick(row, col)
133    call MouseRightRelease(row, col)
134    call assert_match('help.txt$', bufname('%'), msg)
135    call assert_equal('|usr_02.txt|', expand('<cWORD>'), msg)
136
137    helpclose
138  endfor
139
140  let &mouse = save_mouse
141  let &term = save_term
142  let &ttymouse = save_ttymouse
143endfunc
144
145func Test_term_mouse_middle_click()
146  CheckFeature clipboard_working
147
148  new
149  let save_mouse = &mouse
150  let save_term = &term
151  let save_ttymouse = &ttymouse
152  call test_override('no_query_mouse', 1)
153  let save_quotestar = @*
154  let @* = 'abc'
155  set mouse=a term=xterm
156
157  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
158    let msg = 'ttymouse=' .. ttymouse_val
159    exe 'set ttymouse=' .. ttymouse_val
160    call setline(1, ['123456789', '123456789'])
161
162    " Middle-click in the middle of the line pastes text where clicked.
163    let row = 1
164    let col = 6
165    call MouseMiddleClick(row, col)
166    call MouseMiddleRelease(row, col)
167    call assert_equal(['12345abc6789', '123456789'], getline(1, '$'), msg)
168
169    " Middle-click beyond end of the line pastes text at the end of the line.
170    let col = 20
171    call MouseMiddleClick(row, col)
172    call MouseMiddleRelease(row, col)
173    call assert_equal(['12345abc6789abc', '123456789'], getline(1, '$'), msg)
174
175    " Middle-click beyond the last line pastes in the last line.
176    let row = 5
177    let col = 3
178    call MouseMiddleClick(row, col)
179    call MouseMiddleRelease(row, col)
180    call assert_equal(['12345abc6789abc', '12abc3456789'], getline(1, '$'), msg)
181  endfor
182
183  let &mouse = save_mouse
184  let &term = save_term
185  let &ttymouse = save_ttymouse
186  call test_override('no_query_mouse', 0)
187  let @* = save_quotestar
188  bwipe!
189endfunc
190
191" TODO: for unclear reasons this test fails if it comes after
192" Test_xterm_mouse_ctrl_click()
193func Test_1xterm_mouse_wheel()
194  new
195  let save_mouse = &mouse
196  let save_term = &term
197  let save_ttymouse = &ttymouse
198  set mouse=a term=xterm
199  call setline(1, range(1, 100))
200
201  for ttymouse_val in g:Ttymouse_values
202    let msg = 'ttymouse=' .. ttymouse_val
203    exe 'set ttymouse=' .. ttymouse_val
204    go
205    call assert_equal(1, line('w0'), msg)
206    call assert_equal([0, 1, 1, 0], getpos('.'), msg)
207
208    call MouseWheelDown(1, 1)
209    call assert_equal(4, line('w0'), msg)
210    call assert_equal([0, 4, 1, 0], getpos('.'), msg)
211
212    call MouseWheelDown(1, 1)
213    call assert_equal(7, line('w0'), msg)
214    call assert_equal([0, 7, 1, 0], getpos('.'), msg)
215
216    call MouseWheelUp(1, 1)
217    call assert_equal(4, line('w0'), msg)
218    call assert_equal([0, 7, 1, 0], getpos('.'), msg)
219
220    call MouseWheelUp(1, 1)
221    call assert_equal(1, line('w0'), msg)
222    call assert_equal([0, 7, 1, 0], getpos('.'), msg)
223  endfor
224
225  let &mouse = save_mouse
226  let &term = save_term
227  let &ttymouse = save_ttymouse
228  bwipe!
229endfunc
230
231" Test that dragging beyond the window (at the bottom and at the top)
232" scrolls window content by the number of lines beyond the window.
233func Test_term_mouse_drag_beyond_window()
234  let save_mouse = &mouse
235  let save_term = &term
236  let save_ttymouse = &ttymouse
237  call test_override('no_query_mouse', 1)
238  set mouse=a term=xterm
239  let col = 1
240  call setline(1, range(1, 100))
241
242  " Split into 3 windows, and go into the middle window
243  " so we test dragging mouse below and above the window.
244  2split
245  wincmd j
246  2split
247
248  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
249    let msg = 'ttymouse=' .. ttymouse_val
250    exe 'set ttymouse=' .. ttymouse_val
251
252    " Line #10 at the top.
253    norm! 10zt
254    redraw
255    call assert_equal(10, winsaveview().topline, msg)
256    call assert_equal(2, winheight(0), msg)
257
258    let row = 4
259    call MouseLeftClick(row, col)
260    call assert_equal(10, winsaveview().topline, msg)
261
262    " Drag downwards. We're still in the window so topline should
263    " not change yet.
264    let row += 1
265    call MouseLeftDrag(row, col)
266    call assert_equal(10, winsaveview().topline, msg)
267
268    " We now leave the window at the bottom, so the window content should
269    " scroll by 1 line, then 2 lines (etc) as we drag further away.
270    let row += 1
271    call MouseLeftDrag(row, col)
272    call assert_equal(11, winsaveview().topline, msg)
273
274    let row += 1
275    call MouseLeftDrag(row, col)
276    call assert_equal(13, winsaveview().topline, msg)
277
278    " Now drag upwards.
279    let row -= 1
280    call MouseLeftDrag(row, col)
281    call assert_equal(14, winsaveview().topline, msg)
282
283    " We're now back in the window so the topline should not change.
284    let row -= 1
285    call MouseLeftDrag(row, col)
286    call assert_equal(14, winsaveview().topline, msg)
287
288    let row -= 1
289    call MouseLeftDrag(row, col)
290    call assert_equal(14, winsaveview().topline, msg)
291
292    " We now leave the window at the top so the window content should
293    " scroll by 1 line, then 2, then 3 (etc) in the opposite direction.
294    let row -= 1
295    call MouseLeftDrag(row, col)
296    call assert_equal(13, winsaveview().topline, msg)
297
298    let row -= 1
299    call MouseLeftDrag(row, col)
300    call assert_equal(11, winsaveview().topline, msg)
301
302    let row -= 1
303    call MouseLeftDrag(row, col)
304    call assert_equal(8, winsaveview().topline, msg)
305
306    call MouseLeftRelease(row, col)
307    call assert_equal(8, winsaveview().topline, msg)
308    call assert_equal(2, winheight(0), msg)
309  endfor
310
311  let &mouse = save_mouse
312  let &term = save_term
313  let &ttymouse = save_ttymouse
314  call test_override('no_query_mouse', 0)
315  bwipe!
316endfunc
317
318func Test_term_mouse_drag_window_separator()
319  let save_mouse = &mouse
320  let save_term = &term
321  let save_ttymouse = &ttymouse
322  call test_override('no_query_mouse', 1)
323  set mouse=a term=xterm
324
325  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
326    let msg = 'ttymouse=' .. ttymouse_val
327    exe 'set ttymouse=' .. ttymouse_val
328
329    " Split horizontally and test dragging the horizontal window separator.
330    split
331    let rowseparator = winheight(0) + 1
332    let row = rowseparator
333    let col = 1
334
335    " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
336    if ttymouse_val !=# 'xterm2' || row <= 223
337      call MouseLeftClick(row, col)
338      let row -= 1
339      call MouseLeftDrag(row, col)
340      call assert_equal(rowseparator - 1, winheight(0) + 1, msg)
341      let row += 1
342      call MouseLeftDrag(row, col)
343      call assert_equal(rowseparator, winheight(0) + 1, msg)
344      call MouseLeftRelease(row, col)
345      call assert_equal(rowseparator, winheight(0) + 1, msg)
346    endif
347    bwipe!
348
349    " Split vertically and test dragging the vertical window separator.
350    vsplit
351    let colseparator = winwidth(0) + 1
352    let row = 1
353    let col = colseparator
354
355    " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
356    if ttymouse_val !=# 'xterm2' || col <= 223
357      call MouseLeftClick(row, col)
358      let col -= 1
359      call MouseLeftDrag(row, col)
360      call assert_equal(colseparator - 1, winwidth(0) + 1, msg)
361      let col += 1
362      call MouseLeftDrag(row, col)
363      call assert_equal(colseparator, winwidth(0) + 1, msg)
364      call MouseLeftRelease(row, col)
365      call assert_equal(colseparator, winwidth(0) + 1, msg)
366    endif
367    bwipe!
368  endfor
369
370  let &mouse = save_mouse
371  let &term = save_term
372  let &ttymouse = save_ttymouse
373  call test_override('no_query_mouse', 0)
374endfunc
375
376func Test_term_mouse_drag_statusline()
377  let save_mouse = &mouse
378  let save_term = &term
379  let save_ttymouse = &ttymouse
380  call test_override('no_query_mouse', 1)
381  let save_laststatus = &laststatus
382  set mouse=a term=xterm laststatus=2
383
384  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
385    let msg = 'ttymouse=' .. ttymouse_val
386    exe 'set ttymouse=' .. ttymouse_val
387
388    call assert_equal(1, &cmdheight, msg)
389    let rowstatusline = winheight(0) + 1
390    let row = rowstatusline
391    let col = 1
392
393    if ttymouse_val ==# 'xterm2' && row > 223
394      " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
395      continue
396    endif
397
398    call MouseLeftClick(row, col)
399    let row -= 1
400    call MouseLeftDrag(row, col)
401    call assert_equal(2, &cmdheight, msg)
402    call assert_equal(rowstatusline - 1, winheight(0) + 1, msg)
403    let row += 1
404    call MouseLeftDrag(row, col)
405    call assert_equal(1, &cmdheight, msg)
406    call assert_equal(rowstatusline, winheight(0) + 1, msg)
407    call MouseLeftRelease(row, col)
408    call assert_equal(1, &cmdheight, msg)
409    call assert_equal(rowstatusline, winheight(0) + 1, msg)
410  endfor
411
412  let &mouse = save_mouse
413  let &term = save_term
414  let &ttymouse = save_ttymouse
415  call test_override('no_query_mouse', 0)
416  let &laststatus = save_laststatus
417endfunc
418
419func Test_term_mouse_click_tab()
420  let save_mouse = &mouse
421  let save_term = &term
422  let save_ttymouse = &ttymouse
423  call test_override('no_query_mouse', 1)
424  set mouse=a term=xterm
425  let row = 1
426
427  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm
428    let msg = 'ttymouse=' .. ttymouse_val
429    exe 'set ttymouse=' .. ttymouse_val
430    e Xfoo
431    tabnew Xbar
432
433    let a = split(execute(':tabs'), "\n")
434    call assert_equal(['Tab page 1',
435        \              '    Xfoo',
436        \              'Tab page 2',
437        \              '>   Xbar'], a, msg)
438
439    " Test clicking on tab names in the tabline at the top.
440    let col = 2
441    redraw
442    call MouseLeftClick(row, col)
443    call MouseLeftRelease(row, col)
444    let a = split(execute(':tabs'), "\n")
445    call assert_equal(['Tab page 1',
446        \              '>   Xfoo',
447        \              'Tab page 2',
448        \              '    Xbar'], a, msg)
449
450    let col = 9
451    call MouseLeftClick(row, col)
452    call MouseLeftRelease(row, col)
453    let a = split(execute(':tabs'), "\n")
454    call assert_equal(['Tab page 1',
455        \              '    Xfoo',
456        \              'Tab page 2',
457        \              '>   Xbar'], a, msg)
458
459    %bwipe!
460  endfor
461
462  let &mouse = save_mouse
463  let &term = save_term
464  let &ttymouse = save_ttymouse
465  call test_override('no_query_mouse', 0)
466endfunc
467
468func Test_term_mouse_click_X_to_close_tab()
469  let save_mouse = &mouse
470  let save_term = &term
471  let save_ttymouse = &ttymouse
472  call test_override('no_query_mouse', 1)
473  set mouse=a term=xterm
474  let row = 1
475  let col = &columns
476
477  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec + g:Ttymouse_netterm
478    if ttymouse_val ==# 'xterm2' && col > 223
479      " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
480      continue
481    endif
482    let msg = 'ttymouse=' .. ttymouse_val
483    exe 'set ttymouse=' .. ttymouse_val
484    e Xtab1
485    tabnew Xtab2
486    tabnew Xtab3
487    tabn 2
488
489    let a = split(execute(':tabs'), "\n")
490    call assert_equal(['Tab page 1',
491        \              '    Xtab1',
492        \              'Tab page 2',
493        \              '>   Xtab2',
494        \              'Tab page 3',
495        \              '    Xtab3'], a, msg)
496
497    " Click on "X" in tabline to close current tab i.e. Xtab2.
498    redraw
499    call MouseLeftClick(row, col)
500    call MouseLeftRelease(row, col)
501    let a = split(execute(':tabs'), "\n")
502    call assert_equal(['Tab page 1',
503        \              '    Xtab1',
504        \              'Tab page 2',
505        \              '>   Xtab3'], a, msg)
506
507    %bwipe!
508  endfor
509
510  let &mouse = save_mouse
511  let &term = save_term
512  let &ttymouse = save_ttymouse
513  call test_override('no_query_mouse', 0)
514endfunc
515
516func Test_term_mouse_drag_to_move_tab()
517  let save_mouse = &mouse
518  let save_term = &term
519  let save_ttymouse = &ttymouse
520  call test_override('no_query_mouse', 1)
521  " Set 'mousetime' to 1 to avoid recognizing a double-click in the loop
522  set mouse=a term=xterm mousetime=1
523  let row = 1
524
525  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
526    let msg = 'ttymouse=' .. ttymouse_val
527    exe 'set ttymouse=' .. ttymouse_val
528    e Xtab1
529    tabnew Xtab2
530
531    let a = split(execute(':tabs'), "\n")
532    call assert_equal(['Tab page 1',
533        \              '    Xtab1',
534        \              'Tab page 2',
535        \              '>   Xtab2'], a, msg)
536    redraw
537
538    " Click in tab2 and drag it to tab1.
539    " Check getcharmod() to verify that click is not
540    " interpreted as a spurious double-click.
541    call MouseLeftClick(row, 10)
542    call assert_equal(0, getcharmod(), msg)
543    for col in [9, 8, 7, 6]
544      call MouseLeftDrag(row, col)
545    endfor
546    call MouseLeftRelease(row, col)
547    let a = split(execute(':tabs'), "\n")
548    call assert_equal(['Tab page 1',
549        \              '>   Xtab2',
550        \              'Tab page 2',
551        \              '    Xtab1'], a, msg)
552
553    " Click elsewhere so that click in next iteration is not
554    " interpreted as unwanted double-click.
555    call MouseLeftClick(row, 11)
556    call MouseLeftRelease(row, 11)
557
558    %bwipe!
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  set mousetime&
566endfunc
567
568func Test_term_mouse_double_click_to_create_tab()
569  let save_mouse = &mouse
570  let save_term = &term
571  let save_ttymouse = &ttymouse
572  call test_override('no_query_mouse', 1)
573  " Set 'mousetime' to a small value, so that double-click works but we don't
574  " have to wait long to avoid a triple-click.
575  set mouse=a term=xterm mousetime=200
576  let row = 1
577  let col = 10
578
579  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
580    let msg = 'ttymouse=' .. ttymouse_val
581    exe 'set ttymouse=' .. ttymouse_val
582    e Xtab1
583    tabnew Xtab2
584
585    let a = split(execute(':tabs'), "\n")
586    call assert_equal(['Tab page 1',
587        \              '    Xtab1',
588        \              'Tab page 2',
589        \              '>   Xtab2'], a, msg)
590
591    redraw
592    call MouseLeftClick(row, col)
593    " Check getcharmod() to verify that first click is not
594    " interpreted as a spurious double-click.
595    call assert_equal(0, getcharmod(), msg)
596    call MouseLeftRelease(row, col)
597    call MouseLeftClick(row, col)
598    call assert_equal(32, getcharmod(), msg) " double-click
599    call MouseLeftRelease(row, col)
600    let a = split(execute(':tabs'), "\n")
601    call assert_equal(['Tab page 1',
602        \              '    Xtab1',
603        \              'Tab page 2',
604        \              '>   [No Name]',
605        \              'Tab page 3',
606        \              '    Xtab2'], a, msg)
607
608    " Click elsewhere so that click in next iteration is not
609    " interpreted as unwanted double click.
610    call MouseLeftClick(row, col + 1)
611    call MouseLeftRelease(row, col + 1)
612
613    %bwipe!
614  endfor
615
616  let &mouse = save_mouse
617  let &term = save_term
618  let &ttymouse = save_ttymouse
619  call test_override('no_query_mouse', 0)
620  set mousetime&
621endfunc
622
623" Test double/triple/quadruple click in normal mode to visually select.
624func Test_term_mouse_multiple_clicks_to_visually_select()
625  let save_mouse = &mouse
626  let save_term = &term
627  let save_ttymouse = &ttymouse
628  call test_override('no_query_mouse', 1)
629  set mouse=a term=xterm mousetime=200
630  new
631
632  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
633    let msg = 'ttymouse=' .. ttymouse_val
634    exe 'set ttymouse=' .. ttymouse_val
635    call setline(1, ['foo [foo bar] foo', 'foo'])
636
637    " Double-click on word should visually select the word.
638    call MouseLeftClick(1, 2)
639    call assert_equal(0, getcharmod(), msg)
640    call MouseLeftRelease(1, 2)
641    call MouseLeftClick(1, 2)
642    call assert_equal(32, getcharmod(), msg) " double-click
643    call MouseLeftRelease(1, 2)
644    call assert_equal('v', mode(), msg)
645    norm! r1
646    call assert_equal(['111 [foo bar] foo', 'foo'], getline(1, '$'), msg)
647
648    " Double-click on opening square bracket should visually
649    " select the whole [foo bar].
650    call MouseLeftClick(1, 5)
651    call assert_equal(0, getcharmod(), msg)
652    call MouseLeftRelease(1, 5)
653    call MouseLeftClick(1, 5)
654    call assert_equal(32, getcharmod(), msg) " double-click
655    call MouseLeftRelease(1, 5)
656    call assert_equal('v', mode(), msg)
657    norm! r2
658    call assert_equal(['111 222222222 foo', 'foo'], getline(1, '$'), msg)
659
660    " Triple-click should visually select the whole line.
661    call MouseLeftClick(1, 3)
662    call assert_equal(0, getcharmod(), msg)
663    call MouseLeftRelease(1, 3)
664    call MouseLeftClick(1, 3)
665    call assert_equal(32, getcharmod(), msg) " double-click
666    call MouseLeftRelease(1, 3)
667    call MouseLeftClick(1, 3)
668    call assert_equal(64, getcharmod(), msg) " triple-click
669    call MouseLeftRelease(1, 3)
670    call assert_equal('V', mode(), msg)
671    norm! r3
672    call assert_equal(['33333333333333333', 'foo'], getline(1, '$'), msg)
673
674    " Quadruple-click should start visual block select.
675    call MouseLeftClick(1, 2)
676    call assert_equal(0, getcharmod(), msg)
677    call MouseLeftRelease(1, 2)
678    call MouseLeftClick(1, 2)
679    call assert_equal(32, getcharmod(), msg) " double-click
680    call MouseLeftRelease(1, 2)
681    call MouseLeftClick(1, 2)
682    call assert_equal(64, getcharmod(), msg) " triple-click
683    call MouseLeftRelease(1, 2)
684    call MouseLeftClick(1, 2)
685    call assert_equal(96, getcharmod(), msg) " quadruple-click
686    call MouseLeftRelease(1, 2)
687    call assert_equal("\<c-v>", mode(), msg)
688    norm! r4
689    call assert_equal(['34333333333333333', 'foo'], getline(1, '$'), msg)
690  endfor
691
692  let &mouse = save_mouse
693  let &term = save_term
694  let &ttymouse = save_ttymouse
695  set mousetime&
696  call test_override('no_query_mouse', 0)
697  bwipe!
698endfunc
699
700func Test_xterm_mouse_click_in_fold_columns()
701  new
702  let save_mouse = &mouse
703  let save_term = &term
704  let save_ttymouse = &ttymouse
705  let save_foldcolumn = &foldcolumn
706  set mouse=a term=xterm foldcolumn=3 ttymouse=xterm2
707
708  " Create 2 nested folds.
709  call setline(1, range(1, 7))
710  2,6fold
711  norm! zR
712  4,5fold
713  call assert_equal([-1, -1, -1, 4, 4, -1, -1],
714        \           map(range(1, 7), 'foldclosed(v:val)'))
715
716  " Click in "+" of inner fold in foldcolumn should open it.
717  redraw
718  let row = 4
719  let col = 2
720  call MouseLeftClick(row, col)
721  call MouseLeftRelease(row, col)
722  call assert_equal([-1, -1, -1, -1, -1, -1, -1],
723        \           map(range(1, 7), 'foldclosed(v:val)'))
724
725  " Click in "-" of outer fold in foldcolumn should close it.
726  redraw
727  let row = 2
728  let col = 1
729  call MouseLeftClick(row, col)
730  call MouseLeftRelease(row, col)
731  call assert_equal([-1, 2, 2, 2, 2, 2, -1],
732        \           map(range(1, 7), 'foldclosed(v:val)'))
733  norm! zR
734
735  " Click in "|" of inner fold in foldcolumn should close it.
736  redraw
737  let row = 5
738  let col = 2
739  call MouseLeftClick(row, col)
740  call MouseLeftRelease(row, col)
741  call assert_equal([-1, -1, -1, 4, 4, -1, -1],
742        \           map(range(1, 7), 'foldclosed(v:val)'))
743
744  let &foldcolumn = save_foldcolumn
745  let &ttymouse = save_ttymouse
746  let &term = save_term
747  let &mouse = save_mouse
748  bwipe!
749endfunc
750
751" Left or right click in Ex command line sets position of the cursor.
752func Test_term_mouse_click_in_cmdline_to_set_pos()
753  let save_mouse = &mouse
754  let save_term = &term
755  let save_ttymouse = &ttymouse
756  call test_override('no_query_mouse', 1)
757  set mouse=a term=xterm
758  let row = &lines
759
760  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
761    let msg = 'ttymouse=' .. ttymouse_val
762    exe 'set ttymouse=' .. ttymouse_val
763
764    call feedkeys(':"3456789'
765          \       .. MouseLeftClickCode(row, 7)
766          \       .. MouseLeftReleaseCode(row, 7) .. 'L'
767          \       .. MouseRightClickCode(row, 4)
768          \       .. MouseRightReleaseCode(row, 4) .. 'R'
769          \       .. "\<CR>", 'Lx!')
770    call assert_equal('"3R456L789', @:, msg)
771  endfor
772
773  let &mouse = save_mouse
774  let &term = save_term
775  let &ttymouse = save_ttymouse
776  set mousetime&
777  call test_override('no_query_mouse', 0)
778endfunc
779
780" Middle click in command line pastes at position of cursor.
781func Test_term_mouse_middle_click_in_cmdline_to_paste()
782  CheckFeature clipboard_working
783  let save_mouse = &mouse
784  let save_term = &term
785  let save_ttymouse = &ttymouse
786  call test_override('no_query_mouse', 1)
787  set mouse=a term=xterm
788  let row = &lines
789  " Column values does not matter, paste is done at position of cursor.
790  let col = 1
791  let @* = 'paste'
792
793  for ttymouse_val in g:Ttymouse_values + g:Ttymouse_dec
794    let msg = 'ttymouse=' .. ttymouse_val
795    exe 'set ttymouse=' .. ttymouse_val
796
797    call feedkeys(":\"->"
798          \       .. MouseMiddleReleaseCode(row, col)
799          \       .. MouseMiddleClickCode(row, col)
800          \       .. "<-"
801          \       .. MouseMiddleReleaseCode(row, col)
802          \       .. MouseMiddleClickCode(row, col)
803          \       .. "\<CR>", 'Lx!')
804    call assert_equal('"->paste<-paste', @:, msg)
805  endfor
806
807  let &mouse = save_mouse
808  let &term = save_term
809  let &ttymouse = save_ttymouse
810  let @* = ''
811  call test_override('no_query_mouse', 0)
812endfunc
813
814" Test for displaying the popup menu using the right mouse click
815func Test_mouse_popup_menu()
816  CheckFeature menu
817  new
818  call setline(1, 'popup menu test')
819  let save_mouse = &mouse
820  let save_term = &term
821  let save_ttymouse = &ttymouse
822  let save_mousemodel = &mousemodel
823  call test_override('no_query_mouse', 1)
824  set mouse=a term=xterm mousemodel=popup
825
826  menu PopUp.foo :let g:menustr = 'foo'<CR>
827  menu PopUp.bar :let g:menustr = 'bar'<CR>
828  menu PopUp.baz :let g:menustr = 'baz'<CR>
829
830  for ttymouse_val in g:Ttymouse_values
831    exe 'set ttymouse=' .. ttymouse_val
832    let g:menustr = ''
833    call feedkeys(MouseRightClickCode(1, 4)
834		\ .. MouseRightReleaseCode(1, 4) .. "\<Down>\<Down>\<CR>", "x")
835    call assert_equal('bar', g:menustr)
836  endfor
837
838  unmenu PopUp
839  let &mouse = save_mouse
840  let &term = save_term
841  let &ttymouse = save_ttymouse
842  let &mousemodel = save_mousemodel
843  call test_override('no_query_mouse', 0)
844  close!
845endfunc
846
847" This only checks if the sequence is recognized.
848func Test_term_rgb_response()
849  set t_RF=x
850  set t_RB=y
851
852  " response to t_RF, 4 digits
853  let red = 0x12
854  let green = 0x34
855  let blue = 0x56
856  let seq = printf("\<Esc>]10;rgb:%02x00/%02x00/%02x00\x07", red, green, blue)
857  call feedkeys(seq, 'Lx!')
858  call assert_equal(seq, v:termrfgresp)
859
860  " response to t_RF, 2 digits
861  let red = 0x78
862  let green = 0x9a
863  let blue = 0xbc
864  let seq = printf("\<Esc>]10;rgb:%02x/%02x/%02x\x07", red, green, blue)
865  call feedkeys(seq, 'Lx!')
866  call assert_equal(seq, v:termrfgresp)
867
868  " response to t_RB, 4 digits, dark
869  set background=light
870  eval 'background'->test_option_not_set()
871  let red = 0x29
872  let green = 0x4a
873  let blue = 0x6b
874  let seq = printf("\<Esc>]11;rgb:%02x00/%02x00/%02x00\x07", red, green, blue)
875  call feedkeys(seq, 'Lx!')
876  call assert_equal(seq, v:termrbgresp)
877  call assert_equal('dark', &background)
878
879  " response to t_RB, 4 digits, light
880  set background=dark
881  call test_option_not_set('background')
882  let red = 0x81
883  let green = 0x63
884  let blue = 0x65
885  let seq = printf("\<Esc>]11;rgb:%02x00/%02x00/%02x00\x07", red, green, blue)
886  call feedkeys(seq, 'Lx!')
887  call assert_equal(seq, v:termrbgresp)
888  call assert_equal('light', &background)
889
890  " response to t_RB, 2 digits, dark
891  set background=light
892  call test_option_not_set('background')
893  let red = 0x47
894  let green = 0x59
895  let blue = 0x5b
896  let seq = printf("\<Esc>]11;rgb:%02x/%02x/%02x\x07", red, green, blue)
897  call feedkeys(seq, 'Lx!')
898  call assert_equal(seq, v:termrbgresp)
899  call assert_equal('dark', &background)
900
901  " response to t_RB, 2 digits, light
902  set background=dark
903  call test_option_not_set('background')
904  let red = 0x83
905  let green = 0xa4
906  let blue = 0xc2
907  let seq = printf("\<Esc>]11;rgb:%02x/%02x/%02x\x07", red, green, blue)
908  call feedkeys(seq, 'Lx!')
909  call assert_equal(seq, v:termrbgresp)
910  call assert_equal('light', &background)
911
912  set t_RF= t_RB=
913endfunc
914
915" This only checks if the sequence is recognized.
916" This must be after other tests, because it has side effects to xterm
917" properties.
918func Test_xx01_term_style_response()
919  " Termresponse is only parsed when t_RV is not empty.
920  set t_RV=x
921
922  " send the termresponse to trigger requesting the XT codes
923  let seq = "\<Esc>[>41;337;0c"
924  call feedkeys(seq, 'Lx!')
925  call assert_equal(seq, v:termresponse)
926
927  let seq = "\<Esc>P1$r2 q\<Esc>\\"
928  call feedkeys(seq, 'Lx!')
929  call assert_equal(seq, v:termstyleresp)
930
931  set t_RV=
932endfunc
933
934" This checks the iTerm2 version response.
935" This must be after other tests, because it has side effects to xterm
936" properties.
937func Test_xx02_iTerm2_response()
938  " Termresponse is only parsed when t_RV is not empty.
939  set t_RV=x
940
941  " Old versions of iTerm2 used a different style term response.
942  set ttymouse=xterm
943  call test_option_not_set('ttymouse')
944  let seq = "\<Esc>[>0;95;c"
945  call feedkeys(seq, 'Lx!')
946  call assert_equal(seq, v:termresponse)
947  call assert_equal('xterm', &ttymouse)
948
949  set ttymouse=xterm
950  call test_option_not_set('ttymouse')
951  let seq = "\<Esc>[>0;95;0c"
952  call feedkeys(seq, 'Lx!')
953  call assert_equal(seq, v:termresponse)
954  call assert_equal('sgr', &ttymouse)
955
956  set t_RV=
957endfunc
958
959" This checks the libvterm version response.
960" This must be after other tests, because it has side effects to xterm
961" properties.
962func Test_xx03_libvterm_response()
963  " Termresponse is only parsed when t_RV is not empty.
964  set t_RV=x
965
966  set ttymouse=xterm
967  call test_option_not_set('ttymouse')
968  let seq = "\<Esc>[>0;100;0c"
969  call feedkeys(seq, 'Lx!')
970  call assert_equal(seq, v:termresponse)
971  call assert_equal('sgr', &ttymouse)
972
973  set t_RV=
974endfunc
975
976" This checks the Mac Terminal.app version response.
977" This must be after other tests, because it has side effects to xterm
978" properties.
979func Test_xx04_Mac_Terminal_response()
980  " Termresponse is only parsed when t_RV is not empty.
981  set t_RV=x
982
983  set ttymouse=xterm
984  call test_option_not_set('ttymouse')
985  let seq = "\<Esc>[>1;95;0c"
986  call feedkeys(seq, 'Lx!')
987  call assert_equal(seq, v:termresponse)
988  call assert_equal('sgr', &ttymouse)
989
990  " Reset is_not_xterm and is_mac_terminal.
991  set t_RV=
992  set term=xterm
993  set t_RV=x
994endfunc
995
996" This checks the mintty version response.
997" This must be after other tests, because it has side effects to xterm
998" properties.
999func Test_xx05_mintty_response()
1000  " Termresponse is only parsed when t_RV is not empty.
1001  set t_RV=x
1002
1003  set ttymouse=xterm
1004  call test_option_not_set('ttymouse')
1005  let seq = "\<Esc>[>77;20905;0c"
1006  call feedkeys(seq, 'Lx!')
1007  call assert_equal(seq, v:termresponse)
1008  call assert_equal('sgr', &ttymouse)
1009
1010  set t_RV=
1011endfunc
1012
1013" This checks the screen version response.
1014" This must be after other tests, because it has side effects to xterm
1015" properties.
1016func Test_xx06_screen_response()
1017  " Termresponse is only parsed when t_RV is not empty.
1018  set t_RV=x
1019
1020  " Old versions of screen don't support SGR mouse mode.
1021  set ttymouse=xterm
1022  call test_option_not_set('ttymouse')
1023  let seq = "\<Esc>[>83;40500;0c"
1024  call feedkeys(seq, 'Lx!')
1025  call assert_equal(seq, v:termresponse)
1026  call assert_equal('xterm', &ttymouse)
1027
1028  " screen supports SGR mouse mode starting in version 4.7.
1029  set ttymouse=xterm
1030  call test_option_not_set('ttymouse')
1031  let seq = "\<Esc>[>83;40700;0c"
1032  call feedkeys(seq, 'Lx!')
1033  call assert_equal(seq, v:termresponse)
1034  call assert_equal('sgr', &ttymouse)
1035
1036  set t_RV=
1037endfunc
1038
1039" This checks the xterm version response.
1040" This must be after other tests, because it has side effects to xterm
1041" properties.
1042func Test_xx07_xterm_response()
1043  " Termresponse is only parsed when t_RV is not empty.
1044  set t_RV=x
1045
1046  " Do Terminal.app first to check that is_mac_terminal is reset.
1047  set ttymouse=xterm
1048  call test_option_not_set('ttymouse')
1049  let seq = "\<Esc>[>1;95;0c"
1050  call feedkeys(seq, 'Lx!')
1051  call assert_equal(seq, v:termresponse)
1052  call assert_equal('sgr', &ttymouse)
1053
1054  " xterm < 95: "xterm" (actually unmodified)
1055  set t_RV=
1056  set term=xterm
1057  set t_RV=x
1058  set ttymouse=xterm
1059  call test_option_not_set('ttymouse')
1060  let seq = "\<Esc>[>0;94;0c"
1061  call feedkeys(seq, 'Lx!')
1062  call assert_equal(seq, v:termresponse)
1063  call assert_equal('xterm', &ttymouse)
1064
1065  " xterm >= 95 < 277 "xterm2"
1066  set ttymouse=xterm
1067  call test_option_not_set('ttymouse')
1068  let seq = "\<Esc>[>0;267;0c"
1069  call feedkeys(seq, 'Lx!')
1070  call assert_equal(seq, v:termresponse)
1071  call assert_equal('xterm2', &ttymouse)
1072
1073  " xterm >= 277: "sgr"
1074  set ttymouse=xterm
1075  call test_option_not_set('ttymouse')
1076  let seq = "\<Esc>[>0;277;0c"
1077  call feedkeys(seq, 'Lx!')
1078  call assert_equal(seq, v:termresponse)
1079  call assert_equal('sgr', &ttymouse)
1080
1081  set t_RV=
1082endfunc
1083
1084func Test_get_termcode()
1085  try
1086    let k1 = &t_k1
1087  catch /E113/
1088    throw 'Skipped: Unable to query termcodes'
1089  endtry
1090  set t_k1=
1091  set t_k1&
1092  call assert_equal(k1, &t_k1)
1093
1094  " use external termcap first
1095  set nottybuiltin
1096  set t_k1=
1097  set t_k1&
1098  " when using external termcap may get something else, but it must not be
1099  " empty, since we would fallback to the builtin one.
1100  call assert_notequal('', &t_k1)
1101
1102  if &term =~ 'xterm'
1103    " use internal termcap first
1104    let term_save = &term
1105    let &term = 'builtin_' .. &term
1106    set t_k1=
1107    set t_k1&
1108    call assert_equal(k1, &t_k1)
1109    let &term = term_save
1110  endif
1111
1112  set ttybuiltin
1113endfunc
1114
1115func GetEscCodeCSI27(key, modifier)
1116  let key = printf("%d", char2nr(a:key))
1117  let mod = printf("%d", a:modifier)
1118  return "\<Esc>[27;" .. mod .. ';' .. key .. '~'
1119endfunc
1120
1121func GetEscCodeCSIu(key, modifier)
1122  let key = printf("%d", char2nr(a:key))
1123  let mod = printf("%d", a:modifier)
1124  return "\<Esc>[" .. key .. ';' .. mod .. 'u'
1125endfunc
1126
1127" This checks the CSI sequences when in modifyOtherKeys mode.
1128" The mode doesn't need to be enabled, the codes are always detected.
1129func RunTest_modifyOtherKeys(func)
1130  new
1131  set timeoutlen=10
1132
1133  " Shift-X is sent as 'X' with the shift modifier
1134  call feedkeys('a' .. a:func('X', 2) .. "\<Esc>", 'Lx!')
1135  call assert_equal('X', getline(1))
1136
1137  " Ctrl-i is Tab
1138  call setline(1, '')
1139  call feedkeys('a' .. a:func('i', 5) .. "\<Esc>", 'Lx!')
1140  call assert_equal("\t", getline(1))
1141
1142  " Ctrl-I is also Tab
1143  call setline(1, '')
1144  call feedkeys('a' .. a:func('I', 5) .. "\<Esc>", 'Lx!')
1145  call assert_equal("\t", getline(1))
1146
1147  " Alt-x is ø
1148  call setline(1, '')
1149  call feedkeys('a' .. a:func('x', 3) .. "\<Esc>", 'Lx!')
1150  call assert_equal("ø", getline(1))
1151
1152  " Meta-x is also ø
1153  call setline(1, '')
1154  call feedkeys('a' .. a:func('x', 9) .. "\<Esc>", 'Lx!')
1155  call assert_equal("ø", getline(1))
1156
1157  " Alt-X is Ø
1158  call setline(1, '')
1159  call feedkeys('a' .. a:func('X', 3) .. "\<Esc>", 'Lx!')
1160  call assert_equal("Ø", getline(1))
1161
1162  " Meta-X is ø
1163  call setline(1, '')
1164  call feedkeys('a' .. a:func('X', 9) .. "\<Esc>", 'Lx!')
1165  call assert_equal("Ø", getline(1))
1166
1167  " Ctrl-6 is Ctrl-^
1168  split aaa
1169  edit bbb
1170  call feedkeys(a:func('6', 5), 'Lx!')
1171  call assert_equal("aaa", bufname())
1172  bwipe aaa
1173  bwipe bbb
1174
1175  bwipe!
1176  set timeoutlen&
1177endfunc
1178
1179func Test_modifyOtherKeys_basic()
1180  call RunTest_modifyOtherKeys(function('GetEscCodeCSI27'))
1181  call RunTest_modifyOtherKeys(function('GetEscCodeCSIu'))
1182endfunc
1183
1184func Test_modifyOtherKeys_no_mapping()
1185  set timeoutlen=10
1186
1187  let @a = 'aaa'
1188  call feedkeys(":let x = '" .. GetEscCodeCSI27('R', 5) .. GetEscCodeCSI27('R', 5) .. "a'\<CR>", 'Lx!')
1189  call assert_equal("let x = 'aaa'", @:)
1190
1191  new
1192  call feedkeys("a" .. GetEscCodeCSI27('R', 5) .. GetEscCodeCSI27('R', 5) .. "a\<Esc>", 'Lx!')
1193  call assert_equal("aaa", getline(1))
1194  bwipe!
1195
1196  new
1197  call feedkeys("axx\<CR>yy" .. GetEscCodeCSI27('G', 5) .. GetEscCodeCSI27('K', 5) .. "a\<Esc>", 'Lx!')
1198  call assert_equal("axx", getline(1))
1199  call assert_equal("yy", getline(2))
1200  bwipe!
1201
1202  set timeoutlen&
1203endfunc
1204
1205func RunTest_mapping_shift(key, func)
1206  call setline(1, '')
1207  if a:key == '|'
1208    exe 'inoremap \| xyz'
1209  else
1210    exe 'inoremap ' .. a:key .. ' xyz'
1211  endif
1212  call feedkeys('a' .. a:func(a:key, 2) .. "\<Esc>", 'Lx!')
1213  call assert_equal("xyz", getline(1))
1214  if a:key == '|'
1215    exe 'iunmap \|'
1216  else
1217    exe 'iunmap ' .. a:key
1218  endif
1219endfunc
1220
1221func RunTest_mapping_works_with_shift(func)
1222  new
1223  set timeoutlen=10
1224
1225  call RunTest_mapping_shift('@', a:func)
1226  call RunTest_mapping_shift('A', a:func)
1227  call RunTest_mapping_shift('Z', a:func)
1228  call RunTest_mapping_shift('^', a:func)
1229  call RunTest_mapping_shift('_', a:func)
1230  call RunTest_mapping_shift('{', a:func)
1231  call RunTest_mapping_shift('|', a:func)
1232  call RunTest_mapping_shift('}', a:func)
1233  call RunTest_mapping_shift('~', a:func)
1234
1235  bwipe!
1236  set timeoutlen&
1237endfunc
1238
1239func Test_mapping_works_with_shift_plain()
1240  call RunTest_mapping_works_with_shift(function('GetEscCodeCSI27'))
1241  call RunTest_mapping_works_with_shift(function('GetEscCodeCSIu'))
1242endfunc
1243
1244func RunTest_mapping_mods(map, key, func, code)
1245  call setline(1, '')
1246  exe 'inoremap ' .. a:map .. ' xyz'
1247  call feedkeys('a' .. a:func(a:key, a:code) .. "\<Esc>", 'Lx!')
1248  call assert_equal("xyz", getline(1))
1249  exe 'iunmap ' .. a:map
1250endfunc
1251
1252func RunTest_mapping_works_with_mods(func, mods, code)
1253  new
1254  set timeoutlen=10
1255
1256  if a:mods !~ 'S'
1257    " Shift by itself has no effect
1258    call RunTest_mapping_mods('<' .. a:mods .. '-@>', '@', a:func, a:code)
1259  endif
1260  call RunTest_mapping_mods('<' .. a:mods .. '-A>', 'A', a:func, a:code)
1261  call RunTest_mapping_mods('<' .. a:mods .. '-Z>', 'Z', a:func, a:code)
1262  if a:mods !~ 'S'
1263    " with Shift code is always upper case
1264    call RunTest_mapping_mods('<' .. a:mods .. '-a>', 'a', a:func, a:code)
1265    call RunTest_mapping_mods('<' .. a:mods .. '-z>', 'z', a:func, a:code)
1266  endif
1267  if a:mods != 'A'
1268    " with Alt code is not in upper case
1269    call RunTest_mapping_mods('<' .. a:mods .. '-a>', 'A', a:func, a:code)
1270    call RunTest_mapping_mods('<' .. a:mods .. '-z>', 'Z', a:func, a:code)
1271  endif
1272  call RunTest_mapping_mods('<' .. a:mods .. '-á>', 'á', a:func, a:code)
1273  if a:mods !~ 'S'
1274    " Shift by itself has no effect
1275    call RunTest_mapping_mods('<' .. a:mods .. '-^>', '^', a:func, a:code)
1276    call RunTest_mapping_mods('<' .. a:mods .. '-_>', '_', a:func, a:code)
1277    call RunTest_mapping_mods('<' .. a:mods .. '-{>', '{', a:func, a:code)
1278    call RunTest_mapping_mods('<' .. a:mods .. '-\|>', '|', a:func, a:code)
1279    call RunTest_mapping_mods('<' .. a:mods .. '-}>', '}', a:func, a:code)
1280    call RunTest_mapping_mods('<' .. a:mods .. '-~>', '~', a:func, a:code)
1281  endif
1282
1283  bwipe!
1284  set timeoutlen&
1285endfunc
1286
1287func Test_mapping_works_with_shift()
1288  call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'S', 2)
1289  call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'S', 2)
1290endfunc
1291
1292func Test_mapping_works_with_ctrl()
1293  call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C', 5)
1294  call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C', 5)
1295endfunc
1296
1297func Test_mapping_works_with_shift_ctrl()
1298  call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-S', 6)
1299  call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-S', 6)
1300endfunc
1301
1302" Below we also test the "u" code with Alt, This works, but libvterm would not
1303" send the Alt key like this but by prefixing an Esc.
1304
1305func Test_mapping_works_with_alt()
1306  call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'A', 3)
1307  call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'A', 3)
1308endfunc
1309
1310func Test_mapping_works_with_shift_alt()
1311  call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'S-A', 4)
1312  call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'S-A', 4)
1313endfunc
1314
1315func Test_mapping_works_with_ctrl_alt()
1316  call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-A', 7)
1317  call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-A', 7)
1318endfunc
1319
1320func Test_mapping_works_with_shift_ctrl_alt()
1321  call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-S-A', 8)
1322  call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-S-A', 8)
1323endfunc
1324
1325func Test_insert_literal()
1326  set timeoutlen=10
1327  new
1328  " CTRL-V CTRL-X inserts a ^X
1329  call feedkeys('a' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu('X', '5') .. "\<Esc>", 'Lx!')
1330  call assert_equal("\<C-X>", getline(1))
1331
1332  call setline(1, '')
1333  call feedkeys('a' .. GetEscCodeCSI27('V', '5') .. GetEscCodeCSI27('X', '5') .. "\<Esc>", 'Lx!')
1334  call assert_equal("\<C-X>", getline(1))
1335
1336  " CTRL-SHIFT-V CTRL-X inserts escape sequence
1337  call setline(1, '')
1338  call feedkeys('a' .. GetEscCodeCSIu('V', '6') .. GetEscCodeCSIu('X', '5') .. "\<Esc>", 'Lx!')
1339  call assert_equal("\<Esc>[88;5u", getline(1))
1340
1341  call setline(1, '')
1342  call feedkeys('a' .. GetEscCodeCSI27('V', '6') .. GetEscCodeCSI27('X', '5') .. "\<Esc>", 'Lx!')
1343  call assert_equal("\<Esc>[27;5;88~", getline(1))
1344
1345  bwipe!
1346  set timeoutlen&
1347endfunc
1348
1349func Test_cmdline_literal()
1350  set timeoutlen=10
1351
1352  " CTRL-V CTRL-Y inserts a ^Y
1353  call feedkeys(':' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!')
1354  call assert_equal("\"\<C-Y>", @:)
1355
1356  call feedkeys(':' .. GetEscCodeCSI27('V', '5') .. GetEscCodeCSI27('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!')
1357  call assert_equal("\"\<C-Y>", @:)
1358
1359  " CTRL-SHIFT-V CTRL-Y inserts escape sequence
1360  call feedkeys(':' .. GetEscCodeCSIu('V', '6') .. GetEscCodeCSIu('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!')
1361  call assert_equal("\"\<Esc>[89;5u", @:)
1362
1363  call setline(1, '')
1364  call feedkeys(':' .. GetEscCodeCSI27('V', '6') .. GetEscCodeCSI27('Y', '5') .. "\<C-B>\"\<CR>", 'Lx!')
1365  call assert_equal("\"\<Esc>[27;5;89~", @:)
1366
1367  set timeoutlen&
1368endfunc
1369
1370" vim: shiftwidth=2 sts=2 expandtab
1371