0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 8.1.1429: "pos" option of popup window not supported yet

Problem:    "pos" option of popup window not supported yet.
Solution:   Implement the option. Rename popup_getposition() to
            popup_getpos().
This commit is contained in:
Bram Moolenaar
2019-05-30 21:24:26 +02:00
parent cc31ad9f9b
commit ac1f1bc222
5 changed files with 164 additions and 52 deletions

View File

@@ -232,7 +232,8 @@ popup_setoptions({id}, {options}) *popup_setoptions()*
popup_getoptions({id}) *popup_getoptions()* popup_getoptions({id}) *popup_getoptions()*
Return the {options} for popup {id} in a Dict. 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 The "highlight" entry is omitted, use the 'wincolor' option
for that: > for that: >
@@ -240,7 +241,7 @@ popup_getoptions({id}) *popup_getoptions()*
< If popup window {id} is not found an empty Dict is returned. < 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 Return the position and size of popup {id}. Returns a Dict
with these entries: with these entries:
col screen column of the popup, one-based col screen column of the popup, one-based
@@ -303,19 +304,22 @@ optionally text properties. It is in one of three forms:
|popup-props|. |popup-props|.
The second argument of |popup_create()| is a dictionary with options: The second argument of |popup_create()| is a dictionary with options:
line screen line where to position the popup; can use line screen line where to position the popup; can use a
"cursor", "cursor+1" or "cursor-1" to use the line of number or "cursor", "cursor+1" or "cursor-1" to use
the cursor and add or subtract a number of lines; the line of the cursor and add or subtract a number of
default is "cursor-1". lines; if omitted the popup is vertically centered,
col screen column where to position the popup; can use otherwise "pos" is used.
"cursor" to use the column of the cursor, "cursor+99" col screen column where to position the popup; can use a
and "cursor-99" to add or subtract a number of number or "cursor" to use the column of the cursor,
columns; default is "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": pos "topleft", "topright", "botleft" or "botright":
defines what corner of the popup "line" and "col" are defines what corner of the popup "line" and "col" are
used for. When not set "topleft" is used. used for. When not set "topleft" is used.
Alternatively "center" can be used to position the 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} {not implemented yet}
flip when TRUE (the default) and the position is relative flip when TRUE (the default) and the position is relative
to the cursor, flip to below or above the cursor to to the cursor, flip to below or above the cursor to

View File

