]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.1.1429: "pos" option of popup window not supported yet v8.1.1429
authorBram Moolenaar <Bram@vim.org>
Thu, 30 May 2019 19:24:26 +0000 (21:24 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 30 May 2019 19:24:26 +0000 (21:24 +0200)
Problem:    "pos" option of popup window not supported yet.
Solution:   Implement the option. Rename popup_getposition() to
            popup_getpos().

runtime/doc/popup.txt
src/popupwin.c
src/proto/popupwin.pro
src/structs.h
src/version.c

index 58728c8c4ffa2ddfbf321d7108fe0a8733bf9a03..ad30e582703875e9c69df82073c7a06226aae547 100644 (file)
@@ -232,7 +232,8 @@ popup_setoptions({id}, {options})                   *popup_setoptions()*
 
 popup_getoptions({id})                                 *popup_getoptions()*
                Return the {options} for popup {id} in a Dict.
-               A zero value means the option was not set.
+               A zero value means the option was not set.  For "zindex" the
+               default value is returned, not zero.
 
                The "highlight" entry is omitted, use the 'wincolor' option
                for that: >
@@ -240,7 +241,7 @@ popup_getoptions({id})                                      *popup_getoptions()*
 
 <              If popup window {id} is not found an empty Dict is returned.
 
-popup_getposition({id})                                        *popup_getposition()*
+popup_getpos({id})                                     *popup_getpos()*
                Return the position and size of popup {id}.  Returns a Dict
                with these entries:
                    col         screen column of the popup, one-based
@@ -303,19 +304,22 @@ optionally text properties.  It is in one of three forms:
                        |popup-props|.
 
 The second argument of |popup_create()| is a dictionary with options:
-       line            screen line where to position the popup; can use
-                       "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".
-       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"
+       line            screen line where to position the popup; can use a
+                       number or "cursor", "cursor+1" or "cursor-1" to use
+                       the line of the cursor and add or subtract a number of
+                       lines; if omitted the popup is vertically centered,
+                       otherwise "pos" is used.
+       col             screen column where to position the popup; can use a
+                       number or "cursor" to use the column of the cursor,
+                       "cursor+99" and "cursor-99" to add or subtract a
+                       number of columns; if omitted the popup is
+                       horizontally centered, otherwise "pos" is used
        pos             "topleft", "topright", "botleft" or "botright":
                        defines what corner of the popup "line" and "col" are
                        used for.  When not set "topleft" is used.
                        Alternatively "center" can be used to position the
-                       popup in the center of the Vim window.
+                       popup in the center of the Vim window, in which case
+                       "line" and "col" are ignored.
                        {not implemented yet}
        flip            when TRUE (the default) and the position is relative
                        to the cursor, flip to below or above the cursor to
index 9e9bf27e7fee2a0d39427fccc26ade37b18b0dfc..a5c14b0f74c1da9194e3524ef8bea5bf9595cdf6 100644 (file)
 
 #ifdef FEAT_TEXT_PROP
 
+typedef struct {
+    char       *pp_name;
+    poppos_T   pp_val;
+} poppos_entry_T;
+
+static poppos_entry_T poppos_entries[] = {
+    {"botleft", POPPOS_BOTLEFT},
+    {"topleft", POPPOS_TOPLEFT},
+    {"botright", POPPOS_BOTRIGHT},
+    {"topright", POPPOS_TOPRIGHT},
+    {"center", POPPOS_CENTER}
+};
+
 /*
  * 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)
+popup_options_one(dict_T *dict, char_u *key)
 {
     dictitem_T *di;
     char_u     *val;
@@ -58,6 +71,36 @@ popup_options_pos(dict_T *dict, char_u *key)
     return n;
 }
 
+    static void
+get_pos_options(win_T *wp, dict_T *dict)
+{
+    char_u     *str;
+    int                nr;
+
+    nr = popup_options_one(dict, (char_u *)"line");
+    if (nr > 0)
+       wp->w_wantline = nr;
+    nr = popup_options_one(dict, (char_u *)"col");
+    if (nr > 0)
+       wp->w_wantcol = nr;
+
+    str = dict_get_string(dict, (char_u *)"pos", FALSE);
+    if (str != NULL)
+    {
+       for (nr = 0;
+               nr < (int)(sizeof(poppos_entries) / sizeof(poppos_entry_T));
+                                                                         ++nr)
+           if (STRCMP(str, poppos_entries[nr].pp_name) == 0)
+           {
+               wp->w_popup_pos = poppos_entries[nr].pp_val;
+               nr = -1;
+               break;
+           }
+       if (nr != -1)
+           semsg(_(e_invarg2), str);
+    }
+}
+
 /*
  * Go through the options in "dict" and apply them to buffer "buf" displayed in
  * popup window "wp".
@@ -66,7 +109,9 @@ popup_options_pos(dict_T *dict, char_u *key)
     static void
 apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict, int atcursor)
 {
+#if defined(FEAT_TIMERS)
     int            nr;
+#endif
     char_u  *str;
 
     wp->w_minwidth = dict_get_number(dict, (char_u *)"minwidth");
@@ -76,17 +121,18 @@ apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict, int atcursor)
 
     if (atcursor)
     {
+       wp->w_popup_pos = POPPOS_BOTLEFT;
        setcursor_mayforce(TRUE);
        wp->w_wantline = screen_screenrow();
+       if (wp->w_wantline == 0)  // cursor in first line
+       {
+           wp->w_wantline = 2;
+           wp->w_popup_pos = POPPOS_TOPLEFT;
+       }
        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;
+    get_pos_options(wp, dict);
 
     wp->w_zindex = dict_get_number(dict, (char_u *)"zindex");
 
@@ -212,24 +258,42 @@ popup_adjust_position(win_T *wp)
     linenr_T   lnum;
     int                wrapped = 0;
     int                maxwidth;
+    int                center_vert = FALSE;
+    int                center_hor = FALSE;
 
-    // TODO: Compute the size and position properly.
-    if (wp->w_wantline > 0)
-       wp->w_winrow = wp->w_wantline - 1;
+    wp->w_winrow = 0;
+    wp->w_wincol = 0;
+    if (wp->w_popup_pos == POPPOS_CENTER)
+    {
+       // center after computing the size
+       center_vert = TRUE;
+       center_hor = TRUE;
+    }
     else
-       // TODO: better default
-       wp->w_winrow = Rows > 5 ? Rows / 2 - 2 : 0;
-    if (wp->w_winrow >= Rows)
-       wp->w_winrow = Rows - 1;
+    {
+       if (wp->w_wantline == 0)
+           center_vert = TRUE;
+       else if (wp->w_popup_pos == POPPOS_TOPLEFT
+               || wp->w_popup_pos == POPPOS_TOPRIGHT)
+       {
+           wp->w_winrow = wp->w_wantline - 1;
+           if (wp->w_winrow >= Rows)
+               wp->w_winrow = Rows - 1;
+       }
 
-    if (wp->w_wantcol > 0)
-       wp->w_wincol = wp->w_wantcol - 1;
-    else
-       // TODO: better default
-       wp->w_wincol = Columns > 20 ? Columns / 2 - 10 : 0;
-    if (wp->w_wincol >= Columns - 3)
-       wp->w_wincol = Columns - 3;
+       if (wp->w_wantcol == 0)
+           center_hor = TRUE;
+       else if (wp->w_popup_pos == POPPOS_TOPLEFT
+               || wp->w_popup_pos == POPPOS_BOTLEFT)
+       {
+           wp->w_wincol = wp->w_wantcol - 1;
+           if (wp->w_wincol >= Columns - 3)
+               wp->w_wincol = Columns - 3;
+       }
+    }
 
+    // When centering or right aligned, use maximum width.
+    // When left aligned use the space available.
     maxwidth = Columns - wp->w_wincol;
     if (wp->w_maxwidth > 0 && maxwidth > wp->w_maxwidth)
        maxwidth = wp->w_maxwidth;
@@ -255,6 +319,16 @@ popup_adjust_position(win_T *wp)
        wp->w_width = wp->w_minwidth;
     if (wp->w_width > maxwidth)
        wp->w_width = maxwidth;
+    if (center_hor)
+       wp->w_wincol = (Columns - wp->w_width) / 2;
+    else if (wp->w_popup_pos == POPPOS_BOTRIGHT
+           || wp->w_popup_pos == POPPOS_TOPRIGHT)
+    {
+       // Right aligned: move to the right if needed.
+       // No truncation, because that would change the height.
+       if (wp->w_width < wp->w_wantcol)
+           wp->w_wincol = wp->w_wantcol - wp->w_width;
+    }
 
     if (wp->w_height <= 1)
        wp->w_height = wp->w_buffer->b_ml.ml_line_count + wrapped;
@@ -265,6 +339,19 @@ popup_adjust_position(win_T *wp)
     if (wp->w_height > Rows - wp->w_winrow)
        wp->w_height = Rows - wp->w_winrow;
 
+    if (center_vert)
+       wp->w_winrow = (Rows - wp->w_height) / 2;
+    else if (wp->w_popup_pos == POPPOS_BOTRIGHT
+           || wp->w_popup_pos == POPPOS_BOTLEFT)
+    {
+       if (wp->w_height <= wp->w_wantline)
+           // bottom aligned: may move down
+           wp->w_winrow = wp->w_wantline - wp->w_height;
+       else
+           // not enough space, make top aligned
+           wp->w_winrow = wp->w_wantline + 1;
+    }
+
     wp->w_popup_last_changedtick = CHANGEDTICK(wp->w_buffer);
 }
 
@@ -304,7 +391,7 @@ popup_create(typval_T *argvars, typval_T *rettv, int atcursor)
     if (wp == NULL)
        return;
     rettv->vval.v_number = wp->w_id;
-    wp->w_p_wrap = TRUE;  // 'wrap' is default on
+    wp->w_popup_pos = POPPOS_TOPLEFT;
 
     buf = buflist_new(NULL, NULL, (linenr_T)0, BLN_NEW|BLN_LISTED|BLN_DUMMY);
     if (buf == NULL)
@@ -322,6 +409,8 @@ popup_create(typval_T *argvars, typval_T *rettv, int atcursor)
     buf->b_p_swf = FALSE;   // no swap file
     buf->b_p_bl = FALSE;    // unlisted buffer
     buf->b_locked = TRUE;
+    wp->w_p_wrap = TRUE;  // 'wrap' is default on
+
     // Avoid that 'buftype' is reset when this buffer is entered.
     buf->b_p_initialized = TRUE;
 
@@ -578,11 +667,7 @@ f_popup_move(typval_T *argvars, typval_T *rettv UNUSED)
        wp->w_maxwidth = nr;
     if ((nr = dict_get_number(d, (char_u *)"maxheight")) > 0)
        wp->w_maxheight = nr;
-    if ((nr = dict_get_number(d, (char_u *)"line")) > 0)
-       wp->w_wantline = nr;
-    if ((nr = dict_get_number(d, (char_u *)"col")) > 0)
-       wp->w_wantcol = nr;
-    // TODO: "pos"
+    get_pos_options(wp, d);
 
     if (wp->w_winrow + wp->w_height >= cmdline_row)
        clear_cmdline = TRUE;
@@ -591,10 +676,10 @@ f_popup_move(typval_T *argvars, typval_T *rettv UNUSED)
 }
 
 /*
- * popup_getposition({id})
+ * popup_getpos({id})
  */
     void
-f_popup_getposition(typval_T *argvars, typval_T *rettv)
+f_popup_getpos(typval_T *argvars, typval_T *rettv)
 {
     dict_T     *dict;
     int                id = (int)tv_get_number(argvars);
@@ -623,6 +708,7 @@ f_popup_getoptions(typval_T *argvars, typval_T *rettv)
     dict_T     *dict;
     int                id = (int)tv_get_number(argvars);
     win_T      *wp = find_popup_win(id);
+    int                i;
 
     if (rettv_dict_alloc(rettv) == OK)
     {
@@ -637,6 +723,16 @@ f_popup_getoptions(typval_T *argvars, typval_T *rettv)
        dict_add_number(dict, "maxheight", wp->w_maxheight);
        dict_add_number(dict, "maxwidth", wp->w_maxwidth);
        dict_add_number(dict, "zindex", wp->w_zindex);
+
+       for (i = 0; i < (int)(sizeof(poppos_entries) / sizeof(poppos_entry_T));
+                                                                          ++i)
+           if (wp->w_popup_pos == poppos_entries[i].pp_val)
+           {
+               dict_add_string(dict, "pos",
+                                         (char_u *)poppos_entries[i].pp_name);
+               break;
+           }
+
 # if defined(FEAT_TIMERS)
        dict_add_number(dict, "time", wp->w_popup_timer != NULL
                                 ?  (long)wp->w_popup_timer->tr_interval : 0L);
index 404b6cfe85ef9b8c7fa7fc07a6af1deeb611101a..eb9e241528c9af9cf2d6fbf28f6ddb5da6f1309c 100644 (file)
@@ -1,16 +1,16 @@
 /* popupwin.c */
-int popup_any_visible(void);
-void close_all_popups(void);
-void ex_popupclear(exarg_T *eap);
+void popup_adjust_position(win_T *wp);
+void f_popup_create(typval_T *argvars, typval_T *rettv);
 void f_popup_atcursor(typval_T *argvars, typval_T *rettv);
+int popup_any_visible(void);
 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_getpos(typval_T *argvars, typval_T *rettv);
+void f_popup_getoptions(typval_T *argvars, typval_T *rettv);
 /* vim: set ft=c : */
index 9f63949208cae4525dd9574792f4f856a28c5c3e..da3162ec808da91195c43fd24d70ed4ef6e47259 100644 (file)
@@ -1982,6 +1982,15 @@ typedef struct {
 //  # define CRYPT_NOT_INPLACE 1
 #endif
 
+#ifdef FEAT_TEXT_PROP
+typedef enum {
+    POPPOS_BOTLEFT,
+    POPPOS_TOPLEFT,
+    POPPOS_BOTRIGHT,
+    POPPOS_TOPRIGHT,
+    POPPOS_CENTER
+} poppos_T;
+#endif
 
 /*
  * These are items normally related to a buffer.  But when using ":ownsyntax"
@@ -2873,7 +2882,8 @@ 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_popup_flags;      // POPF_ values
+    poppos_T   w_popup_pos;
     int                w_zindex;
     int                w_minheight;        // "minheight" for popup window
     int                w_minwidth;         // "minwidth" for popup window
index 6d04157ab8adff7a9bdcfa8c74fa0b2f793d32ca..c3b96e933173e1dc8c6281b8d8c59a534b35672d 100644 (file)
@@ -767,6 +767,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1429,
 /**/
     1428,
 /**/