To: vim_dev@googlegroups.com Subject: Patch 8.2.3040 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3040 Problem: GUI: dropping files not tested. Solution: Add test_gui_drop_files() and tests. (Yegappan Lakshmanan, closes #8434) Files: runtime/doc/eval.txt, runtime/doc/testing.txt, runtime/doc/usr_41.txt, src/evalfunc.c, src/gui.c, src/proto/testing.pro, src/testdir/test_gui.vim, src/testing.c *** ../vim-8.2.3039/runtime/doc/eval.txt 2021-06-21 18:43:46.132307993 +0200 --- runtime/doc/eval.txt 2021-06-23 20:41:29.763392942 +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_drop_files({list}, {row}, {col}, {mods}) + none drop a list of files in a window 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 *** ../vim-8.2.3039/runtime/doc/testing.txt 2021-06-21 18:43:46.132307993 +0200 --- runtime/doc/testing.txt 2021-06-23 20:44:13.842785459 +0200 *************** *** 79,88 **** 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 --- 79,101 ---- Can also be used as a |method|: > GetName()->test_getvalue() < + *test_gui_drop_files()* + test_gui_drop_files({list}, {row}, {col}, {mods}) + Drop one or more files in {list} in the window at {row}, {col}. + This function only works when the GUI is running. + + The supported values for {mods} are: + 0x4 Shift + 0x8 Alt + 0x10 Ctrl + The files are added to the argument list and the first file in + {list} is edited in the window. See |drag-n-drop| for more + information. + *test_gui_mouse_event()* test_gui_mouse_event({button}, {row}, {col}, {multiclick}, {modifiers}) ! Inject a mouse button click event. This function only works ! when the GUI is running. The supported values for {button} are: 0 right mouse button 1 middle mouse button *************** *** 92,98 **** 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 --- 105,113 ---- 5 scroll wheel up 6 scroll wheel left 7 scroll wheel right ! {row} and {col} specify the location of the mouse click. The ! first row of the Vim window is 1 and the last row is 'lines'. ! The maximum value of {col} is 'columns'. To inject a multiclick event, set {multiclick} to 1. The supported values for {modifiers} are: 4 shift is pressed *** ../vim-8.2.3039/runtime/doc/usr_41.txt 2021-06-21 18:43:46.132307993 +0200 --- runtime/doc/usr_41.txt 2021-06-23 20:41:29.763392942 +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_drop_files() drop file(s) in a window 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 *** ../vim-8.2.3039/src/evalfunc.c 2021-06-22 19:52:23.901800877 +0200 --- src/evalfunc.c 2021-06-23 20:41:29.763392942 +0200 *************** *** 1700,1705 **** --- 1700,1707 ---- ret_void, f_test_garbagecollect_soon}, {"test_getvalue", 1, 1, FEARG_1, NULL, ret_number, f_test_getvalue}, + {"test_gui_drop_files", 4, 4, 0, NULL, + ret_void, f_test_gui_drop_files}, {"test_gui_mouse_event", 5, 5, 0, NULL, ret_void, f_test_gui_mouse_event}, {"test_ignore_error", 1, 1, FEARG_1, NULL, *** ../vim-8.2.3039/src/gui.c 2021-06-08 20:13:27.359916592 +0200 --- src/gui.c 2021-06-23 20:41:29.763392942 +0200 *************** *** 5567,5572 **** --- 5567,5573 ---- { vim_free(fnames[0]); vim_free(fnames); + vim_free(p); } else handle_drop(count, fnames, (modifiers & MOUSE_CTRL) != 0, *** ../vim-8.2.3039/src/proto/testing.pro 2021-06-21 18:43:46.136307978 +0200 --- src/proto/testing.pro 2021-06-23 20:41:29.763392942 +0200 *************** *** 36,39 **** --- 36,40 ---- 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); + void f_test_gui_drop_files(typval_T *argvars, typval_T *rettv); /* vim: set ft=c : */ *** ../vim-8.2.3039/src/testdir/test_gui.vim 2021-06-22 19:52:23.901800877 +0200 --- src/testdir/test_gui.vim 2021-06-23 20:41:29.767392926 +0200 *************** *** 1158,1161 **** --- 1158,1250 ---- let &lines = save_lines endfunc + " Test for dropping files into a window in GUI + func DropFilesInCmdLine() + call feedkeys(":\"", 'L') + call test_gui_drop_files(['a.c', 'b.c'], &lines, 1, 0) + call feedkeys("\", 'L') + endfunc + + func Test_gui_drop_files() + call assert_fails('call test_gui_drop_files(1, 1, 1, 0)', 'E474:') + call assert_fails('call test_gui_drop_files(["x"], "", 1, 0)', 'E474:') + call assert_fails('call test_gui_drop_files(["x"], 1, "", 0)', 'E474:') + call assert_fails('call test_gui_drop_files(["x"], 1, 1, "")', 'E474:') + + %bw! + %argdelete + call test_gui_drop_files([], 1, 1, 0) + call assert_equal([], argv()) + call test_gui_drop_files([1, 2], 1, 1, 0) + call assert_equal([], argv()) + + call test_gui_drop_files(['a.c', 'b.c'], 1, 1, 0) + call assert_equal(['a.c', 'b.c'], argv()) + %bw! + %argdelete + call test_gui_drop_files([], 1, 1, 0) + 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 + call test_gui_drop_files(['x.c', 'y.c'], 1, 1, 0) + 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 + call test_gui_drop_files(['s.py', 't.py'], 1, 1, 0x10) + 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 + call test_gui_drop_files(['a.py', 'b.py'], 1, 1, 0) + 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('Xdir1') + call writefile([], 'Xdir1/Xfile1') + call writefile([], 'Xdir1/Xfile2') + call test_gui_drop_files(['Xdir1/Xfile1', 'Xdir1/Xfile2'], 1, 1, 0x4) + call assert_equal('Xdir1', fnamemodify(getcwd(), ':t')) + call assert_equal('Xfile1', @%) + call chdir(save_cwd) + " pressing shift when dropping directory and files should change directory + call test_gui_drop_files(['Xdir1', 'Xdir1/Xfile2'], 1, 1, 0x4) + call assert_equal('Xdir1', fnamemodify(getcwd(), ':t')) + call assert_equal('Xdir1', fnamemodify(@%, ':t')) + call chdir(save_cwd) + %bw! + %argdelete + " dropping a directory should edit it + call test_gui_drop_files(['Xdir1'], 1, 1, 0) + call assert_equal('Xdir1', @%) + %bw! + %argdelete + " dropping only a directory name with Shift should ignore it + call test_gui_drop_files(['Xdir1'], 1, 1, 0x4) + call assert_equal('', @%) + %bw! + %argdelete + call delete('Xdir1', 'rf') + " 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. + cnoremap DropFilesInCmdLine() + call feedkeys(":\"\\", 'xt') + call feedkeys('k', 'Lx!') + call assert_equal('"a.c b.c', @:) + cunmap + endfunc + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.3039/src/testing.c 2021-06-22 19:52:23.901800877 +0200 --- src/testing.c 2021-06-23 20:41:29.767392926 +0200 *************** *** 1224,1230 **** void f_test_gui_mouse_event(typval_T *argvars UNUSED, typval_T *rettv UNUSED) { ! #ifdef FEAT_GUI int button; int row; int col; --- 1224,1230 ---- void f_test_gui_mouse_event(typval_T *argvars UNUSED, typval_T *rettv UNUSED) { ! # ifdef FEAT_GUI int button; int row; int col; *************** *** 1248,1254 **** mods = tv_get_number(&argvars[4]); gui_send_mouse_event(button, TEXT_X(col - 1), TEXT_Y(row - 1), repeated_click, mods); ! #endif } void --- 1248,1254 ---- mods = tv_get_number(&argvars[4]); gui_send_mouse_event(button, TEXT_X(col - 1), TEXT_Y(row - 1), repeated_click, mods); ! # endif } void *************** *** 1257,1261 **** --- 1257,1317 ---- time_for_testing = (time_t)tv_get_number(&argvars[0]); } + void + f_test_gui_drop_files(typval_T *argvars UNUSED, typval_T *rettv UNUSED) + { + # ifdef FEAT_GUI + int row; + int col; + int_u mods; + char_u **fnames; + int count = 0; + list_T *l; + listitem_T *li; + + if (argvars[0].v_type != VAR_LIST + || (argvars[1].v_type) != VAR_NUMBER + || (argvars[2].v_type) != VAR_NUMBER + || (argvars[3].v_type) != VAR_NUMBER) + { + emsg(_(e_invarg)); + return; + } + + row = tv_get_number(&argvars[1]); + col = tv_get_number(&argvars[2]); + mods = tv_get_number(&argvars[3]); + + l = argvars[0].vval.v_list; + if (list_len(l) == 0) + return; + + fnames = ALLOC_MULT(char_u *, list_len(l)); + if (fnames == NULL) + return; + + FOR_ALL_LIST_ITEMS(l, li) + { + // ignore non-string items + if (li->li_tv.v_type != VAR_STRING) + continue; + + fnames[count] = vim_strsave(li->li_tv.vval.v_string); + if (fnames[count] == NULL) + { + while (--count >= 0) + vim_free(fnames[count]); + vim_free(fnames); + return; + } + count++; + } + + if (count > 0) + gui_handle_drop(TEXT_X(col - 1), TEXT_Y(row - 1), mods, fnames, count); + else + vim_free(fnames); + # endif + } #endif // defined(FEAT_EVAL) *** ../vim-8.2.3039/src/version.c 2021-06-23 20:20:49.654780609 +0200 --- src/version.c 2021-06-23 20:42:56.483065794 +0200 *************** *** 757,758 **** --- 757,760 ---- { /* Add new patch number below this line */ + /**/ + 3040, /**/ -- Now it is such a bizarrely improbable coincidence that anything as mind-bogglingly useful as the Babel fish could have evolved purely by chance that some thinkers have chosen to see it as a final and clinching proof of the NON-existence of God. The argument goes something like this: 'I refuse to prove that I exist,' says God, 'for proof denies faith, and without faith I am nothing.' 'But,' says Man, 'the Babel fish is a dead giveaway, isn't it? It could not have evolved by chance. It proves you exist, and so therefore, by your own arguments, you don't. QED.' 'Oh dear,' says God, 'I hadn't thought of that,' and promptly vanishes in a puff of logic. 'Oh, that was easy,' says Man, and for an encore goes on to prove that black is white and gets himself killed on the next pedestrian crossing. -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy" /// 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 ///