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