forked from aniani/vim
Problem: spurious CursorHold triggered in GUI on startup
Solution: init global did_cursorhold flag to true
(Gary Johnson)
When Vim is started in GUI mode, the CursorHold autocommand event is
triggered 'updatetime' milliseconds later, even when the user has not
pressed a key. This is different from the behavior of Vim in terminal
mode, which does not trigger a CursorHold autocommand event at startup,
and contradicts the description of the CursorHold event in ":help
CursorHold", which states that the event is "[n]ot triggered until the
user has pressed a key".
The fix is to change the initial value of did_cursorhold from FALSE to
TRUE. While it is true that the CursorDone event has not been done yet
at startup, it should appear to have been done until the user presses
a key.
fixes #17350
closes: #17382
Signed-off-by: Gary Johnson <garyjohn@spocom.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
1773 lines
54 KiB
VimL
1773 lines
54 KiB
VimL
" Tests specifically for the GUI
|
|
|
|
source shared.vim
|
|
source check.vim
|
|
CheckCanRunGui
|
|
|
|
source setup_gui.vim
|
|
|
|
func Setup()
|
|
call GUISetUpCommon()
|
|
endfunc
|
|
|
|
func TearDown()
|
|
call GUITearDownCommon()
|
|
endfunc
|
|
|
|
" Test for resetting "secure" flag after GUI has started.
|
|
" Must be run first, since it starts the GUI on Unix.
|
|
func Test_1_set_secure()
|
|
set exrc secure
|
|
gui -f
|
|
call assert_equal(1, has('gui_running'))
|
|
endfunc
|
|
|
|
" As for non-GUI, a balloon_show() test was already added with patch 8.0.0401
|
|
func Test_balloon_show()
|
|
CheckFeature balloon_eval
|
|
" This won't do anything but must not crash either.
|
|
call balloon_show('hi!')
|
|
endfunc
|
|
|
|
func Test_colorscheme()
|
|
call assert_equal('16777216', &t_Co)
|
|
|
|
let colorscheme_saved = exists('g:colors_name') ? g:colors_name : 'default'
|
|
let g:color_count = 0
|
|
augroup TestColors
|
|
au!
|
|
au ColorScheme * let g:color_count += 1
|
|
\ | let g:after_colors = g:color_count
|
|
\ | let g:color_after = expand('<amatch>')
|
|
au ColorSchemePre * let g:color_count += 1
|
|
\ | let g:before_colors = g:color_count
|
|
\ | let g:color_pre = expand('<amatch>')
|
|
augroup END
|
|
|
|
colorscheme torte
|
|
redraw!
|
|
call assert_equal('dark', &background)
|
|
call assert_equal(1, g:before_colors)
|
|
call assert_equal(2, g:after_colors)
|
|
call assert_equal('torte', g:color_pre)
|
|
call assert_equal('torte', g:color_after)
|
|
call assert_equal("\ntorte", execute('colorscheme'))
|
|
|
|
let a = substitute(execute('hi Search'), "\n\\s\\+", ' ', 'g')
|
|
" FIXME: temporarily check less while the colorscheme changes
|
|
" call assert_match("\nSearch xxx term=reverse cterm=reverse ctermfg=196 ctermbg=16 gui=reverse guifg=#ff0000 guibg=#000000", a)
|
|
call assert_match("\nSearch xxx term=reverse ", a)
|
|
|
|
call assert_fails('colorscheme does_not_exist', 'E185:')
|
|
call assert_equal('does_not_exist', g:color_pre)
|
|
call assert_equal('torte', g:color_after)
|
|
|
|
exec 'colorscheme' colorscheme_saved
|
|
augroup TestColors
|
|
au!
|
|
augroup END
|
|
unlet g:color_count g:after_colors g:before_colors
|
|
redraw!
|
|
endfunc
|
|
|
|
func Test_getfontname_with_arg()
|
|
CheckX11BasedGui
|
|
|
|
if has('gui_motif')
|
|
" Invalid font name. The result should be an empty string.
|
|
call assert_equal('', getfontname('notexist'))
|
|
|
|
" Valid font name. This is usually the real name of 7x13 by default.
|
|
let fname = '-Misc-Fixed-Medium-R-Normal--13-120-75-75-C-70-ISO8859-1'
|
|
call assert_match(fname, getfontname(fname))
|
|
|
|
elseif has('gui_gtk2') || has('gui_gnome') || has('gui_gtk3')
|
|
" Invalid font name. The result should be the name plus the default size.
|
|
call assert_equal('notexist 10', getfontname('notexist'))
|
|
call assert_equal('', getfontname('*'))
|
|
|
|
" Valid font name. This is usually the real name of Monospace by default.
|
|
let fname = 'Bitstream Vera Sans Mono 12'
|
|
call assert_equal(fname, getfontname(fname))
|
|
endif
|
|
endfunc
|
|
|
|
func Test_getfontname_without_arg()
|
|
CheckX11BasedGui
|
|
|
|
let fname = getfontname()
|
|
|
|
if has('gui_kde')
|
|
" 'expected' is the value specified by SetUp() above.
|
|
call assert_equal('Courier 10 Pitch/8/-1/5/50/0/0/0/0/0', fname)
|
|
elseif has('gui_motif')
|
|
" 'expected' is DFLT_FONT of gui_x11.c or its real name.
|
|
let pat = '\(7x13\)\|\(\c-Misc-Fixed-Medium-R-Normal--13-120-75-75-C-70-ISO8859-1\)'
|
|
call assert_match(pat, fname)
|
|
elseif has('gui_gtk2') || has('gui_gnome') || has('gui_gtk3')
|
|
" 'expected' is DEFAULT_FONT of gui_gtk_x11.c (any size)
|
|
call assert_match('^Monospace\>', fname)
|
|
endif
|
|
endfunc
|
|
|
|
func Test_getwinpos()
|
|
CheckX11
|
|
|
|
call assert_match('Window position: X \d\+, Y \d\+', execute('winpos'))
|
|
call assert_true(getwinposx() >= 0)
|
|
call assert_true(getwinposy() >= 0)
|
|
call assert_equal([getwinposx(), getwinposy()], getwinpos())
|
|
endfunc
|
|
|
|
func Test_quoteplus()
|
|
CheckX11BasedGui
|
|
|
|
let g:test_is_flaky = 1
|
|
|
|
let quoteplus_saved = @+
|
|
|
|
let test_call = 'Can you hear me?'
|
|
let test_response = 'Yes, I can.'
|
|
let testee = 'VIMRUNTIME=' .. $VIMRUNTIME .. '; export VIMRUNTIME;'
|
|
\ .. GetVimCommand() .. ' --noplugin --not-a-term -c ''%s'''
|
|
" Ignore the "failed to create input context" error.
|
|
let cmd = 'call test_ignore_error("E285") | '
|
|
\ . 'gui -f | '
|
|
\ . 'call feedkeys("'
|
|
\ . '\"+p'
|
|
\ . ':s/' . test_call . '/' . test_response . '/\<CR>'
|
|
\ . '\"+yis'
|
|
\ . ':q!\<CR>", "tx")'
|
|
let run_vimtest = printf(testee, cmd)
|
|
|
|
" Set the quoteplus register to test_call, and another gvim will launched.
|
|
" Then, it first tries to paste the content of its own quotedplus register
|
|
" onto it. Second, it tries to substitute test_response for the pasted
|
|
" sentence. If the sentence is identical to test_call, the substitution
|
|
" should succeed. Third, it tries to yank the result of the substitution
|
|
" to its own quoteplus register, and last it quits. When system()
|
|
" returns, the content of the quoteplus register should be identical to
|
|
" test_response if those quoteplus registers are synchronized properly
|
|
" with/through the X11 clipboard.
|
|
let @+ = test_call
|
|
call system(run_vimtest)
|
|
call assert_equal(test_response, @+)
|
|
|
|
let @+ = quoteplus_saved
|
|
endfunc
|
|
|
|
func Test_gui_read_stdin()
|
|
CheckUnix
|
|
|
|
call writefile(['some', 'lines'], 'Xstdin', 'D')
|
|
let script =<< trim END
|
|
call writefile(getline(1, '$'), 'XstdinOK')
|
|
qa!
|
|
END
|
|
call writefile(script, 'Xscript', 'D')
|
|
|
|
" Cannot use --not-a-term here, the "reading from stdin" message would not be
|
|
" displayed.
|
|
" However, when using XIM we might get E285, do use it then.
|
|
if has('xim')
|
|
let vimcmd = GetVimCommand()
|
|
else
|
|
let vimcmd = substitute(GetVimCommand(), '--not-a-term', '', '')
|
|
endif
|
|
|
|
call system('cat Xstdin | ' .. vimcmd .. ' -f -g -S Xscript -')
|
|
call assert_equal(['some', 'lines'], readfile('XstdinOK'))
|
|
|
|
call delete('XstdinOK')
|
|
endfunc
|
|
|
|
func Test_set_background()
|
|
let background_saved = &background
|
|
|
|
set background&
|
|
call assert_equal('light', &background)
|
|
|
|
set background=dark
|
|
call assert_equal('dark', &background)
|
|
|
|
let &background = background_saved
|
|
endfunc
|
|
|
|
func Test_set_balloondelay()
|
|
CheckOption balloondelay
|
|
|
|
let balloondelay_saved = &balloondelay
|
|
|
|
" Check if the default value is identical to that described in the manual.
|
|
set balloondelay&
|
|
call assert_equal(600, &balloondelay)
|
|
|
|
" Edge cases
|
|
|
|
" XXX This fact should be hidden so that people won't be tempted to write
|
|
" plugin/TimeMachine.vim. TODO Add reasonable range checks to the source
|
|
" code.
|
|
set balloondelay=-1
|
|
call assert_equal(-1, &balloondelay)
|
|
|
|
" Though it's possible to interpret the zero delay to be 'as soon as
|
|
" possible' or even 'indefinite', its actual meaning depends on the GUI
|
|
" toolkit in use after all.
|
|
set balloondelay=0
|
|
call assert_equal(0, &balloondelay)
|
|
|
|
set balloondelay=1
|
|
call assert_equal(1, &balloondelay)
|
|
|
|
" Since p_bdelay is of type long currently, the upper bound can be
|
|
" impractically huge and machine-dependent. Practically, it's sufficient
|
|
" to check if balloondelay works with 0x7fffffff (32 bits) for now.
|
|
set balloondelay=2147483647
|
|
call assert_equal(2147483647, &balloondelay)
|
|
|
|
let &balloondelay = balloondelay_saved
|
|
endfunc
|
|
|
|
func Test_set_ballooneval()
|
|
CheckOption ballooneval
|
|
|
|
let ballooneval_saved = &ballooneval
|
|
|
|
set ballooneval&
|
|
call assert_equal(0, &ballooneval)
|
|
|
|
set ballooneval
|
|
call assert_notequal(0, &ballooneval)
|
|
|
|
set noballooneval
|
|
call assert_equal(0, &ballooneval)
|
|
|
|
let &ballooneval = ballooneval_saved
|
|
endfunc
|
|
|
|
func Test_set_balloonexpr()
|
|
CheckOption balloonexpr
|
|
|
|
let balloonexpr_saved = &balloonexpr
|
|
|
|
" Default value
|
|
set balloonexpr&
|
|
call assert_equal('', &balloonexpr)
|
|
|
|
" User-defined function
|
|
new
|
|
func MyBalloonExpr()
|
|
return 'Cursor is at line ' . v:beval_lnum .
|
|
\', column ' . v:beval_col .
|
|
\ ' of file ' . bufname(v:beval_bufnr) .
|
|
\ ' on word "' . v:beval_text . '"' .
|
|
\ ' in window ' . v:beval_winid . ' (#' . v:beval_winnr . ')'
|
|
endfunc
|
|
setl balloonexpr=MyBalloonExpr()
|
|
setl ballooneval
|
|
call assert_equal('MyBalloonExpr()', &balloonexpr)
|
|
" TODO Read non-empty text, place the pointer at a character of a word,
|
|
" and check if the content of the balloon is the same as what is expected.
|
|
" Also, check if textlock works as expected.
|
|
setl balloonexpr&
|
|
call assert_equal('', &balloonexpr)
|
|
delfunc MyBalloonExpr
|
|
|
|
" Using a script-local function
|
|
func s:NewBalloonExpr()
|
|
endfunc
|
|
set balloonexpr=s:NewBalloonExpr()
|
|
call assert_equal(expand('<SID>') .. 'NewBalloonExpr()', &balloonexpr)
|
|
set balloonexpr=<SID>NewBalloonExpr()
|
|
call assert_equal(expand('<SID>') .. 'NewBalloonExpr()', &balloonexpr)
|
|
delfunc s:NewBalloonExpr
|
|
bwipe!
|
|
|
|
" Multiline support
|
|
if has('balloon_multiline')
|
|
" Multiline balloon using NL
|
|
new
|
|
func MyBalloonFuncForMultilineUsingNL()
|
|
return "Multiline\nSupported\nBalloon\nusing NL"
|
|
endfunc
|
|
setl balloonexpr=MyBalloonFuncForMultilineUsingNL()
|
|
setl ballooneval
|
|
call assert_equal('MyBalloonFuncForMultilineUsingNL()', &balloonexpr)
|
|
" TODO Read non-empty text, place the pointer at a character of a word,
|
|
" and check if the content of the balloon is the same as what is
|
|
" expected. Also, check if textlock works as expected.
|
|
setl balloonexpr&
|
|
delfunc MyBalloonFuncForMultilineUsingNL
|
|
bwipe!
|
|
|
|
" Multiline balloon using List
|
|
new
|
|
func MyBalloonFuncForMultilineUsingList()
|
|
return [ 'Multiline', 'Supported', 'Balloon', 'using List' ]
|
|
endfunc
|
|
setl balloonexpr=MyBalloonFuncForMultilineUsingList()
|
|
setl ballooneval
|
|
call assert_equal('MyBalloonFuncForMultilineUsingList()', &balloonexpr)
|
|
" TODO Read non-empty text, place the pointer at a character of a word,
|
|
" and check if the content of the balloon is the same as what is
|
|
" expected. Also, check if textlock works as expected.
|
|
setl balloonexpr&
|
|
delfunc MyBalloonFuncForMultilineUsingList
|
|
bwipe!
|
|
endif
|
|
|
|
let &balloonexpr = balloonexpr_saved
|
|
endfunc
|
|
|
|
" Invalid arguments are tested with test_options in conjunction with segfaults
|
|
" caused by them (Patch 8.0.0357, 24922ec233).
|
|
func Test_set_guicursor()
|
|
let guicursor_saved = &guicursor
|
|
|
|
let default = [
|
|
\ "n-v-c:block-Cursor/lCursor",
|
|
\ "ve:ver35-Cursor",
|
|
\ "o:hor50-Cursor",
|
|
\ "i-ci:ver25-Cursor/lCursor",
|
|
\ "r-cr:hor20-Cursor/lCursor",
|
|
\ "sm:block-Cursor-blinkwait175-blinkoff150-blinkon175"
|
|
\ ]
|
|
|
|
" Default Value
|
|
set guicursor&
|
|
call assert_equal(join(default, ','), &guicursor)
|
|
|
|
" Argument List Example 1
|
|
let opt_list = copy(default)
|
|
let opt_list[0] = "n-c-v:block-nCursor"
|
|
exec "set guicursor=" . join(opt_list, ',')
|
|
call assert_equal(join(opt_list, ','), &guicursor)
|
|
unlet opt_list
|
|
|
|
" Argument List Example 2
|
|
let opt_list = copy(default)
|
|
let opt_list[3] = "i-ci:ver30-iCursor-blinkwait300-blinkon200-blinkoff150"
|
|
exec "set guicursor=" . join(opt_list, ',')
|
|
call assert_equal(join(opt_list, ','), &guicursor)
|
|
unlet opt_list
|
|
|
|
" 'a' Mode
|
|
set guicursor&
|
|
let &guicursor .= ',a:blinkon0'
|
|
call assert_equal(join(default, ',') . ",a:blinkon0", &guicursor)
|
|
|
|
let &guicursor = guicursor_saved
|
|
endfunc
|
|
|
|
func Test_set_guifont_errors()
|
|
if has('win32')
|
|
" Invalid font names are accepted in GTK GUI
|
|
call assert_fails('set guifont=xa1bc23d7f', 'E596:')
|
|
endif
|
|
|
|
" This only works if 'renderoptions' exists and does not work for Windows XP
|
|
" and older.
|
|
if exists('+renderoptions') && windowsversion() !~ '^[345]\.'
|
|
" doing this four times used to cause a crash
|
|
set renderoptions=type:directx
|
|
for i in range(5)
|
|
set guifont=
|
|
endfor
|
|
set renderoptions=
|
|
for i in range(5)
|
|
set guifont=
|
|
endfor
|
|
endif
|
|
endfunc
|
|
|
|
func Test_set_guifont()
|
|
CheckX11BasedGui
|
|
|
|
let guifont_saved = &guifont
|
|
if has('xfontset')
|
|
" Prevent 'guifontset' from canceling 'guifont'.
|
|
let guifontset_saved = &guifontset
|
|
set guifontset=
|
|
endif
|
|
|
|
if has('gui_motif')
|
|
" Non-empty font list with invalid font names.
|
|
"
|
|
" This test is twofold: (1) It checks if the command fails as expected
|
|
" when there are no loadable fonts found in the list. (2) It checks if
|
|
" 'guifont' remains the same after the command loads none of the fonts
|
|
" listed.
|
|
let flist = &guifont
|
|
call assert_fails('set guifont=-notexist1-*,-notexist2-*')
|
|
call assert_equal(flist, &guifont)
|
|
|
|
" Non-empty font list with a valid font name. Should pick up the first
|
|
" valid font.
|
|
set guifont=-notexist1-*,fixed,-notexist2-*
|
|
let pat = '\(fixed\)\|\(\c-Misc-Fixed-Medium-R-SemiCondensed--13-120-75-75-C-60-ISO8859-1\)'
|
|
call assert_match(pat, getfontname())
|
|
|
|
" Empty list. Should fallback to the built-in default.
|
|
set guifont=
|
|
let pat = '\(7x13\)\|\(\c-Misc-Fixed-Medium-R-Normal--13-120-75-75-C-70-ISO8859-1\)'
|
|
call assert_match(pat, getfontname())
|
|
|
|
elseif has('gui_gtk2') || has('gui_gnome') || has('gui_gtk3')
|
|
" For GTK, what we refer to as 'font names' in our manual are actually
|
|
" 'initial font patterns'. A valid font which matches the 'canonical font
|
|
" pattern' constructed from a given 'initial pattern' is to be looked up
|
|
" and loaded. That explains why the GTK GUIs appear to accept 'invalid
|
|
" font names'.
|
|
"
|
|
" Non-empty list. Should always pick up the first element, no matter how
|
|
" strange it is, as explained above.
|
|
set guifont=(´・ω・`)\ 12,Courier\ 12
|
|
call assert_equal('(´・ω・`) 12', getfontname())
|
|
|
|
" Empty list. Should fallback to the built-in default.
|
|
set guifont=
|
|
call assert_match('^Monospace\>', getfontname())
|
|
endif
|
|
|
|
if has('xfontset')
|
|
let &guifontset = guifontset_saved
|
|
endif
|
|
let &guifont = guifont_saved
|
|
endfunc
|
|
|
|
func Test_set_guifontset()
|
|
CheckFeature xfontset
|
|
let skipped = ''
|
|
|
|
call assert_fails('set guifontset=*', 'E597:')
|
|
|
|
let ctype_saved = v:ctype
|
|
|
|
" First, since XCreateFontSet(3) is very sensitive to locale, fonts must
|
|
" be chosen meticulously.
|
|
let font_head = '-misc-fixed-medium-r-normal--14'
|
|
|
|
let font_aw70 = font_head . '-130-75-75-c-70'
|
|
let font_aw140 = font_head . '-130-75-75-c-140'
|
|
|
|
let font_jisx0201 = font_aw70 . '-jisx0201.1976-0'
|
|
let font_jisx0208 = font_aw140 . '-jisx0208.1983-0'
|
|
|
|
let full_XLFDs = join([ font_jisx0208, font_jisx0201 ], ',')
|
|
let short_XLFDs = join([ font_aw140, font_aw70 ], ',')
|
|
let singleton = font_head . '-*'
|
|
let aliases = 'k14,r14'
|
|
|
|
" Second, among 'locales', look up such a locale that gets 'set
|
|
" guifontset=' to work successfully with every fontset specified with
|
|
" 'fontsets'.
|
|
let locales = [ 'ja_JP.UTF-8', 'ja_JP.eucJP', 'ja_JP.SJIS' ]
|
|
let fontsets = [ full_XLFDs, short_XLFDs, singleton, aliases ]
|
|
|
|
let feasible = 0
|
|
for locale in locales
|
|
try
|
|
exec 'language ctype' locale
|
|
catch /^Vim\%((\a\+)\)\=:E197/
|
|
continue
|
|
endtry
|
|
let done = 0
|
|
for fontset in fontsets
|
|
try
|
|
exec 'set guifontset=' . fontset
|
|
catch /^Vim\%((\a\+)\)\=:E\%(250\|252\|234\|597\|598\)/
|
|
break
|
|
endtry
|
|
let done += 1
|
|
endfor
|
|
if done == len(fontsets)
|
|
let feasible = 1
|
|
break
|
|
endif
|
|
endfor
|
|
|
|
" Third, give a set of tests if it is found feasible.
|
|
if !feasible
|
|
let skipped = g:not_hosted
|
|
else
|
|
" N.B. 'v:ctype' has already been set to an appropriate value in the
|
|
" previous loop.
|
|
for fontset in fontsets
|
|
exec 'set guifontset=' . fontset
|
|
call assert_equal(fontset, &guifontset)
|
|
endfor
|
|
endif
|
|
|
|
" Finally, restore ctype.
|
|
exec 'language ctype' ctype_saved
|
|
|
|
if !empty(skipped)
|
|
throw skipped
|
|
endif
|
|
endfunc
|
|
|
|
func Test_set_guifontwide()
|
|
CheckX11BasedGui
|
|
|
|
call assert_fails('set guifontwide=*', 'E533:')
|
|
|
|
if has('gui_gtk')
|
|
let guifont_saved = &guifont
|
|
let guifontwide_saved = &guifontwide
|
|
|
|
let fc_match = exepath('fc-match')
|
|
if empty(fc_match)
|
|
let skipped = g:not_hosted
|
|
else
|
|
let &guifont = system('fc-match -f "%{family[0]} %{size}" monospace:size=10:lang=en')
|
|
let wide = system('fc-match -f "%{family[0]} %{size}" monospace:size=10:lang=ja')
|
|
exec 'set guifontwide=' . fnameescape(wide)
|
|
call assert_equal(wide, &guifontwide)
|
|
endif
|
|
|
|
let &guifontwide = guifontwide_saved
|
|
let &guifont = guifont_saved
|
|
|
|
elseif has('gui_motif')
|
|
" guifontwide is premised upon the xfontset feature.
|
|
if !has('xfontset')
|
|
let skipped = g:not_supported . 'xfontset'
|
|
else
|
|
let encoding_saved = &encoding
|
|
let guifont_saved = &guifont
|
|
let guifontset_saved = &guifontset
|
|
let guifontwide_saved = &guifontwide
|
|
|
|
let nfont = '-misc-fixed-medium-r-normal-*-18-120-100-100-c-90-iso10646-1'
|
|
let wfont = '-misc-fixed-medium-r-normal-*-18-120-100-100-c-180-iso10646-1'
|
|
|
|
set encoding=utf-8
|
|
|
|
" Case 1: guifontset is empty
|
|
set guifontset=
|
|
|
|
" Case 1-1: Automatic selection
|
|
set guifontwide=
|
|
exec 'set guifont=' . nfont
|
|
call assert_equal(wfont, &guifontwide)
|
|
|
|
" Case 1-2: Manual selection
|
|
exec 'set guifontwide=' . wfont
|
|
exec 'set guifont=' . nfont
|
|
call assert_equal(wfont, &guifontwide)
|
|
|
|
" Case 2: guifontset is invalid
|
|
try
|
|
set guifontset=-*-notexist-*
|
|
call assert_report("'set guifontset=-*-notexist-*' should have failed")
|
|
catch
|
|
call assert_exception('E598:')
|
|
endtry
|
|
|
|
" Case 2-1: Automatic selection
|
|
set guifontwide=
|
|
exec 'set guifont=' . nfont
|
|
call assert_equal(wfont, &guifontwide)
|
|
|
|
" Case 2-2: Manual selection
|
|
exec 'set guifontwide=' . wfont
|
|
exec 'set guifont=' . nfont
|
|
call assert_equal(wfont, &guifontwide)
|
|
|
|
let &guifontwide = guifontwide_saved
|
|
let &guifontset = guifontset_saved
|
|
let &guifont = guifont_saved
|
|
let &encoding = encoding_saved
|
|
endif
|
|
endif
|
|
endfunc
|
|
|
|
func Test_expand_guifont()
|
|
if has('gui_win32')
|
|
let guifont_saved = &guifont
|
|
let guifontwide_saved = &guifontwide
|
|
|
|
" Test recalling existing option, and suggesting current font size
|
|
set guifont=Courier\ New:h11:cANSI
|
|
call assert_equal('Courier\ New:h11:cANSI', getcompletion('set guifont=', 'cmdline')[0])
|
|
call assert_equal('h11', getcompletion('set guifont=Lucida\ Console:', 'cmdline')[0])
|
|
|
|
" Test auto-completion working for font names
|
|
call assert_equal(['Courier\ New'], getcompletion('set guifont=Couri*ew$', 'cmdline'))
|
|
call assert_equal(['Courier\ New'], getcompletion('set guifontwide=Couri*ew$', 'cmdline'))
|
|
|
|
" Make sure non-monospace fonts are filtered out
|
|
call assert_equal([], getcompletion('set guifont=Arial', 'cmdline'))
|
|
call assert_equal([], getcompletion('set guifontwide=Arial', 'cmdline'))
|
|
|
|
" Test auto-completion working for font options
|
|
call assert_notequal(-1, index(getcompletion('set guifont=Courier\ New:', 'cmdline'), 'b'))
|
|
call assert_equal(['cDEFAULT'], getcompletion('set guifont=Courier\ New:cD*T', 'cmdline'))
|
|
call assert_equal(['qCLEARTYPE'], getcompletion('set guifont=Courier\ New:qC*TYPE', 'cmdline'))
|
|
|
|
let &guifontwide = guifontwide_saved
|
|
let &guifont = guifont_saved
|
|
elseif has('gui_gtk')
|
|
let guifont_saved = &guifont
|
|
let guifontwide_saved = &guifontwide
|
|
|
|
" Test recalling default and existing option
|
|
set guifont=
|
|
call assert_match('^Monospace\>', getcompletion('set guifont=', 'cmdline')[0])
|
|
set guifont=Monospace\ 9
|
|
call assert_equal('Monospace\ 9', getcompletion('set guifont=', 'cmdline')[0])
|
|
|
|
" Test auto-completion working for font names
|
|
call assert_equal(['Monospace'], getcompletion('set guifont=Mono*pace$', 'cmdline'))
|
|
call assert_equal(['Monospace'], getcompletion('set guifontwide=Mono*pace$', 'cmdline'))
|
|
|
|
" Make sure non-monospace fonts are filtered out only in 'guifont'
|
|
call assert_equal([], getcompletion('set guifont=Sans$', 'cmdline'))
|
|
call assert_equal(['Sans'], getcompletion('set guifontwide=Sans$', 'cmdline'))
|
|
|
|
let &guifontwide = guifontwide_saved
|
|
let &guifont = guifont_saved
|
|
else
|
|
call assert_equal([], getcompletion('set guifont=', 'cmdline'))
|
|
endif
|
|
endfunc
|
|
|
|
func Test_set_guiligatures()
|
|
CheckX11BasedGui
|
|
|
|
if has('gui_gtk') || has('gui_gtk2') || has('gui_gnome') || has('gui_gtk3') || has('win32')
|
|
" Try correct value
|
|
set guiligatures=<>=ab
|
|
call assert_equal("<>=ab", &guiligatures)
|
|
" Try to throw error
|
|
try
|
|
set guiligatures=<>=šab
|
|
call assert_report("'set guiligatures=<>=šab should have failed")
|
|
catch
|
|
call assert_exception('E1243:')
|
|
endtry
|
|
endif
|
|
endfunc
|
|
|
|
func Test_set_guiheadroom()
|
|
CheckX11BasedGui
|
|
|
|
" Since this script is to be read together with '-U NONE', the default
|
|
" value must be preserved.
|
|
call assert_equal(50, &guiheadroom)
|
|
endfunc
|
|
|
|
func Test_set_guioptions()
|
|
let guioptions_saved = &guioptions
|
|
let duration = '200m'
|
|
|
|
if has('win32')
|
|
" Default Value
|
|
set guioptions&
|
|
call assert_equal('egmrLtT', &guioptions)
|
|
|
|
else
|
|
" Default Value
|
|
set guioptions&
|
|
call assert_equal('aegimrLtT', &guioptions)
|
|
|
|
" To activate scrollbars of type 'L' or 'R'.
|
|
wincmd v
|
|
redraw!
|
|
|
|
" Remove all default GUI ornaments
|
|
set guioptions-=T
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegimrLt', &guioptions)
|
|
set guioptions-=t
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegimrL', &guioptions)
|
|
set guioptions-=L
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegimr', &guioptions)
|
|
set guioptions-=r
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegim', &guioptions)
|
|
set guioptions-=m
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegi', &guioptions)
|
|
|
|
" Try non-default GUI ornaments
|
|
set guioptions+=l
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegil', &guioptions)
|
|
set guioptions-=l
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegi', &guioptions)
|
|
|
|
set guioptions+=R
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegiR', &guioptions)
|
|
set guioptions-=R
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegi', &guioptions)
|
|
|
|
set guioptions+=b
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegib', &guioptions)
|
|
set guioptions+=h
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegibh', &guioptions)
|
|
set guioptions-=h
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegib', &guioptions)
|
|
set guioptions-=b
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegi', &guioptions)
|
|
|
|
set guioptions+=v
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegiv', &guioptions)
|
|
set guioptions-=v
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegi', &guioptions)
|
|
|
|
if has('gui_motif')
|
|
set guioptions+=F
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegiF', &guioptions)
|
|
set guioptions-=F
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegi', &guioptions)
|
|
endif
|
|
|
|
if has('gui_gtk3')
|
|
set guioptions+=d
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegid', &guioptions)
|
|
set guioptions-=d
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegi', &guioptions)
|
|
endif
|
|
|
|
" Restore GUI ornaments to the default state.
|
|
set guioptions+=m
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegim', &guioptions)
|
|
set guioptions+=r
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegimr', &guioptions)
|
|
set guioptions+=L
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegimrL', &guioptions)
|
|
set guioptions+=t
|
|
exec 'sleep' . duration
|
|
call assert_equal('aegimrLt', &guioptions)
|
|
set guioptions+=T
|
|
exec 'sleep' . duration
|
|
call assert_equal("aegimrLtT", &guioptions)
|
|
|
|
wincmd o
|
|
redraw!
|
|
endif
|
|
|
|
let &guioptions = guioptions_saved
|
|
endfunc
|
|
|
|
func Test_scrollbars()
|
|
" buffer with 200 lines
|
|
call setline(1, repeat(['one', 'two'], 100))
|
|
set scrolloff=0
|
|
set guioptions=rlbk
|
|
|
|
" scroll to move line 11 at top, moves the cursor there
|
|
let args = #{which: 'left', value: 10, dragging: 0}
|
|
call test_gui_event('scrollbar', args)
|
|
redraw
|
|
call assert_equal(1, winline())
|
|
call assert_equal(11, line('.'))
|
|
|
|
" FIXME: This test should also pass with Motif and 24 lines
|
|
if &lines > 24 || !has('gui_motif')
|
|
" scroll to move line 1 at top, cursor stays in line 11
|
|
let args = #{which: 'right', value: 0, dragging: 0}
|
|
call test_gui_event('scrollbar', args)
|
|
redraw
|
|
call assert_equal(11, winline())
|
|
call assert_equal(11, line('.'))
|
|
endif
|
|
|
|
set nowrap
|
|
call setline(11, repeat('x', 150))
|
|
redraw
|
|
call assert_equal(1, wincol())
|
|
set number
|
|
redraw
|
|
call assert_equal(5, wincol())
|
|
set nonumber
|
|
redraw
|
|
call assert_equal(1, col('.'))
|
|
|
|
" scroll to character 11, cursor is moved
|
|
let args = #{which: 'hor', value: 10, dragging: 0}
|
|
call test_gui_event('scrollbar', args)
|
|
redraw
|
|
call assert_equal(1, wincol())
|
|
set number
|
|
redraw
|
|
call assert_equal(5, wincol())
|
|
set nonumber
|
|
redraw
|
|
call assert_equal(11, col('.'))
|
|
|
|
" Invalid arguments
|
|
call assert_false(test_gui_event('scrollbar', {}))
|
|
call assert_false(test_gui_event('scrollbar', #{value: 10, dragging: 0}))
|
|
call assert_false(test_gui_event('scrollbar', #{which: 'hor', dragging: 0}))
|
|
call assert_false(test_gui_event('scrollbar', #{which: 'hor', value: 1}))
|
|
call assert_fails("call test_gui_event('scrollbar', #{which: 'a', value: 1, dragging: 0})", 'E475:')
|
|
|
|
set guioptions&
|
|
set scrolloff&
|
|
set wrap&
|
|
bwipe!
|
|
endfunc
|
|
|
|
func Test_menu()
|
|
CheckFeature quickfix
|
|
|
|
" Check Help menu exists
|
|
let help_menu = execute('menu Help')
|
|
call assert_match('Overview', help_menu)
|
|
|
|
" Check Help menu works
|
|
emenu Help.Overview
|
|
call assert_equal('help', &buftype)
|
|
close
|
|
|
|
" Check deleting menu doesn't cause trouble.
|
|
aunmenu Help
|
|
if exists(':tlmenu')
|
|
tlunmenu Help
|
|
endif
|
|
call assert_fails('menu Help', 'E329:')
|
|
endfunc
|
|
|
|
func Test_set_guipty()
|
|
let guipty_saved = &guipty
|
|
|
|
" Default Value
|
|
set guipty&
|
|
call assert_equal(1, &guipty)
|
|
|
|
set noguipty
|
|
call assert_equal(0, &guipty)
|
|
|
|
let &guipty = guipty_saved
|
|
endfunc
|
|
|
|
func Test_encoding_conversion()
|
|
" GTK supports conversion between 'encoding' and "utf-8"
|
|
CheckFeature gui_gtk
|
|
let encoding_saved = &encoding
|
|
set encoding=latin1
|
|
|
|
" would be nice if we could take a screenshot
|
|
intro
|
|
" sets the window title
|
|
edit SomeFile
|
|
|
|
let &encoding = encoding_saved
|
|
endfunc
|
|
|
|
func Test_shell_command()
|
|
new
|
|
r !echo hello
|
|
call assert_equal('hello', substitute(getline(2), '\W', '', 'g'))
|
|
bwipe!
|
|
endfunc
|
|
|
|
func Test_syntax_colortest()
|
|
runtime syntax/colortest.vim
|
|
redraw!
|
|
sleep 200m
|
|
bwipe!
|
|
endfunc
|
|
|
|
func Test_set_term()
|
|
" It's enough to check the current value since setting 'term' to anything
|
|
" other than builtin_gui makes no sense at all.
|
|
call assert_equal('builtin_gui', &term)
|
|
call assert_fails('set term=xterm', 'E530:')
|
|
endfunc
|
|
|
|
func Test_windowid_variable()
|
|
if g:x11_based_gui || has('win32')
|
|
call assert_true(v:windowid > 0)
|
|
else
|
|
call assert_equal(0, v:windowid)
|
|
endif
|
|
endfunc
|
|
|
|
" Test "vim -g" and also the GUIEnter autocommand.
|
|
func Test_gui_dash_g()
|
|
let cmd = GetVimCommand('Xscriptgui')
|
|
call writefile([""], "Xtestgui", 'D')
|
|
let lines =<< trim END
|
|
au GUIEnter * call writefile(["insertmode: " . &insertmode], "Xtestgui")
|
|
au GUIEnter * qall
|
|
END
|
|
call writefile(lines, 'Xscriptgui', 'D')
|
|
call system(cmd . ' -g')
|
|
call WaitForAssert({-> assert_equal(['insertmode: 0'], readfile('Xtestgui'))})
|
|
endfunc
|
|
|
|
" Test "vim -7" and also the GUIEnter autocommand.
|
|
func Test_gui_dash_y()
|
|
let cmd = GetVimCommand('Xscriptgui')
|
|
call writefile([""], "Xtestgui", 'D')
|
|
let lines =<< trim END
|
|
au GUIEnter * call writefile(["insertmode: " . &insertmode], "Xtestgui")
|
|
au GUIEnter * qall
|
|
END
|
|
call writefile(lines, 'Xscriptgui', 'D')
|
|
call system(cmd . ' -y')
|
|
call WaitForAssert({-> assert_equal(['insertmode: 1'], readfile('Xtestgui'))})
|
|
endfunc
|
|
|
|
" Test for "!" option in 'guioptions'. Use a terminal for running external
|
|
" commands
|
|
func Test_gui_run_cmd_in_terminal()
|
|
CheckFeature terminal
|
|
let save_guioptions = &guioptions
|
|
set guioptions+=!
|
|
if has('win32')
|
|
let cmd = 'type'
|
|
else
|
|
" assume all the other systems have a cat command
|
|
let cmd = 'cat'
|
|
endif
|
|
exe "silent !" . cmd . " test_gui.vim"
|
|
" TODO: how to check that the command ran in a separate terminal?
|
|
" Maybe check for $TERM (dumb vs xterm) in the spawned shell?
|
|
let &guioptions = save_guioptions
|
|
endfunc
|
|
|
|
func Test_gui_recursive_mapping()
|
|
nmap ' <C-W>
|
|
nmap <C-W>a :let didit = 1<CR>
|
|
call feedkeys("'a", 'xt')
|
|
call assert_equal(1, didit)
|
|
|
|
nunmap '
|
|
nunmap <C-W>a
|
|
endfunc
|
|
|
|
" Test GUI mouse events
|
|
func Test_gui_mouse_event()
|
|
" Low level input isn't 100% reliable
|
|
let g:test_is_flaky = 1
|
|
|
|
set mousemodel=extend
|
|
call test_override('no_query_mouse', 1)
|
|
new
|
|
call setline(1, ['one two three', 'four five six'])
|
|
call cursor(1, 1)
|
|
redraw!
|
|
|
|
" place the cursor using left click and release in normal mode
|
|
let args = #{button: 0, row: 2, col: 4, multiclick: 0, modifiers: 0}
|
|
call test_gui_event('mouse', args)
|
|
let args.button = 3
|
|
eval 'mouse'->test_gui_event(args)
|
|
call feedkeys("\<Esc>", 'Lx!')
|
|
call assert_equal([0, 2, 4, 0], getpos('.'))
|
|
|
|
" select and yank a word
|
|
let @" = ''
|
|
let args = #{button: 0, row: 1, col: 9, multiclick: 0, modifiers: 0}
|
|
call test_gui_event('mouse', args)
|
|
let args.multiclick = 1
|
|
call test_gui_event('mouse', args)
|
|
let args.button = 3
|
|
let args.multiclick = 0
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys("y", 'Lx!')
|
|
call assert_equal('three', @")
|
|
|
|
" create visual selection using right click
|
|
let @" = ''
|
|
let args = #{button: 0, row: 2, col: 6, multiclick: 0, modifiers: 0}
|
|
call test_gui_event('mouse', args)
|
|
let args.button = 3
|
|
call test_gui_event('mouse', args)
|
|
let args = #{button: 2, row: 2, col: 13, multiclick: 0, modifiers: 0}
|
|
call test_gui_event('mouse', args)
|
|
let args.button = 3
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys("y", 'Lx!')
|
|
call assert_equal('five six', @")
|
|
|
|
" paste using middle mouse button
|
|
let @* = 'abc '
|
|
call feedkeys('""', 'Lx!')
|
|
let args = #{button: 1, row: 1, col: 9, multiclick: 0, modifiers: 0}
|
|
call test_gui_event('mouse', args)
|
|
let args.button = 3
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys("\<Esc>", 'Lx!')
|
|
call assert_equal(['one two abc three', 'four five six'], getline(1, '$'))
|
|
|
|
" extend visual selection using right click in visual mode
|
|
let @" = ''
|
|
call cursor(1, 1)
|
|
call feedkeys('v', 'Lx!')
|
|
let args = #{button: 2, row: 1, col: 17, multiclick: 0, modifiers: 0}
|
|
call test_gui_event('mouse', args)
|
|
let args.button = 3
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys("y", 'Lx!')
|
|
call assert_equal('one two abc three', @")
|
|
|
|
" extend visual selection using mouse drag
|
|
let @" = ''
|
|
call cursor(1, 1)
|
|
let args = #{button: 0, row: 2, col: 1, multiclick: 0, modifiers: 0}
|
|
call test_gui_event('mouse', args)
|
|
let args = #{button: 0x43, row: 2, col: 9, multiclick: 0, modifiers: 0}
|
|
call test_gui_event('mouse', args)
|
|
let args.button = 0x3
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys("y", 'Lx!')
|
|
call assert_equal('four five', @")
|
|
|
|
" select text by moving the mouse
|
|
let @" = ''
|
|
call cursor(1, 1)
|
|
redraw!
|
|
let args = #{button: 0, row: 1, col: 4, multiclick: 0, modifiers: 0}
|
|
call test_gui_event('mouse', args)
|
|
let args.button = 0x700
|
|
let args.col = 9
|
|
call test_gui_event('mouse', args)
|
|
let args.col = 13
|
|
call test_gui_event('mouse', args)
|
|
let args.button = 3
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys("y", 'Lx!')
|
|
call assert_equal(' two abc t', @")
|
|
|
|
" Using mouse in insert mode
|
|
call cursor(1, 1)
|
|
call feedkeys('i', 't')
|
|
let args = #{button: 0, row: 2, col: 11, multiclick: 0, modifiers: 0}
|
|
call test_gui_event('mouse', args)
|
|
let args.button = 3
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys("po\<Esc>", 'Lx!')
|
|
call assert_equal(['one two abc three', 'four five posix'], getline(1, '$'))
|
|
|
|
%d _
|
|
set scrolloff=0
|
|
call setline(1, range(1, 100))
|
|
" scroll up
|
|
let args = #{button: 0x200, row: 2, col: 1, multiclick: 0, modifiers: 0}
|
|
call test_gui_event('mouse', args)
|
|
call test_gui_event('mouse', args)
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys("H", 'Lx!')
|
|
call assert_equal(10, line('.'))
|
|
|
|
" scroll down
|
|
let args = #{button: 0x100, row: 2, col: 1, multiclick: 0, modifiers: 0}
|
|
call test_gui_event('mouse', args)
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys("H", 'Lx!')
|
|
call assert_equal(4, line('.'))
|
|
set scrolloff&
|
|
|
|
%d _
|
|
set nowrap
|
|
call setline(1, range(10)->join('')->repeat(10))
|
|
" scroll left
|
|
let args = #{button: 0x500, row: 1, col: 5, multiclick: 0, modifiers: 0}
|
|
call test_gui_event('mouse', args)
|
|
let args.col = 10
|
|
call test_gui_event('mouse', args)
|
|
let args.col = 15
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys('g0', 'Lx!')
|
|
call assert_equal(19, col('.'))
|
|
|
|
" scroll right
|
|
let args = #{button: 0x600, row: 1, col: 15, multiclick: 0, modifiers: 0}
|
|
call test_gui_event('mouse', args)
|
|
let args.col = 10
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys('g0', 'Lx!')
|
|
call assert_equal(7, col('.'))
|
|
set wrap&
|
|
|
|
%d _
|
|
call setline(1, repeat([repeat('a', 60)], 10))
|
|
|
|
" record various mouse events
|
|
let mouseEventNames = [
|
|
\ 'LeftMouse', 'LeftRelease', '2-LeftMouse', '3-LeftMouse',
|
|
\ 'S-LeftMouse', 'A-LeftMouse', 'C-LeftMouse', 'MiddleMouse',
|
|
\ 'MiddleRelease', '2-MiddleMouse', '3-MiddleMouse',
|
|
\ 'S-MiddleMouse', 'A-MiddleMouse', 'C-MiddleMouse',
|
|
\ 'RightMouse', 'RightRelease', '2-RightMouse',
|
|
\ '3-RightMouse', 'S-RightMouse', 'A-RightMouse', 'C-RightMouse',
|
|
\ 'X1Mouse', 'S-X1Mouse', 'A-X1Mouse', 'C-X1Mouse', 'X2Mouse',
|
|
\ 'S-X2Mouse', 'A-X2Mouse', 'C-X2Mouse'
|
|
\ ]
|
|
let mouseEventCodes = map(copy(mouseEventNames), "'<' .. v:val .. '>'")
|
|
let g:events = []
|
|
for e in mouseEventCodes
|
|
exe 'nnoremap ' .. e .. ' <Cmd>call add(g:events, "' ..
|
|
\ substitute(e, '[<>]', '', 'g') .. '")<CR>'
|
|
endfor
|
|
|
|
" Test various mouse buttons (0 - Left, 1 - Middle, 2 - Right, 0x300 - X1,
|
|
" 0x300- X2)
|
|
for button in [0, 1, 2, 0x300, 0x400]
|
|
" Single click
|
|
let args = #{button: button, row: 2, col: 5, multiclick: 0, modifiers: 0}
|
|
call test_gui_event('mouse', args)
|
|
let args.button = 3
|
|
call test_gui_event('mouse', args)
|
|
|
|
" Double/Triple click is supported by only the Left/Middle/Right mouse
|
|
" buttons
|
|
if button <= 2
|
|
" Double Click
|
|
let args.button = button
|
|
call test_gui_event('mouse', args)
|
|
let args.multiclick = 1
|
|
call test_gui_event('mouse', args)
|
|
let args.button = 3
|
|
let args.multiclick = 0
|
|
call test_gui_event('mouse', args)
|
|
|
|
" Triple Click
|
|
let args.button = button
|
|
call test_gui_event('mouse', args)
|
|
let args.multiclick = 1
|
|
call test_gui_event('mouse', args)
|
|
call test_gui_event('mouse', args)
|
|
let args.button = 3
|
|
let args.multiclick = 0
|
|
call test_gui_event('mouse', args)
|
|
endif
|
|
|
|
" Shift click
|
|
let args = #{button: button, row: 3, col: 7, multiclick: 0, modifiers: 4}
|
|
call test_gui_event('mouse', args)
|
|
let args.button = 3
|
|
call test_gui_event('mouse', args)
|
|
|
|
" Alt click
|
|
let args.button = button
|
|
let args.modifiers = 8
|
|
call test_gui_event('mouse', args)
|
|
let args.button = 3
|
|
call test_gui_event('mouse', args)
|
|
|
|
" Ctrl click
|
|
let args.button = button
|
|
let args.modifiers = 16
|
|
call test_gui_event('mouse', args)
|
|
let args.button = 3
|
|
call test_gui_event('mouse', args)
|
|
|
|
call feedkeys("\<Esc>", 'Lx!')
|
|
endfor
|
|
|
|
call assert_equal(['LeftMouse', 'LeftRelease', 'LeftMouse', '2-LeftMouse',
|
|
\ 'LeftMouse', '2-LeftMouse', '3-LeftMouse', 'S-LeftMouse',
|
|
\ 'A-LeftMouse', 'C-LeftMouse', 'MiddleMouse', 'MiddleRelease',
|
|
\ 'MiddleMouse', '2-MiddleMouse', 'MiddleMouse', '2-MiddleMouse',
|
|
\ '3-MiddleMouse', 'S-MiddleMouse', 'A-MiddleMouse', 'C-MiddleMouse',
|
|
\ 'RightMouse', 'RightRelease', 'RightMouse', '2-RightMouse',
|
|
\ 'RightMouse', '2-RightMouse', '3-RightMouse', 'S-RightMouse',
|
|
\ 'A-RightMouse', 'C-RightMouse', 'X1Mouse', 'S-X1Mouse', 'A-X1Mouse',
|
|
\ 'C-X1Mouse', 'X2Mouse', 'S-X2Mouse', 'A-X2Mouse', 'C-X2Mouse'],
|
|
\ g:events)
|
|
|
|
for e in mouseEventCodes
|
|
exe 'nunmap ' .. e
|
|
endfor
|
|
|
|
" modeless selection
|
|
set mouse=
|
|
let save_guioptions = &guioptions
|
|
set guioptions+=A
|
|
%d _
|
|
call setline(1, ['one two three', 'four five sixteen'])
|
|
call cursor(1, 1)
|
|
redraw!
|
|
" Double click should select the word and copy it to clipboard
|
|
let @* = ''
|
|
let args = #{button: 0, row: 2, col: 11, multiclick: 0, modifiers: 0}
|
|
call test_gui_event('mouse', args)
|
|
let args.multiclick = 1
|
|
call test_gui_event('mouse', args)
|
|
let args.button = 3
|
|
let args.multiclick = 0
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys("\<Esc>", 'Lx!')
|
|
call assert_equal([0, 1, 1, 0], getpos('.'))
|
|
call assert_equal('sixteen', @*)
|
|
" Right click should extend the selection from cursor
|
|
call cursor(1, 6)
|
|
redraw!
|
|
let @* = ''
|
|
let args = #{button: 2, row: 1, col: 11, multiclick: 0, modifiers: 0}
|
|
call test_gui_event('mouse', args)
|
|
let args.button = 3
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys("\<Esc>", 'Lx!')
|
|
call assert_equal([0, 1, 6, 0], getpos('.'))
|
|
call assert_equal('wo thr', @*)
|
|
" Middle click should paste the clipboard contents
|
|
call cursor(2, 1)
|
|
redraw!
|
|
let args = #{button: 1, row: 1, col: 11, multiclick: 0, modifiers: 0}
|
|
call test_gui_event('mouse', args)
|
|
let args.button = 3
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys("\<Esc>", 'Lx!')
|
|
call assert_equal([0, 2, 7, 0], getpos('.'))
|
|
call assert_equal('wo thrfour five sixteen', getline(2))
|
|
|
|
set mouse&
|
|
let &guioptions = save_guioptions
|
|
bw!
|
|
call test_override('no_query_mouse', 0)
|
|
set mousemodel&
|
|
endfunc
|
|
|
|
" Test invalid parameters for test_gui_event()
|
|
func Test_gui_event_mouse_fails()
|
|
call test_override('no_query_mouse', 1)
|
|
new
|
|
call setline(1, ['one two three', 'four five six'])
|
|
set mousemodel=extend
|
|
|
|
let args = #{row: 2, col: 4, multiclick: 0, modifiers: 0}
|
|
call assert_false(test_gui_event('mouse', args))
|
|
let args = #{button: 0, col: 4, multiclick: 0, modifiers: 0}
|
|
call assert_false(test_gui_event('mouse', args))
|
|
let args = #{button: 0, row: 2, multiclick: 0, modifiers: 0}
|
|
call assert_false(test_gui_event('mouse', args))
|
|
let args = #{button: 0, row: 2, col: 4, modifiers: 0}
|
|
call assert_false(test_gui_event('mouse', args))
|
|
let args = #{button: 0, row: 2, col: 4, multiclick: 0}
|
|
call assert_false(test_gui_event('mouse', args))
|
|
|
|
" Error cases for test_gui_event()
|
|
call assert_fails("call test_gui_event('a1b2c3', args)", 'E475:')
|
|
call assert_fails("call test_gui_event([], args)", 'E1174:')
|
|
call assert_fails("call test_gui_event('abc', [])", 'E1206:')
|
|
call assert_fails("call test_gui_event(test_null_string(), {})", 'E475:')
|
|
call assert_false(test_gui_event('mouse', test_null_dict()))
|
|
|
|
bw!
|
|
call test_override('no_query_mouse', 0)
|
|
set mousemodel&
|
|
endfunc
|
|
|
|
" Move the mouse to the top-left in preparation for mouse events
|
|
func PrepareForMouseEvent(args)
|
|
call extend(a:args, #{row: 1, col: 1})
|
|
call test_gui_event('mouse', a:args)
|
|
let g:eventlist = []
|
|
call feedkeys('', 'Lx!')
|
|
|
|
" Wait a bit for the event. I may not come if the mouse didn't move, wait up
|
|
" to 100 msec.
|
|
for n in range(10)
|
|
if len(g:eventlist) > 0
|
|
break
|
|
endif
|
|
sleep 10m
|
|
endfor
|
|
let g:eventlist = []
|
|
endfunc
|
|
|
|
func MouseWasMoved()
|
|
let pos = getmousepos()
|
|
call add(g:eventlist, #{row: pos.screenrow, col: pos.screencol})
|
|
endfunc
|
|
|
|
func Test_gui_mouse_move_event()
|
|
let args = #{move: 1, button: 0, multiclick: 0, modifiers: 0}
|
|
|
|
" by default, no mouse move events are generated
|
|
set mousemev&
|
|
call assert_false(&mousemev)
|
|
|
|
let g:eventlist = []
|
|
nnoremap <special> <silent> <MouseMove> :call MouseWasMoved()<CR>
|
|
|
|
" start at mouse pos (1,1), clear counter
|
|
call PrepareForMouseEvent(args)
|
|
|
|
call extend(args, #{row: 3, col: 30, cell: v:true})
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys('', 'Lx!')
|
|
|
|
call extend(args, #{row: 10, col: 30, cell: v:true})
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys('', 'Lx!')
|
|
|
|
" no events since 'mousemev' is off
|
|
call assert_equal([], g:eventlist)
|
|
|
|
" turn on mouse events and try the same thing
|
|
set mousemev
|
|
call PrepareForMouseEvent(args)
|
|
|
|
call extend(args, #{row: 3, col: 30, cell: v:true})
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys('', 'Lx!')
|
|
|
|
call extend(args, #{row: 10, col: 30, cell: v:true})
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys('', 'Lx!')
|
|
|
|
" FIXME: on MS-Windows we get a stray event first
|
|
if has('win32') && len(g:eventlist) == 3
|
|
let g:eventlist = g:eventlist[1 : ]
|
|
endif
|
|
|
|
call assert_equal([#{row: 3, col: 30}, #{row: 10, col: 30}], g:eventlist)
|
|
|
|
" wiggle the mouse around within a screen cell, shouldn't trigger events
|
|
call extend(args, #{cell: v:false})
|
|
call PrepareForMouseEvent(args)
|
|
|
|
call extend(args, #{row: 1, col: 2, cell: v:false})
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys('', 'Lx!')
|
|
|
|
call extend(args, #{row: 2, col: 2, cell: v:false})
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys('', 'Lx!')
|
|
|
|
call extend(args, #{row: 2, col: 1, cell: v:false})
|
|
call test_gui_event('mouse', args)
|
|
call feedkeys('', 'Lx!')
|
|
|
|
call assert_equal([], g:eventlist)
|
|
|
|
unlet g:eventlist
|
|
unmap <MouseMove>
|
|
set mousemev&
|
|
endfunc
|
|
|
|
" Test for 'guitablabel' and 'guitabtooltip' options
|
|
func TestGuiTabLabel()
|
|
call add(g:TabLabels, v:lnum + 100)
|
|
let bufnrlist = tabpagebuflist(v:lnum)
|
|
return bufname(bufnrlist[tabpagewinnr(v:lnum) - 1])
|
|
endfunc
|
|
|
|
func TestGuiTabToolTip()
|
|
call add(g:TabToolTips, v:lnum + 200)
|
|
let bufnrlist = tabpagebuflist(v:lnum)
|
|
return bufname(bufnrlist[tabpagewinnr(v:lnum) - 1])
|
|
endfunc
|
|
|
|
func Test_gui_tablabel_tooltip()
|
|
%bw!
|
|
" Removing the tabline at the end of this test, reduces the window height by
|
|
" one. Save and restore it after the test.
|
|
let save_lines = &lines
|
|
edit one
|
|
set modified
|
|
tabnew two
|
|
set modified
|
|
tabnew three
|
|
set modified
|
|
let g:TabLabels = []
|
|
set guitablabel=%{TestGuiTabLabel()}
|
|
call test_override('starting', 1)
|
|
redrawtabline
|
|
call test_override('starting', 0)
|
|
call assert_true(index(g:TabLabels, 101) != -1)
|
|
call assert_true(index(g:TabLabels, 102) != -1)
|
|
call assert_true(index(g:TabLabels, 103) != -1)
|
|
set guitablabel&
|
|
unlet g:TabLabels
|
|
|
|
if has('gui_gtk')
|
|
" Only on GTK+, the tooltip function is called even if the mouse is not
|
|
" on the tabline. on Win32 and Motif, the tooltip function is called only
|
|
" when the mouse pointer is over the tabline.
|
|
let g:TabToolTips = []
|
|
set guitabtooltip=%{TestGuiTabToolTip()}
|
|
call test_override('starting', 1)
|
|
redrawtabline
|
|
call test_override('starting', 0)
|
|
call assert_true(index(g:TabToolTips, 201) != -1)
|
|
call assert_true(index(g:TabToolTips, 202) != -1)
|
|
call assert_true(index(g:TabToolTips, 203) != -1)
|
|
set guitabtooltip&
|
|
unlet g:TabToolTips
|
|
endif
|
|
%bw!
|
|
let &lines = save_lines
|
|
endfunc
|
|
|
|
" Test for dropping files into a window in GUI
|
|
func DropFilesInCmdLine()
|
|
call feedkeys(":\"", 'L')
|
|
let d = #{files: ['a.c', 'b.c'], row: &lines, col: 1, modifiers: 0}
|
|
call test_gui_event('dropfiles', d)
|
|
call feedkeys("\<CR>", 'L')
|
|
endfunc
|
|
|
|
func Test_gui_drop_files()
|
|
CheckFeature drop_file
|
|
|
|
%bw!
|
|
%argdelete
|
|
let d = #{files: [], row: 1, col: 1, modifiers: 0}
|
|
call test_gui_event('dropfiles', d)
|
|
call assert_equal([], argv())
|
|
let d = #{files: [1, 2], row: 1, col: 1, modifiers: 0}
|
|
call test_gui_event('dropfiles', d)
|
|
call assert_equal([], argv())
|
|
|
|
let d = #{files: ['a.c', 'b.c'], row: 1, col: 1, modifiers: 0}
|
|
call test_gui_event('dropfiles', d)
|
|
call assert_equal(['a.c', 'b.c'], argv())
|
|
%bw!
|
|
%argdelete
|
|
let d = #{files: [], row: 1, col: 1, modifiers: 0}
|
|
call test_gui_event('dropfiles', d)
|
|
call assert_equal([], argv())
|
|
%bw!
|
|
" if the buffer in the window is modified, then the file should be opened in
|
|
" a new window
|
|
set modified
|
|
let d = #{files: ['x.c', 'y.c'], row: 1, col: 1, modifiers: 0}
|
|
call test_gui_event('dropfiles', d)
|
|
call assert_equal(['x.c', 'y.c'], argv())
|
|
call assert_equal(2, winnr('$'))
|
|
call assert_equal('x.c', bufname(winbufnr(1)))
|
|
%bw!
|
|
%argdelete
|
|
" if Ctrl is pressed, then the file should be opened in a new window
|
|
let d = #{files: ['s.py', 't.py'], row: 1, col: 1, modifiers: 0x10}
|
|
eval 'dropfiles'->test_gui_event(d)
|
|
call assert_equal(['s.py', 't.py'], argv())
|
|
call assert_equal(2, winnr('$'))
|
|
call assert_equal('s.py', bufname(winbufnr(1)))
|
|
%bw!
|
|
%argdelete
|
|
" drop the files in a non-current window
|
|
belowright new
|
|
let d = #{files: ['a.py', 'b.py'], row: 1, col: 1, modifiers: 0}
|
|
call test_gui_event('dropfiles', d)
|
|
call assert_equal(['a.py', 'b.py'], argv())
|
|
call assert_equal(2, winnr('$'))
|
|
call assert_equal(1, winnr())
|
|
call assert_equal('a.py', bufname(winbufnr(1)))
|
|
%bw!
|
|
%argdelete
|
|
" pressing shift when dropping files should change directory
|
|
let save_cwd = getcwd()
|
|
call mkdir('Xdropdir1', 'R')
|
|
call writefile([], 'Xdropdir1/Xfile1')
|
|
call writefile([], 'Xdropdir1/Xfile2')
|
|
let d = #{files: ['Xdropdir1/Xfile1', 'Xdropdir1/Xfile2'], row: 1, col: 1,
|
|
\ modifiers: 0x4}
|
|
call test_gui_event('dropfiles', d)
|
|
call assert_equal('Xdropdir1', fnamemodify(getcwd(), ':t'))
|
|
call assert_equal('Xfile1', @%)
|
|
call chdir(save_cwd)
|
|
" pressing shift when dropping directory and files should change directory
|
|
let d = #{files: ['Xdropdir1', 'Xdropdir1/Xfile2'], row: 1, col: 1, modifiers: 0x4}
|
|
call test_gui_event('dropfiles', d)
|
|
call assert_equal('Xdropdir1', fnamemodify(getcwd(), ':t'))
|
|
call assert_equal('Xdropdir1', fnamemodify(@%, ':t'))
|
|
call chdir(save_cwd)
|
|
%bw!
|
|
%argdelete
|
|
" dropping a directory should edit it
|
|
let d = #{files: ['Xdropdir1'], row: 1, col: 1, modifiers: 0}
|
|
call test_gui_event('dropfiles', d)
|
|
call assert_equal('Xdropdir1', @%)
|
|
%bw!
|
|
%argdelete
|
|
" dropping only a directory name with Shift should ignore it
|
|
let d = #{files: ['Xdropdir1'], row: 1, col: 1, modifiers: 0x4}
|
|
call test_gui_event('dropfiles', d)
|
|
call assert_equal('', @%)
|
|
%bw!
|
|
%argdelete
|
|
|
|
" drop files in the command line. The GUI drop files adds the file names to
|
|
" the low level input buffer. So need to use a cmdline map and feedkeys()
|
|
" with 'Lx!' to process it in this function itself.
|
|
" This sometimes fails, e.g. when using valgrind.
|
|
let g:test_is_flaky = 1
|
|
cnoremap <expr> <buffer> <F4> DropFilesInCmdLine()
|
|
call feedkeys(":\"\<F4>\<CR>", 'xt')
|
|
call feedkeys('k', 'Lx!')
|
|
call assert_equal('"a.c b.c', @:)
|
|
cunmap <buffer> <F4>
|
|
|
|
" Invalid arguments
|
|
call assert_false(test_gui_event("dropfiles", {}))
|
|
let d = #{row: 1, col: 1, modifiers: 0}
|
|
call assert_false(test_gui_event("dropfiles", d))
|
|
let d = #{files: 1, row: 1, col: 1, modifiers: 0}
|
|
call assert_false(test_gui_event("dropfiles", d))
|
|
let d = #{files: test_null_list(), row: 1, col: 1, modifiers: 0}
|
|
call assert_false(test_gui_event("dropfiles", d))
|
|
let d = #{files: [test_null_string()], row: 1, col: 1, modifiers: 0}
|
|
call assert_true(test_gui_event("dropfiles", d))
|
|
endfunc
|
|
|
|
" Test for generating a GUI tabline event to select a tab page
|
|
func Test_gui_tabline_event()
|
|
%bw!
|
|
edit Xfile1
|
|
tabedit Xfile2
|
|
tabedit Xfile3
|
|
|
|
tabfirst
|
|
call assert_equal(v:true, test_gui_event('tabline', #{tabnr: 2}))
|
|
call feedkeys("y", "Lx!")
|
|
call assert_equal(2, tabpagenr())
|
|
call assert_equal(v:true, test_gui_event('tabline', #{tabnr: 3}))
|
|
call feedkeys("y", "Lx!")
|
|
call assert_equal(3, tabpagenr())
|
|
call assert_equal(v:false, 'tabline'->test_gui_event(#{tabnr: 3}))
|
|
|
|
" From the cmdline window, tabline event should not be handled
|
|
call feedkeys("q::let t = test_gui_event('tabline', #{tabnr: 2})\<CR>:q\<CR>", 'x!')
|
|
call assert_equal(v:false, t)
|
|
|
|
" Invalid arguments
|
|
call assert_false(test_gui_event('tabline', {}))
|
|
call assert_false(test_gui_event('tabline', #{abc: 1}))
|
|
|
|
%bw!
|
|
endfunc
|
|
|
|
" Test for generating a GUI tabline menu event to execute an action
|
|
func Test_gui_tabmenu_event()
|
|
%bw!
|
|
|
|
" Try to close the last tab page
|
|
call test_gui_event('tabmenu', #{tabnr: 1, item: 1})
|
|
call feedkeys("y", "Lx!")
|
|
|
|
edit Xfile1
|
|
tabedit Xfile2
|
|
call test_gui_event('tabmenu', #{tabnr: 1, item: 1})
|
|
call feedkeys("y", "Lx!")
|
|
call assert_equal(1, tabpagenr('$'))
|
|
call assert_equal('Xfile2', bufname())
|
|
|
|
eval 'tabmenu'->test_gui_event(#{tabnr: 1, item: 2})
|
|
call feedkeys("y", "Lx!")
|
|
call assert_equal(2, tabpagenr('$'))
|
|
|
|
" If tabnr is 0, then the current tabpage should be used.
|
|
call test_gui_event('tabmenu', #{tabnr: 0, item: 2})
|
|
call feedkeys("y", "Lx!")
|
|
call assert_equal(3, tabpagenr('$'))
|
|
call test_gui_event('tabmenu', #{tabnr: 0, item: 1})
|
|
call feedkeys("y", "Lx!")
|
|
call assert_equal(2, tabpagenr('$'))
|
|
|
|
" Invalid arguments
|
|
call assert_false(test_gui_event('tabmenu', {}))
|
|
call assert_false(test_gui_event('tabmenu', #{tabnr: 1}))
|
|
call assert_false(test_gui_event('tabmenu', #{item: 1}))
|
|
call assert_false(test_gui_event('tabmenu', #{abc: 1}))
|
|
|
|
%bw!
|
|
endfunc
|
|
|
|
" Test for find/replace text dialog event
|
|
func Test_gui_findrepl()
|
|
" Find/Replace dialog is supported only on GTK, Motif and MS-Windows.
|
|
if !has('gui_gtk') && !has('gui_motif') && !has('gui_win32')
|
|
return
|
|
endif
|
|
|
|
new
|
|
call setline(1, ['one two one', 'Twoo One two oneo'])
|
|
|
|
" Replace all instances of a string with another
|
|
let args = #{find_text: 'one', repl_text: 'ONE', flags: 0x4, forward: 1}
|
|
call test_gui_event('findrepl', args)
|
|
call assert_equal(['ONE two ONE', 'Twoo ONE two ONEo'], getline(1, '$'))
|
|
|
|
" Replace all instances of a whole string with another
|
|
call cursor(1, 1)
|
|
let args = #{find_text: 'two', repl_text: 'TWO', flags: 0xC, forward: 1}
|
|
call test_gui_event('findrepl', args)
|
|
call assert_equal(['ONE TWO ONE', 'Twoo ONE TWO ONEo'], getline(1, '$'))
|
|
|
|
" Find next occurrence of a string (in a find dialog)
|
|
call cursor(1, 11)
|
|
let args = #{find_text: 'TWO', repl_text: '', flags: 0x11, forward: 1}
|
|
call test_gui_event('findrepl', args)
|
|
call assert_equal([2, 10], [line('.'), col('.')])
|
|
|
|
" Find previous occurrences of a string (in a find dialog)
|
|
call cursor(1, 11)
|
|
let args = #{find_text: 'TWO', repl_text: '', flags: 0x11, forward: 0}
|
|
call test_gui_event('findrepl', args)
|
|
call assert_equal([1, 5], [line('.'), col('.')])
|
|
|
|
" Find next occurrence of a string (in a replace dialog)
|
|
call cursor(1, 1)
|
|
let args = #{find_text: 'Twoo', repl_text: '', flags: 0x2, forward: 1}
|
|
call test_gui_event('findrepl', args)
|
|
call assert_equal([2, 1], [line('.'), col('.')])
|
|
|
|
" Replace only the next occurrence of a string (once)
|
|
call cursor(1, 5)
|
|
let args = #{find_text: 'TWO', repl_text: 'two', flags: 0x3, forward: 1}
|
|
call test_gui_event('findrepl', args)
|
|
call assert_equal(['ONE two ONE', 'Twoo ONE TWO ONEo'], getline(1, '$'))
|
|
|
|
" Replace all instances of a whole string with another matching case
|
|
call cursor(1, 1)
|
|
let args = #{find_text: 'TWO', repl_text: 'two', flags: 0x1C, forward: 1}
|
|
call test_gui_event('findrepl', args)
|
|
call assert_equal(['ONE two ONE', 'Twoo ONE two ONEo'], getline(1, '$'))
|
|
|
|
" Replace all instances with sub-replace specials
|
|
call cursor(1, 1)
|
|
let args = #{find_text: 'ONE', repl_text: '&~&', flags: 0x4, forward: 1}
|
|
call test_gui_event('findrepl', args)
|
|
call assert_equal(['&~& two &~&', 'Twoo &~& two &~&o'], getline(1, '$'))
|
|
|
|
" Invalid arguments
|
|
call assert_false(test_gui_event('findrepl', {}))
|
|
let args = #{repl_text: 'a', flags: 1, forward: 1}
|
|
call assert_false(test_gui_event('findrepl', args))
|
|
let args = #{find_text: 'a', flags: 1, forward: 1}
|
|
call assert_false(test_gui_event('findrepl', args))
|
|
let args = #{find_text: 'a', repl_text: 'b', forward: 1}
|
|
call assert_false(test_gui_event('findrepl', args))
|
|
let args = #{find_text: 'a', repl_text: 'b', flags: 1}
|
|
call assert_false(test_gui_event('findrepl', args))
|
|
|
|
bw!
|
|
endfunc
|
|
|
|
func Test_gui_CTRL_SHIFT_V()
|
|
call feedkeys(":let g:str = '\<*C-S-V>\<*C-S-I>\<*C-S-V>\<*C-S-@>'\<CR>", 'tx')
|
|
call assert_equal('<C-S-I><C-S-@>', g:str)
|
|
unlet g:str
|
|
endfunc
|
|
|
|
func Test_gui_dialog_file()
|
|
" make sure the file does not exist, otherwise a dialog makes Vim hang
|
|
call delete('Xdialfile')
|
|
|
|
let lines =<< trim END
|
|
file Xdialfile
|
|
normal axxx
|
|
confirm qa
|
|
END
|
|
call writefile(lines, 'Xlines', 'D')
|
|
let prefix = '!'
|
|
if has('win32')
|
|
let prefix = '!start '
|
|
endif
|
|
execute prefix .. GetVimCommand() .. ' -g -f --clean --gui-dialog-file Xdialog -S Xlines'
|
|
|
|
call WaitForAssert({-> assert_true(filereadable('Xdialog'))})
|
|
call assert_match('Question: Save changes to "Xdialfile"?', readfile('Xdialog')->join('<NL>'))
|
|
|
|
call delete('Xdialog')
|
|
call delete('Xdialfile')
|
|
endfunc
|
|
|
|
" Test for sending low level key presses
|
|
func SendKeys(keylist)
|
|
for k in a:keylist
|
|
call test_gui_event("key", #{event: "keydown", keycode: k})
|
|
endfor
|
|
for k in reverse(a:keylist)
|
|
call test_gui_event("key", #{event: "keyup", keycode: k})
|
|
endfor
|
|
endfunc
|
|
|
|
func Test_gui_lowlevel_keyevent()
|
|
CheckMSWindows
|
|
new
|
|
|
|
" Test for <Ctrl-A> to <Ctrl-Z> keys
|
|
" FIXME: <Ctrl-C> is excluded for now. It makes the test flaky.
|
|
for kc in range(65, 66) + range(68, 90)
|
|
call SendKeys([0x11, kc])
|
|
try
|
|
let ch = getcharstr()
|
|
catch /^Vim:Interrupt$/
|
|
let ch = "\<c-c>"
|
|
endtry
|
|
call assert_equal(nr2char(kc - 64), ch)
|
|
endfor
|
|
|
|
" Testing more extensive windows keyboard handling
|
|
" is covered in test_mswin_event.vim
|
|
|
|
bw!
|
|
endfunc
|
|
|
|
func Test_gui_macro_csi()
|
|
" Test for issue #11270
|
|
nnoremap <C-L> <Cmd>let g:triggered = 1<CR>
|
|
let @q = "\x9b\xfc\x04L"
|
|
norm @q
|
|
call assert_equal(1, g:triggered)
|
|
unlet g:triggered
|
|
nunmap <C-L>
|
|
|
|
" Test for issue #11057
|
|
inoremap <C-D>t bbb
|
|
call setline(1, "\t")
|
|
let @q = "i\x9b\xfc\x04D"
|
|
" The end of :normal is like a mapping timing out
|
|
norm @q
|
|
call assert_equal('', getline(1))
|
|
iunmap <C-D>t
|
|
endfunc
|
|
|
|
func Test_gui_csi_keytrans()
|
|
call assert_equal('<C-L>', keytrans("\x9b\xfc\x04L"))
|
|
call assert_equal('<C-D>', keytrans("\x9b\xfc\x04D"))
|
|
endfunc
|
|
|
|
" Test that CursorHold is NOT triggered at startup before a keypress
|
|
func Test_CursorHold_not_triggered_at_startup()
|
|
defer delete('Xcursorhold.log')
|
|
defer delete('Xcursorhold_test.vim')
|
|
call writefile([
|
|
\ 'set updatetime=300',
|
|
\ 'let g:cursorhold_triggered = 0',
|
|
\ 'autocmd CursorHold * let g:cursorhold_triggered += 1 | call writefile(["CursorHold triggered"], "Xcursorhold.log", "a")',
|
|
\ 'call timer_start(400, {-> execute(''call writefile(["g:cursorhold_triggered=" . g:cursorhold_triggered], "Xcursorhold.log", "a") | qa!'')})',
|
|
\ ], 'Xcursorhold_test.vim')
|
|
|
|
let vimcmd = v:progpath . ' -g -f -N -u NONE -i NONE -S Xcursorhold_test.vim'
|
|
call system(vimcmd)
|
|
|
|
let lines = filereadable('Xcursorhold.log') ? readfile('Xcursorhold.log') : []
|
|
|
|
" Assert that CursorHold did NOT trigger at startup
|
|
call assert_false(index(lines, 'CursorHold triggered') != -1)
|
|
let found = filter(copy(lines), 'v:val =~ "^g:cursorhold_triggered="')
|
|
call assert_equal(['g:cursorhold_triggered=0'], found)
|
|
endfunc
|
|
|
|
" vim: shiftwidth=2 sts=2 expandtab
|