# HG changeset patch # User Bram Moolenaar # Date 1600804803 -7200 # Node ID 0e231e8e70f89134b5d3acf8e97bcafd23a60756 # Parent 09065c79110e04ce7ab5419b281501c5027fc30d patch 8.2.1727: a popup created with "cursorline" will ignore "firstline" Commit: https://github.com/vim/vim/commit/99ca9c4868bb1669706b9e3de9a9218bd11cc459 Author: Bram Moolenaar Date: Tue Sep 22 21:55:41 2020 +0200 patch 8.2.1727: a popup created with "cursorline" will ignore "firstline" Problem: A popup created with "cursorline" will ignore "firstline". Solution: When both "cursorline" and "firstline" are present put the cursor on "firstline". (closes #7000) Add the "winid" argument to getcurpos(). diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 8.2. Last change: 2020 Sep 16 +*eval.txt* For Vim version 8.2. Last change: 2020 Sep 22 VIM REFERENCE MANUAL by Bram Moolenaar @@ -2516,7 +2516,7 @@ getcmdtype() String return current com getcmdwintype() String return current command-line window type getcompletion({pat}, {type} [, {filtered}]) List list of cmdline completion matches -getcurpos() List position of the cursor +getcurpos([{winnr}]) List position of the cursor getcwd([{winnr} [, {tabnr}]]) String get the current working directory getenv({name}) String return environment variable getfontname([{name}]) String name of font being used @@ -5261,13 +5261,20 @@ getcompletion({pat}, {type} [, {filtered GetPattern()->getcompletion('color') < *getcurpos()* -getcurpos() Get the position of the cursor. This is like getpos('.'), but +getcurpos([{winid}]) + Get the position of the cursor. This is like getpos('.'), but includes an extra "curswant" item in the list: [0, lnum, col, off, curswant] ~ The "curswant" number is the preferred column when moving the cursor vertically. Also see |getpos()|. The first "bufnum" item is always zero. + The optional {winid} argument can specify the window. It can + be the window number or the |window-ID|. The last known + cursor position is returned, this may be invalid for the + current value of the buffer if it is not the current window. + If {winid} is invalid a list with zeroes is returned. + This can be used to save and restore the cursor position: > let save_cursor = getcurpos() MoveTheCursorAround @@ -5478,8 +5485,9 @@ getloclist({nr} [, {what}]) *getlocli |location-list-file-window| for more details. - Returns an empty Dictionary if there is no location list for - the window {nr} or the window is not present. + Returns a Dictionary with default values if there is no location + list for the window {nr}. + Returns an empty Dictionary if window {nr} does not exist. Examples (See also |getqflist-examples|): > :echo getloclist(3, {'all': 0}) diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -646,7 +646,7 @@ static funcentry_T global_functions[] = {"getcmdtype", 0, 0, 0, ret_string, f_getcmdtype}, {"getcmdwintype", 0, 0, 0, ret_string, f_getcmdwintype}, {"getcompletion", 2, 3, FEARG_1, ret_list_string, f_getcompletion}, - {"getcurpos", 0, 0, 0, ret_list_number, f_getcurpos}, + {"getcurpos", 0, 1, FEARG_1, ret_list_number, f_getcurpos}, {"getcwd", 0, 2, FEARG_1, ret_string, f_getcwd}, {"getenv", 1, 1, FEARG_1, ret_string, f_getenv}, {"getfontname", 0, 1, 0, ret_string, f_getfontname}, @@ -3259,7 +3259,8 @@ getpos_both( typval_T *rettv, int getcurpos) { - pos_T *fp; + pos_T *fp = NULL; + win_T *wp = curwin; list_T *l; int fnum = -1; @@ -3267,7 +3268,16 @@ getpos_both( { l = rettv->vval.v_list; if (getcurpos) - fp = &curwin->w_cursor; + { + if (argvars[0].v_type != VAR_UNKNOWN) + { + wp = find_win_by_nr_or_id(&argvars[0]); + if (wp != NULL) + fp = &wp->w_cursor; + } + else + fp = &curwin->w_cursor; + } else fp = var2fpos(&argvars[0], TRUE, &fnum); if (fnum != -1) @@ -3287,13 +3297,14 @@ getpos_both( colnr_T save_curswant = curwin->w_curswant; colnr_T save_virtcol = curwin->w_virtcol; - update_curswant(); - list_append_number(l, curwin->w_curswant == MAXCOL ? - (varnumber_T)MAXCOL : (varnumber_T)curwin->w_curswant + 1); + if (wp == curwin) + update_curswant(); + list_append_number(l, wp == NULL ? 0 : wp->w_curswant == MAXCOL + ? (varnumber_T)MAXCOL : (varnumber_T)wp->w_curswant + 1); // Do not change "curswant", as it is unexpected that a get // function has a side effect. - if (save_set_curswant) + if (wp == curwin && save_set_curswant) { curwin->w_set_curswant = save_set_curswant; curwin->w_curswant = save_curswant; diff --git a/src/evalwindow.c b/src/evalwindow.c --- a/src/evalwindow.c +++ b/src/evalwindow.c @@ -530,6 +530,22 @@ f_getwininfo(typval_T *argvars, typval_T return; } } +#ifdef FEAT_PROP_POPUP + if (wparg != NULL) + { + tabnr = 0; + FOR_ALL_TABPAGES(tp) + { + tabnr++; + FOR_ALL_POPUPWINS_IN_TAB(tp, wp) + if (wp == wparg) + break; + } + d = get_win_info(wparg, tp == NULL ? 0 : tabnr, 0); + if (d != NULL) + list_append_dict(rettv->vval.v_list, d); + } +#endif } /* diff --git a/src/popupwin.c b/src/popupwin.c --- a/src/popupwin.c +++ b/src/popupwin.c @@ -593,8 +593,9 @@ popup_show_curline(win_T *wp) ++wp->w_topline; } - // Don't use "firstline" now. - wp->w_firstline = 0; + // Don't let "firstline" cause a scroll. + if (wp->w_firstline > 0) + wp->w_firstline = wp->w_topline; } /* @@ -948,6 +949,18 @@ apply_options(win_T *wp, dict_T *dict) if (nr > 0) wp->w_popup_flags |= POPF_HIDDEN; + // when "firstline" and "cursorline" are both set move the cursor to the + // "firstline". + if (wp->w_firstline > 0 && (wp->w_popup_flags & POPF_CURSORLINE)) + { + if (wp->w_firstline > wp->w_buffer->b_ml.ml_line_count) + wp->w_cursor.lnum = wp->w_buffer->b_ml.ml_line_count; + else + wp->w_cursor.lnum = wp->w_firstline; + wp->w_topline = wp->w_cursor.lnum; + curwin->w_valid &= ~VALID_BOTLINE; + } + popup_mask_refresh = TRUE; popup_highlight_curline(wp); } diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim --- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -2520,7 +2520,19 @@ func Test_getcurpos_setpos() call assert_equal('6', @") call assert_equal(-1, setpos('.', test_null_list())) call assert_equal(-1, setpos('.', {})) + + let winid = win_getid() + normal G$ + let pos = getcurpos() + wincmd w + call assert_equal(pos, getcurpos(winid)) + + wincmd w close! + + call assert_equal(getcurpos(), getcurpos(0)) + call assert_equal([0, 0, 0, 0, 0], getcurpos(-1)) + call assert_equal([0, 0, 0, 0, 0], getcurpos(1999)) endfunc " Test for glob() 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 @@ -516,6 +516,19 @@ func Test_popup_firstline() call popup_close(winid) endfunc +func Test_popup_firstline_cursorline() + let winid = popup_create(['1111', '222222', '33333', '44444'], #{ + \ maxheight: 2, + \ firstline: 3, + \ cursorline: 1, + \ }) + call assert_equal(3, popup_getoptions(winid).firstline) + call assert_equal(3, getwininfo(winid)[0].topline) + call assert_equal(3, getcurpos(winid)[1]) + + call popup_close(winid) +endfunc + func Test_popup_noscrolloff() set scrolloff=5 let winid = popup_create(['xxx']->repeat(50), #{ diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1727, +/**/ 1726, /**/ 1725,