]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.1.1406: popup_hide() and popup_show() not implemented yet v8.1.1406
authorBram Moolenaar <Bram@vim.org>
Sun, 26 May 2019 20:17:52 +0000 (22:17 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 26 May 2019 20:17:52 +0000 (22:17 +0200)
Problem:    popup_hide() and popup_show() not implemented yet.
Solution:   Implement the functions.

runtime/doc/popup.txt
src/evalfunc.c
src/popupwin.c
src/proto/popupwin.pro
src/screen.c
src/structs.h
src/testdir/test_popupwin.vim
src/version.c
src/vim.h

index 3b17f7795392cfc2685ac78bc7955cd4aef0a995..bbab6d03da0f532edf2e4ec1135f501e9cdd60c8 100644 (file)
@@ -85,7 +85,6 @@ Probably 2. is the best choice.
 IMPLEMENTATION:
 - Code is in popupwin.c
 - Implement list of lines with text properties
-- Implement popup_hide() and popup_show()
 - Implement filter.
 - Handle screen resize in screenalloc().
 - Make redrawing more efficient and avoid flicker.
@@ -179,15 +178,16 @@ popup_menu({text}, {options})                              *popup_menu()*
                "callback" to a function that handles the selected item.
 
 
-popup_show({id})                                               *popup_show()*
-               {not implemented yet}
-               If {id} is a hidden popup, show it now.
-
 popup_hide({id})                                               *popup_hide()*
-               {not implemented yet}
                If {id} is a displayed popup, hide it now. If the popup has a
                filter it will not be invoked for so long as the popup is
                hidden.
+               If window {id} does not exist nothing happens.  If window {id}
+               exists but is not a popup window an error is given. *E993*
+
+popup_show({id})                                               *popup_show()*
+               If {id} is a hidden popup, show it now.
+               For {id} see `popup_hide()`.
 
 popup_move({id}, {options})                                    *popup_move()*
                {not implemented yet}
@@ -195,6 +195,7 @@ popup_move({id}, {options})                                 *popup_move()*
                {options} may contain the items from |popup_create()| that
                specify the popup position: "line", "col", "pos", "maxheight",
                "minheight", "maxwidth" and "minwidth".
+               For {id} see `popup_hide()`.
 
 
 popup_filter_menu({id}, {key})                         *popup_filter_menu()*
index 3256b22c9d4094ba823d87db8df68f2425bf5982..b15e74d438b6ac3ed89709d73813824bdeeb657a 100644 (file)
@@ -810,6 +810,8 @@ static struct fst
 #ifdef FEAT_TEXT_PROP
     {"popup_close",    1, 1, f_popup_close},
     {"popup_create",   2, 2, f_popup_create},
+    {"popup_hide",     1, 1, f_popup_hide},
+    {"popup_show",     1, 1, f_popup_show},
 #endif
 #ifdef FEAT_FLOAT
     {"pow",            2, 2, f_pow},
index e39ee67d48917c44280bfeee36f8ab6ad748cf7d..0857f6b0a3ee176e14bd9591061950413f54e809 100644 (file)
@@ -194,19 +194,86 @@ f_popup_create(typval_T *argvars, typval_T *rettv)
     redraw_all_later(NOT_VALID);
 }
 
+/*
+ * Find the popup window with window-ID "id".
+ * If the popup window does not exist NULL is returned.
+ * If the window is not a popup window, and error message is given.
+ */
+    static win_T *
+find_popup_win(int id)
+{
+    win_T *wp = win_id2wp(id);
+
+    if (wp != NULL && !bt_popup(wp->w_buffer))
+    {
+       semsg(_("E993: window %d is not a popup window"), id);
+       return NULL;
+    }
+    return wp;
+}
+
+/*
+ * Return TRUE if there any popups that are not hidden.
+ */
+    int
+popup_any_visible(void)
+{
+    win_T *wp;
+
+    for (wp = first_popupwin; wp != NULL; wp = wp->w_next)
+       if ((wp->w_popup_flags & PFL_HIDDEN) == 0)
+           return TRUE;
+    for (wp = curtab->tp_first_popupwin; wp != NULL; wp = wp->w_next)
+       if ((wp->w_popup_flags & PFL_HIDDEN) == 0)
+           return TRUE;
+    return FALSE;
+}
+
 /*
  * popup_close({id})
  */
     void
 f_popup_close(typval_T *argvars, typval_T *rettv UNUSED)
 {
-    int                nr = (int)tv_get_number(argvars);
+    int                id = (int)tv_get_number(argvars);
+
+    popup_close(id);
+}
 
