# HG changeset patch # User Bram Moolenaar # Date 1573310704 -3600 # Node ID e5ef5d820b5bea54365de705700112ea9ecdd3dc # Parent 6b3126903e2e2b8c606058c82e2120fb9e3be54f patch 8.1.2273: wrong default when "pos" is changed with popup_atcursor() Commit: https://github.com/vim/vim/commit/4dd8fe0b4f49ec267640fb457672452825b11df0 Author: Bram Moolenaar Date: Sat Nov 9 15:33:31 2019 +0100 patch 8.1.2273: wrong default when "pos" is changed with popup_atcursor() Problem: Wrong default when "pos" is changed with popup_atcursor(). Solution: Adjust the default line and col when "pos" is not the default value. (#5151) diff --git a/runtime/doc/popup.txt b/runtime/doc/popup.txt --- a/runtime/doc/popup.txt +++ b/runtime/doc/popup.txt @@ -1,4 +1,4 @@ -*popup.txt* For Vim version 8.1. Last change: 2019 Nov 03 +*popup.txt* For Vim version 8.1. Last change: 2019 Nov 09 VIM REFERENCE MANUAL by Bram Moolenaar @@ -186,6 +186,8 @@ popup_atcursor({what}, {options}) *pop \ moved: 'WORD', \ }) < Use {options} to change the properties. + If "pos" is passed as "topleft" then the default for "line" + becomes "cursor+1". Can also be used as a |method|: > GetText()->popup_atcursor({}) @@ -362,7 +364,8 @@ popup_getpos({id}) *popup_getpos()* core_height height of the text box in screen cells firstline line of the buffer at top (1 unless scrolled) (not the value of the "firstline" property) - lastline line of the buffer at the bottom + lastline line of the buffer at the bottom (updated when + the popup is redrawn) scrollbar non-zero if a scrollbar is displayed visible one if the popup is displayed, zero if hidden Note that these are the actual screen positions. They differ @@ -566,6 +569,11 @@ The second argument of |popup_create()| Alternatively "center" can be used to position the popup in the center of the Vim window, in which case "line" and "col" are ignored. + posinvert When FALSE the value of "pos" is always used. When + TRUE (the default) and the popup does not fit + vertically and there is more space on the other side + then the popup is placed on the other side of the + position indicated by "line". textprop When present the popup is positioned next to a text property with this name and will move when the text property moves. Use an empty string to remove. See @@ -686,6 +694,8 @@ The second argument of |popup_create()| - [{lnum}, {start}, {end}]: if the cursor moved away from line {lnum}, before column {start} or after {end} + - [0, 0, 0] do not close the popup when the cursor + moves The popup also closes if the cursor moves to another line or to another window. mousemoved Like "moved" but referring to the mouse pointer @@ -852,9 +862,9 @@ Some recommended key actions: cursor keys select another entry Tab accept current suggestion -A mouse click arrives as . The coordinates are in -v:mouse_popup_col and v:mouse_popup_row. The top-left screen cell of the -popup is col 1, row 1 (not counting the border). +A mouse click arrives as . The coordinates are in |v:mouse_col| +and |v:mouse_lnum|. The top-left screen cell of the popup is col 1, row 1 +(not counting the border). Vim provides standard filters |popup_filter_menu()| and |popup_filter_yesno()|. diff --git a/src/ex_cmds.c b/src/ex_cmds.c --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -4960,7 +4960,7 @@ prepare_tagpreview( { wp = popup_find_preview_window(); if (wp != NULL) - popup_set_wantpos_cursor(wp, wp->w_minwidth); + popup_set_wantpos_cursor(wp, wp->w_minwidth, NULL); } else if (use_popup != USEPOPUP_NONE) { diff --git a/src/popupwin.c b/src/popupwin.c --- a/src/popupwin.c +++ b/src/popupwin.c @@ -390,6 +390,25 @@ popup_add_timeout(win_T *wp, int time) } #endif + static poppos_T +get_pos_entry(dict_T *d, int give_error) +{ + char_u *str = dict_get_string(d, (char_u *)"pos", FALSE); + int nr; + + if (str == NULL) + return POPPOS_NONE; + + for (nr = 0; nr < (int)(sizeof(poppos_entries) / sizeof(poppos_entry_T)); + ++nr) + if (STRCMP(str, poppos_entries[nr].pp_name) == 0) + return poppos_entries[nr].pp_val; + + if (give_error) + semsg(_(e_invarg2), str); + return POPPOS_NONE; +} + /* * Shared between popup_create() and f_popup_move(). */ @@ -420,20 +439,11 @@ apply_move_options(win_T *wp, dict_T *d) if (di != NULL) wp->w_popup_fixed = dict_get_number(d, (char_u *)"fixed") != 0; - str = dict_get_string(d, (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); + poppos_T ppt = get_pos_entry(d, TRUE); + + if (ppt != POPPOS_NONE) + wp->w_popup_pos = ppt; } str = dict_get_string(d, (char_u *)"textprop", FALSE); @@ -512,6 +522,8 @@ handle_moved_argument(win_T *wp, dictite else wp->w_popup_lnum = nr; li = li->li_next; + if (nr == 0) + wp->w_popup_curwin = NULL; } mincol = tv_get_number(&li->li_tv); @@ -1634,14 +1646,27 @@ parse_completepopup(win_T *wp) * Keep at least "width" columns from the right of the screen. */ void -popup_set_wantpos_cursor(win_T *wp, int width) +popup_set_wantpos_cursor(win_T *wp, int width, dict_T *d) { + poppos_T ppt = POPPOS_NONE; + + if (d != NULL) + ppt = get_pos_entry(d, FALSE); + setcursor_mayforce(TRUE); - wp->w_wantline = curwin->w_winrow + curwin->w_wrow; - if (wp->w_wantline == 0) // cursor in first line + if (ppt == POPPOS_TOPRIGHT || ppt == POPPOS_TOPLEFT) + { + wp->w_wantline = curwin->w_winrow + curwin->w_wrow + 2; + } + else { - wp->w_wantline = 2; - wp->w_popup_pos = POPPOS_TOPLEFT; + wp->w_wantline = curwin->w_winrow + curwin->w_wrow; + if (wp->w_wantline == 0) // cursor in first line + { + wp->w_wantline = 2; + wp->w_popup_pos = ppt == POPPOS_BOTRIGHT + ? POPPOS_TOPRIGHT : POPPOS_TOPLEFT; + } } wp->w_wantcol = curwin->w_wincol + curwin->w_wcol + 1; @@ -1651,6 +1676,7 @@ popup_set_wantpos_cursor(win_T *wp, int if (wp->w_wantcol < 1) wp->w_wantcol = 1; } + popup_adjust_position(wp); } @@ -1834,7 +1860,7 @@ popup_create(typval_T *argvars, typval_T } if (type == TYPE_ATCURSOR) { - popup_set_wantpos_cursor(wp, 0); + popup_set_wantpos_cursor(wp, 0, d); set_moved_values(wp); set_moved_columns(wp, FIND_STRING); } @@ -1935,7 +1961,7 @@ popup_create(typval_T *argvars, typval_T for (i = 0; i < 4; ++i) wp->w_popup_border[i] = 1; parse_previewpopup(wp); - popup_set_wantpos_cursor(wp, wp->w_minwidth); + popup_set_wantpos_cursor(wp, wp->w_minwidth, d); } # ifdef FEAT_QUICKFIX if (type == TYPE_INFO) diff --git a/src/proto/popupwin.pro b/src/proto/popupwin.pro --- a/src/proto/popupwin.pro +++ b/src/proto/popupwin.pro @@ -12,7 +12,7 @@ int popup_width(win_T *wp); int popup_extra_width(win_T *wp); int parse_previewpopup(win_T *wp); int parse_completepopup(win_T *wp); -void popup_set_wantpos_cursor(win_T *wp, int width); +void popup_set_wantpos_cursor(win_T *wp, int width, dict_T *d); void popup_set_wantpos_rowcol(win_T *wp, int row, int col); void f_popup_clear(typval_T *argvars, typval_T *rettv); void f_popup_create(typval_T *argvars, typval_T *rettv); diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -2113,7 +2113,8 @@ typedef enum { POPPOS_TOPLEFT, POPPOS_BOTRIGHT, POPPOS_TOPRIGHT, - POPPOS_CENTER + POPPOS_CENTER, + POPPOS_NONE } poppos_T; typedef enum { diff --git a/src/testdir/dumps/Test_popupwin_atcursor_pos.dump b/src/testdir/dumps/Test_popupwin_atcursor_pos.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_atcursor_pos.dump @@ -0,0 +1,12 @@ +|-+0&#ffffff0@59| @14 +|-@59| @14 +|-@25|%|-@16>@|-@14| @14 +|-@25|f+0#0000001#ffd7ff255|i|R|S|t| |-+0#0000000#ffffff0@6|F+0#0000001#ffd7ff255|i|r|s|t| |-+0#0000000#ffffff0@14| @14 +|-@25|s+0#0000001#ffd7ff255|e|C|O|n|d|-+0#0000000#ffffff0@6|S+0#0000001#ffd7ff255|e|c|o|n|D|-+0#0000000#ffffff0@14| @14 +|-@59| @14 +|-@1|f+0#0000001#ffd7ff255|i|r|s|t| |-+0#0000000#ffffff0@6|F+0#0000001#ffd7ff255|I|r|s|T| |-+0#0000000#ffffff0@38| @14 +|-@1|s+0#0000001#ffd7ff255|e|c|o|n|d|-+0#0000000#ffffff0@6|S+0#0000001#ffd7ff255|E|c|o|N|D|-+0#0000000#ffffff0@38| @14 +|-@1|#|-@16|&|-@38| @14 +|-@59| @14 +|-@59| @14 +@57|3|,|4|5| @9|T|o|p| diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -1294,6 +1294,42 @@ func Test_popup_atcursor() bwipe! endfunc +func Test_popup_atcursor_pos() + CheckScreendump + + let lines =<< trim END + call setline(1, repeat([repeat('-', 60)], 15)) + set so=0 + + normal 9G3|r# + let winid1 = popup_atcursor(['first', 'second'], #{ + \ moved: [0, 0, 0], + \ }) + normal 9G21|r& + let winid1 = popup_atcursor(['FIrsT', 'SEcoND'], #{ + \ pos: 'botright', + \ moved: [0, 0, 0], + \ }) + normal 3G27|r% + let winid1 = popup_atcursor(['fiRSt', 'seCOnd'], #{ + \ pos: 'topleft', + \ moved: [0, 0, 0], + \ }) + normal 3G45|r@ + let winid1 = popup_atcursor(['First', 'SeconD'], #{ + \ pos: 'topright', + \ moved: [0, 0, 0], + \ }) + END + call writefile(lines, 'XtestPopupAtcursorPos') + let buf = RunVimInTerminal('-S XtestPopupAtcursorPos', #{rows: 12}) + call VerifyScreenDump(buf, 'Test_popupwin_atcursor_pos', {}) + + " clean up + call StopVimInTerminal(buf) + call delete('XtestPopupAtcursorPos') +endfunc + func Test_popup_beval() CheckScreendump CheckFeature balloon_eval_term diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -742,6 +742,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2273, +/**/ 2272, /**/ 2271,