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