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
9
10" xterm2 and sgr always work, urxvt is optional.
11let s:ttymouse_values = ['xterm2', 'sgr']
12if has('mouse_urxvt')
13  call add(s:ttymouse_values, 'urxvt')
14endif
15
16" dec doesn't support all the functionality
17if has('mouse_dec')
18  let s:ttymouse_dec = ['dec']
19else
20  let s:ttymouse_dec = []
21endif
22
23" netterm only supports left click
24if has('mouse_netterm')
25  let s:ttymouse_netterm = ['netterm']
26else
27  let s:ttymouse_netterm = []
28endif
29
30" Helper function to emit a terminal escape code.
31func TerminalEscapeCode(code, row, col, m)
32  if &ttymouse ==# 'xterm2'
33    " need to use byte encoding here.
34    let str = list2str([a:code + 0x20, a:col + 0x20, a:row + 0x20])
35    if has('iconv')
36      let bytes = str->iconv('utf-8', 'latin1')
37    else
38      " Hopefully the numbers are not too big.
39      let bytes = str
40    endif
41    call feedkeys("\<Esc>[M" .. bytes, 'Lx!')
42  elseif &ttymouse ==# 'sgr'
43    call feedkeys(printf("\<Esc>[<%d;%d;%d%s", a:code, a:col, a:row, a:m), 'Lx!')
44  elseif &ttymouse ==# 'urxvt'
45    call feedkeys(printf("\<Esc>[%d;%d;%dM", a:code + 0x20, a:col, a:row), 'Lx!')
46  endif
47endfunc
48
49func DecEscapeCode(code, down, row, col)
50    call feedkeys(printf("\<Esc>[%d;%d;%d;%d&w", a:code, a:down, a:row, a:col), 'Lx!')
51endfunc
52
53func NettermEscapeCode(row, col)
54    call feedkeys(printf("\<Esc>}%d,%d\r", a:row, a:col), 'Lx!')
55endfunc
56
57func MouseLeftClick(row, col)
58  if &ttymouse ==# 'dec'
59    call DecEscapeCode(2, 4, a:row, a:col)
60  elseif &ttymouse ==# 'netterm'
61    call NettermEscapeCode(a:row, a:col)
62  else
63    call TerminalEscapeCode(0, a:row, a:col, 'M')
64  endif
65endfunc
66
67func MouseMiddleClick(row, col)
68  if &ttymouse ==# 'dec'
69    call DecEscapeCode(4, 2, a:row, a:col)
70  else
71    call TerminalEscapeCode(1, a:row, a:col, 'M')
72  endif
73endfunc
74
75func MouseCtrlLeftClick(row, col)
76  let ctrl = 0x10
77  call TerminalEscapeCode(0 + ctrl, a:row, a:col, 'M')
78endfunc
79
80func MouseCtrlRightClick(row, col)
81  let ctrl = 0x10
82  call TerminalEscapeCode(2 + ctrl, a:row, a:col, 'M')
83endfunc
84
85func MouseLeftRelease(row, col)
86  if &ttymouse ==# 'dec'
87    call DecEscapeCode(3, 0, a:row, a:col)
88  elseif &ttymouse ==# 'netterm'
89    " send nothing
90  else
91    call TerminalEscapeCode(3, a:row, a:col, 'm')
92  endif
93endfunc
94
95func MouseMiddleRelease(row, col)
96  if &ttymouse ==# 'dec'
97    call DecEscapeCode(5, 0, a:row, a:col)
98  else
99    call TerminalEscapeCode(3, a:row, a:col, 'm')
100  endif
101endfunc
102
103func MouseRightRelease(row, col)
104  call TerminalEscapeCode(3, a:row, a:col, 'm')
105endfunc
106
107func MouseLeftDrag(row, col)
108  if &ttymouse ==# 'dec'
109    call DecEscapeCode(1, 4, a:row, a:col)
110  else
111    call TerminalEscapeCode(0x20, a:row, a:col, 'M')
112  endif
113endfunc
114
115func MouseWheelUp(row, col)
116  call TerminalEscapeCode(0x40, a:row, a:col, 'M')
117endfunc
118
119func MouseWheelDown(row, col)
120  call TerminalEscapeCode(0x41, a:row, a:col, 'M')
121endfunc
122
123func Test_term_mouse_left_click()
124  new
125  let save_mouse = &mouse
126  let save_term = &term
127  let save_ttymouse = &ttymouse
128  call test_override('no_query_mouse', 1)
129  set mouse=a term=xterm
130  call setline(1, ['line 1', 'line 2', 'line 3 is a bit longer'])
131
132  for ttymouse_val in s:ttymouse_values + s:ttymouse_dec + s:ttymouse_netterm
133    let msg = 'ttymouse=' .. ttymouse_val
134    exe 'set ttymouse=' .. ttymouse_val
135    go
136    call assert_equal([0, 1, 1, 0], getpos('.'), msg)
137    let row = 2
138    let col = 6
139    call MouseLeftClick(row, col)
140    call MouseLeftRelease(row, col)
141    call assert_equal([0, 2, 6, 0], getpos('.'), msg)
142  endfor
143
144  let &mouse = save_mouse
145  let &term = save_term
146  let &ttymouse = save_ttymouse
147  call test_override('no_query_mouse', 0)
148  bwipe!
149endfunc
150
151" Test that <C-LeftMouse> jumps to help tag and <C-RightMouse> jumps back.
152func Test_xterm_mouse_ctrl_click()
153  let save_mouse = &mouse
154  let save_term = &term
155  let save_ttymouse = &ttymouse
156  set mouse=a term=xterm
157
158  for ttymouse_val in s:ttymouse_values
159    let msg = 'ttymouse=' .. ttymouse_val
160    exe 'set ttymouse=' .. ttymouse_val
161    help
162    /usr_02.txt
163    norm! zt
164    let row = 1
165    let col = 1
166    call MouseCtrlLeftClick(row, col)
167    call MouseLeftRelease(row, col)
168    call assert_match('usr_02.txt$', bufname('%'), msg)
169    call assert_equal('*usr_02.txt*', expand('<cWORD>'), msg)
170
171    call MouseCtrlRightClick(row, col)
172    call MouseRightRelease(row, col)
173    call assert_match('help.txt$', bufname('%'), msg)
174    call assert_equal('|usr_02.txt|', expand('<cWORD>'), msg)
175
176    helpclose
177  endfor
178
179  let &mouse = save_mouse
180  let &term = save_term
181  let &ttymouse = save_ttymouse
182endfunc
183
184func Test_term_mouse_middle_click()
185  CheckFeature clipboard_working
186
187  new
188  let save_mouse = &mouse
189  let save_term = &term
190  let save_ttymouse = &ttymouse
191  call test_override('no_query_mouse', 1)
192  let save_quotestar = @*
193  let @* = 'abc'
194  set mouse=a term=xterm
195
196  for ttymouse_val in s:ttymouse_values + s:ttymouse_dec
197    let msg = 'ttymouse=' .. ttymouse_val
198    exe 'set ttymouse=' .. ttymouse_val
199    call setline(1, ['123456789', '123456789'])
200
201    " Middle-click in the middle of the line pastes text where clicked.
202    let row = 1
203    let col = 6
204    call MouseMiddleClick(row, col)
205    call MouseMiddleRelease(row, col)
206    call assert_equal(['12345abc6789', '123456789'], getline(1, '$'), msg)
207
208    " Middle-click beyond end of the line pastes text at the end of the line.
209    let col = 20
210    call MouseMiddleClick(row, col)
211    call MouseMiddleRelease(row, col)
212    call assert_equal(['12345abc6789abc', '123456789'], getline(1, '$'), msg)
213
214    " Middle-click beyond the last line pastes in the last line.
215    let row = 5
216    let col = 3
217    call MouseMiddleClick(row, col)
218    call MouseMiddleRelease(row, col)
219    call assert_equal(['12345abc6789abc', '12abc3456789'], getline(1, '$'), msg)
220  endfor
221
222  let &mouse = save_mouse
223  let &term = save_term
224  let &ttymouse = save_ttymouse
225  call test_override('no_query_mouse', 0)
226  let @* = save_quotestar
227  bwipe!
228endfunc
229
230" TODO: for unclear reasons this test fails if it comes after
231" Test_xterm_mouse_ctrl_click()
232func Test_1xterm_mouse_wheel()
233  new
234  let save_mouse = &mouse
235  let save_term = &term
236  let save_ttymouse = &ttymouse
237  set mouse=a term=xterm
238  call setline(1, range(1, 100))
239
240  for ttymouse_val in s:ttymouse_values
241    let msg = 'ttymouse=' .. ttymouse_val
242    exe 'set ttymouse=' .. ttymouse_val
243    go
244    call assert_equal(1, line('w0'), msg)
245    call assert_equal([0, 1, 1, 0], getpos('.'), msg)
246
247    call MouseWheelDown(1, 1)
248    call assert_equal(4, line('w0'), msg)
249    call assert_equal([0, 4, 1, 0], getpos('.'), msg)
250
251    call MouseWheelDown(1, 1)
252    call assert_equal(7, line('w0'), msg)
253    call assert_equal([0, 7, 1, 0], getpos('.'), msg)
254
255    call MouseWheelUp(1, 1)
256    call assert_equal(4, line('w0'), msg)
257    call assert_equal([0, 7, 1, 0], getpos('.'), msg)
258
259    call MouseWheelUp(1, 1)
260    call assert_equal(1, line('w0'), msg)
261    call assert_equal([0, 7, 1, 0], getpos('.'), msg)
262  endfor
263
264  let &mouse = save_mouse
265  let &term = save_term
266  let &ttymouse = save_ttymouse
267  bwipe!
268endfunc
269
270" Test that dragging beyond the window (at the bottom and at the top)
271" scrolls window content by the number of of lines beyond the window.
272func Test_term_mouse_drag_beyond_window()
273  let save_mouse = &mouse
274  let save_term = &term
275  let save_ttymouse = &ttymouse
276  call test_override('no_query_mouse', 1)
277  set mouse=a term=xterm
278  let col = 1
279  call setline(1, range(1, 100))
280
281  " Split into 3 windows, and go into the middle window
282  " so we test dragging mouse below and above the window.
283  2split
284  wincmd j
285  2split
286
287  for ttymouse_val in s:ttymouse_values + s:ttymouse_dec
288    let msg = 'ttymouse=' .. ttymouse_val
289    exe 'set ttymouse=' .. ttymouse_val
290
291    " Line #10 at the top.
292    norm! 10zt
293    redraw
294    call assert_equal(10, winsaveview().topline, msg)
295    call assert_equal(2, winheight(0), msg)
296
297    let row = 4
298    call MouseLeftClick(row, col)
299    call assert_equal(10, winsaveview().topline, msg)
300
301    " Drag downwards. We're still in the window so topline should
302    " not change yet.
303    let row += 1
304    call MouseLeftDrag(row, col)
305    call assert_equal(10, winsaveview().topline, msg)
306
307    " We now leave the window at the bottom, so the window content should
308    " scroll by 1 line, then 2 lines (etc) as we drag further away.
309    let row += 1
310    call MouseLeftDrag(row, col)
311    call assert_equal(11, winsaveview().topline, msg)
312
313    let row += 1
314    call MouseLeftDrag(row, col)
315    call assert_equal(13, winsaveview().topline, msg)
316
317    " Now drag upwards.
318    let row -= 1
319    call MouseLeftDrag(row, col)
320    call assert_equal(14, winsaveview().topline, msg)
321
322    " We're now back in the window so the topline should not change.
323    let row -= 1
324    call MouseLeftDrag(row, col)
325    call assert_equal(14, winsaveview().topline, msg)
326
327    let row -= 1
328    call MouseLeftDrag(row, col)
329    call assert_equal(14, winsaveview().topline, msg)
330
331    " We now leave the window at the top so the window content should
332    " scroll by 1 line, then 2, then 3 (etc) in the opposite direction.
333    let row -= 1
334    call MouseLeftDrag(row, col)
335    call assert_equal(13, winsaveview().topline, msg)
336
337    let row -= 1
338    call MouseLeftDrag(row, col)
339    call assert_equal(11, winsaveview().topline, msg)
340
341    let row -= 1
342    call MouseLeftDrag(row, col)
343    call assert_equal(8, winsaveview().topline, msg)
344
345    call MouseLeftRelease(row, col)
346    call assert_equal(8, winsaveview().topline, msg)
347    call assert_equal(2, winheight(0), msg)
348  endfor
349
350  let &mouse = save_mouse
351  let &term = save_term
352  let &ttymouse = save_ttymouse
353  call test_override('no_query_mouse', 0)
354  bwipe!
355endfunc
356
357func Test_term_mouse_drag_window_separator()
358  let save_mouse = &mouse
359  let save_term = &term
360  let save_ttymouse = &ttymouse
361  call test_override('no_query_mouse', 1)
362  set mouse=a term=xterm
363
364  for ttymouse_val in s:ttymouse_values + s:ttymouse_dec
365    let msg = 'ttymouse=' .. ttymouse_val
366    exe 'set ttymouse=' .. ttymouse_val
367
368    " Split horizontally and test dragging the horizontal window separator.
369    split
370    let rowseparator = winheight(0) + 1
371    let row = rowseparator
372    let col = 1
373
374    " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
375    if ttymouse_val !=# 'xterm2' || row <= 223
376      call MouseLeftClick(row, col)
377      let row -= 1
378      call MouseLeftDrag(row, col)
379      call assert_equal(rowseparator - 1, winheight(0) + 1, msg)
380      let row += 1
381      call MouseLeftDrag(row, col)
382      call assert_equal(rowseparator, winheight(0) + 1, msg)
383      call MouseLeftRelease(row, col)
384      call assert_equal(rowseparator, winheight(0) + 1, msg)
385    endif
386    bwipe!
387
388    " Split vertically and test dragging the vertical window separator.
389    vsplit
390    let colseparator = winwidth(0) + 1
391    let row = 1
392    let col = colseparator
393
394    " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
395    if ttymouse_val !=# 'xterm2' || col <= 223
396      call MouseLeftClick(row, col)
397      let col -= 1
398      call MouseLeftDrag(row, col)
399      call assert_equal(colseparator - 1, winwidth(0) + 1, msg)
400      let col += 1
401      call MouseLeftDrag(row, col)
402      call assert_equal(colseparator, winwidth(0) + 1, msg)
403      call MouseLeftRelease(row, col)
404      call assert_equal(colseparator, winwidth(0) + 1, msg)
405    endif
406    bwipe!
407  endfor
408
409  let &mouse = save_mouse
410  let &term = save_term
411  let &ttymouse = save_ttymouse
412  call test_override('no_query_mouse', 0)
413endfunc
414
415func Test_term_mouse_drag_statusline()
416  let save_mouse = &mouse
417  let save_term = &term
418  let save_ttymouse = &ttymouse
419  call test_override('no_query_mouse', 1)
420  let save_laststatus = &laststatus
421  set mouse=a term=xterm laststatus=2
422
423  for ttymouse_val in s:ttymouse_values + s:ttymouse_dec
424    let msg = 'ttymouse=' .. ttymouse_val
425    exe 'set ttymouse=' .. ttymouse_val
426
427    call assert_equal(1, &cmdheight, msg)
428    let rowstatusline = winheight(0) + 1
429    let row = rowstatusline
430    let col = 1
431
432    if ttymouse_val ==# 'xterm2' && row > 223
433      " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
434      continue
435    endif
436
437    call MouseLeftClick(row, col)
438    let row -= 1
439    call MouseLeftDrag(row, col)
440    call assert_equal(2, &cmdheight, msg)
441    call assert_equal(rowstatusline - 1, winheight(0) + 1, msg)
442    let row += 1
443    call MouseLeftDrag(row, col)
444    call assert_equal(1, &cmdheight, msg)
445    call assert_equal(rowstatusline, winheight(0) + 1, msg)
446    call MouseLeftRelease(row, col)
447    call assert_equal(1, &cmdheight, msg)
448    call assert_equal(rowstatusline, winheight(0) + 1, msg)
449  endfor
450
451  let &mouse = save_mouse
452  let &term = save_term
453  let &ttymouse = save_ttymouse
454  call test_override('no_query_mouse', 0)
455  let &laststatus = save_laststatus
456endfunc
457
458func Test_term_mouse_click_tab()
459  let save_mouse = &mouse
460  let save_term = &term
461  let save_ttymouse = &ttymouse
462  call test_override('no_query_mouse', 1)
463  set mouse=a term=xterm
464  let row = 1
465
466  for ttymouse_val in s:ttymouse_values + s:ttymouse_dec + s:ttymouse_netterm
467    let msg = 'ttymouse=' .. ttymouse_val
468    exe 'set ttymouse=' .. ttymouse_val
469    e Xfoo
470    tabnew Xbar
471
472    let a = split(execute(':tabs'), "\n")
473    call assert_equal(['Tab page 1',
474        \              '    Xfoo',
475        \              'Tab page 2',
476        \              '>   Xbar'], a, msg)
477
478    " Test clicking on tab names in the tabline at the top.
479    let col = 2
480    redraw
481    call MouseLeftClick(row, col)
482    call MouseLeftRelease(row, col)
483    let a = split(execute(':tabs'), "\n")
484    call assert_equal(['Tab page 1',
485        \              '>   Xfoo',
486        \              'Tab page 2',
487        \              '    Xbar'], a, msg)
488
489    let col = 9
490    call MouseLeftClick(row, col)
491    call MouseLeftRelease(row, col)
492    let a = split(execute(':tabs'), "\n")
493    call assert_equal(['Tab page 1',
494        \              '    Xfoo',
495        \              'Tab page 2',
496        \              '>   Xbar'], a, msg)
497
498    %bwipe!
499  endfor
500
501  let &mouse = save_mouse
502  let &term = save_term
503  let &ttymouse = save_ttymouse
504  call test_override('no_query_mouse', 0)
505endfunc
506
507func Test_term_mouse_click_X_to_close_tab()
508  let save_mouse = &mouse
509  let save_term = &term
510  let save_ttymouse = &ttymouse
511  call test_override('no_query_mouse', 1)
512  set mouse=a term=xterm
513  let row = 1
514  let col = &columns
515
516  for ttymouse_val in s:ttymouse_values + s:ttymouse_dec + s:ttymouse_netterm
517    if ttymouse_val ==# 'xterm2' && col > 223
518      " When 'ttymouse' is 'xterm2', row/col bigger than 223 are not supported.
519      continue
520    endif
521    let msg = 'ttymouse=' .. ttymouse_val
522    exe 'set ttymouse=' .. ttymouse_val
523    e Xtab1
524    tabnew Xtab2
525    tabnew Xtab3
526    tabn 2
527
528    let a = split(execute(':tabs'), "\n")
529    call assert_equal(['Tab page 1',
530        \              '    Xtab1',
531        \              'Tab page 2',
532        \              '>   Xtab2',
533        \              'Tab page 3',
534        \              '    Xtab3'], a, msg)
535
536    " Click on "X" in tabline to close current tab i.e. Xtab2.
537    redraw
538    call MouseLeftClick(row, col)
539    call MouseLeftRelease(row, col)
540    let a = split(execute(':tabs'), "\n")
541    call assert_equal(['Tab page 1',
542        \              '    Xtab1',
543        \              'Tab page 2',
544        \              '>   Xtab3'], a, msg)
545
546    %bwipe!
547  endfor
548
549  let &mouse = save_mouse
550  let &term = save_term
551  let &ttymouse = save_ttymouse
552  call test_override('no_query_mouse', 0)
553endfunc
554
555func Test_term_mouse_drag_to_move_tab()
556  let save_mouse = &mouse
557  let save_term = &term
558  let save_ttymouse = &ttymouse
559  call test_override('no_query_mouse', 1)
560  " Set 'mousetime' to 1 to avoid recognizing a double-click in the loop
561  set mouse=a term=xterm mousetime=1
562  let row = 1
563
564  for ttymouse_val in s:ttymouse_values + s:ttymouse_dec
565    let msg = 'ttymouse=' .. ttymouse_val
566    exe 'set ttymouse=' .. ttymouse_val
567    e Xtab1
568    tabnew Xtab2
569
570    let a = split(execute(':tabs'), "\n")
571    call assert_equal(['Tab page 1',
572        \              '    Xtab1',
573        \              'Tab page 2',
574        \              '>   Xtab2'], a, msg)
575    redraw
576
577    " Click in tab2 and drag it to tab1.
578    " Check getcharmod() to verify that click is not
579    " interpreted as a spurious double-click.
580    call MouseLeftClick(row, 10)
581    call assert_equal(0, getcharmod(), msg)
582    for col in [9, 8, 7, 6]
583      call MouseLeftDrag(row, col)
584    endfor
585    call MouseLeftRelease(row, col)
586    let a = split(execute(':tabs'), "\n")
587    call assert_equal(['Tab page 1',
588        \              '>   Xtab2',
589        \              'Tab page 2',
590        \              '    Xtab1'], a, msg)
591
592    " brief sleep to avoid causing a double-click
593    sleep 20m
594    %bwipe!
595  endfor
596
597  let &mouse = save_mouse
598  let &term = save_term
599  let &ttymouse = save_ttymouse
600  call test_override('no_query_mouse', 0)
601  set mousetime&
602endfunc
603
604func Test_term_mouse_double_click_to_create_tab()
605  let save_mouse = &mouse
606  let save_term = &term
607  let save_ttymouse = &ttymouse
608  call test_override('no_query_mouse', 1)
609  " Set 'mousetime' to a small value, so that double-click works but we don't
610  " have to wait long to avoid a triple-click.
611  set mouse=a term=xterm mousetime=100
612  let row = 1
613  let col = 10
614
615  let round = 0
616  for ttymouse_val in s:ttymouse_values + s:ttymouse_dec
617    let msg = 'ttymouse=' .. ttymouse_val
618    exe 'set ttymouse=' .. ttymouse_val
619    e Xtab1
620    tabnew Xtab2
621
622    if round > 0
623      " We need to sleep, or else the first MouseLeftClick() will be
624      " interpreted as a spurious triple-click.
625      sleep 100m
626    endif
627    let round += 1
628
629    let a = split(execute(':tabs'), "\n")
630    call assert_equal(['Tab page 1',
631        \              '    Xtab1',
632        \              'Tab page 2',
633        \              '>   Xtab2'], a, msg)
634
635    redraw
636    call MouseLeftClick(row, col)
637    " Check getcharmod() to verify that first click is not
638    " interpreted as a spurious double-click.
639    call assert_equal(0, getcharmod(), msg)
640    call MouseLeftRelease(row, col)
641    call MouseLeftClick(row, col)
642    call assert_equal(32, getcharmod(), msg) " double-click
643    call MouseLeftRelease(row, col)
644    let a = split(execute(':tabs'), "\n")
645    call assert_equal(['Tab page 1',
646        \              '    Xtab1',
647        \              'Tab page 2',
648        \              '>   [No Name]',
649        \              'Tab page 3',
650        \              '    Xtab2'], a, msg)
651
652    %bwipe!
653  endfor
654
655  let &mouse = save_mouse
656  let &term = save_term
657  let &ttymouse = save_ttymouse
658  call test_override('no_query_mouse', 0)
659  set mousetime&
660endfunc
661
662func Test_xterm_mouse_click_in_fold_columns()
663  new
664  let save_mouse = &mouse
665  let save_term = &term
666  let save_ttymouse = &ttymouse
667  let save_foldcolumn = &foldcolumn
668  set mouse=a term=xterm foldcolumn=3 ttymouse=xterm2
669
670  " Create 2 nested folds.
671  call setline(1, range(1, 7))
672  2,6fold
673  norm! zR
674  4,5fold
675  call assert_equal([-1, -1, -1, 4, 4, -1, -1],
676        \           map(range(1, 7), 'foldclosed(v:val)'))
677
678  " Click in "+" of inner fold in foldcolumn should open it.
679  redraw
680  let row = 4
681  let col = 2
682  call MouseLeftClick(row, col)
683  call MouseLeftRelease(row, col)
684  call assert_equal([-1, -1, -1, -1, -1, -1, -1],
685        \           map(range(1, 7), 'foldclosed(v:val)'))
686
687  " Click in "-" of outer fold in foldcolumn should close it.
688  redraw
689  let row = 2
690  let col = 1
691  call MouseLeftClick(row, col)
692  call MouseLeftRelease(row, col)
693  call assert_equal([-1, 2, 2, 2, 2, 2, -1],
694        \           map(range(1, 7), 'foldclosed(v:val)'))
695  norm! zR
696
697  " Click in "|" of inner fold in foldcolumn should close it.
698  redraw
699  let row = 5
700  let col = 2
701  call MouseLeftClick(row, col)
702  call MouseLeftRelease(row, col)
703  call assert_equal([-1, -1, -1, 4, 4, -1, -1],
704        \           map(range(1, 7), 'foldclosed(v:val)'))
705
706  let &foldcolumn = save_foldcolumn
707  let &ttymouse = save_ttymouse
708  let &term = save_term
709  let &mouse = save_mouse
710  bwipe!
711endfunc
712
713" This only checks if the sequence is recognized.
714func Test_term_rgb_response()
715  set t_RF=x
716  set t_RB=y
717
718  " response to t_RF, 4 digits
719  let red = 0x12
720  let green = 0x34
721  let blue = 0x56
722  let seq = printf("\<Esc>]10;rgb:%02x00/%02x00/%02x00\x07", red, green, blue)
723  call feedkeys(seq, 'Lx!')
724  call assert_equal(seq, v:termrfgresp)
725
726  " response to t_RF, 2 digits
727  let red = 0x78
728  let green = 0x9a
729  let blue = 0xbc
730  let seq = printf("\<Esc>]10;rgb:%02x/%02x/%02x\x07", red, green, blue)
731  call feedkeys(seq, 'Lx!')
732  call assert_equal(seq, v:termrfgresp)
733
734  " response to t_RB, 4 digits, dark
735  set background=light
736  eval 'background'->test_option_not_set()
737  let red = 0x29
738  let green = 0x4a
739  let blue = 0x6b
740  let seq = printf("\<Esc>]11;rgb:%02x00/%02x00/%02x00\x07", red, green, blue)
741  call feedkeys(seq, 'Lx!')
742  call assert_equal(seq, v:termrbgresp)
743  call assert_equal('dark', &background)
744
745  " response to t_RB, 4 digits, light
746  set background=dark
747  call test_option_not_set('background')
748  let red = 0x81
749  let green = 0x63
750  let blue = 0x65
751  let seq = printf("\<Esc>]11;rgb:%02x00/%02x00/%02x00\x07", red, green, blue)
752  call feedkeys(seq, 'Lx!')
753  call assert_equal(seq, v:termrbgresp)
754  call assert_equal('light', &background)
755
756  " response to t_RB, 2 digits, dark
757  set background=light
758  call test_option_not_set('background')
759  let red = 0x47
760  let green = 0x59
761  let blue = 0x5b
762  let seq = printf("\<Esc>]11;rgb:%02x/%02x/%02x\x07", red, green, blue)
763  call feedkeys(seq, 'Lx!')
764  call assert_equal(seq, v:termrbgresp)
765  call assert_equal('dark', &background)
766
767  " response to t_RB, 2 digits, light
768  set background=dark
769  call test_option_not_set('background')
770  let red = 0x83
771  let green = 0xa4
772  let blue = 0xc2
773  let seq = printf("\<Esc>]11;rgb:%02x/%02x/%02x\x07", red, green, blue)
774  call feedkeys(seq, 'Lx!')
775  call assert_equal(seq, v:termrbgresp)
776  call assert_equal('light', &background)
777
778  set t_RF= t_RB=
779endfunc
780
781" This only checks if the sequence is recognized.
782" This must be last, because it has side effects to xterm properties.
783" TODO: check that the values were parsed properly
784func Test_xx_term_style_response()
785  " Termresponse is only parsed when t_RV is not empty.
786  set t_RV=x
787
788  " send the termresponse to trigger requesting the XT codes
789  let seq = "\<Esc>[>41;337;0c"
790  call feedkeys(seq, 'Lx!')
791  call assert_equal(seq, v:termresponse)
792
793  let seq = "\<Esc>P1$r2 q\<Esc>\\"
794  call feedkeys(seq, 'Lx!')
795  call assert_equal(seq, v:termstyleresp)
796
797  set t_RV=
798endfunc
799
800func Test_get_termcode()
801  try
802    let k1 = &t_k1
803  catch /E113/
804    throw 'Skipped: Unable to query termcodes'
805  endtry
806  set t_k1=
807  set t_k1&
808  call assert_equal(k1, &t_k1)
809
810  " use external termcap first
811  set nottybuiltin
812  set t_k1=
813  set t_k1&
814  " when using external termcap may get something else, but it must not be
815  " empty, since we would fallback to the builtin one.
816  call assert_notequal('', &t_k1)
817
818  if &term =~ 'xterm'
819    " use internal termcap first
820    let term_save = &term
821    let &term = 'builtin_' .. &term
822    set t_k1=
823    set t_k1&
824    call assert_equal(k1, &t_k1)
825    let &term = term_save
826  endif
827
828  set ttybuiltin
829endfunc
830