xref: /vim-8.2.3635/src/testdir/test_gui.vim (revision f4d8b76d)
1" Tests specifically for the GUI
2
3source shared.vim
4source check.vim
5CheckCanRunGui
6
7source setup_gui.vim
8
9func Setup()
10  call GUISetUpCommon()
11endfunc
12
13func TearDown()
14  call GUITearDownCommon()
15endfunc
16
17" Test for resetting "secure" flag after GUI has started.
18" Must be run first, since it starts the GUI on Unix.
19func Test_1_set_secure()
20  set exrc secure
21  gui -f
22  call assert_equal(1, has('gui_running'))
23endfunc
24
25" As for non-GUI, a balloon_show() test was already added with patch 8.0.0401
26func Test_balloon_show()
27  CheckFeature balloon_eval
28  " This won't do anything but must not crash either.
29  call balloon_show('hi!')
30endfunc
31
32func Test_colorscheme()
33  call assert_equal('16777216', &t_Co)
34
35  let colorscheme_saved = exists('g:colors_name') ? g:colors_name : 'default'
36  let g:color_count = 0
37  augroup TestColors
38    au!
39    au ColorScheme * let g:color_count += 1| let g:after_colors = g:color_count
40    au ColorSchemePre * let g:color_count += 1 |let g:before_colors = g:color_count
41  augroup END
42
43  colorscheme torte
44  redraw!
45  call assert_equal('dark', &background)
46  call assert_equal(1, g:before_colors)
47  call assert_equal(2, g:after_colors)
48  call assert_equal("\ntorte", execute('colorscheme'))
49
50  let a = substitute(execute('hi Search'), "\n\\s\\+", ' ', 'g')
51  call assert_match("\nSearch         xxx term=reverse ctermfg=0 ctermbg=12 gui=bold guifg=Black guibg=Red", a)
52
53  call assert_fails('colorscheme does_not_exist', 'E185:')
54
55  exec 'colorscheme' colorscheme_saved
56  augroup TestColors
57    au!
58  augroup END
59  unlet g:color_count g:after_colors g:before_colors
60  redraw!
61endfunc
62
63func Test_getfontname_with_arg()
64  CheckX11BasedGui
65
66  if has('gui_athena') || has('gui_motif')
67    " Invalid font name. The result should be an empty string.
68    call assert_equal('', getfontname('notexist'))
69
70    " Valid font name. This is usually the real name of 7x13 by default.
71    let fname = '-Misc-Fixed-Medium-R-Normal--13-120-75-75-C-70-ISO8859-1'
72    call assert_match(fname, getfontname(fname))
73
74  elseif has('gui_gtk2') || has('gui_gnome') || has('gui_gtk3')
75    " Invalid font name. The result should be the name plus the default size.
76    call assert_equal('notexist 10', getfontname('notexist'))
77    call assert_equal('', getfontname('*'))
78
79    " Valid font name. This is usually the real name of Monospace by default.
80    let fname = 'Bitstream Vera Sans Mono 12'
81    call assert_equal(fname, getfontname(fname))
82  endif
83endfunc
84
85func Test_getfontname_without_arg()
86  CheckX11BasedGui
87
88  let fname = getfontname()
89
90  if has('gui_kde')
91    " 'expected' is the value specified by SetUp() above.
92    call assert_equal('Courier 10 Pitch/8/-1/5/50/0/0/0/0/0', fname)
93  elseif has('gui_athena') || has('gui_motif')
94    " 'expected' is DFLT_FONT of gui_x11.c or its real name.
95    let pat = '\(7x13\)\|\(\c-Misc-Fixed-Medium-R-Normal--13-120-75-75-C-70-ISO8859-1\)'
96    call assert_match(pat, fname)
97  elseif has('gui_gtk2') || has('gui_gnome') || has('gui_gtk3')
98    " 'expected' is DEFAULT_FONT of gui_gtk_x11.c.
99    call assert_equal('Monospace 10', fname)
100  endif
101endfunc
102
103func Test_getwinpos()
104  call assert_match('Window position: X \d\+, Y \d\+', execute('winpos'))
105  call assert_true(getwinposx() >= 0)
106  call assert_true(getwinposy() >= 0)
107  call assert_equal([getwinposx(), getwinposy()], getwinpos())
108endfunc
109
110func Test_quoteplus()
111  CheckX11BasedGui
112
113  let g:test_is_flaky = 1
114
115  let quoteplus_saved = @+
116
117  let test_call     = 'Can you hear me?'
118  let test_response = 'Yes, I can.'
119  let vim_exe = GetVimCommand()
120  let testee = 'VIMRUNTIME=' . $VIMRUNTIME . '; export VIMRUNTIME;'
121        \ . vim_exe . ' --noplugin --not-a-term -c ''%s'''
122  " Ignore the "failed to create input context" error.
123  let cmd = 'call test_ignore_error("E285") | '
124        \ . 'gui -f | '
125        \ . 'call feedkeys("'
126        \ . '\"+p'
127        \ . ':s/' . test_call . '/' . test_response . '/\<CR>'
128        \ . '\"+yis'
129        \ . ':q!\<CR>", "tx")'
130  let run_vimtest = printf(testee, cmd)
131
132  " Set the quoteplus register to test_call, and another gvim will launched.
133  " Then, it first tries to paste the content of its own quotedplus register
134  " onto it.  Second, it tries to substitute test_response for the pasted
135  " sentence.  If the sentence is identical to test_call, the substitution
136  " should succeed.  Third, it tries to yank the result of the substitution
137  " to its own quoteplus register, and last it quits.  When system()
138  " returns, the content of the quoteplus register should be identical to
139  " test_response if those quoteplus registers are synchronized properly
140  " with/through the X11 clipboard.
141  let @+ = test_call
142  call system(run_vimtest)
143  call assert_equal(test_response, @+)
144
145  let @+ = quoteplus_saved
146endfunc
147
148func Test_set_background()
149  let background_saved = &background
150
151  set background&
152  call assert_equal('light', &background)
153
154  set background=dark
155  call assert_equal('dark', &background)
156
157  let &background = background_saved
158endfunc
159
160func Test_set_balloondelay()
161  CheckOption balloondelay
162
163  let balloondelay_saved = &balloondelay
164
165  " Check if the default value is identical to that described in the manual.
166  set balloondelay&
167  call assert_equal(600, &balloondelay)
168
169  " Edge cases
170
171  " XXX This fact should be hidden so that people won't be tempted to write
172  " plugin/TimeMachine.vim.  TODO Add reasonable range checks to the source
173  " code.
174  set balloondelay=-1
175  call assert_equal(-1, &balloondelay)
176
177  " Though it's possible to interpret the zero delay to be 'as soon as
178  " possible' or even 'indefinite', its actual meaning depends on the GUI
179  " toolkit in use after all.
180  set balloondelay=0
181  call assert_equal(0, &balloondelay)
182
183  set balloondelay=1
184  call assert_equal(1, &balloondelay)
185
186  " Since p_bdelay is of type long currently, the upper bound can be
187  " impractically huge and machine-dependent.  Practically, it's sufficient
188  " to check if balloondelay works with 0x7fffffff (32 bits) for now.
189  set balloondelay=2147483647
190  call assert_equal(2147483647, &balloondelay)
191
192  let &balloondelay = balloondelay_saved
193endfunc
194
195func Test_set_ballooneval()
196  CheckOption ballooneval
197
198  let ballooneval_saved = &ballooneval
199
200  set ballooneval&
201  call assert_equal(0, &ballooneval)
202
203  set ballooneval
204  call assert_notequal(0, &ballooneval)
205
206  set noballooneval
207  call assert_equal(0, &ballooneval)
208
209  let &ballooneval = ballooneval_saved
210endfunc
211
212func Test_set_balloonexpr()
213  CheckOption balloonexpr
214
215  let balloonexpr_saved = &balloonexpr
216
217  " Default value
218  set balloonexpr&
219  call assert_equal('', &balloonexpr)
220
221  " User-defined function
222  new
223  func MyBalloonExpr()
224      return 'Cursor is at line ' . v:beval_lnum .
225	      \', column ' . v:beval_col .
226	      \ ' of file ' .  bufname(v:beval_bufnr) .
227	      \ ' on word "' . v:beval_text . '"' .
228	      \ ' in window ' . v:beval_winid . ' (#' . v:beval_winnr . ')'
229  endfunc
230  setl balloonexpr=MyBalloonExpr()
231  setl ballooneval
232  call assert_equal('MyBalloonExpr()', &balloonexpr)
233  " TODO Read non-empty text, place the pointer at a character of a word,
234  " and check if the content of the balloon is the same as what is expected.
235  " Also, check if textlock works as expected.
236  setl balloonexpr&
237  call assert_equal('', &balloonexpr)
238  delfunc MyBalloonExpr
239  bwipe!
240
241  " Multiline support
242  if has('balloon_multiline')
243    " Multiline balloon using NL
244    new
245    func MyBalloonFuncForMultilineUsingNL()
246      return "Multiline\nSuppported\nBalloon\nusing NL"
247    endfunc
248    setl balloonexpr=MyBalloonFuncForMultilineUsingNL()
249    setl ballooneval
250    call assert_equal('MyBalloonFuncForMultilineUsingNL()', &balloonexpr)
251    " TODO Read non-empty text, place the pointer at a character of a word,
252    " and check if the content of the balloon is the same as what is
253    " expected.  Also, check if textlock works as expected.
254    setl balloonexpr&
255    delfunc MyBalloonFuncForMultilineUsingNL
256    bwipe!
257
258    " Multiline balloon using List
259    new
260    func MyBalloonFuncForMultilineUsingList()
261      return [ 'Multiline', 'Suppported', 'Balloon', 'using List' ]
262    endfunc
263    setl balloonexpr=MyBalloonFuncForMultilineUsingList()
264    setl ballooneval
265    call assert_equal('MyBalloonFuncForMultilineUsingList()', &balloonexpr)
266    " TODO Read non-empty text, place the pointer at a character of a word,
267    " and check if the content of the balloon is the same as what is
268    " expected.  Also, check if textlock works as expected.
269    setl balloonexpr&
270    delfunc MyBalloonFuncForMultilineUsingList
271    bwipe!
272  endif
273
274  let &balloonexpr = balloonexpr_saved
275endfunc
276
277" Invalid arguments are tested with test_options in conjunction with segfaults
278" caused by them (Patch 8.0.0357, 24922ec233).
279func Test_set_guicursor()
280  let guicursor_saved = &guicursor
281
282  let default = [
283        \ "n-v-c:block-Cursor/lCursor",
284        \ "ve:ver35-Cursor",
285        \ "o:hor50-Cursor",
286        \ "i-ci:ver25-Cursor/lCursor",
287        \ "r-cr:hor20-Cursor/lCursor",
288        \ "sm:block-Cursor-blinkwait175-blinkoff150-blinkon175"
289        \ ]
290
291  " Default Value
292  set guicursor&
293  call assert_equal(join(default, ','), &guicursor)
294
295  " Argument List Example 1
296  let opt_list = copy(default)
297  let opt_list[0] = "n-c-v:block-nCursor"
298  exec "set guicursor=" . join(opt_list, ',')
299  call assert_equal(join(opt_list, ','), &guicursor)
300  unlet opt_list
301
302  " Argument List Example 2
303  let opt_list = copy(default)
304  let opt_list[3] = "i-ci:ver30-iCursor-blinkwait300-blinkon200-blinkoff150"
305  exec "set guicursor=" . join(opt_list, ',')
306  call assert_equal(join(opt_list, ','), &guicursor)
307  unlet opt_list
308
309  " 'a' Mode
310  set guicursor&
311  let &guicursor .= ',a:blinkon0'
312  call assert_equal(join(default, ',') . ",a:blinkon0", &guicursor)
313
314  let &guicursor = guicursor_saved
315endfunc
316
317func Test_set_guifont_errors()
318  if has('win32')
319    " Invalid font names are accepted in GTK GUI
320    call assert_fails('set guifont=xa1bc23d7f', 'E596:')
321  endif
322
323  " This only works if 'renderoptions' exists and does not work for Windows XP
324  " and older.
325  if exists('+renderoptions') && windowsversion() !~ '^[345]\.'
326    " doing this four times used to cause a crash
327    set renderoptions=type:directx
328    for i in range(5)
329      set guifont=
330    endfor
331    set renderoptions=
332    for i in range(5)
333      set guifont=
334    endfor
335  endif
336endfunc
337
338func Test_set_guifont()
339  CheckX11BasedGui
340
341  let guifont_saved = &guifont
342  if has('xfontset')
343    " Prevent 'guifontset' from canceling 'guifont'.
344    let guifontset_saved = &guifontset
345    set guifontset=
346  endif
347
348  if has('gui_athena') || has('gui_motif')
349    " Non-empty font list with invalid font names.
350    "
351    " This test is twofold: (1) It checks if the command fails as expected
352    " when there are no loadable fonts found in the list. (2) It checks if
353    " 'guifont' remains the same after the command loads none of the fonts
354    " listed.
355    let flist = &guifont
356    call assert_fails('set guifont=-notexist1-*,-notexist2-*')
357    call assert_equal(flist, &guifont)
358
359    " Non-empty font list with a valid font name.  Should pick up the first
360    " valid font.
361    set guifont=-notexist1-*,fixed,-notexist2-*
362    let pat = '\(fixed\)\|\(\c-Misc-Fixed-Medium-R-SemiCondensed--13-120-75-75-C-60-ISO8859-1\)'
363    call assert_match(pat, getfontname())
364
365    " Empty list. Should fallback to the built-in default.
366    set guifont=
367    let pat = '\(7x13\)\|\(\c-Misc-Fixed-Medium-R-Normal--13-120-75-75-C-70-ISO8859-1\)'
368    call assert_match(pat, getfontname())
369
370  elseif has('gui_gtk2') || has('gui_gnome') || has('gui_gtk3')
371    " For GTK, what we refer to as 'font names' in our manual are actually
372    " 'initial font patterns'.  A valid font which matches the 'canonical font
373    " pattern' constructed from a given 'initial pattern' is to be looked up
374    " and loaded.  That explains why the GTK GUIs appear to accept 'invalid
375    " font names'.
376    "
377    " Non-empty list.  Should always pick up the first element, no matter how
378    " strange it is, as explained above.
379    set guifont=(´・ω・`)\ 12,Courier\ 12
380    call assert_equal('(´・ω・`) 12', getfontname())
381
382    " Empty list. Should fallback to the built-in default.
383    set guifont=
384    call assert_equal('Monospace 10', getfontname())
385  endif
386
387  if has('xfontset')
388    let &guifontset = guifontset_saved
389  endif
390  let &guifont = guifont_saved
391endfunc
392
393func Test_set_guifontset()
394  CheckFeature xfontset
395  let skipped = ''
396
397  call assert_fails('set guifontset=*', 'E597:')
398
399  let ctype_saved = v:ctype
400
401  " First, since XCreateFontSet(3) is very sensitive to locale, fonts must
402  " be chosen meticulously.
403  let font_head = '-misc-fixed-medium-r-normal--14'
404
405  let font_aw70 = font_head . '-130-75-75-c-70'
406  let font_aw140 = font_head . '-130-75-75-c-140'
407
408  let font_jisx0201 = font_aw70 . '-jisx0201.1976-0'
409  let font_jisx0208 = font_aw140 . '-jisx0208.1983-0'
410
411  let full_XLFDs = join([ font_jisx0208, font_jisx0201 ], ',')
412  let short_XLFDs = join([ font_aw140, font_aw70 ], ',')
413  let singleton = font_head . '-*'
414  let aliases = 'k14,r14'
415
416  " Second, among 'locales', look up such a locale that gets 'set
417  " guifontset=' to work successfully with every fontset specified with
418  " 'fontsets'.
419  let locales = [ 'ja_JP.UTF-8', 'ja_JP.eucJP', 'ja_JP.SJIS' ]
420  let fontsets = [ full_XLFDs, short_XLFDs, singleton, aliases ]
421
422  let feasible = 0
423  for locale in locales
424    try
425      exec 'language ctype' locale
426    catch /^Vim\%((\a\+)\)\=:E197/
427      continue
428    endtry
429    let done = 0
430    for fontset in fontsets
431      try
432	exec 'set guifontset=' . fontset
433      catch /^Vim\%((\a\+)\)\=:E\%(250\|252\|234\|597\|598\)/
434	break
435      endtry
436      let done += 1
437    endfor
438    if done == len(fontsets)
439      let feasible = 1
440      break
441    endif
442  endfor
443
444  " Third, give a set of tests if it is found feasible.
445  if !feasible
446    let skipped = g:not_hosted
447  else
448    " N.B. 'v:ctype' has already been set to an appropriate value in the
449    " previous loop.
450    for fontset in fontsets
451      exec 'set guifontset=' . fontset
452      call assert_equal(fontset, &guifontset)
453    endfor
454  endif
455
456  " Finally, restore ctype.
457  exec 'language ctype' ctype_saved
458
459  if !empty(skipped)
460    throw skipped
461  endif
462endfunc
463
464func Test_set_guifontwide()
465  CheckX11BasedGui
466
467  call assert_fails('set guifontwide=*', 'E533:')
468
469  if has('gui_gtk')
470    let guifont_saved = &guifont
471    let guifontwide_saved = &guifontwide
472
473    let fc_match = exepath('fc-match')
474    if empty(fc_match)
475      let skipped = g:not_hosted
476    else
477      let &guifont = system('fc-match -f "%{family[0]} %{size}" monospace:size=10:lang=en')
478      let wide = system('fc-match -f "%{family[0]} %{size}" monospace:size=10:lang=ja')
479      exec 'set guifontwide=' . fnameescape(wide)
480      call assert_equal(wide, &guifontwide)
481    endif
482
483    let &guifontwide = guifontwide_saved
484    let &guifont = guifont_saved
485
486  elseif has('gui_athena') || has('gui_motif')
487    " guifontwide is premised upon the xfontset feature.
488    if !has('xfontset')
489      let skipped = g:not_supported . 'xfontset'
490    else
491      let encoding_saved    = &encoding
492      let guifont_saved     = &guifont
493      let guifontset_saved  = &guifontset
494      let guifontwide_saved = &guifontwide
495
496      let nfont = '-misc-fixed-medium-r-normal-*-18-120-100-100-c-90-iso10646-1'
497      let wfont = '-misc-fixed-medium-r-normal-*-18-120-100-100-c-180-iso10646-1'
498
499      set encoding=utf-8
500
501      " Case 1: guifontset is empty
502      set guifontset=
503
504      " Case 1-1: Automatic selection
505      set guifontwide=
506      exec 'set guifont=' . nfont
507      call assert_equal(wfont, &guifontwide)
508
509      " Case 1-2: Manual selection
510      exec 'set guifontwide=' . wfont
511      exec 'set guifont=' . nfont
512      call assert_equal(wfont, &guifontwide)
513
514      " Case 2: guifontset is invalid
515      try
516        set guifontset=-*-notexist-*
517        call assert_report("'set guifontset=-*-notexist-*' should have failed")
518      catch
519        call assert_exception('E598:')
520      endtry
521      " Set it to an invalid value brutally for preparation.
522      let &guifontset = '-*-notexist-*'
523
524      " Case 2-1: Automatic selection
525      set guifontwide=
526      exec 'set guifont=' . nfont
527      call assert_equal(wfont, &guifontwide)
528
529      " Case 2-2: Manual selection
530      exec 'set guifontwide=' . wfont
531      exec 'set guifont=' . nfont
532      call assert_equal(wfont, &guifontwide)
533
534      let &guifontwide = guifontwide_saved
535      let &guifontset  = guifontset_saved
536      let &guifont     = guifont_saved
537      let &encoding    = encoding_saved
538    endif
539  endif
540endfunc
541
542func Test_set_guiligatures()
543  CheckX11BasedGui
544
545  if has('gui_gtk') || has('gui_gtk2') || has('gui_gnome') || has('gui_gtk3')
546    " Try correct value
547    set guiligatures=<>=ab
548    call assert_equal("<>=ab", &guiligatures)
549    " Try to throw error
550    try
551      set guiligatures=<>=šab
552      call assert_report("'set guiligatures=<>=šab should have failed")
553    catch
554      call assert_exception('E1243:')
555    endtry
556  endif
557endfunc
558
559func Test_set_guiheadroom()
560  CheckX11BasedGui
561
562  " Since this script is to be read together with '-U NONE', the default
563  " value must be preserved.
564  call assert_equal(50, &guiheadroom)
565endfunc
566
567func Test_set_guioptions()
568  let guioptions_saved = &guioptions
569  let duration = '200m'
570
571  if has('win32')
572    " Default Value
573    set guioptions&
574    call assert_equal('egmrLtT', &guioptions)
575
576  else
577    " Default Value
578    set guioptions&
579    call assert_equal('aegimrLtT', &guioptions)
580
581    " To activate scrollbars of type 'L' or 'R'.
582    wincmd v
583    redraw!
584
585    " Remove all default GUI ornaments
586    set guioptions-=T
587    exec 'sleep' . duration
588    call assert_equal('aegimrLt', &guioptions)
589    set guioptions-=t
590    exec 'sleep' . duration
591    call assert_equal('aegimrL', &guioptions)
592    set guioptions-=L
593    exec 'sleep' . duration
594    call assert_equal('aegimr', &guioptions)
595    set guioptions-=r
596    exec 'sleep' . duration
597    call assert_equal('aegim', &guioptions)
598    set guioptions-=m
599    exec 'sleep' . duration
600    call assert_equal('aegi', &guioptions)
601
602    " Try non-default GUI ornaments
603    set guioptions+=l
604    exec 'sleep' . duration
605    call assert_equal('aegil', &guioptions)
606    set guioptions-=l
607    exec 'sleep' . duration
608    call assert_equal('aegi', &guioptions)
609
610    set guioptions+=R
611    exec 'sleep' . duration
612    call assert_equal('aegiR', &guioptions)
613    set guioptions-=R
614    exec 'sleep' . duration
615    call assert_equal('aegi', &guioptions)
616
617    set guioptions+=b
618    exec 'sleep' . duration
619    call assert_equal('aegib', &guioptions)
620    set guioptions+=h
621    exec 'sleep' . duration
622    call assert_equal('aegibh', &guioptions)
623    set guioptions-=h
624    exec 'sleep' . duration
625    call assert_equal('aegib', &guioptions)
626    set guioptions-=b
627    exec 'sleep' . duration
628    call assert_equal('aegi', &guioptions)
629
630    set guioptions+=v
631    exec 'sleep' . duration
632    call assert_equal('aegiv', &guioptions)
633    set guioptions-=v
634    exec 'sleep' . duration
635    call assert_equal('aegi', &guioptions)
636
637    if has('gui_motif')
638      set guioptions+=F
639      exec 'sleep' . duration
640      call assert_equal('aegiF', &guioptions)
641      set guioptions-=F
642      exec 'sleep' . duration
643      call assert_equal('aegi', &guioptions)
644    endif
645
646    if has('gui_gtk3')
647      set guioptions+=d
648      exec 'sleep' . duration
649      call assert_equal('aegid', &guioptions)
650      set guioptions-=d
651      exec 'sleep' . duration
652      call assert_equal('aegi', &guioptions)
653    endif
654
655    " Restore GUI ornaments to the default state.
656    set guioptions+=m
657    exec 'sleep' . duration
658    call assert_equal('aegim', &guioptions)
659    set guioptions+=r
660    exec 'sleep' . duration
661    call assert_equal('aegimr', &guioptions)
662    set guioptions+=L
663    exec 'sleep' . duration
664    call assert_equal('aegimrL', &guioptions)
665    set guioptions+=t
666    exec 'sleep' . duration
667    call assert_equal('aegimrLt', &guioptions)
668    set guioptions+=T
669    exec 'sleep' . duration
670    call assert_equal("aegimrLtT", &guioptions)
671
672    wincmd o
673    redraw!
674  endif
675
676  let &guioptions = guioptions_saved
677endfunc
678
679func Test_scrollbars()
680  new
681  " buffer with 200 lines
682  call setline(1, repeat(['one', 'two'], 100))
683  set guioptions+=rlb
684
685  " scroll to move line 11 at top, moves the cursor there
686  eval 10->test_scrollbar('left', 0)
687  redraw
688  call assert_equal(1, winline())
689  call assert_equal(11, line('.'))
690
691  " scroll to move line 1 at top, cursor stays in line 11
692  call test_scrollbar('right', 0, 0)
693  redraw
694  call assert_equal(11, winline())
695  call assert_equal(11, line('.'))
696
697  set nowrap
698  call setline(11, repeat('x', 150))
699  redraw
700  call assert_equal(1, wincol())
701  set number
702  redraw
703  call assert_equal(5, wincol())
704  set nonumber
705  redraw
706  call assert_equal(1, col('.'))
707
708  " scroll to character 11, cursor is moved
709  call test_scrollbar('hor', 10, 0)
710  redraw
711  call assert_equal(1, wincol())
712  set number
713  redraw
714  call assert_equal(5, wincol())
715  set nonumber
716  redraw
717  call assert_equal(11, col('.'))
718
719  set guioptions&
720  set wrap&
721  bwipe!
722endfunc
723
724func Test_menu()
725  CheckFeature quickfix
726
727  " Check Help menu exists
728  let help_menu = execute('menu Help')
729  call assert_match('Overview', help_menu)
730
731  " Check Help menu works
732  emenu Help.Overview
733  call assert_equal('help', &buftype)
734  close
735
736  " Check deleting menu doesn't cause trouble.
737  aunmenu Help
738  if exists(':tlmenu')
739    tlunmenu Help
740  endif
741  call assert_fails('menu Help', 'E329:')
742endfunc
743
744func Test_set_guipty()
745  let guipty_saved = &guipty
746
747  " Default Value
748  set guipty&
749  call assert_equal(1, &guipty)
750
751  set noguipty
752  call assert_equal(0, &guipty)
753
754  let &guipty = guipty_saved
755endfunc
756
757func Test_encoding_conversion()
758  " GTK supports conversion between 'encoding' and "utf-8"
759  CheckFeature gui_gtk
760  let encoding_saved = &encoding
761  set encoding=latin1
762
763  " would be nice if we could take a screenshot
764  intro
765  " sets the window title
766  edit SomeFile
767
768  let &encoding = encoding_saved
769endfunc
770
771func Test_shell_command()
772  new
773  r !echo hello
774  call assert_equal('hello', substitute(getline(2), '\W', '', 'g'))
775  bwipe!
776endfunc
777
778func Test_syntax_colortest()
779  runtime syntax/colortest.vim
780  redraw!
781  sleep 200m
782  bwipe!
783endfunc
784
785func Test_set_term()
786  " It's enough to check the current value since setting 'term' to anything
787  " other than builtin_gui makes no sense at all.
788  call assert_equal('builtin_gui', &term)
789  call assert_fails('set term=xterm', 'E530:')
790endfunc
791
792func Test_windowid_variable()
793  if g:x11_based_gui || has('win32')
794    call assert_true(v:windowid > 0)
795  else
796    call assert_equal(0, v:windowid)
797  endif
798endfunc
799
800" Test "vim -g" and also the GUIEnter autocommand.
801func Test_gui_dash_g()
802  let cmd = GetVimCommand('Xscriptgui')
803  call writefile([""], "Xtestgui")
804  let lines =<< trim END
805	au GUIEnter * call writefile(["insertmode: " . &insertmode], "Xtestgui")
806	au GUIEnter * qall
807  END
808  call writefile(lines, 'Xscriptgui')
809  call system(cmd . ' -g')
810  call WaitForAssert({-> assert_equal(['insertmode: 0'], readfile('Xtestgui'))})
811
812  call delete('Xscriptgui')
813  call delete('Xtestgui')
814endfunc
815
816" Test "vim -7" and also the GUIEnter autocommand.
817func Test_gui_dash_y()
818  let cmd = GetVimCommand('Xscriptgui')
819  call writefile([""], "Xtestgui")
820  let lines =<< trim END
821	au GUIEnter * call writefile(["insertmode: " . &insertmode], "Xtestgui")
822	au GUIEnter * qall
823  END
824  call writefile(lines, 'Xscriptgui')
825  call system(cmd . ' -y')
826  call WaitForAssert({-> assert_equal(['insertmode: 1'], readfile('Xtestgui'))})
827
828  call delete('Xscriptgui')
829  call delete('Xtestgui')
830endfunc
831
832" Test for "!" option in 'guioptions'. Use a terminal for running external
833" commands
834func Test_gui_run_cmd_in_terminal()
835  CheckFeature terminal
836  let save_guioptions = &guioptions
837  set guioptions+=!
838  if has('win32')
839    let cmd = 'type'
840  else
841    " assume all the other systems have a cat command
842    let cmd = 'cat'
843  endif
844  exe "silent !" . cmd . " test_gui.vim"
845  " TODO: how to check that the command ran in a separate terminal?
846  " Maybe check for $TERM (dumb vs xterm) in the spawned shell?
847  let &guioptions = save_guioptions
848endfunc
849
850func Test_gui_recursive_mapping()
851  nmap ' <C-W>
852  nmap <C-W>a :let didit = 1<CR>
853  call feedkeys("'a", 'xt')
854  call assert_equal(1, didit)
855
856  nunmap '
857  nunmap <C-W>a
858endfunc
859
860" Test GUI mouse events
861func Test_gui_mouse_event()
862  set mousemodel=extend
863  call test_override('no_query_mouse', 1)
864  new
865  call setline(1, ['one two three', 'four five six'])
866
867  " place the cursor using left click in normal mode
868  call cursor(1, 1)
869  call test_gui_mouse_event(0, 2, 4, 0, 0)
870  call test_gui_mouse_event(3, 2, 4, 0, 0)
871  call feedkeys("\<Esc>", 'Lx!')
872  call assert_equal([0, 2, 4, 0], getpos('.'))
873
874  " select and yank a word
875  let @" = ''
876  call test_gui_mouse_event(0, 1, 9, 0, 0)
877  call test_gui_mouse_event(0, 1, 9, 1, 0)
878  call test_gui_mouse_event(3, 1, 9, 0, 0)
879  call feedkeys("y", 'Lx!')
880  call assert_equal('three', @")
881
882  " create visual selection using right click
883  let @" = ''
884  call test_gui_mouse_event(0, 2, 6, 0, 0)
885  call test_gui_mouse_event(3, 2, 6, 0, 0)
886  call test_gui_mouse_event(2, 2, 13, 0, 0)
887  call test_gui_mouse_event(3, 2, 13, 0, 0)
888  call feedkeys("y", 'Lx!')
889  call assert_equal('five six', @")
890
891  " paste using middle mouse button
892  let @* = 'abc '
893  call feedkeys('""', 'Lx!')
894  call test_gui_mouse_event(1, 1, 9, 0, 0)
895  call test_gui_mouse_event(3, 1, 9, 0, 0)
896  call feedkeys("\<Esc>", 'Lx!')
897  call assert_equal(['one two abc three', 'four five six'], getline(1, '$'))
898
899  " extend visual selection using right click in visual mode
900  let @" = ''
901  call cursor(1, 1)
902  call feedkeys('v', 'Lx!')
903  call test_gui_mouse_event(2, 1, 17, 0, 0)
904  call test_gui_mouse_event(3, 1, 17, 0, 0)
905  call feedkeys("y", 'Lx!')
906  call assert_equal('one two abc three', @")
907
908  " extend visual selection using mouse drag
909  let @" = ''
910  call cursor(1, 1)
911  call test_gui_mouse_event(0, 2, 1, 0, 0)
912  call test_gui_mouse_event(0x43, 2, 9, 0, 0)
913  call test_gui_mouse_event(0x3, 2, 9, 0, 0)
914  call feedkeys("y", 'Lx!')
915  call assert_equal('four five', @")
916
917  " select text by moving the mouse
918  let @" = ''
919  call cursor(1, 1)
920  redraw!
921  call test_gui_mouse_event(0, 1, 4, 0, 0)
922  call test_gui_mouse_event(0x700, 1, 9, 0, 0)
923  call test_gui_mouse_event(0x700, 1, 13, 0, 0)
924  call test_gui_mouse_event(0x3, 1, 13, 0, 0)
925  call feedkeys("y", 'Lx!')
926  call assert_equal(' two abc t', @")
927
928  " Using mouse in insert mode
929  call cursor(1, 1)
930  call feedkeys('i', 't')
931  call test_gui_mouse_event(0, 2, 11, 0, 0)
932  call test_gui_mouse_event(3, 2, 11, 0, 0)
933  call feedkeys("po\<Esc>", 'Lx!')
934  call assert_equal(['one two abc three', 'four five posix'], getline(1, '$'))
935
936  %d _
937  call setline(1, range(1, 100))
938  " scroll up
939  call test_gui_mouse_event(0x200, 2, 1, 0, 0)
940  call test_gui_mouse_event(0x200, 2, 1, 0, 0)
941  call test_gui_mouse_event(0x200, 2, 1, 0, 0)
942  call feedkeys("H", 'Lx!')
943  call assert_equal(10, line('.'))
944
945  " scroll down
946  call test_gui_mouse_event(0x100, 2, 1, 0, 0)
947  call test_gui_mouse_event(0x100, 2, 1, 0, 0)
948  call feedkeys("H", 'Lx!')
949  call assert_equal(4, line('.'))
950
951  %d _
952  set nowrap
953  call setline(1, range(10)->join('')->repeat(10))
954  " scroll left
955  call test_gui_mouse_event(0x500, 1, 5, 0, 0)
956  call test_gui_mouse_event(0x500, 1, 10, 0, 0)
957  call test_gui_mouse_event(0x500, 1, 15, 0, 0)
958  call feedkeys('g0', 'Lx!')
959  call assert_equal(19, col('.'))
960
961  " scroll right
962  call test_gui_mouse_event(0x600, 1, 15, 0, 0)
963  call test_gui_mouse_event(0x600, 1, 10, 0, 0)
964  call feedkeys('g0', 'Lx!')
965  call assert_equal(7, col('.'))
966  set wrap&
967
968  %d _
969  call setline(1, repeat([repeat('a', 60)], 10))
970
971  " record various mouse events
972  let mouseEventNames = [
973        \ 'LeftMouse', 'LeftRelease', '2-LeftMouse', '3-LeftMouse',
974        \ 'S-LeftMouse', 'A-LeftMouse', 'C-LeftMouse', 'MiddleMouse',
975        \ 'MiddleRelease', '2-MiddleMouse', '3-MiddleMouse',
976        \ 'S-MiddleMouse', 'A-MiddleMouse', 'C-MiddleMouse',
977        \ 'RightMouse', 'RightRelease', '2-RightMouse',
978        \ '3-RightMouse', 'S-RightMouse', 'A-RightMouse', 'C-RightMouse',
979        \ 'X1Mouse', 'S-X1Mouse', 'A-X1Mouse', 'C-X1Mouse', 'X2Mouse',
980        \ 'S-X2Mouse', 'A-X2Mouse', 'C-X2Mouse'
981        \ ]
982  let mouseEventCodes = map(copy(mouseEventNames), "'<' .. v:val .. '>'")
983  let g:events = []
984  for e in mouseEventCodes
985    exe 'nnoremap ' .. e .. ' <Cmd>call add(g:events, "' ..
986          \ substitute(e, '[<>]', '', 'g') .. '")<CR>'
987  endfor
988
989  " Test various mouse buttons (0 - Left, 1 - Middle, 2 - Right, 0x300 - X1,
990  " 0x300- X2)
991  for button in [0, 1, 2, 0x300, 0x400]
992    " Single click
993    call test_gui_mouse_event(button, 2, 5, 0, 0)
994    call test_gui_mouse_event(3, 2, 5, 0, 0)
995
996    " Double/Triple click is supported by only the Left/Middle/Right mouse
997    " buttons
998    if button <= 2
999      " Double Click
1000      call test_gui_mouse_event(button, 2, 5, 0, 0)
1001      call test_gui_mouse_event(button, 2, 5, 1, 0)
1002      call test_gui_mouse_event(3, 2, 5, 0, 0)
1003
1004      " Triple Click
1005      call test_gui_mouse_event(button, 2, 5, 0, 0)
1006      call test_gui_mouse_event(button, 2, 5, 1, 0)
1007      call test_gui_mouse_event(button, 2, 5, 1, 0)
1008      call test_gui_mouse_event(3, 2, 5, 0, 0)
1009    endif
1010
1011    " Shift click
1012    call test_gui_mouse_event(button, 3, 7, 0, 4)
1013    call test_gui_mouse_event(3, 3, 7, 0, 4)
1014
1015    " Alt click
1016    call test_gui_mouse_event(button, 3, 7, 0, 8)
1017    call test_gui_mouse_event(3, 3, 7, 0, 8)
1018
1019    " Ctrl click
1020    call test_gui_mouse_event(button, 3, 7, 0, 16)
1021    call test_gui_mouse_event(3, 3, 7, 0, 16)
1022
1023    call feedkeys("\<Esc>", 'Lx!')
1024  endfor
1025
1026  call assert_equal(['LeftMouse', 'LeftRelease', 'LeftMouse', '2-LeftMouse',
1027        \ 'LeftMouse', '2-LeftMouse', '3-LeftMouse', 'S-LeftMouse',
1028        \ 'A-LeftMouse', 'C-LeftMouse', 'MiddleMouse', 'MiddleRelease',
1029        \ 'MiddleMouse', '2-MiddleMouse', 'MiddleMouse', '2-MiddleMouse',
1030        \ '3-MiddleMouse', 'S-MiddleMouse', 'A-MiddleMouse', 'C-MiddleMouse',
1031        \ 'RightMouse', 'RightRelease', 'RightMouse', '2-RightMouse',
1032        \ 'RightMouse', '2-RightMouse', '3-RightMouse', 'S-RightMouse',
1033        \ 'A-RightMouse', 'C-RightMouse', 'X1Mouse', 'S-X1Mouse', 'A-X1Mouse',
1034        \ 'C-X1Mouse', 'X2Mouse', 'S-X2Mouse', 'A-X2Mouse', 'C-X2Mouse'],
1035        \ g:events)
1036
1037  for e in mouseEventCodes
1038    exe 'nunmap ' .. e
1039  endfor
1040
1041  " modeless selection
1042  set mouse=
1043  let save_guioptions = &guioptions
1044  set guioptions+=A
1045  %d _
1046  call setline(1, ['one two three', 'four five sixteen'])
1047  call cursor(1, 1)
1048  redraw!
1049  " Double click should select the word and copy it to clipboard
1050  let @* = ''
1051  call test_gui_mouse_event(0, 2, 11, 0, 0)
1052  call test_gui_mouse_event(0, 2, 11, 1, 0)
1053  call test_gui_mouse_event(3, 2, 11, 0, 0)
1054  call feedkeys("\<Esc>", 'Lx!')
1055  call assert_equal([0, 1, 1, 0], getpos('.'))
1056  call assert_equal('sixteen', @*)
1057  " Right click should extend the selection from cursor
1058  call cursor(1, 6)
1059  redraw!
1060  let @* = ''
1061  call test_gui_mouse_event(2, 1, 11, 0, 0)
1062  call test_gui_mouse_event(3, 1, 11, 0, 0)
1063  call feedkeys("\<Esc>", 'Lx!')
1064  call assert_equal([0, 1, 6, 0], getpos('.'))
1065  call assert_equal('wo thr', @*)
1066  " Middle click should paste the clipboard contents
1067  call cursor(2, 1)
1068  redraw!
1069  call test_gui_mouse_event(1, 1, 11, 0, 0)
1070  call test_gui_mouse_event(3, 1, 11, 0, 0)
1071  call feedkeys("\<Esc>", 'Lx!')
1072  call assert_equal([0, 2, 7, 0], getpos('.'))
1073  call assert_equal('wo thrfour five sixteen', getline(2))
1074  set mouse&
1075  let &guioptions = save_guioptions
1076
1077  " Test invalid parameters for test_gui_mouse_event()
1078  call assert_fails('call test_gui_mouse_event("", 1, 2, 3, 4)', 'E1210:')
1079  call assert_fails('call test_gui_mouse_event(0, "", 2, 3, 4)', 'E1210:')
1080  call assert_fails('call test_gui_mouse_event(0, 1, "", 3, 4)', 'E1210:')
1081  call assert_fails('call test_gui_mouse_event(0, 1, 2, "", 4)', 'E1210:')
1082  call assert_fails('call test_gui_mouse_event(0, 1, 2, 3, "")', 'E1210:')
1083
1084  bw!
1085  call test_override('no_query_mouse', 0)
1086  set mousemodel&
1087endfunc
1088
1089" Test for 'guitablabel' and 'guitabtooltip' options
1090func TestGuiTabLabel()
1091  call add(g:TabLabels, v:lnum + 100)
1092  let bufnrlist = tabpagebuflist(v:lnum)
1093  return bufname(bufnrlist[tabpagewinnr(v:lnum) - 1])
1094endfunc
1095
1096func TestGuiTabToolTip()
1097  call add(g:TabToolTips, v:lnum + 200)
1098  let bufnrlist = tabpagebuflist(v:lnum)
1099  return bufname(bufnrlist[tabpagewinnr(v:lnum) - 1])
1100endfunc
1101
1102func Test_gui_tablabel_tooltip()
1103  CheckNotFeature gui_athena
1104
1105  %bw!
1106  " Removing the tabline at the end of this test, reduces the window height by
1107  " one. Save and restore it after the test.
1108  let save_lines = &lines
1109  edit one
1110  set modified
1111  tabnew two
1112  set modified
1113  tabnew three
1114  set modified
1115  let g:TabLabels = []
1116  set guitablabel=%{TestGuiTabLabel()}
1117  call test_override('starting', 1)
1118  redrawtabline
1119  call test_override('starting', 0)
1120  call assert_true(index(g:TabLabels, 101) != -1)
1121  call assert_true(index(g:TabLabels, 102) != -1)
1122  call assert_true(index(g:TabLabels, 103) != -1)
1123  set guitablabel&
1124  unlet g:TabLabels
1125
1126  if has('gui_gtk')
1127    " Only on GTK+, the tooltip function is called even if the mouse is not
1128    " on the tabline. on Win32 and Motif, the tooltip function is called only
1129    " when the mouse pointer is over the tabline.
1130    let g:TabToolTips = []
1131    set guitabtooltip=%{TestGuiTabToolTip()}
1132    call test_override('starting', 1)
1133    redrawtabline
1134    call test_override('starting', 0)
1135    call assert_true(index(g:TabToolTips, 201) != -1)
1136    call assert_true(index(g:TabToolTips, 202) != -1)
1137    call assert_true(index(g:TabToolTips, 203) != -1)
1138    set guitabtooltip&
1139    unlet g:TabToolTips
1140  endif
1141  %bw!
1142  let &lines = save_lines
1143endfunc
1144
1145" Test for dropping files into a window in GUI
1146func DropFilesInCmdLine()
1147  CheckFeature drop_file
1148
1149  call feedkeys(":\"", 'L')
1150  call test_gui_drop_files(['a.c', 'b.c'], &lines, 1, 0)
1151  call feedkeys("\<CR>", 'L')
1152endfunc
1153
1154func Test_gui_drop_files()
1155  CheckFeature drop_file
1156
1157  call assert_fails('call test_gui_drop_files(1, 1, 1, 0)', 'E1211:')
1158  call assert_fails('call test_gui_drop_files(["x"], "", 1, 0)', 'E1210:')
1159  call assert_fails('call test_gui_drop_files(["x"], 1, "", 0)', 'E1210:')
1160  call assert_fails('call test_gui_drop_files(["x"], 1, 1, "")', 'E1210:')
1161
1162  %bw!
1163  %argdelete
1164  call test_gui_drop_files([], 1, 1, 0)
1165  call assert_equal([], argv())
1166  call test_gui_drop_files([1, 2], 1, 1, 0)
1167  call assert_equal([], argv())
1168
1169  call test_gui_drop_files(['a.c', 'b.c'], 1, 1, 0)
1170  call assert_equal(['a.c', 'b.c'], argv())
1171  %bw!
1172  %argdelete
1173  call test_gui_drop_files([], 1, 1, 0)
1174  call assert_equal([], argv())
1175  %bw!
1176  " if the buffer in the window is modified, then the file should be opened in
1177  " a new window
1178  set modified
1179  call test_gui_drop_files(['x.c', 'y.c'], 1, 1, 0)
1180  call assert_equal(['x.c', 'y.c'], argv())
1181  call assert_equal(2, winnr('$'))
1182  call assert_equal('x.c', bufname(winbufnr(1)))
1183  %bw!
1184  %argdelete
1185  " if Ctrl is pressed, then the file should be opened in a new window
1186  call test_gui_drop_files(['s.py', 't.py'], 1, 1, 0x10)
1187  call assert_equal(['s.py', 't.py'], argv())
1188  call assert_equal(2, winnr('$'))
1189  call assert_equal('s.py', bufname(winbufnr(1)))
1190  %bw!
1191  %argdelete
1192  " drop the files in a non-current window
1193  belowright new
1194  call test_gui_drop_files(['a.py', 'b.py'], 1, 1, 0)
1195  call assert_equal(['a.py', 'b.py'], argv())
1196  call assert_equal(2, winnr('$'))
1197  call assert_equal(1, winnr())
1198  call assert_equal('a.py', bufname(winbufnr(1)))
1199  %bw!
1200  %argdelete
1201  " pressing shift when dropping files should change directory
1202  let save_cwd = getcwd()
1203  call mkdir('Xdir1')
1204  call writefile([], 'Xdir1/Xfile1')
1205  call writefile([], 'Xdir1/Xfile2')
1206  call test_gui_drop_files(['Xdir1/Xfile1', 'Xdir1/Xfile2'], 1, 1, 0x4)
1207  call assert_equal('Xdir1', fnamemodify(getcwd(), ':t'))
1208  call assert_equal('Xfile1', @%)
1209  call chdir(save_cwd)
1210  " pressing shift when dropping directory and files should change directory
1211  call test_gui_drop_files(['Xdir1', 'Xdir1/Xfile2'], 1, 1, 0x4)
1212  call assert_equal('Xdir1', fnamemodify(getcwd(), ':t'))
1213  call assert_equal('Xdir1', fnamemodify(@%, ':t'))
1214  call chdir(save_cwd)
1215  %bw!
1216  %argdelete
1217  " dropping a directory should edit it
1218  call test_gui_drop_files(['Xdir1'], 1, 1, 0)
1219  call assert_equal('Xdir1', @%)
1220  %bw!
1221  %argdelete
1222  " dropping only a directory name with Shift should ignore it
1223  call test_gui_drop_files(['Xdir1'], 1, 1, 0x4)
1224  call assert_equal('', @%)
1225  %bw!
1226  %argdelete
1227  call delete('Xdir1', 'rf')
1228  " drop files in the command line. The GUI drop files adds the file names to
1229  " the low level input buffer. So need to use a cmdline map and feedkeys()
1230  " with 'Lx!' to process it in this function itself.
1231  cnoremap <expr> <buffer> <F4> DropFilesInCmdLine()
1232  call feedkeys(":\"\<F4>\<CR>", 'xt')
1233  call feedkeys('k', 'Lx!')
1234  call assert_equal('"a.c b.c', @:)
1235  cunmap <buffer> <F4>
1236endfunc
1237
1238" vim: shiftwidth=2 sts=2 expandtab
1239