To: vim_dev@googlegroups.com Subject: Patch 8.2.3028 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3028 Problem: GUI mouse events not tested. Solution: Add test_gui_mouse_event(). Add mouse tests. Also add a few viminfo tests. (Yegappan Lakshmanan, closes #8407) Files: runtime/doc/eval.txt, runtime/doc/testing.txt, runtime/doc/usr_41.txt, src/evalfunc.c, src/proto/testing.pro, src/testdir/test_gui.vim, src/testdir/test_viminfo.vim, src/testing.c *** ../vim-8.2.3027/runtime/doc/eval.txt 2021-06-20 14:01:25.976924630 +0200 --- runtime/doc/eval.txt 2021-06-21 18:36:38.181841691 +0200 *************** *** 3016,3021 **** --- 3022,3029 ---- test_garbagecollect_now() none free memory right now for testing test_garbagecollect_soon() none free memory soon for testing test_getvalue({string}) any get value of an internal variable + test_gui_mouse_event({button}, {row}, {col}, {repeated}, {mods}) + none add a mouse event to the input buffer test_ignore_error({expr}) none ignore a specific error test_null_blob() Blob null value for testing test_null_channel() Channel null value for testing *** ../vim-8.2.3027/runtime/doc/testing.txt 2021-04-02 18:55:52.054322785 +0200 --- runtime/doc/testing.txt 2021-06-21 18:40:52.636907316 +0200 *************** *** 78,83 **** --- 78,107 ---- Can also be used as a |method|: > GetName()->test_getvalue() + < + *test_gui_mouse_event()* + test_gui_mouse_event({button}, {row}, {col}, {multiclick}, {modifiers}) + Inject a mouse button click event. This function works only + when GUI is running. + The supported values for {button} are: + 0 right mouse button + 1 middle mouse button + 2 left mouse button + 3 mouse button release + 4 scroll wheel down + 5 scroll wheel up + 6 scroll wheel left + 7 scroll wheel right + {row} and {col} specify the location of the mouse click. + To inject a multiclick event, set {multiclick} to 1. + The supported values for {modifiers} are: + 4 shift is pressed + 8 alt is pressed + 16 ctrl is pressed + After injecting the mouse event you probably should call + |feedkeys()| to have them processed, e.g.: > + call feedkeys("y", 'Lx!') + test_ignore_error({expr}) *test_ignore_error()* Ignore any error containing {expr}. A normal message is given *************** *** 168,173 **** --- 192,198 ---- wait time of up to 3 seconds for messages term_props reset all terminal properties when the version string is detected + uptime overrules sysinfo.uptime ALL clear all overrides ({val} is not used) "starting" is to be used when a test should behave like *** ../vim-8.2.3027/runtime/doc/usr_41.txt 2021-06-07 18:49:58.616217351 +0200 --- runtime/doc/usr_41.txt 2021-06-21 18:36:38.181841691 +0200 *************** *** 1013,1018 **** --- 1021,1027 ---- test_garbagecollect_now() free memory right now test_garbagecollect_soon() set a flag to free memory soon test_getvalue() get value of an internal variable + test_gui_mouse_event() add a GUI mouse event to the input buffer test_ignore_error() ignore a specific error message test_null_blob() return a null Blob test_null_channel() return a null Channel *** ../vim-8.2.3027/src/evalfunc.c 2021-06-20 14:40:57.584007589 +0200 --- src/evalfunc.c 2021-06-21 18:36:38.181841691 +0200 *************** *** 1696,1701 **** --- 1696,1703 ---- ret_void, f_test_garbagecollect_soon}, {"test_getvalue", 1, 1, FEARG_1, NULL, ret_number, f_test_getvalue}, + {"test_gui_mouse_event", 5, 5, 0, NULL, + ret_void, f_test_gui_mouse_event}, {"test_ignore_error", 1, 1, FEARG_1, NULL, ret_void, f_test_ignore_error}, {"test_null_blob", 0, 0, 0, NULL, *** ../vim-8.2.3027/src/proto/testing.pro 2021-04-02 18:55:52.058322772 +0200 --- src/proto/testing.pro 2021-06-21 18:36:38.181841691 +0200 *************** *** 34,38 **** --- 34,39 ---- void f_test_void(typval_T *argvars, typval_T *rettv); void f_test_scrollbar(typval_T *argvars, typval_T *rettv); void f_test_setmouse(typval_T *argvars, typval_T *rettv); + void f_test_gui_mouse_event(typval_T *argvars, typval_T *rettv); void f_test_settime(typval_T *argvars, typval_T *rettv); /* vim: set ft=c : */ *** ../vim-8.2.3027/src/testdir/test_gui.vim 2021-02-28 23:13:36.368951782 +0100 --- src/testdir/test_gui.vim 2021-06-21 18:36:38.181841691 +0200 *************** *** 389,395 **** 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 --- 389,395 ---- 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 *************** *** 875,878 **** --- 875,1100 ---- nunmap a endfunc + " Test GUI mouse events + func Test_gui_mouse_event() + set mousemodel=extend + call test_override('no_query_mouse', 1) + new + call setline(1, ['one two three', 'four five six']) + + " place the cursor using left click + call cursor(1, 1) + call test_gui_mouse_event(0, 2, 4, 0, 0) + call test_gui_mouse_event(3, 2, 4, 0, 0) + call feedkeys("\", 'Lx!') + call assert_equal([0, 2, 4, 0], getpos('.')) + + " select and yank a word + let @" = '' + call test_gui_mouse_event(0, 1, 9, 0, 0) + call test_gui_mouse_event(0, 1, 9, 1, 0) + call test_gui_mouse_event(3, 1, 9, 0, 0) + call feedkeys("y", 'Lx!') + call assert_equal('three', @") + + " create visual selection using right click + let @" = '' + call test_gui_mouse_event(0, 2, 6, 0, 0) + call test_gui_mouse_event(3, 2, 6, 0, 0) + call test_gui_mouse_event(2, 2, 13, 0, 0) + call test_gui_mouse_event(3, 2, 13, 0, 0) + call feedkeys("y", 'Lx!') + call assert_equal('five six', @") + + " paste using middle mouse button + let @* = 'abc ' + call feedkeys('""', 'Lx!') + call test_gui_mouse_event(1, 1, 9, 0, 0) + call test_gui_mouse_event(3, 1, 9, 0, 0) + call feedkeys("\", '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!') + call test_gui_mouse_event(2, 1, 17, 0, 0) + call test_gui_mouse_event(3, 1, 17, 0, 0) + call feedkeys("y", 'Lx!') + call assert_equal('one two abc three', @") + + " extend visual selection using mouse drag + let @" = '' + call cursor(1, 1) + call test_gui_mouse_event(0, 2, 1, 0, 0) + call test_gui_mouse_event(0x43, 2, 9, 0, 0) + call test_gui_mouse_event(0x3, 2, 9, 0, 0) + call feedkeys("y", 'Lx!') + call assert_equal('four five', @") + + " select text by moving the mouse + let @" = '' + call cursor(1, 1) + redraw! + call test_gui_mouse_event(0, 1, 4, 0, 0) + call test_gui_mouse_event(0x700, 1, 9, 0, 0) + call test_gui_mouse_event(0x700, 1, 13, 0, 0) + call test_gui_mouse_event(0x3, 1, 13, 0, 0) + call feedkeys("y", 'Lx!') + call assert_equal(' two abc t', @") + + " Using mouse in insert mode + call cursor(1, 1) + call feedkeys('i', 't') + call test_gui_mouse_event(0, 2, 11, 0, 0) + call test_gui_mouse_event(3, 2, 11, 0, 0) + call feedkeys("po\", 'Lx!') + call assert_equal(['one two abc three', 'four five posix'], getline(1, '$')) + + %d _ + call setline(1, range(1, 100)) + " scroll up + call test_gui_mouse_event(0x200, 2, 1, 0, 0) + call test_gui_mouse_event(0x200, 2, 1, 0, 0) + call test_gui_mouse_event(0x200, 2, 1, 0, 0) + call feedkeys("H", 'Lx!') + call assert_equal(10, line('.')) + + " scroll down + call test_gui_mouse_event(0x100, 2, 1, 0, 0) + call test_gui_mouse_event(0x100, 2, 1, 0, 0) + call feedkeys("H", 'Lx!') + call assert_equal(4, line('.')) + + %d _ + set nowrap + call setline(1, range(10)->join('')->repeat(10)) + " scroll left + call test_gui_mouse_event(0x500, 1, 5, 0, 0) + call test_gui_mouse_event(0x500, 1, 10, 0, 0) + call test_gui_mouse_event(0x500, 1, 15, 0, 0) + call feedkeys('g0', 'Lx!') + call assert_equal(19, col('.')) + + " scroll right + call test_gui_mouse_event(0x600, 1, 15, 0, 0) + call test_gui_mouse_event(0x600, 1, 10, 0, 0) + 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 .. ' call add(g:events, "' .. + \ substitute(e, '[<>]', '', 'g') .. '")' + 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 + call test_gui_mouse_event(button, 2, 5, 0, 0) + call test_gui_mouse_event(3, 2, 5, 0, 0) + + " Double/Triple click is supported by only the Left/Middle/Right mouse + " buttons + if button <= 2 + " Double Click + call test_gui_mouse_event(button, 2, 5, 0, 0) + call test_gui_mouse_event(button, 2, 5, 1, 0) + call test_gui_mouse_event(3, 2, 5, 0, 0) + + " Triple Click + call test_gui_mouse_event(button, 2, 5, 0, 0) + call test_gui_mouse_event(button, 2, 5, 1, 0) + call test_gui_mouse_event(button, 2, 5, 1, 0) + call test_gui_mouse_event(3, 2, 5, 0, 0) + endif + + " Shift click + call test_gui_mouse_event(button, 3, 7, 0, 4) + call test_gui_mouse_event(3, 3, 7, 0, 4) + + " Alt click + call test_gui_mouse_event(button, 3, 7, 0, 8) + call test_gui_mouse_event(3, 3, 7, 0, 8) + + " Ctrl click + call test_gui_mouse_event(button, 3, 7, 0, 16) + call test_gui_mouse_event(3, 3, 7, 0, 16) + + call feedkeys("\", '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 @* = '' + call test_gui_mouse_event(0, 2, 11, 0, 0) + call test_gui_mouse_event(0, 2, 11, 1, 0) + call test_gui_mouse_event(3, 2, 11, 0, 0) + call feedkeys("\", '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 @* = '' + call test_gui_mouse_event(2, 1, 11, 0, 0) + call test_gui_mouse_event(3, 1, 11, 0, 0) + call feedkeys("\", '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! + call test_gui_mouse_event(1, 1, 11, 0, 0) + call test_gui_mouse_event(3, 1, 11, 0, 0) + call feedkeys("\", '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 + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.3027/src/testdir/test_viminfo.vim 2021-06-17 22:08:13.376738576 +0200 --- src/testdir/test_viminfo.vim 2021-06-21 18:36:38.181841691 +0200 *************** *** 63,68 **** --- 63,69 ---- let g:MY_GLOBAL_NULL = test_null let test_none = v:none let g:MY_GLOBAL_NONE = test_none + let g:MY_GLOBAL_FUNCREF = function('min') set viminfo='100,<50,s10,h,!,nviminfo wv! Xviminfo *************** *** 77,82 **** --- 78,84 ---- unlet g:MY_GLOBAL_TRUE unlet g:MY_GLOBAL_NULL unlet g:MY_GLOBAL_NONE + unlet g:MY_GLOBAL_FUNCREF rv! Xviminfo call assert_equal("Vim Editor", g:MY_GLOBAL_STRING) *************** *** 89,94 **** --- 91,97 ---- call assert_equal(test_true, g:MY_GLOBAL_TRUE) call assert_equal(test_null, g:MY_GLOBAL_NULL) call assert_equal(test_none, g:MY_GLOBAL_NONE) + call assert_false(exists("g:MY_GLOBAL_FUNCREF")) " When reading global variables from viminfo, if a variable cannot be " modified, then the value should not be changed. *************** *** 230,236 **** --- 233,258 ---- call assert_equal("echo " . long800, histget(':', -2)) call assert_equal("echo 'one'", histget(':', -3)) + " If the value for the '/' or ':' or '@' field in 'viminfo' is zero, then + " the corresponding history entries are not saved. + set viminfo='100,/0,:0,@0,<50,s10,h,!,nviminfo + call histdel('/') + call histdel(':') + call histdel('@') + call histadd('/', 'foo') + call histadd(':', 'bar') + call histadd('@', 'baz') + wviminfo! Xviminfo + call histdel('/') + call histdel(':') + call histdel('@') + rviminfo! Xviminfo + call assert_equal('', histget('/')) + call assert_equal('', histget(':')) + call assert_equal('', histget('@')) + call delete('Xviminfo') + set viminfo&vim endfunc func Test_cmdline_history_order() *************** *** 346,352 **** --- 368,400 ---- let len += 1 endwhile + " If the maximum number of lines saved for a register ('<' in 'viminfo') is + " zero, then register values should not be saved. + let @a = 'abc' + set viminfo='100,<0,s10,h,!,nviminfo + wviminfo Xviminfo + let @a = 'xyz' + rviminfo! Xviminfo + call assert_equal('xyz', @a) + " repeat the test with '"' instead of '<' + let @b = 'def' + set viminfo='100,\"0,s10,h,!,nviminfo + wviminfo Xviminfo + let @b = 'rst' + rviminfo! Xviminfo + call assert_equal('rst', @b) + + " If the maximum size of an item ('s' in 'viminfo') is zero, then register + " values should not be saved. + let @c = '123' + set viminfo='100,<20,s0,h,!,nviminfo + wviminfo Xviminfo + let @c = '456' + rviminfo! Xviminfo + call assert_equal('456', @c) + call delete('Xviminfo') + set viminfo&vim endfunc func Test_viminfo_marks() *************** *** 541,555 **** call delete('Xviminfo') endfunc ! func Test_viminfo_bad_register_syntax() let lines = [] call add(lines, '|1,4') ! call add(lines, '|3') " invalid number of fields for a register type ! call add(lines, '|3,1,1,1,1,,1,"x"') " invalid value for the width field call add(lines, '|3,0,80,1,1,1,1,"x"') " invalid register number call add(lines, '|3,0,10,5,1,1,1,"x"') " invalid register type call add(lines, '|3,0,10,1,20,1,1,"x"') " invalid line count call add(lines, '|3,0,10,1,0,1,1') " zero line count call writefile(lines, 'Xviminfo') rviminfo Xviminfo call delete('Xviminfo') --- 589,618 ---- call delete('Xviminfo') endfunc ! func Test_viminfo_bad_syntax2() let lines = [] call add(lines, '|1,4') ! ! " bad viminfo syntax for history barline ! call add(lines, '|2') " invalid number of fields in a history barline ! call add(lines, '|2,9,1,1,"x"') " invalid value for the history type ! call add(lines, '|2,0,,1,"x"') " no timestamp ! call add(lines, '|2,0,1,1,10') " non-string text ! ! " bad viminfo syntax for register barline ! call add(lines, '|3') " invalid number of fields in a register barline ! call add(lines, '|3,1,1,1,1,,1,"x"') " missing width field call add(lines, '|3,0,80,1,1,1,1,"x"') " invalid register number call add(lines, '|3,0,10,5,1,1,1,"x"') " invalid register type call add(lines, '|3,0,10,1,20,1,1,"x"') " invalid line count call add(lines, '|3,0,10,1,0,1,1') " zero line count + + " bad viminfo syntax for mark barline + call add(lines, '|4') " invalid number of fields in a mark barline + call add(lines, '|4,1,1,1,1,1') " invalid value for file name + call add(lines, '|4,20,1,1,1,"x"') " invalid value for file name + call add(lines, '|4,49,0,1,1,"x"') " invalid value for line number + call writefile(lines, 'Xviminfo') rviminfo Xviminfo call delete('Xviminfo') *************** *** 901,906 **** --- 964,970 ---- " Try to write the viminfo to a directory call mkdir('Xdir') call assert_fails('wviminfo Xdir', 'E137:') + call assert_fails('rviminfo Xdir', 'E195:') call delete('Xdir', 'rf') endfunc *** ../vim-8.2.3027/src/testing.c 2021-05-07 17:55:51.971584412 +0200 --- src/testing.c 2021-06-21 18:36:38.181841691 +0200 *************** *** 1216,1221 **** --- 1216,1235 ---- } void + f_test_gui_mouse_event(typval_T *argvars UNUSED, typval_T *rettv UNUSED) + { + #ifdef FEAT_GUI + int button = tv_get_number(&argvars[0]); + int row = tv_get_number(&argvars[1]); + int col = tv_get_number(&argvars[2]); + int repeated_click = tv_get_number(&argvars[3]); + int_u mods = tv_get_number(&argvars[4]); + + gui_send_mouse_event(button, TEXT_X(col - 1), TEXT_Y(row - 1), repeated_click, mods); + #endif + } + + void f_test_settime(typval_T *argvars, typval_T *rettv UNUSED) { time_for_testing = (time_t)tv_get_number(&argvars[0]); *** ../vim-8.2.3027/src/version.c 2021-06-20 20:09:38.594432364 +0200 --- src/version.c 2021-06-21 18:38:09.977495196 +0200 *************** *** 757,758 **** --- 757,760 ---- { /* Add new patch number below this line */ + /**/ + 3028, /**/ -- I have a drinking problem -- I don't have a drink! /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///