To: vim_dev@googlegroups.com Subject: Patch 8.1.2265 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.2265 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) Files: src/popupwin.c, src/testdir/test_popupwin.vim, src/vim.h, src/testdir/dumps/Test_popupwin_nospace.dump *** ../vim-8.1.2264/src/popupwin.c 2019-11-03 22:29:19.469793561 +0100 --- src/popupwin.c 2019-11-06 19:17:46.571609017 +0100 *************** *** 673,678 **** --- 673,688 ---- 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,1397 **** wp->w_winrow = 0; } else if (wp->w_popup_pos == POPPOS_BOTRIGHT ! || 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 ! // Not enough space, make top aligned. wp->w_winrow = (wantline < 0 ? 0 : wantline) + 1; } if (wp->w_winrow >= Rows) wp->w_winrow = Rows - 1; else if (wp->w_winrow < 0) --- 1393,1427 ---- wp->w_winrow = 0; } else if (wp->w_popup_pos == POPPOS_BOTRIGHT ! || 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 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,1736 **** 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; if (buf != NULL) { --- 1760,1766 ---- 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 | POPF_POSINVERT; if (buf != NULL) { *************** *** 2670,2675 **** --- 2700,2707 ---- 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,2836 **** argv[2].v_type = VAR_UNKNOWN; ! // NOTE: The callback might close the popup, thus 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); --- 2862,2868 ---- argv[2].v_type = VAR_UNKNOWN; ! // 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); *** ../vim-8.1.2264/src/testdir/test_popupwin.vim 2019-11-03 22:29:19.469793561 +0100 --- src/testdir/test_popupwin.vim 2019-11-06 19:20:35.974855239 +0100 *************** *** 323,328 **** --- 323,420 ---- call delete('XtestPopupCorners') endfunc + func Test_popup_nospace() + CheckScreendump + + let lines =<< trim END + call setline(1, repeat([repeat('-', 60)], 15)) + set so=0 + + " cursor in a line in top half, using "botleft" with popup that + " does fit + normal 5G2|r@ + let winid1 = popup_create(['one', 'two'], #{ + \ line: 'cursor-1', + \ col: 'cursor', + \ pos: 'botleft', + \ border: [], + \ }) + " cursor in a line in top half, using "botleft" with popup that + " doesn't fit: gets truncated + normal 5G9|r# + let winid1 = popup_create(['one', 'two', 'tee'], #{ + \ line: 'cursor-1', + \ col: 'cursor', + \ pos: 'botleft', + \ posinvert: 0, + \ border: [], + \ }) + " cursor in a line in top half, using "botleft" with popup that + " doesn't fit and 'posinvert' set: flips to below. + normal 5G16|r% + let winid1 = popup_create(['one', 'two', 'tee'], #{ + \ line: 'cursor-1', + \ col: 'cursor', + \ pos: 'botleft', + \ border: [], + \ }) + " cursor in a line in bottom half, using "botleft" with popup that + " doesn't fit: does not flip. + normal 8G23|r* + let winid1 = popup_create(['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff'], #{ + \ line: 'cursor-1', + \ col: 'cursor', + \ pos: 'botleft', + \ border: [], + \ }) + + " cursor in a line in bottom half, using "topleft" with popup that + " does fit + normal 8G30|r@ + let winid1 = popup_create(['one', 'two'], #{ + \ line: 'cursor+1', + \ col: 'cursor', + \ pos: 'topleft', + \ border: [], + \ }) + " cursor in a line in top half, using "topleft" with popup that + " doesn't fit: truncated + normal 8G37|r# + let winid1 = popup_create(['one', 'two', 'tee'], #{ + \ line: 'cursor+1', + \ col: 'cursor', + \ pos: 'topleft', + \ posinvert: 0, + \ border: [], + \ }) + " cursor in a line in top half, using "topleft" with popup that + " doesn't fit and "posinvert" set: flips to below. + normal 8G44|r% + let winid1 = popup_create(['one', 'two', 'tee'], #{ + \ line: 'cursor+1', + \ col: 'cursor', + \ pos: 'topleft', + \ border: [], + \ }) + " cursor in a line in top half, using "topleft" with popup that + " doesn't fit: does not flip. + normal 5G51|r* + let winid1 = popup_create(['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff'], #{ + \ line: 'cursor+1', + \ col: 'cursor', + \ pos: 'topleft', + \ border: [], + \ }) + END + call writefile(lines, 'XtestPopupNospace') + let buf = RunVimInTerminal('-S XtestPopupNospace', #{rows: 12}) + call VerifyScreenDump(buf, 'Test_popupwin_nospace', {}) + + " clean up + call StopVimInTerminal(buf) + call delete('XtestPopupNospace') + endfunc + func Test_popup_firstline() CheckScreendump *************** *** 586,591 **** --- 678,684 ---- \], #{ \ line: 1, \ col: 10, + \ posinvert: 0, \ wrap: 0, \ fixed: 1, \ zindex: 90, *************** *** 604,609 **** --- 697,703 ---- \], #{ \ line: 7, \ col: 10, + \ posinvert: 0, \ wrap: 0, \ fixed: 1, \ close: 'button', *** ../vim-8.1.2264/src/vim.h 2019-11-02 22:54:37.409188799 +0100 --- src/vim.h 2019-11-06 18:30:24.227318430 +0100 *************** *** 632,637 **** --- 632,638 ---- #define POPF_MAPPING 0x80 // mapping keys #define POPF_INFO 0x100 // used for info of popup menu #define POPF_INFO_MENU 0x200 // align info popup with popup menu + #define POPF_POSINVERT 0x400 // vertical position can be inverted #ifdef FEAT_TEXT_PROP # define WIN_IS_POPUP(wp) ((wp)->w_popup_flags != 0) *** ../vim-8.1.2264/src/testdir/dumps/Test_popupwin_nospace.dump 2019-11-06 19:24:23.249873836 +0100 --- src/testdir/dumps/Test_popupwin_nospace.dump 2019-11-06 19:01:00.531770824 +0100 *************** *** 0 **** --- 1,12 ---- + |-+0&#ffffff0|╔+0#0000001#ffd7ff255|═@2|╗|-+0#0000000#ffffff0@1|╔+0#0000001#ffd7ff255|═@2|╗|-+0#0000000#ffffff0@8|╔+0#0000001#ffd7ff255|═@2|╗|-+0#0000000#ffffff0@32| @14 + |-|║+0#0000001#ffd7ff255|o|n|e|║|-+0#0000000#ffffff0@1|║+0#0000001#ffd7ff255|o|n|e|║|-+0#0000000#ffffff0@8|║+0#0000001#ffd7ff255|a@2|║|-+0#0000000#ffffff0@32| @14 + |-|║+0#0000001#ffd7ff255|t|w|o|║|-+0#0000000#ffffff0@1|║+0#0000001#ffd7ff255|t|w|o|║|-+0#0000000#ffffff0@8|║+0#0000001#ffd7ff255|b@2|║|-+0#0000000#ffffff0@15|╔+0#0000001#ffd7ff255|═@2|╗|-+0#0000000#ffffff0@11| @14 + |-|╚+0#0000001#ffd7ff255|═@2|╝|-+0#0000000#ffffff0@1|╚+0#0000001#ffd7ff255|═@2|╝|-+0#0000000#ffffff0@8|║+0#0000001#ffd7ff255|c@2|║|-+0#0000000#ffffff0@15|║+0#0000001#ffd7ff255|o|n|e|║|-+0#0000000#ffffff0@11| @14 + |-|@|-@5|#|-@5|%|-@5|║+0#0000001#ffd7ff255|d@2|║|-+0#0000000#ffffff0@15|║+0#0000001#ffd7ff255|t|w|o|║|-+0#0000000#ffffff0@1>*|-@8| @14 + |-@14|╔+0#0000001#ffd7ff255|═@2|╗|-+0#0000000#ffffff0@1|║+0#0000001#ffd7ff255|e@2|║|-+0#0000000#ffffff0@15|║+0#0000001#ffd7ff255|t|e@1|║|-+0#0000000#ffffff0@1|╔+0#0000001#ffd7ff255|═@2|╗|-+0#0000000#ffffff0@4| @14 + |-@14|║+0#0000001#ffd7ff255|o|n|e|║|-+0#0000000#ffffff0@1|╚+0#0000001#ffd7ff255|═@2|╝|-+0#0000000#ffffff0@15|╚+0#0000001#ffd7ff255|═@2|╝|-+0#0000000#ffffff0@1|║+0#0000001#ffd7ff255|a@2|║|-+0#0000000#ffffff0@4| @14 + |-@14|║+0#0000001#ffd7ff255|t|w|o|║|-+0#0000000#ffffff0@1|*|-@5|@|-@5|#|-@5|%|-@5|║+0#0000001#ffd7ff255|b@2|║|-+0#0000000#ffffff0@4| @14 + |-@14|║+0#0000001#ffd7ff255|t|e@1|║|-+0#0000000#ffffff0@8|╔+0#0000001#ffd7ff255|═@2|╗|-+0#0000000#ffffff0@1|╔+0#0000001#ffd7ff255|═@2|╗|-+0#0000000#ffffff0@8|║+0#0000001#ffd7ff255|c@2|║|-+0#0000000#ffffff0@4| @14 + |-@14|╚+0#0000001#ffd7ff255|═@2|╝|-+0#0000000#ffffff0@8|║+0#0000001#ffd7ff255|o|n|e|║|-+0#0000000#ffffff0@1|║+0#0000001#ffd7ff255|o|n|e|║|-+0#0000000#ffffff0@8|║+0#0000001#ffd7ff255|d@2|║|-+0#0000000#ffffff0@4| @14 + |-@28|║+0#0000001#ffd7ff255|t|w|o|║|-+0#0000000#ffffff0@1|║+0#0000001#ffd7ff255|t|w|o|║|-+0#0000000#ffffff0@8|║+0#0000001#ffd7ff255|e@2|║|-+0#0000000#ffffff0@4| @14 + @29|╚+0#0000001#ffd7ff255|═@2|╝| +0#0000000#ffffff0@1|║+0#0000001#ffd7ff255|t|e@1|║| +0#0000000#ffffff0@8|║+0#0000001#ffd7ff255|f@2|║| +0#0000000#ffffff0@1|5|,|5|1| @9|T|o|p| *** ../vim-8.1.2264/src/version.c 2019-11-06 15:21:56.720396416 +0100 --- src/version.c 2019-11-06 19:03:12.831241148 +0100 *************** *** 743,744 **** --- 743,746 ---- { /* Add new patch number below this line */ + /**/ + 2265, /**/ -- A day without sunshine is like, well, night. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///