]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.1.1445: popup window border highlight not implemented yet v8.1.1445
authorBram Moolenaar <Bram@vim.org>
Sat, 1 Jun 2019 20:15:29 +0000 (22:15 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 1 Jun 2019 20:15:29 +0000 (22:15 +0200)
Problem:    Popup window border highlight not implemented yet.
Solution:   Implement the "borderhighlight" option.

runtime/doc/popup.txt
src/popupwin.c
src/screen.c
src/structs.h
src/testdir/dumps/Test_popupwin_22.dump [new file with mode: 0644]
src/testdir/test_popupwin.vim
src/version.c
src/window.c

index db00e60e0e69e25746dc98ef63025fa737fb8b89..ac16b221c4e9e493c4b80935be3dd4441444a5fc 100644 (file)
@@ -368,15 +368,19 @@ The second argument of |popup_create()| is a dictionary with options:
        border          list with numbers, defining the border thickness
                        above/right/below/left of the popup (similar to CSS);
                        only values of zero and non-zero are recognized;
-                       an empty list uses a border of 1 all around
-       borderhighlight highlight group name to use for the border
-                       {not implemented yet}
+                       an empty list uses a border all around
+       borderhighlight list of highlight group names to use for the border;
+                       when one entry it is used for all borders, otherwise
+                       the highlight for the top/right/bottom/left border
        borderchars     list with characters, defining the character to use
                        for the top/right/bottom/left border; optionally
                        followed by the character to use for the
-                       topright/botright/botleft/topleft corner; an empty
-                       list can be used to show a double line all around
-                       {not implemented yet}
+                       topleft/topright/botright/botleft corner; when the
+                       list has one character it is used for all; when
+                       the list has two characters the first is used for the
+                       border lines, the second for the corners; by default
+                       a double line is used all around when 'encoding' is
+                       "utf-8", otherwise ASCII characters are used.
        zindex          priority for the popup, default 50
        time            time in milliseconds after which the popup will close;
                        when omitted |popup_close()| must be used.
index 8052ca50ce9f32ac137c5a6a389f21c33e524b7c..810987aace23ffb22ed73f6dea6c34be480fdff1 100644 (file)
@@ -144,6 +144,7 @@ apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict, int atcursor)
     int                nr;
     char_u     *str;
     dictitem_T *di;
+    int                i;
 
     wp->w_minwidth = dict_get_number(dict, (char_u *)"minwidth");
     wp->w_minheight = dict_get_number(dict, (char_u *)"minheight");
@@ -211,6 +212,66 @@ apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict, int atcursor)
 
     get_padding_border(dict, wp->w_popup_padding, "padding", 999);
     get_padding_border(dict, wp->w_popup_border, "border", 1);
