xref: /vim-8.2.3635/src/testdir/test_gui.vim (revision 2286304c)
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_guiheadroom()
571  let skipped = ''
572
573  if !g:x11_based_gui
574    let skipped = g:not_supported . 'guiheadroom'
575  else
576    " Since this script is to be read together with '-U NONE', the default
577    " value must be preserved.
578    call assert_equal(50, &guiheadroom)
579  endif
580
581  if !empty(skipped)
582    throw skipped
583  endif
584endfunc
585
586func Test_set_guioptions()
587  let guioptions_saved = &guioptions
588  let duration = '200m'
589
590  if has('win32')
591    " Default Value
592    set guioptions&
593    call assert_equal('egmrLtT', &guioptions)
594
595  else
596    " Default Value
597    set guioptions&
598    call assert_equal('aegimrLtT', &guioptions)
599
600    " To activate scrollbars of type 'L' or 'R'.
601    wincmd v
602    redraw!
603
604    " Remove all default GUI ornaments
605    set guioptions-=T
606    exec 'sleep' . duration
607    call assert_equal('aegimrLt', &guioptions)
608    set guioptions-=t
609    exec 'sleep' . duration
610    call assert_equal('aegimrL', &guioptions)
611    set guioptions-=L
612    exec 'sleep' . duration
613    call assert_equal('aegimr', &guioptions)
614    set guioptions-=r
615    exec 'sleep' . duration
616    call assert_equal('aegim', &guioptions)
617    set guioptions-=m
618    exec 'sleep' . duration
619    call assert_equal('aegi', &guioptions)
620
621    " Try non-default GUI ornaments
622    set guioptions+=l
623    exec 'sleep' . duration
624    call assert_equal('aegil', &guioptions)
625    set guioptions-=l
626    exec 'sleep' . duration
627    call assert_equal('aegi', &guioptions)
628
629    set guioptions+=R
630    exec 'sleep' . duration
631    call assert_equal('aegiR', &guioptions)
632    set guioptions-=R
633    exec 'sleep' . duration
634    call assert_equal('aegi', &guioptions)
635
636    set guioptions+=b
637    exec 'sleep' . duration
638    call assert_equal('aegib', &guioptions)
639    set guioptions+=h
640    exec 'sleep' . duration
641    call assert_equal('aegibh', &guioptions)
642    set guioptions-=h
643    exec 'sleep' . duration
644    call assert_equal('aegib', &guioptions)
645    set guioptions-=b
646    exec 'sleep' . duration
647    call assert_equal('aegi', &guioptions)
648
649    set guioptions+=v
650    exec 'sleep' . duration
651    call assert_equal('aegiv', &guioptions)
652    set guioptions-=v
653    exec 'sleep' . duration
654    call assert_equal('aegi', &guioptions)
655
656    if has('gui_motif')
657      set guioptions+=F
658      exec 'sleep' . duration
659      call assert_equal('aegiF', &guioptions)
660      set guioptions-=F
661      exec 'sleep' . duration
662      call assert_equal('aegi', &guioptions)
663    endif
664
665    if has('gui_gtk3')
666      set guioptions+=d
667      exec 'sleep' . duration
668      call assert_equal('aegid', &guioptions)
669      set guioptions-=d
670      exec 'sleep' . duration
671      call assert_equal('aegi', &guioptions)
672    endif
673
674    " Restore GUI ornaments to the default state.
675    set guioptions+=m
676    exec 'sleep' . duration
677    call assert_equal('aegim', &guioptions)
678    set guioptions+=r
679    exec 'sleep' . duration
680    call assert_equal('aegimr', &guioptions)
681    set guioptions+=L
682    exec 'sleep' . duration
683    call assert_equal('aegimrL', &guioptions)
684    set guioptions+=t
685    exec 'sleep' . duration
686    call assert_equal('aegimrLt', &guioptions)
687    set guioptions+=T
688    exec 'sleep' . duration
689    call assert_equal("aegimrLtT", &guioptions)
690
691    wincmd o
692    redraw!
693  endif
694
695  let &guioptions = guioptions_saved
696endfunc
697
698func Test_scrollbars()
699  new
700  " buffer with 200 lines
701  call setline(1, repeat(['one', 'two'], 100))
702  set guioptions+=rlb
703
704  " scroll to move line 11 at top, moves the cursor there
705  eval 10->test_scrollbar('left', 0)
706  redraw
707  call assert_equal(1, winline())
708  call assert_equal(11, line('.'))
709
710  " scroll to move line 1 at top, cursor stays in line 11
711  call test_scrollbar('right', 0, 0)
712  redraw
713  call assert_equal(11, winline())
714  call assert_equal(11, line('.'))
715
716  set nowrap
717  call setline(11, repeat('x', 150))
718  redraw
719  call assert_equal(1, wincol())
720  set number
721  redraw
722  call assert_equal(5, wincol())
723  set nonumber
724  redraw
725  call assert_equal(1, col('.'))
726
727  " scroll to character 11, cursor is moved
728  call test_scrollbar('hor', 10, 0)
729  redraw
730  call assert_equal(1, wincol())
731  set number
732  redraw
733  call assert_equal(5, wincol())
734  set nonumber
735  redraw
736  call assert_equal(11, col('.'))
737
738  set guioptions&
739  set wrap&
740  bwipe!
741endfunc
742
743func Test_menu()
744  CheckFeature quickfix
745
746  " Check Help menu exists
747  let help_menu = execute('menu Help')
748  call assert_match('Overview', help_menu)
749
750  " Check Help menu works
751  emenu Help.Overview
752  call assert_equal('help', &buftype)
753  close
754
755  " Check deleting menu doesn't cause trouble.
756  aunmenu Help
757  if exists(':tlmenu')
758    tlunmenu Help
759  endif
760  call assert_fails('menu Help', 'E329:')
761endfunc
762
763func Test_set_guipty()
764  let guipty_saved = &guipty
765
766  " Default Value
767  set guipty&
768  call assert_equal(1, &guipty)
769
770  set noguipty
771  call assert_equal(0, &guipty)
772
773  let &guipty = guipty_saved
774endfunc
775
776func Test_encoding_conversion()
777  " GTK supports conversion between 'encoding' and "utf-8"
778  CheckFeature gui_gtk
779  let encoding_saved = &encoding
780  set encoding=latin1
781
782  " would be nice if we could take a screenshot
783  intro
784  " sets the window title
785  edit SomeFile
786
787  let &encoding = encoding_saved
788endfunc
789
790func Test_shell_command()
791  new
792  r !echo hello
793  call assert_equal('hello', substitute(getline(2), '\W', '', 'g'))
794  bwipe!
795endfunc
796
797func Test_syntax_colortest()
798  runtime syntax/colortest.vim
799  redraw!
800  sleep 200m
801  bwipe!
802endfunc
803
804func Test_set_term()
805  " It's enough to check the current value since setting 'term' to anything
806  " other than builtin_gui makes no sense at all.
807  call assert_equal('builtin_gui', &term)
808  call assert_fails('set term=xterm', 'E530:')
809endfunc
810
811func Test_windowid_variable()
812  if g:x11_based_gui || has('win32')
813    call assert_true(v:windowid > 0)
814  else
815    call assert_equal(0, v:windowid)
816  endif
817endfunc
818
819" Test "vim -g" and also the GUIEnter autocommand.
820func Test_gui_dash_g()
821  let cmd = GetVimCommand('Xscriptgui')
822  call writefile([""], "Xtestgui")
823  let lines =<< trim END
824	au GUIEnter * call writefile(["insertmode: " . &insertmode], "Xtestgui")
825	au GUIEnter * qall
826  END
827  call writefile(lines, 'Xscriptgui')
828  call system(cmd . ' -g')
829  call WaitForAssert({-> assert_equal(['insertmode: 0'], readfile('Xtestgui'))})
830
831  call delete('Xscriptgui')
832  call delete('Xtestgui')
833endfunc
834
835" Test "vim -7" and also the GUIEnter autocommand.
836func Test_gui_dash_y()
837  let cmd = GetVimCommand('Xscriptgui')
838  call writefile([""], "Xtestgui")
839  let lines =<< trim END
840	au GUIEnter * call writefile(["insertmode: " . &insertmode], "Xtestgui")
841	au GUIEnter * qall
842  END
843  call writefile(lines, 'Xscriptgui')
844  call system(cmd . ' -y')
845  call WaitForAssert({-> assert_equal(['insertmode: 1'], readfile('Xtestgui'))})
846
847  call delete('Xscriptgui')
848  call delete('Xtestgui')
849endfunc
850
851" Test for "!" option in 'guioptions'. Use a terminal for running external
852" commands
853func Test_gui_run_cmd_in_terminal()
854  CheckFeature terminal
855  let save_guioptions = &guioptions
856  set guioptions+=!
857  if has('win32')
858    let cmd = 'type'
859  else
860    " assume all the other systems have a cat command
861    let cmd = 'cat'
862  endif
863  exe "silent !" . cmd . " test_gui.vim"
864  " TODO: how to check that the command ran in a separate terminal?
865  " Maybe check for $TERM (dumb vs xterm) in the spawned shell?
866  let &guioptions = save_guioptions
867endfunc
868
869func Test_gui_recursive_mapping()
870  nmap ' <C-W>
871  nmap <C-W>a :let didit = 1<CR>
872  call feedkeys("'a", 'xt')
873  call assert_equal(1, didit)
874
875  nunmap '
876  nunmap <C-W>a
877endfunc
878
879" Test GUI mouse events
880func Test_gui_mouse_event()
881  set mousemodel=extend
882  call test_override('no_query_mouse', 1)
883  new
884  call setline(1, ['one two three', 'four five six'])
885
886  " place the cursor using left click in normal mode
887  call cursor(1, 1)
888  call test_gui_mouse_event(0, 2, 4, 0, 0)
889  call test_gui_mouse_event(3, 2, 4, 0, 0)
890  call feedkeys("\<Esc>", 'Lx!')
891  call assert_equal([0, 2, 4, 0], getpos('.'))
892
893  " select and yank a word
894  let @" = ''
895  call test_gui_mouse_event(0, 1, 9, 0, 0)
896  call test_gui_mouse_event(0, 1, 9, 1, 0)
897  call test_gui_mouse_event(3, 1, 9, 0, 0)
898  call feedkeys("y", 'Lx!')
899  call assert_equal('three', @")
900
901  " create visual selection using right click
902  let @" = ''
903  call test_gui_mouse_event(0, 2, 6, 0, 0)
904  call test_gui_mouse_event(3, 2, 6, 0, 0)
905  call test_gui_mouse_event(2, 2, 13, 0, 0)
906  call test_gui_mouse_event(3, 2, 13, 0, 0)
907  call feedkeys("y", 'Lx!')
908  call assert_equal('five six', @")
909
910  " paste using middle mouse button
911  let @* = 'abc '
912  call feedkeys('""', 'Lx!')
913  call test_gui_mouse_event(1, 1, 9, 0, 0)
914  call test_gui_mouse_event(3, 1, 9, 0, 0)
915  call feedkeys("\<Esc>", 'Lx!')
916  call assert_equal(['one two abc three', 'four five six'], getline(1, '$'))
917
918  " extend visual selection using right click in visual mode
919  let @" = ''
920  call cursor(1, 1)
921  call feedkeys('v', 'Lx!')
922  call test_gui_mouse_event(2, 1, 17, 0, 0)
923  call test_gui_mouse_event(3, 1, 17, 0, 0)
924  call feedkeys("y", 'Lx!')
925  call assert_equal('one two abc three', @")
926
927  " extend visual selection using mouse drag
928  let @" = ''
929  call cursor(1, 1)
930  call test_gui_mouse_event(0, 2, 1, 0, 0)
931  call test_gui_mouse_event(0x43, 2, 9, 0, 0)
932  call test_gui_mouse_event(0x3, 2, 9, 0, 0)
933  call feedkeys("y", 'Lx!')
934  call assert_equal('four five', @")
935
936  " select text by moving the mouse
937  let @" = ''
938  call cursor(1, 1)
939  redraw!
940  call test_gui_mouse_event(0, 1, 4, 0, 0)
941  call test_gui_mouse_event(0x700, 1, 9, 0, 0)
942  call test_gui_mouse_event(0x700, 1, 13, 0, 0)
943  call test_gui_mouse_event(0x3, 1, 13, 0, 0)
944  call feedkeys("y", 'Lx!')
945  call assert_equal(' two abc t', @")
946
947  " Using mouse in insert mode
948  call cursor(1, 1)
949  call feedkeys('i', 't')
950  call test_gui_mouse_event(0, 2, 11, 0, 0)
951  call test_gui_mouse_event(3, 2, 11, 0, 0)
952  call feedkeys("po\<Esc>", 'Lx!')
953  call assert_equal(['one two abc three', 'four five posix'], getline(1, '$'))
954
955  %d _
956  call setline(1, range(1, 100))
957  " scroll up
958  call test_gui_mouse_event(0x200, 2, 1, 0, 0)
959  call test_gui_mouse_event(0x200, 2, 1, 0, 0)
960  call test_gui_mouse_event(0x200, 2, 1, 0, 0)
961  call feedkeys("H", 'Lx!')
962  call assert_equal(10, line('.'))
963
964  " scroll down
965  call test_gui_mouse_event(0x100, 2, 1, 0, 0)
966  call test_gui_mouse_event(0x100, 2, 1, 0, 0)
967  call feedkeys("H", 'Lx!')
968  call assert_equal(4, line('.'))
969
970  %d _
971  set nowrap
972  call setline(1, range(10)->join('')->repeat(10))
973  " scroll left
974  call test_gui_mouse_event(0x500, 1, 5, 0, 0)
975  call test_gui_mouse_event(0x500, 1, 10, 0, 0)
976  call test_gui_mouse_event(0x500, 1, 15, 0, 0)
977  call feedkeys('g0', 'Lx!')
978  call assert_equal(19, col('.'))
979
980  " scroll right
981  call test_gui_mouse_event(0x600, 1, 15, 0, 0)
982  call test_gui_mouse_event(0x600, 1, 10, 0, 0)
983  call feedkeys('g0', 'Lx!')
984  call assert_equal(7, col('.'))
985  set wrap&
986
987  %d _
988  call setline(1, repeat([repeat('a', 60)], 10))
989
990  " record various mouse events
991  let mouseEventNames = [
992        \ 'LeftMouse', 'LeftRelease', '2-LeftMouse', '3-LeftMouse',
993        \ 'S-LeftMouse', 'A-LeftMouse', 'C-LeftMouse', 'MiddleMouse',
994        \ 'MiddleRelease', '2-MiddleMouse', '3-MiddleMouse',
995        \ 'S-MiddleMouse', 'A-MiddleMouse', 'C-MiddleMouse',
996        \ 'RightMouse', 'RightRelease', '2-RightMouse',
997        \ '3-RightMouse', 'S-RightMouse', 'A-RightMouse', 'C-RightMouse',
998        \ 'X1Mouse', 'S-X1Mouse', 'A-X1Mouse', 'C-X1Mouse', 'X2Mouse',
999        \ 'S-X2Mouse', 'A-X2Mouse', 'C-X2Mouse'
1000        \ ]
1001  let mouseEventCodes = map(copy(mouseEventNames), "'<' .. v:val .. '>'")
1002  let g:events = []
1003  for e in mouseEventCodes
1004    exe 'nnoremap ' .. e .. ' <Cmd>call add(g:events, "' ..
1005          \ substitute(e, '[<>]', '', 'g') .. '")<CR>'
1006  endfor
1007
1008  " Test various mouse buttons (0 - Left, 1 - Middle, 2 - Right, 0x300 - X1,
1009  " 0x300- X2)
1010  for button in [0, 1, 2, 0x300, 0x400]
1011    " Single click
1012    call test_gui_mouse_event(button, 2, 5, 0, 0)
1013    call test_gui_mouse_event(3, 2, 5, 0, 0)
1014
1015    " Double/Triple click is supported by only the Left/Middle/Right mouse
1016    " buttons
1017    if button <= 2
1018      " Double Click
1019      call test_gui_mouse_event(button, 2, 5, 0, 0)
1020      call test_gui_mouse_event(button, 2, 5, 1, 0)
1021      call test_gui_mouse_event(3, 2, 5, 0, 0)
1022
1023      " Triple Click
1024      call test_gui_mouse_event(button, 2, 5, 0, 0)
1025      call test_gui_mouse_event(button, 2, 5, 1, 0)
1026      call test_gui_mouse_event(button, 2, 5, 1, 0)
1027      call test_gui_mouse_event(3, 2, 5, 0, 0)
1028    endif
1029
1030    " Shift click
1031    call test_gui_mouse_event(button, 3, 7, 0, 4)
1032    call test_gui_mouse_event(3, 3, 7, 0, 4)
1033
1034    " Alt click
1035    call test_gui_mouse_event(button, 3, 7, 0, 8)
1036    call test_gui_mouse_event(3, 3, 7, 0, 8)
1037
1038    " Ctrl click
1039    call test_gui_mouse_event(button, 3, 7, 0, 16)
1040    call test_gui_mouse_event(3, 3, 7, 0, 16)
1041
1042    call feedkeys("\<Esc>", 'Lx!')
1043  endfor
1044
1045  call assert_equal(['LeftMouse', 'LeftRelease', 'LeftMouse', '2-LeftMouse',
1046        \ 'LeftMouse', '2-LeftMouse', '3-LeftMouse', 'S-LeftMouse',
1047        \ 'A-LeftMouse', 'C-LeftMouse', 'MiddleMouse', 'MiddleRelease',
1048        \ 'MiddleMouse', '2-MiddleMouse', 'MiddleMouse', '2-MiddleMouse',
1049        \ '3-MiddleMouse', 'S-MiddleMouse', 'A-MiddleMouse', 'C-MiddleMouse',
1050        \ 'RightMouse', 'RightRelease', 'RightMouse', '2-RightMouse',
1051        \ 'RightMouse', '2-RightMouse', '3-RightMouse', 'S-RightMouse',
1052        \ 'A-RightMouse', 'C-RightMouse', 'X1Mouse', 'S-X1Mouse', 'A-X1Mouse',
1053        \ 'C-X1Mouse', 'X2Mouse', 'S-X2Mouse', 'A-X2Mouse', 'C-X2Mouse'],
1054        \ g:events)
1055
1056  for e in mouseEventCodes
1057    exe 'nunmap ' .. e
1058  endfor
1059
1060  " modeless selection
1061  set mouse=
1062  let save_guioptions = &guioptions
1063  set guioptions+=A
1064  %d _
1065  call setline(1, ['one two three', 'four five sixteen'])
1066  call cursor(1, 1)
1067  redraw!
1068  " Double click should select the word and copy it to clipboard
1069  let @* = ''
1070  call test_gui_mouse_event(0, 2, 11, 0, 0)
1071  call test_gui_mouse_event(0, 2, 11, 1, 0)
1072  call test_gui_mouse_event(3, 2, 11, 0, 0)
1073  call feedkeys("\<Esc>", 'Lx!')
1074  call assert_equal([0, 1, 1, 0], getpos('.'))
1075  call assert_equal('sixteen', @*)
1076  " Right click should extend the selection from cursor
1077  call cursor(1, 6)
1078  redraw!
1079  let @* = ''
1080  call test_gui_mouse_event(2, 1, 11, 0, 0)
1081  call test_gui_mouse_event(3, 1, 11, 0, 0)
1082  call feedkeys("\<Esc>", 'Lx!')
1083  call assert_equal([0, 1, 6, 0], getpos('.'))
1084  call assert_equal('wo thr', @*)
1085  " Middle click should paste the clipboard contents
1086  call cursor(2, 1)
1087  redraw!
1088  call test_gui_mouse_event(1, 1, 11, 0, 0)
1089  call test_gui_mouse_event(3, 1, 11, 0, 0)
1090  call feedkeys("\<Esc>", 'Lx!')
1091  call assert_equal([0, 2, 7, 0], getpos('.'))
1092  call assert_equal('wo thrfour five sixteen', getline(2))
1093  set mouse&
1094  let &guioptions = save_guioptions
1095
1096  " Test invalid parameters for test_gui_mouse_event()
1097  call assert_fails('call test_gui_mouse_event("", 1, 2, 3, 4)', 'E1210:')
1098  call assert_fails('call test_gui_mouse_event(0, "", 2, 3, 4)', 'E1210:')
1099  call assert_fails('call test_gui_mouse_event(0, 1, "", 3, 4)', 'E1210:')
1100  call assert_fails('call test_gui_mouse_event(0, 1, 2, "", 4)', 'E1210:')
1101  call assert_fails('call test_gui_mouse_event(0, 1, 2, 3, "")', 'E1210:')
1102
1103  bw!
1104  call test_override('no_query_mouse', 0)
1105  set mousemodel&
1106endfunc
1107
1108" Test for 'guitablabel' and 'guitabtooltip' options
1109func TestGuiTabLabel()
1110  call add(g:TabLabels, v:lnum + 100)
1111  let bufnrlist = tabpagebuflist(v:lnum)
1112  return bufname(bufnrlist[tabpagewinnr(v:lnum) - 1])
1113endfunc
1114
1115func TestGuiTabToolTip()
1116  call add(g:TabToolTips, v:lnum + 200)
1117  let bufnrlist = tabpagebuflist(v:lnum)
1118  return bufname(bufnrlist[tabpagewinnr(v:lnum) - 1])
1119endfunc
1120
1121func Test_gui_tablabel_tooltip()
1122  CheckNotFeature gui_athena
1123
1124  %bw!
1125  " Removing the tabline at the end of this test, reduces the window height by
1126  " one. Save and restore it after the test.
1127  let save_lines = &lines
1128  edit one
1129  set modified
1130  tabnew two
1131  set modified
1132  tabnew three
1133  set modified
1134  let g:TabLabels = []
1135  set guitablabel=%{TestGuiTabLabel()}
1136  call test_override('starting', 1)
1137  redrawtabline
1138  call test_override('starting', 0)
1139  call assert_true(index(g:TabLabels, 101) != -1)
1140  call assert_true(index(g:TabLabels, 102) != -1)
1141  call assert_true(index(g:TabLabels, 103) != -1)
1142  set guitablabel&
1143  unlet g:TabLabels
1144
1145  if has('gui_gtk')
1146    " Only on GTK+, the tooltip function is called even if the mouse is not
1147    " on the tabline. on Win32 and Motif, the tooltip function is called only
1148    " when the mouse pointer is over the tabline.
1149    let g:TabToolTips = []
1150    set guitabtooltip=%{TestGuiTabToolTip()}
1151    call test_override('starting', 1)
1152    redrawtabline
1153    call test_override('starting', 0)
1154    call assert_true(index(g:TabToolTips, 201) != -1)
1155    call assert_true(index(g:TabToolTips, 202) != -1)
1156    call assert_true(index(g:TabToolTips, 203) != -1)
1157    set guitabtooltip&
1158    unlet g:TabToolTips
1159  endif
1160  %bw!
1161  let &lines = save_lines
1162endfunc
1163
1164" Test for dropping files into a window in GUI
1165func DropFilesInCmdLine()
1166  CheckFeature drop_file
1167
1168  call feedkeys(":\"", 'L')
1169  call test_gui_drop_files(['a.c', 'b.c'], &lines, 1, 0)
1170  call feedkeys("\<CR>", 'L')
1171endfunc
1172
1173func Test_gui_drop_files()
1174  CheckFeature drop_file
1175
1176  call assert_fails('call test_gui_drop_files(1, 1, 1, 0)', 'E1211:')
1177  call assert_fails('call test_gui_drop_files(["x"], "", 1, 0)', 'E1210:')
1178  call assert_fails('call test_gui_drop_files(["x"], 1, "", 0)', 'E1210:')
1179  call assert_fails('call test_gui_drop_files(["x"], 1, 1, "")', 'E1210:')
1180
1181  %bw!
1182  %argdelete
1183  call test_gui_drop_files([], 1, 1, 0)
1184  call assert_equal([], argv())
1185  call test_gui_drop_files([1, 2], 1, 1, 0)
1186  call assert_equal([], argv())
1187
1188  call test_gui_drop_files(['a.c', 'b.c'], 1, 1, 0)
1189  call assert_equal(['a.c', 'b.c'], argv())
1190  %bw!
1191  %argdelete
1192  call test_gui_drop_files([], 1, 1, 0)
1193  call assert_equal([], argv())
1194  %bw!
1195  " if the buffer in the window is modified, then the file should be opened in
1196  " a new window
1197  set modified
1198  call test_gui_drop_files(['x.c', 'y.c'], 1, 1, 0)
1199  call assert_equal(['x.c', 'y.c'], argv())
1200  call assert_equal(2, winnr('$'))
1201  call assert_equal('x.c', bufname(winbufnr(1)))
1202  %bw!
1203  %argdelete
1204  " if Ctrl is pressed, then the file should be opened in a new window
1205  call test_gui_drop_files(['s.py', 't.py'], 1, 1, 0x10)
1206  call assert_equal(['s.py', 't.py'], argv())
1207  call assert_equal(2, winnr('$'))
1208  call assert_equal('s.py', bufname(winbufnr(1)))
1209  %bw!
1210  %argdelete
1211  " drop the files in a non-current window
1212  belowright new
1213  call test_gui_drop_files(['a.py', 'b.py'], 1, 1, 0)
1214  call assert_equal(['a.py', 'b.py'], argv())
1215  call assert_equal(2, winnr('$'))
1216  call assert_equal(1, winnr())
1217  call assert_equal('a.py', bufname(winbufnr(1)))
1218  %bw!
1219  %argdelete
1220  " pressing shift when dropping files should change directory
1221  let save_cwd = getcwd()
1222  call mkdir('Xdir1')
1223  call writefile([], 'Xdir1/Xfile1')
1224  call writefile([], 'Xdir1/Xfile2')
1225  call test_gui_drop_files(['Xdir1/Xfile1', 'Xdir1/Xfile2'], 1, 1, 0x4)
1226  call assert_equal('Xdir1', fnamemodify(getcwd(), ':t'))
1227  call assert_equal('Xfile1', @%)
1228  call chdir(save_cwd)
1229  " pressing shift when dropping directory and files should change directory
1230  call test_gui_drop_files(['Xdir1', 'Xdir1/Xfile2'], 1, 1, 0x4)
1231  call assert_equal('Xdir1', fnamemodify(getcwd(), ':t'))
1232  call assert_equal('Xdir1', fnamemodify(@%, ':t'))
1233  call chdir(save_cwd)
1234  %bw!
1235  %argdelete
1236  " dropping a directory should edit it
1237  call test_gui_drop_files(['Xdir1'], 1, 1, 0)
1238  call assert_equal('Xdir1', @%)
1239  %bw!
1240  %argdelete
1241  " dropping only a directory name with Shift should ignore it
1242  call test_gui_drop_files(['Xdir1'], 1, 1, 0x4)
1243  call assert_equal('', @%)
1244  %bw!
1245  %argdelete
1246  call delete('Xdir1', 'rf')
1247  " drop files in the command line. The GUI drop files adds the file names to
1248  " the low level input buffer. So need to use a cmdline map and feedkeys()
1249  " with 'Lx!' to process it in this function itself.
1250  cnoremap <expr> <buffer> <F4> DropFilesInCmdLine()
1251  call feedkeys(":\"\<F4>\<CR>", 'xt')
1252  call feedkeys('k', 'Lx!')
1253  call assert_equal('"a.c b.c', @:)
1254  cunmap <buffer> <F4>
1255endfunc
1256
1257" vim: shiftwidth=2 sts=2 expandtab
1258