]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.1.1428: popup_atcursor() not implemented yet v8.1.1428
authorBram Moolenaar <Bram@vim.org>
Thu, 30 May 2019 17:25:06 +0000 (19:25 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 30 May 2019 17:25:06 +0000 (19:25 +0200)
Problem:    Popup_atcursor() not implemented yet.
Solution:   Implement it. (Yasuhiro Matsumoto, closes #4456)

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

index 174ea094a3ea3b9f898bab6c41b2cedf2dd31369..58728c8c4ffa2ddfbf321d7108fe0a8733bf9a03 100644 (file)
@@ -85,11 +85,11 @@ Probably 2. is the best choice.
 
 IMPLEMENTATION:
 - Code is in popupwin.c
-- when creating the window set options to Vim default? (verify with 'number')
+- Implement the "pos" option.
 - Implement filter.
   Check that popup_close() works in the filter.
-- Implement the "pos" option.
 - Handle screen resize in screenalloc().
+- show [Popup] instead of [Scratch] in ":ls!"
 - Make redrawing more efficient and avoid flicker.
     Store popup info in a mask, use the mask in screen_line()
     Fix redrawing problem with completion.
@@ -97,7 +97,7 @@ IMPLEMENTATION:
     Fix redrawing the statusline on top of a popup
 - Figure out the size and position better.
     if wrapping splits a double-wide character
-    if wrapping has an indent
+    if wrapping inserts indent
 - Can the buffer be re-used, to avoid using up lots of buffer numbers?
 - Implement all the unimplemented options and features.
 
@@ -160,10 +160,10 @@ popup_notification({text}, {options})                      *popup_notification()*
 
 
 popup_atcursor({text}, {options})                       *popup_atcursor()*
-               {not implemented yet}
                Show the {text} above the cursor, and close it when the cursor
                moves.  This works like: >
                        call popup_create({text}, {
+                               \ 'pos': 'botleft',
                                \ 'line': 'cursor-1',
                                \ 'col': 'cursor',
                                \ 'moved': 'WORD',
@@ -270,10 +270,11 @@ manipulation is restricted:
 - 'bufhidden' is "hide"
 - 'buflisted' is off
 - 'undolevels' is -1: no undo at all
-TODO: more
+- all other buffer-local and window_local options are set to their Vim default
+  value.
 
-It is possible to change these options, but anything might break then, so
-better leave them alone.
+It is possible to change the specifically mentioned options, but anything
+might break then, so better leave them alone.
 
 The window does have a cursor position, but the cursor is not displayed.
 
@@ -306,12 +307,10 @@ The second argument of |popup_create()| is a dictionary with options:
                        "cursor", "cursor+1" or "cursor-1" to use the line of
                        the cursor and add or subtract a number of lines;
                        default is "cursor-1".
-                       {only number is implemented}
        col             screen column where to position the popup; can use
                        "cursor" to use the column of the cursor, "cursor+99"
                        and "cursor-99" to add or subtract a number of
                        columns; default is "cursor"
-                       {only number is implemented}
        pos             "topleft", "topright", "botleft" or "botright":
                        defines what corner of the popup "line" and "col" are
                        used for.  When not set "topleft" is used.
@@ -342,9 +341,17 @@ The second argument of |popup_create()| is a dictionary with options:
                        {not implemented yet}
        highlight       highlight group name to use for the text, stored in
                        the 'wincolor' option
+       padding         list with numbers, defining the padding
+                       above/right/below/left of the popup (similar to CSS);
+                       an empty list uses a padding of 1 all around; the
+                       padding goes around the text, inside any border;
+                       padding uses the 'wincolor' highlight; Example: [1, 2,
+                       1, 3] has 1 line of padding above, 2 columns on the
+                       right, 1 line below and 3 columns on the left
+                       {not implemented yet}
        border          list with numbers, defining the border thickness
-                       above/right/below/left of the popup; an empty list
-                       uses a border of 1 all around
+                       above/right/below/left of the popup (similar to CSS);
+                       an empty list uses a border of 1 all around
                        {not implemented yet}
        borderhighlight highlight group name to use for the border
                        {not implemented yet}
index d1e89eb99b91b7fb60f70996db9a4019e53902d6..a6703d18b50cca348974e378a5ab03f834d064a7 100644 (file)
@@ -809,6 +809,7 @@ static struct fst
     {"perleval",       1, 1, f_perleval},
 #endif
 #ifdef FEAT_TEXT_PROP
+    {"popup_atcursor", 2, 2, f_popup_atcursor},
     {"popup_close",    1, 1, f_popup_close},
     {"popup_create",   2, 2, f_popup_create},
     {"popup_getoptions", 1, 1, f_popup_getoptions},
index ee59af2eaef87e66775a0a0d3029e2c80393e7ea..9e9bf27e7fee2a0d39427fccc26ade37b18b0dfc 100644 (file)
 
 #ifdef FEAT_TEXT_PROP
 
+/*
+ * Get option value for"key", which is "line" or "col".
+ * Handles "cursor+N" and "cursor-N".
+ */
+    static int
+popup_options_pos(dict_T *dict, char_u *key)
+{
+    dictitem_T *di;
+    char_u     *val;
+    char_u     *s;
+    char_u     *endp;
+    int                n = 0;
+
+    di = dict_find(dict, key, -1);
+    if (di == NULL)
+       return 0;
+
+    val = tv_get_string(&di->di_tv);
+    if (STRNCMP(val, "cursor", 6) != 0)
+       return dict_get_number(dict, key);
+
+    setcursor_mayforce(TRUE);
+    s = val + 6;
+    if (*s != NUL)
+    {
+       n = strtol((char *)s, (char **)&endp, 10);
+       if (endp != NULL && *skipwhite(endp) != NUL)
+       {
+           semsg(_(e_invexpr2), val);
+           return 0;
+       }
+    }
+
+    if (STRCMP(key, "line") == 0)
+       n = screen_screenrow() + 1 + n;
+    else // "col"
+       n = screen_screencol() + 1 + n;
+
+    if (n < 1)
+       n = 1;
+    return n;
+}
+
 /*
  * Go through the options in "dict" and apply them to buffer "buf" displayed in
  * popup window "wp".
+ * When called from f_popup_atcursor() "atcursor" is TRUE.
  */
     static void
-apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict)
+apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict, int atcursor)
 {
     int            nr;
     char_u  *str;
@@ -30,8 +74,19 @@ apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict)
     wp->w_maxwidth = dict_get_number(dict, (char_u *)"maxwidth");
     wp->w_maxheight = dict_get_number(dict, (char_u *)"maxheight");
 
-    wp->w_wantline = dict_get_number(dict, (char_u *)"line");
-    wp->w_wantcol = dict_get_number(dict, (char_u *)"col");
+    if (atcursor)
+    {
+       setcursor_mayforce(TRUE);
+       wp->w_wantline = screen_screenrow();
+       wp->w_wantcol = screen_screencol() + 1;
+    }
+
+    nr = popup_options_pos(dict, (char_u *)"line");
+    if (nr > 0)
+       wp->w_wantline = nr;
+    nr = popup_options_pos(dict, (char_u *)"col");
+    if (nr > 0)
+       wp->w_wantcol = nr;
 
     wp->w_zindex = dict_get_number(dict, (char_u *)"zindex");
 
@@ -215,9 +270,11 @@ popup_adjust_position(win_T *wp)
 
 /*
  * popup_create({text}, {options})
+ * popup_atcursor({text}, {options})
+ * When called from f_popup_atcursor() "atcursor" is TRUE.
  */
-    void
-f_popup_create(typval_T *argvars, typval_T *rettv)
+    static void
+popup_create(typval_T *argvars, typval_T *rettv, int atcursor)
 {
     win_T   *wp;
     buf_T   *buf;
@@ -309,7 +366,7 @@ f_popup_create(typval_T *argvars, typval_T *rettv)
     curbuf = curwin->w_buffer;
 
     // Deal with options.
-    apply_options(wp, buf, argvars[1].vval.v_dict);
+    apply_options(wp, buf, argvars[1].vval.v_dict, atcursor);
 
     // set default values
     if (wp->w_zindex == 0)
@@ -322,6 +379,24 @@ f_popup_create(typval_T *argvars, typval_T *rettv)
     redraw_all_later(NOT_VALID);
 }
 
+/*
+ * popup_create({text}, {options})
+ */
+    void
+f_popup_create(typval_T *argvars, typval_T *rettv)
+{
+    popup_create(argvars, rettv, FALSE);
+}
+
+/*
+ * popup_atcursor({text}, {options})
+ */
+    void
+f_popup_atcursor(typval_T *argvars, typval_T *rettv)
+{
+    popup_create(argvars, rettv, TRUE);
+}
+
 /*
  * Find the popup window with window-ID "id".
  * If the popup window does not exist NULL is returned.
index 7337457126792e0b9b80ad65098af5536a4b4676..404b6cfe85ef9b8c7fa7fc07a6af1deeb611101a 100644 (file)
@@ -1,15 +1,16 @@
 /* popupwin.c */
-void popup_adjust_position(win_T *wp);
-void f_popup_create(typval_T *argvars, typval_T *rettv);
 int popup_any_visible(void);
+void close_all_popups(void);
+void ex_popupclear(exarg_T *eap);
+void f_popup_atcursor(typval_T *argvars, typval_T *rettv);
 void f_popup_close(typval_T *argvars, typval_T *rettv);
+void f_popup_create(typval_T *argvars, typval_T *rettv);
+void f_popup_getoptions(typval_T *argvars, typval_T *rettv);
+void f_popup_getposition(typval_T *argvars, typval_T *rettv);
 void f_popup_hide(typval_T *argvars, typval_T *rettv);
+void f_popup_move(typval_T *argvars, typval_T *rettv);
 void f_popup_show(typval_T *argvars, typval_T *rettv);
+void popup_adjust_position(win_T *wp);
 void popup_close(int id);
 void popup_close_tabpage(tabpage_T *tp, int id);
-void close_all_popups(void);
-void ex_popupclear(exarg_T *eap);
-void f_popup_move(typval_T *argvars, typval_T *rettv);
-void f_popup_getoptions(typval_T *argvars, typval_T *rettv);
-void f_popup_getposition(typval_T *argvars, typval_T *rettv);
 /* vim: set ft=c : */
index d92d8b12a78759208715a67e54c10a7b2993925a..ee188e39c3f92b1b89b060dd5f7f2719136a6a76 100644 (file)
@@ -335,3 +335,52 @@ func Test_popup_option_values()
   call popup_close(winid)
   bwipe
 endfunc
+
+func Test_popup_atcursor()
+  topleft vnew
+  call setline(1, [
+  \  'xxxxxxxxxxxxxxxxx',
+  \  'xxxxxxxxxxxxxxxxx',
+  \  'xxxxxxxxxxxxxxxxx',
+  \])
+
+  call cursor(2, 2)
+  redraw
+  let winid = popup_atcursor('vim', {})
+  redraw
+  let line = join(map(range(1, 17), 'screenstring(1, v:val)'), '')
+  call assert_equal('xvimxxxxxxxxxxxxx', line)
+  call popup_close(winid)
+
+  call cursor(3, 4)
+  redraw
+  let winid = popup_atcursor('vim', {})
+  redraw
+  let line = join(map(range(1, 17), 'screenstring(2, v:val)'), '')
+  call assert_equal('xxxvimxxxxxxxxxxx', line)
+  call popup_close(winid)
+
+  call cursor(1, 1)
+  redraw
+  let winid = popup_create('vim', {
+  \ 'line': 'cursor+2',
+  \ 'col': 'cursor+1',
+  \})
+  redraw
+  let line = join(map(range(1, 17), 'screenstring(3, v:val)'), '')
+  call assert_equal('xvimxxxxxxxxxxxxx', line)
+  call popup_close(winid)
+
+  call cursor(3, 3)
+  redraw
+  let winid = popup_create('vim', {
+  \ 'line': 'cursor-2',
+  \ 'col': 'cursor-1',
+  \})
+  redraw
+  let line = join(map(range(1, 17), 'screenstring(1, v:val)'), '')
+  call assert_equal('xvimxxxxxxxxxxxxx', line)
+  call popup_close(winid)
+
+  bwipe!
+endfunc
index 282d045e652ea4773cb73e922ba6f79d36c9500a..6d04157ab8adff7a9bdcfa8c74fa0b2f793d32ca 100644 (file)
@@ -767,6 +767,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1428,
 /**/
     1427,
 /**/