changeset 22357:0e231e8e70f8 v8.2.1727

patch 8.2.1727: a popup created with "cursorline" will ignore "firstline" Commit: https://github.com/vim/vim/commit/99ca9c4868bb1669706b9e3de9a9218bd11cc459 Author: Bram Moolenaar <Bram@vim.org> 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().
author Bram Moolenaar <Bram@vim.org>
date Tue, 22 Sep 2020 22:00:03 +0200
parents 09065c79110e
children b6037eb43146
files runtime/doc/eval.txt src/evalfunc.c src/evalwindow.c src/popupwin.c src/testdir/test_functions.vim src/testdir/test_popupwin.vim src/version.c
diffstat 7 files changed, 89 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- 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})
--- 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;
--- 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
 }
 
 /*
--- 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);
 }
--- 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()
--- 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), #{
--- 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,