+
+    for (i = 0; i < 4; ++i)
+       VIM_CLEAR(wp->w_border_highlight[i]);
+    di = dict_find(dict, (char_u *)"borderhighlight", -1);
+    if (di != NULL)
+    {
+       if (di->di_tv.v_type != VAR_LIST)
+           emsg(_(e_listreq));
+       else
+       {
+           list_T      *list = di->di_tv.vval.v_list;
+           listitem_T  *li;
+
+           if (list != NULL)
+               for (i = 0, li = list->lv_first; i < 4 && i < list->lv_len;
+                                                        ++i, li = li->li_next)
+               {
+                   str = tv_get_string(&li->li_tv);
+                   if (*str != NUL)
+                       wp->w_border_highlight[i] = vim_strsave(str);
+               }
+           if (list->lv_len == 1 && wp->w_border_highlight[0] != NULL)
+               for (i = 1; i < 4; ++i)
+                       wp->w_border_highlight[i] =
+                                       vim_strsave(wp->w_border_highlight[0]);
+       }
+    }
+
+    for (i = 0; i < 8; ++i)
+       wp->w_border_char[i] = 0;
+    di = dict_find(dict, (char_u *)"borderchars", -1);
+    if (di != NULL)
+    {
+       if (di->di_tv.v_type != VAR_LIST)
+           emsg(_(e_listreq));
+       else
+       {
+           list_T      *list = di->di_tv.vval.v_list;
+           listitem_T  *li;
+
+           if (list != NULL)
+               for (i = 0, li = list->lv_first; i < 8 && i < list->lv_len;
+                                                        ++i, li = li->li_next)
+               {
+                   str = tv_get_string(&li->li_tv);
+                   if (*str != NUL)
+                       wp->w_border_char[i] = mb_ptr2char(str);
+               }
+           if (list->lv_len == 1)
+               for (i = 1; i < 8; ++i)
+                   wp->w_border_char[i] = wp->w_border_char[0];
+           if (list->lv_len == 2)
+           {
+               for (i = 4; i < 8; ++i)
+                   wp->w_border_char[i] = wp->w_border_char[1];
+               for (i = 1; i < 4; ++i)
+                   wp->w_border_char[i] = wp->w_border_char[0];
+           }
+       }
+    }
 }
 
 /*
index 66c3a39b452d4d4ad4d03a7f94ecc3795d440d58..387c398650a6217ea6e2efb1bb163956c9889cf9 100644 (file)
@@ -1030,13 +1030,11 @@ update_popups(void)
     int            total_width;
     int            total_height;
     int            popup_attr;
+    int            border_attr[4];
+    int            border_char[8] = {'-', '|', '-', '|', '+', '+', '+', '+', };
+    char_u  buf[MB_MAXBYTES];
     int            row;
-    int            tl_corner_char = '+';
-    char    *tr_corner_str = "+";
-    int            bl_corner_char = '+';
-    char    *br_corner_str = "+";
-    int            hor_line_char = '-';
-    char    *ver_line_str = "|";
+    int            i;
 
     // Find the window with the lowest zindex that hasn't been updated yet,
     // so that the window with a higher zindex is drawn later, thus goes on
@@ -1070,12 +1068,22 @@ update_popups(void)
 
        if (enc_utf8)
        {
-           tl_corner_char = 0x2554;
-           tr_corner_str = "\xe2\x95\x97";
-           bl_corner_char = 0x255a;
-           br_corner_str = "\xe2\x95\x9d";
-           hor_line_char = 0x2550;
-           ver_line_str = "\xe2\x95\x91";
+           border_char[0] = border_char[2] = 0x2550;
+           border_char[1] = border_char[3] = 0x2551;
+           border_char[4] = 0x2554;
+           border_char[5] = 0x2557;
+           border_char[6] = 0x255d;
+           border_char[7] = 0x255a;
+       }
+       for (i = 0; i < 8; ++i)
+           if (wp->w_border_char[i] != 0)
+               border_char[i] = wp->w_border_char[i];
+
+       for (i = 0; i < 4; ++i)
+       {
+           border_attr[i] = popup_attr;
+           if (wp->w_border_highlight[i] != NULL)
+               border_attr[i] = syn_name2attr(wp->w_border_highlight[i]);
        }
 
        if (wp->w_popup_border[0] > 0)
@@ -1085,11 +1093,14 @@ update_popups(void)
                    wp->w_wincol,
                    wp->w_wincol + total_width,
                    wp->w_popup_border[3] != 0
-                                            ? tl_corner_char : hor_line_char,
-                   hor_line_char, popup_attr);
+                                            ? border_char[4] : border_char[0],
+                   border_char[0], border_attr[0]);
            if (wp->w_popup_border[1] > 0)
-               screen_puts((char_u *)tr_corner_str, wp->w_winrow,
-                       wp->w_wincol + total_width - 1, popup_attr);
+           {
+               buf[mb_char2bytes(border_char[5], buf)] = NUL;
+               screen_puts(buf, wp->w_winrow,
+                              wp->w_wincol + total_width - 1, border_attr[1]);
+           }
        }
 
        if (wp->w_popup_padding[0] > 0)
@@ -1108,15 +1119,21 @@ update_popups(void)
        {
            // left border
            if (wp->w_popup_border[3] > 0)
-               screen_puts((char_u *)ver_line_str, row, wp->w_wincol, popup_attr);
+           {
+               buf[mb_char2bytes(border_char[3], buf)] = NUL;
+               screen_puts(buf, row, wp->w_wincol, border_attr[3]);
+           }
            // left padding
            if (wp->w_popup_padding[3] > 0)
                screen_puts(get_spaces(wp->w_popup_padding[3]), row,
                        wp->w_wincol + wp->w_popup_border[3], popup_attr);
            // right border
            if (wp->w_popup_border[1] > 0)
-               screen_puts((char_u *)ver_line_str, row,
-                       wp->w_wincol + total_width - 1, popup_attr);
+           {
+               buf[mb_char2bytes(border_char[1], buf)] = NUL;
+               screen_puts(buf, row,
+                              wp->w_wincol + total_width - 1, border_attr[1]);
+           }
            // right padding
            if (wp->w_popup_padding[1] > 0)
                screen_puts(get_spaces(wp->w_popup_padding[1]), row,
@@ -1142,11 +1159,15 @@ update_popups(void)
            screen_fill(row , row + 1,
                    wp->w_wincol,
                    wp->w_wincol + total_width,
-                   wp->w_popup_border[3] != 0 ? bl_corner_char : hor_line_char,
-                   hor_line_char, popup_attr);
+                   wp->w_popup_border[3] != 0
+                                            ? border_char[7] : border_char[2],
+                   border_char[2], border_attr[2]);
            if (wp->w_popup_border[1] > 0)
-               screen_puts((char_u *)br_corner_str, row,
-                       wp->w_wincol + total_width - 1, popup_attr);
+           {
+               buf[mb_char2bytes(border_char[6], buf)] = NUL;
+               screen_puts(buf, row,
+                              wp->w_wincol + total_width - 1, border_attr[2]);
+           }
        }
     }
 }
index fb277450cf059ac595f0ae49891dd03a47fe07f6..f6db26465bde39c9473365bd6074abcd02fd1abf 100644 (file)
@@ -2890,6 +2890,8 @@ struct window_S
     int                w_wantcol;          // "col" for popup window
     int                w_popup_padding[4]; // popup padding top/right/bot/left
     int                w_popup_border[4];  // popup border top/right/bot/left
+    char_u     *w_border_highlight[4];  // popup border highlight
+    int                w_border_char[8];   // popup border characters
     varnumber_T        w_popup_last_changedtick; // b:changedtick when position was
                                          // computed
     callback_T w_filter_cb;        // popup filter callback
diff --git a/src/testdir/dumps/Test_popupwin_22.dump b/src/testdir/dumps/Test_popupwin_22.dump
new file mode 100644 (file)
index 0000000..7e38906
--- /dev/null
@@ -0,0 +1,12 @@
+>1+0&#ffffff0| @73
+|2| |╔+0&#5fd7ff255|═@11|╗| +0&#ffffff0@5|╔+0&#dadada255|═@11|╗+0&#8a8a8a255| +0&#ffffff0@5|x+0&#5fd7ff255@13| +0&#ffffff0@2|#+0&#5fd7ff255|x@11|#| +0&#ffffff0@1
+|3| |║+0&#5fd7ff255|h+0#0000001#ffd7ff255|e|l@1|o| |b|o|r|d|e|r|║+0#0000000#5fd7ff255| +0&#ffffff0@5|║+0&#a8a8a8255|h+0#0000001#ffd7ff255|e|l@1|o| |b|o|r|d|e|r|║+0#0000000#8a8a8a255| +0&#ffffff0@5|x+0&#5fd7ff255|h+0#0000001#ffd7ff255|e|l@1|o| |b|o|r|d|e|r|x+0#0000000#5fd7ff255| +0&#ffffff0@2|x+0&#5fd7ff255|h+0#0000001#ffd7ff255|e|l@1|o| |b|o|r|d|e|r|x+0#0000000#5fd7ff255| +0&#ffffff0@1
+|4| |╚+0&#5fd7ff255|═@11|╝| +0&#ffffff0@5|║+0&#a8a8a8255|a+0#0000001#ffd7ff255|n|d| |m|o|r|e| @3|║+0#0000000#8a8a8a255| +0&#ffffff0@5|x+0&#5fd7ff255|l+0#0000001#ffd7ff255|i|n|e|s| |o|n|l|y| @1|x+0#0000000#5fd7ff255| +0&#ffffff0@2|x+0&#5fd7ff255|w+0#0000001#ffd7ff255|i|t|h| |c|o|r|n|e|r|s|x+0#0000000#5fd7ff255| +0&#ffffff0@1
+|5| @20|╚+0&#585858255|═@11|╝| +0&#ffffff0@5|x+0&#5fd7ff255@13| +0&#ffffff0@2|#+0&#5fd7ff255|x@11|#| +0&#ffffff0@1
+|6| |4+0&#5fd7ff255|0@11|5| +0&#ffffff0@58
+|7| |3+0&#5fd7ff255|h+0#0000001#ffd7ff255|e|l@1|o| |b|o|r|d|e|r|1+0#0000000#5fd7ff255| +0&#ffffff0@5| +0&#5fd7ff255@13| +0&#ffffff0@38
+|8| |3+0&#5fd7ff255|w+0#0000001#ffd7ff255|i|t|h| |n|u|m|b|e|r|s|1+0#0000000#5fd7ff255| +0&#ffffff0@5| +0&#5fd7ff255|h+0#0000001#ffd7ff255|e|l@1|o| |b|o|r|d|e|r| +0#0000000#5fd7ff255| +0&#ffffff0@38
+|9| |7+0&#5fd7ff255|2@11|6| +0&#ffffff0@5| +0&#5fd7ff255|j+0#0000001#ffd7ff255|u|s|t| |b|l|a|n|k|s| | +0#0000000#5fd7ff255| +0&#ffffff0@38
+|1|0| @19| +0&#5fd7ff255@13| +0&#ffffff0@38
+|1@1| @72
+@57|1|,|1| @10|T|o|p| 
index 523bd592a9b5985ed786ce595698680c3c1e74f8..6a2ef24a472380765754a30826272bc3f85c0da7 100644 (file)
@@ -77,6 +77,26 @@ func Test_popup_with_border_and_padding()
     call delete('XtestPopupBorder')
   endfor
 
+  call writefile([
+       \ "call setline(1, range(1, 100))",
+       \ "hi BlueColor ctermbg=lightblue",
+       \ "hi TopColor ctermbg=253",
+       \ "hi RightColor ctermbg=245",
+       \ "hi BottomColor ctermbg=240",
+       \ "hi LeftColor ctermbg=248",
+       \ "call popup_create('hello border', {'line': 2, 'col': 3, 'border': [], 'borderhighlight': ['BlueColor']})",
+       \ "call popup_create(['hello border', 'and more'], {'line': 2, 'col': 23, 'border': [], 'borderhighlight': ['TopColor', 'RightColor', 'BottomColor', 'LeftColor']})",
+       \ "call popup_create(['hello border', 'lines only'], {'line': 2, 'col': 43, 'border': [], 'borderhighlight': ['BlueColor'], 'borderchars': ['x']})",
+       \ "call popup_create(['hello border', 'with corners'], {'line': 2, 'col': 60, 'border': [], 'borderhighlight': ['BlueColor'], 'borderchars': ['x', '#']})",
+       \ "call popup_create(['hello border', 'with numbers'], {'line': 6, 'col': 3, 'border': [], 'borderhighlight': ['BlueColor'], 'borderchars': ['0', '1', '2', '3', '4', '5', '6', '7']})",
+       \ "call popup_create(['hello border', 'just blanks'], {'line': 7, 'col': 23, 'border': [], 'borderhighlight': ['BlueColor'], 'borderchars': [' ']})",
+       \], 'XtestPopupBorder')
+  let buf = RunVimInTerminal('-S XtestPopupBorder', {'rows': 12})
+  call VerifyScreenDump(buf, 'Test_popupwin_22', {})
+
+  call StopVimInTerminal(buf)
+  call delete('XtestPopupBorder')
+
   let with_border_or_padding = {
        \ 'line': 2,
        \ 'core_line': 3,
index a82e6e9633fa91b69a31718bcf723a8ae413312e..3be4e657abdd7aced48648c32c2fcb836ece5bde 100644 (file)
@@ -767,6 +767,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1445,
 /**/
     1444,
 /**/
index b4ab11be31cfe3997381c881dc576809f5731b22..e15b31191fa53e97ac50b4fb1f1a6a9bfea81c59 100644 (file)
@@ -4846,6 +4846,8 @@ win_free(
 #endif
 #ifdef FEAT_TEXT_PROP
     free_callback(&wp->w_filter_cb);
+    for (i = 0; i < 4; ++i)
+       VIM_CLEAR(wp->w_border_highlight[i]);
 #endif
 
 #ifdef FEAT_SYN_HL