Mercurial > vim
diff src/popupwin.c @ 18542:244b336b94ce v8.1.2265
patch 8.1.2265: when popup with "botleft" does not fit it flips incorrectly
Commit: https://github.com/vim/vim/commit/638a4a7508082f8700b135953e4f9465f675a0f5
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Nov 6 19:25:22 2019 +0100
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)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 06 Nov 2019 19:30:03 +0100 |
parents | e855058e0c23 |
children | a6dbbedddce1 |
line wrap: on
line diff
--- a/src/popupwin.c +++ b/src/popupwin.c @@ -673,6 +673,16 @@ apply_general_options(win_T *wp, dict_T 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 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, ty 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);