summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYegappan Lakshmanan <yegappan@yahoo.com>2021-06-23 20:46:52 +0200
committerBram Moolenaar <Bram@vim.org>2021-06-23 20:46:52 +0200
commit18d46587b985923ef4b90b19a0cf37a094607fec (patch)
tree6e680815dc89cd49aa178486f320df88191fecf8
parent8cec9273d2518f2a9abcbd326722a2eba38d2a13 (diff)
patch 8.2.3040: GUI: dropping files not testedv8.2.3040
Problem: GUI: dropping files not tested. Solution: Add test_gui_drop_files() and tests. (Yegappan Lakshmanan, closes #8434)
-rw-r--r--runtime/doc/eval.txt2
-rw-r--r--runtime/doc/testing.txt21
-rw-r--r--runtime/doc/usr_41.txt1
-rw-r--r--src/evalfunc.c2
-rw-r--r--src/gui.c1
-rw-r--r--src/proto/testing.pro1
-rw-r--r--src/testdir/test_gui.vim89
-rw-r--r--src/testing.c60
-rw-r--r--src/version.c2
9 files changed, 174 insertions, 5 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 1f52d9f05b..8a8431281d 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -3022,6 +3022,8 @@ test_feedinput({string}) none add key sequence to input buffer
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
diff --git a/runtime/doc/testing.txt b/runtime/doc/testing.txt
index db505e7efc..eef322714e 100644
--- a/runtime/doc/testing.txt
+++ b/runtime/doc/testing.txt
@@ -79,10 +79,23 @@ test_getvalue({name}) *test_getvalue()*
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 works only
- when GUI is running.
+ 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,7 +105,9 @@ test_gui_mouse_event({button}, {row}, {col}, {multiclick}, {modifiers})
5 scroll wheel up
6 scroll wheel left
7 scroll wheel right
- {row} and {col} specify the location of the mouse click.
+ {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
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index de7f197078..54e5e2930d 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -1021,6 +1021,7 @@ Testing: *test-functions*
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
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 21d28afec6..3dd887b888 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -1700,6 +1700,8 @@ static funcentry_T global_functions[] =
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,
diff --git a/src/gui.c b/src/gui.c
index b5ec007405..c748fae4ce 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -5567,6 +5567,7 @@ gui_handle_drop(
{
vim_free(fnames[0]);
vim_free(fnames);
+ vim_free(p);
}
else
handle_drop(count, fnames, (modifiers & MOUSE_CTRL) != 0,
diff --git a/src/proto/testing.pro b/src/proto/testing.pro
index 3e203f8fd6..0d4ff49955 100644
--- a/src/proto/testing.pro
+++ b/src/proto/testing.pro
@@ -36,4 +36,5 @@ 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);
+void f_test_gui_drop_files(typval_T *argvars, typval_T *rettv);
/* vim: set ft=c : */
diff --git a/src/testdir/test_gui.vim b/src/testdir/test_gui.vim
index e935e5fdd2..5c18d5d227 100644
--- a/src/testdir/test_gui.vim
+++ b/src/testdir/test_gui.vim
@@ -1158,4 +1158,93 @@ func Test_gui_tablabel_tooltip()
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("\<CR>", '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 <expr> <buffer> <F4> DropFilesInCmdLine()
+ call feedkeys(":\"\<F4>\<CR>", 'xt')
+ call feedkeys('k', 'Lx!')
+ call assert_equal('"a.c b.c', @:)
+ cunmap <buffer> <F4>
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testing.c b/src/testing.c
index 5ebcefbdf0..b32eb1a374 100644
--- a/src/testing.c
+++ b/src/testing.c
@@ -1224,7 +1224,7 @@ f_test_setmouse(typval_T *argvars, typval_T *rettv UNUSED)
void
f_test_gui_mouse_event(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
{
-#ifdef FEAT_GUI
+# ifdef FEAT_GUI
int button;
int row;
int col;
@@ -1248,7 +1248,7 @@ f_test_gui_mouse_event(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
mods = tv_get_number(&argvars[4]);
gui_send_mouse_event(button, TEXT_X(col - 1), TEXT_Y(row - 1), repeated_click, mods);
-#endif
+# endif
}
void
@@ -1257,5 +1257,61 @@ f_test_settime(typval_T *argvars, typval_T *rettv UNUSED)
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)
diff --git a/src/version.c b/src/version.c
index 83c7460c27..bf3331238c 100644
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3040,
+/**/
3039,
/**/
3038,