-    popup_close(nr);
+/*
+ * popup_hide({id})
+ */
+    void
+f_popup_hide(typval_T *argvars, typval_T *rettv UNUSED)
+{
+    int                id = (int)tv_get_number(argvars);
+    win_T      *wp = find_popup_win(id);
+
+    if (wp != NULL && (wp->w_popup_flags & PFL_HIDDEN) == 0)
+    {
+       wp->w_popup_flags |= PFL_HIDDEN;
+       redraw_all_later(NOT_VALID);
+    }
+}
+
+/*
+ * popup_show({id})
+ */
+    void
+f_popup_show(typval_T *argvars, typval_T *rettv UNUSED)
+{
+    int                id = (int)tv_get_number(argvars);
+    win_T      *wp = find_popup_win(id);
+
+    if (wp != NULL && (wp->w_popup_flags & PFL_HIDDEN) != 0)
+    {
+       wp->w_popup_flags &= ~PFL_HIDDEN;
+       redraw_all_later(NOT_VALID);
+    }
 }
 
     static void
-popup_undisplay(win_T *wp)
+popup_free(win_T *wp)
 {
     if (wp->w_winrow + wp->w_height >= cmdline_row)
        clear_cmdline = TRUE;
@@ -232,7 +299,7 @@ popup_close(int id)
                first_popupwin = wp->w_next;
            else
                prev->w_next = wp->w_next;
-           popup_undisplay(wp);
+           popup_free(wp);
            return;
        }
 
@@ -258,7 +325,7 @@ popup_close_tabpage(tabpage_T *tp, int id)
                *root = wp->w_next;
            else
                prev->w_next = wp->w_next;
-           popup_undisplay(wp);
+           popup_free(wp);
            return;
        }
 }
index 172c0794d22e129b262c5a34312164413a8e0c60..64fca5ff56bc4c53f9fa24e1f420a00a14cce7c5 100644 (file)
@@ -1,6 +1,9 @@
 /* popupwin.c */
 void f_popup_create(typval_T *argvars, typval_T *rettv);
+int popup_any_visible(void);
 void f_popup_close(typval_T *argvars, typval_T *rettv);
+void f_popup_hide(typval_T *argvars, typval_T *rettv);
+void f_popup_show(typval_T *argvars, typval_T *rettv);
 void popup_close(int id);
 void popup_close_tabpage(tabpage_T *tp, int id);
 void close_all_popups(void);
index 30e1bb21ab3ae1626ccd4e61b13fbcc97ec8f99c..40cff9acc2284b6c884f794865ef1075c7433ade 100644 (file)
@@ -610,7 +610,7 @@ update_screen(int type_arg)
     }
 #ifdef FEAT_TEXT_PROP
     // TODO: avoid redrawing everything when there is a popup window.
-    if (first_popupwin != NULL || curtab->tp_first_popupwin != NULL)
+    if (popup_any_visible())
        type = NOT_VALID;
 #endif
 
@@ -999,9 +999,9 @@ update_popups(void)
 
     // Reset all the VALID_POPUP flags.
     for (wp = first_popupwin; wp != NULL; wp = wp->w_next)
-       wp->w_valid &= ~VALID_POPUP;
+       wp->w_popup_flags &= ~PFL_REDRAWN;
     for (wp = curtab->tp_first_popupwin; wp != NULL; wp = wp->w_next)
-       wp->w_valid &= ~VALID_POPUP;
+       wp->w_popup_flags &= ~PFL_REDRAWN;
 
     // TODO: don't redraw every popup every time.
     for (;;)