@@ -15,12 +15,25 @@
#ifdef FEAT_TEXT_PROP #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". * Get option value for"key", which is "line" or "col".
* Handles "cursor+N" and "cursor-N". * Handles "cursor+N" and "cursor-N".
*/ */
static int static int
popup_options_pos(dict_T *dict, char_u *key) popup_options_one(dict_T *dict, char_u *key)
{ {
dictitem_T *di; dictitem_T *di;
char_u *val; char_u *val;
@@ -58,6 +71,36 @@ popup_options_pos(dict_T *dict, char_u *key)
return n; 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 * Go through the options in "dict" and apply them to buffer "buf" displayed in
* popup window "wp". * popup window "wp".
@@ -66,7 +109,9 @@ popup_options_pos(dict_T *dict, char_u *key)
static void static void
apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict, int atcursor) apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict, int atcursor)
{ {
#if defined(FEAT_TIMERS)
int nr; int nr;
#endif
char_u *str; char_u *str;
wp->w_minwidth = dict_get_number(dict, (char_u *)"minwidth"); 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) if (atcursor)
{ {
wp->w_popup_pos = POPPOS_BOTLEFT;
setcursor_mayforce(TRUE); setcursor_mayforce(TRUE);
wp->w_wantline = screen_screenrow(); 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; wp->w_wantcol = screen_screencol() + 1;
} }
nr = popup_options_pos(dict, (char_u *)"line"); get_pos_options(wp, dict);
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"); wp->w_zindex = dict_get_number(dict, (char_u *)"zindex");
@@ -212,24 +258,42 @@ popup_adjust_position(win_T *wp)
linenr_T lnum; linenr_T lnum;
int wrapped = 0; int wrapped = 0;
int maxwidth; int maxwidth;
int center_vert = FALSE;
int center_hor = FALSE;
// TODO: Compute the size and position properly. wp->w_winrow = 0;
if (wp->w_wantline > 0) wp->w_wincol = 0;
wp->w_winrow = wp->w_wantline - 1; if (wp->w_popup_pos == POPPOS_CENTER)
{
// center after computing the size
center_vert = TRUE;
center_hor = TRUE;
}
else else
// TODO: better default {
wp->w_winrow = Rows > 5 ? Rows / 2 - 2 : 0; if (wp->w_wantline == 0)
if (wp->w_winrow >= Rows) center_vert = TRUE;
wp->w_winrow = Rows - 1; 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) if (wp->w_wantcol == 0)
wp->w_wincol = wp->w_wantcol - 1; center_hor = TRUE;
else else if (wp->w_popup_pos == POPPOS_TOPLEFT
// TODO: better default || wp->w_popup_pos == POPPOS_BOTLEFT)
wp->w_wincol = Columns > 20 ? Columns / 2 - 10 : 0; {
if (wp->w_wincol >= Columns - 3) wp->w_wincol = wp->w_wantcol - 1;
wp->w_wincol = Columns - 3; 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; maxwidth = Columns - wp->w_wincol;
if (wp->w_maxwidth > 0 && maxwidth > wp->w_maxwidth) if (wp->w_maxwidth > 0 && maxwidth > wp->w_maxwidth)
maxwidth = wp->w_maxwidth; maxwidth = wp->w_maxwidth;
@@ -255,6 +319,16 @@ popup_adjust_position(win_T *wp)
wp->w_width = wp->w_minwidth; wp->w_width = wp->w_minwidth;
if (wp->w_width > maxwidth) if (wp->w_width > maxwidth)
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) if (wp->w_height <= 1)
wp->w_height = wp->w_buffer->b_ml.ml_line_count + wrapped; 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) if (wp->w_height > Rows - wp->w_winrow)
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); 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) if (wp == NULL)
return; return;
rettv->vval.v_number = wp->w_id; 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); buf = buflist_new(NULL, NULL, (linenr_T)0, BLN_NEW|BLN_LISTED|BLN_DUMMY);
if (buf == NULL) 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_swf = FALSE; // no swap file
buf->b_p_bl = FALSE; // unlisted buffer buf->b_p_bl = FALSE; // unlisted buffer
buf->b_locked = TRUE; buf->b_locked = TRUE;
wp->w_p_wrap = TRUE; // 'wrap' is default on
// Avoid that 'buftype' is reset when this buffer is entered. // Avoid that 'buftype' is reset when this buffer is entered.
buf->b_p_initialized = TRUE; buf->b_p_initialized = TRUE;
@@ -578,11 +667,7 @@ f_popup_move(typval_T *argvars, typval_T *rettv UNUSED)
wp->w_maxwidth = nr; wp->w_maxwidth = nr;
if ((nr = dict_get_number(d, (char_u *)"maxheight")) > 0) if ((nr = dict_get_number(d, (char_u *)"maxheight")) > 0)
wp->w_maxheight = nr; wp->w_maxheight = nr;
if ((nr = dict_get_number(d, (char_u *)"line")) > 0) get_pos_options(wp, d);
wp->w_wantline = nr;
if ((nr = dict_get_number(d, (char_u *)"col")) > 0)
wp->w_wantcol = nr;
// TODO: "pos"
if (wp->w_winrow + wp->w_height >= cmdline_row) if (wp->w_winrow + wp->w_height >= cmdline_row)
clear_cmdline = TRUE; clear_cmdline = TRUE;
@@ -591,10 +676,10 @@ f_popup_move(typval_T *argvars, typval_T *rettv UNUSED)
} }
/* /*
* popup_getposition({id}) * popup_getpos({id})
*/ */
void void
f_popup_getposition(typval_T *argvars, typval_T *rettv) f_popup_getpos(typval_T *argvars, typval_T *rettv)
{ {
dict_T *dict; dict_T *dict;
int id = (int)tv_get_number(argvars); int id = (int)tv_get_number(argvars);
@@ -623,6 +708,7 @@ f_popup_getoptions(typval_T *argvars, typval_T *rettv)
dict_T *dict; dict_T *dict;
int id = (int)tv_get_number(argvars); int id = (int)tv_get_number(argvars);
win_T *wp = find_popup_win(id); win_T *wp = find_popup_win(id);
int i;
if (rettv_dict_alloc(rettv) == OK) 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, "maxheight", wp->w_maxheight);
dict_add_number(dict, "maxwidth", wp->w_maxwidth); dict_add_number(dict, "maxwidth", wp->w_maxwidth);
dict_add_number(dict, "zindex", wp->w_zindex); 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) # if defined(FEAT_TIMERS)
dict_add_number(dict, "time", wp->w_popup_timer != NULL dict_add_number(dict, "time", wp->w_popup_timer != NULL
? (long)wp->w_popup_timer->tr_interval : 0L); ? (long)wp->w_popup_timer->tr_interval : 0L);

View File

@@ -1,16 +1,16 @@
/* popupwin.c */ /* popupwin.c */
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_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_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(int id);
void popup_close_tabpage(tabpage_T *tp, 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 : */ /* vim: set ft=c : */

View File

@@ -1982,6 +1982,15 @@ typedef struct {
// # define CRYPT_NOT_INPLACE 1 // # define CRYPT_NOT_INPLACE 1
#endif #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" * 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). */ int w_vsep_width; /* Number of separator columns (0 or 1). */
pos_save_T w_save_cursor; /* backup of cursor pos and topline */ pos_save_T w_save_cursor; /* backup of cursor pos and topline */
#ifdef FEAT_TEXT_PROP #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_zindex;
int w_minheight; // "minheight" for popup window int w_minheight; // "minheight" for popup window
int w_minwidth; // "minwidth" for popup window int w_minwidth; // "minwidth" for popup window

View File

@@ -767,6 +767,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1429,
/**/ /**/
1428, 1428,
/**/ /**/