1
0
forked from aniani/vim

patch 8.1.2265: when popup with "botleft" does not fit it flips incorrectly

Problem:    When popup with "botleft" does not fit it flips incorrectly.
Solution:   Only flip when there is more space on the other side.  Add the
            "posinvert" option to disable flipping and do it in both
            directions if enabled.  (closes #5151)
This commit is contained in:
Bram Moolenaar
2019-11-06 19:25:22 +01:00
parent fcf8a8743b
commit 638a4a7508
5 changed files with 145 additions and 4 deletions

View File

@@ -673,6 +673,16 @@ apply_general_options(win_T *wp, dict_T *dict)
wp->w_popup_flags &= ~POPF_DRAG;
}
di = dict_find(dict, (char_u *)"posinvert", -1);
if (di != NULL)
{
nr = dict_get_number(dict, (char_u *)"posinvert");
if (nr)
wp->w_popup_flags |= POPF_POSINVERT;
else
wp->w_popup_flags &= ~POPF_POSINVERT;
}
di = dict_find(dict, (char_u *)"resize", -1);
if (di != NULL)
{
@@ -1383,15 +1393,35 @@ popup_adjust_position(win_T *wp)
wp->w_winrow = 0;
}
else if (wp->w_popup_pos == POPPOS_BOTRIGHT
|| wp->w_popup_pos == POPPOS_BOTLEFT)
|| wp->w_popup_pos == POPPOS_BOTLEFT)
{
if ((wp->w_height + extra_height) <= wantline)
// bottom aligned: may move down
wp->w_winrow = wantline - (wp->w_height + extra_height);
else if (wantline * 2 >= Rows || !(wp->w_popup_flags & POPF_POSINVERT))
{
// Bottom aligned but does not fit, and less space on the other
// side or "posinvert" is off: reduce height.
wp->w_winrow = 0;
wp->w_height = wantline - extra_height;
}
else
// Not enough space, make top aligned.
// Not enough space and more space on the other side: make top
// aligned.
wp->w_winrow = (wantline < 0 ? 0 : wantline) + 1;
}
else if (wp->w_popup_pos == POPPOS_TOPRIGHT
|| wp->w_popup_pos == POPPOS_TOPLEFT)
{
if (wantline + (wp->w_height + extra_height) - 1 > Rows
&& wantline * 2 > Rows
&& (wp->w_popup_flags & POPF_POSINVERT))
// top aligned and not enough space below but there is space above:
// make bottom aligned
wp->w_winrow = wantline - 2 - wp->w_height - extra_height;
else
wp->w_winrow = wantline - 1;
}
if (wp->w_winrow >= Rows)
wp->w_winrow = Rows - 1;
else if (wp->w_winrow < 0)
@@ -1730,7 +1760,7 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type)
if (rettv != NULL)
rettv->vval.v_number = wp->w_id;
wp->w_popup_pos = POPPOS_TOPLEFT;
wp->w_popup_flags = POPF_IS_POPUP | POPF_MAPPING;
wp->w_popup_flags = POPF_IS_POPUP | POPF_MAPPING | POPF_POSINVERT;
if (buf != NULL)
{
@@ -2670,6 +2700,8 @@ f_popup_getoptions(typval_T *argvars, typval_T *rettv)
dict_add_number(dict, "mapping",
(wp->w_popup_flags & POPF_MAPPING) != 0);
dict_add_number(dict, "resize", (wp->w_popup_flags & POPF_RESIZE) != 0);
dict_add_number(dict, "posinvert",
(wp->w_popup_flags & POPF_POSINVERT) != 0);
dict_add_number(dict, "cursorline",
(wp->w_popup_flags & POPF_CURSORLINE) != 0);
dict_add_string(dict, "highlight", wp->w_p_wcr);
@@ -2830,7 +2862,7 @@ invoke_popup_filter(win_T *wp, int c)
argv[2].v_type = VAR_UNKNOWN;
// NOTE: The callback might close the popup, thus make "wp" invalid.
// NOTE: The callback might close the popup and make "wp" invalid.
call_callback(&wp->w_filter_cb, -1, &rettv, 2, argv);
if (win_valid_popup(wp) && old_lnum != wp->w_cursor.lnum)
popup_highlight_curline(wp);