@@ -1012,14 +1012,14 @@ update_popups(void)
        lowest_zindex = INT_MAX;
        lowest_wp = NULL;
        for (wp = first_popupwin; wp != NULL; wp = wp->w_next)
-           if ((wp->w_valid & VALID_POPUP) == 0
+           if ((wp->w_popup_flags & (PFL_REDRAWN|PFL_HIDDEN)) == 0
                                               && wp->w_zindex < lowest_zindex)
            {
                lowest_zindex = wp->w_zindex;
                lowest_wp = wp;
            }
        for (wp = curtab->tp_first_popupwin; wp != NULL; wp = wp->w_next)
-           if ((wp->w_valid & VALID_POPUP) == 0
+           if ((wp->w_popup_flags & (PFL_REDRAWN|PFL_HIDDEN)) == 0
                                               && wp->w_zindex < lowest_zindex)
            {
                lowest_zindex = wp->w_zindex;
@@ -1029,7 +1029,7 @@ update_popups(void)
        if (lowest_wp == NULL)
            break;
        win_update(lowest_wp);
-       lowest_wp->w_valid |= VALID_POPUP;
+       lowest_wp->w_popup_flags |= PFL_REDRAWN;
     }
 }
 #endif
index ca7c5407039c692bc501d2e74273b269fcca6942..925bf0363bb3731927e35832b815b9fcb22e5dae 100644 (file)
@@ -2871,6 +2871,7 @@ struct window_S
     int                w_vsep_width;       /* Number of separator columns (0 or 1). */
     pos_save_T w_save_cursor;      /* backup of cursor pos and topline */
 #ifdef FEAT_TEXT_PROP
+    int                w_popup_flags;      // PFL_ values
     int                w_zindex;
     int                w_maxheight;        // "maxheight" for popup window
     int                w_maxwidth;         // "maxwidth" for popup window
index 04c67a227a7a20858033e05d2e79e77b94daf7ce..73efe0a738ebc15b1cb56de384dd8be154a96850 100644 (file)
@@ -76,3 +76,41 @@ func Test_popup_time()
 
   bwipe!
 endfunc
+
+func Test_popup_hide()
+  topleft vnew
+  call setline(1, 'hello')
+
+  let winid = popup_create('world', {
+       \ 'line': 1,
+       \ 'col': 1,
+       \})
+  redraw
+  let line = join(map(range(1, 5), 'screenstring(1, v:val)'), '')
+  call assert_equal('world', line)
+
+  call popup_hide(winid)
+  redraw
+  let line = join(map(range(1, 5), 'screenstring(1, v:val)'), '')
+  call assert_equal('hello', line)
+
+  call popup_show(winid)
+  redraw
+  let line = join(map(range(1, 5), 'screenstring(1, v:val)'), '')
+  call assert_equal('world', line)
+
+
+  call popup_close(winid)
+  redraw
+  let line = join(map(range(1, 5), 'screenstring(1, v:val)'), '')
+  call assert_equal('hello', line)
+
+  " error is given for existing non-popup window
+  call assert_fails('call popup_hide(win_getid())', 'E993:')
+
+  " no error non-existing window
+  call popup_hide(1234234)
+  call popup_show(41234234)
+
+  bwipe!
+endfunc
index 04de1af85a360ed9524464f07fd28f821f7c6744..5df9639743220925af6cd2ee92edf57f25ce673e 100644 (file)
@@ -767,6 +767,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1406,
 /**/
     1405,
 /**/
index 3389ef5a1db23ff16ac77c53c99e1b95cd9f6331..a52ba5e64c7a31bedbd273fdee1d4660ca5034b3 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
@@ -612,7 +612,10 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
 #define VALID_BOTLINE  0x20    // w_botine and w_empty_rows are valid
 #define VALID_BOTLINE_AP 0x40  // w_botine is approximated
 #define VALID_TOPLINE  0x80    // w_topline is valid (for cursor position)
-#define VALID_POPUP    0x100   // popup has been redrawn
+
+// Values for w_popup_flags.
+#define PFL_HIDDEN     1       // popup is not displayed
+#define PFL_REDRAWN    2       // popup was just redrawn
 
 /*
  * Terminal highlighting attribute bits.