]> granicus.if.org Git - vim/commitdiff
patch 8.2.3040: GUI: dropping files not tested v8.2.3040
authorYegappan Lakshmanan <yegappan@yahoo.com>
Wed, 23 Jun 2021 18:46:52 +0000 (20:46 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 23 Jun 2021 18:46:52 +0000 (20:46 +0200)
Problem:    GUI: dropping files not tested.
Solution:   Add test_gui_drop_files() and tests. (Yegappan Lakshmanan,
            closes #8434)

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
src/version.c

index 1f52d9f05bacccb8ec248fe23ec5556bd1651f61..8a8431281dedc08e72d6cded02088a519dc772f3 100644 (file)
@@ -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
index db505e7efce75522bc1618e02858b114877d450a..eef322714e5563b730c0d5dfc2e164da842328bd 100644 (file)
@@ -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
index de7f19707880335e8af43384aff729328c6b74cf..54e5e2930ddc21d8231c818abffb67ec99d243b1 100644 (file)
@@ -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
index 21d28afec61e2648cdd2dfa1e085046add977fc3..3dd887b8884663000f3a2e3f2cddb2b9d1148523 100644 (file)
@@ -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,
index b5ec007405f411125c7592daba67f2233ee3c150..c748fae4cea0a115ec86bf169b7f9c0f0fa99670 100644 (file)
--- 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,
index 3e203f8fd608d384ec1691c8efd6ed8e9f175ac0..0d4ff4995532c54620f778f8c7978b9a49046c69 100644 (file)
@@ -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 : */
index e935e5fdd218feaa6926c1b4c55529d46c0c3c49..5c18d5d227eca4f1bb9ca80b2cbde7af3f2cb554 100644 (file)
@@ -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
index 5ebcefbdf03a09ebcfa641ca52d7cc99ee6a9f4a..b32eb1a374650abc2906806109a3a0008b8c6d93 100644 (file)
@@ -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)
index 83c7460c27e3c58b9953739af47a166d0a608cfa..bf3331238c75a05a9ebdc36eff23ad7587e806eb 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3040,
 /**/
     3039,
 /**/