changeset 17942:664cc72f50c5 v8.1.1967

patch 8.1.1967: line() only works for the current window Commit: https://github.com/vim/vim/commit/8e0a8e7eb7c177807f44db6b76d8e52314248ab5 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Sep 2 22:56:24 2019 +0200 patch 8.1.1967: line() only works for the current window Problem: Line() only works for the current window. Solution: Add an optional argument for the window to use.
author Bram Moolenaar <Bram@vim.org>
date Mon, 02 Sep 2019 23:00:04 +0200
parents d64d967b1e35
children 7c6b79acf9b9
files src/evalfunc.c src/testdir/test_popupwin.vim src/version.c
diffstat 3 files changed, 39 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -634,7 +634,7 @@ static funcentry_T global_functions[] =
     {"len",		1, 1, FEARG_1,	  f_len},
     {"libcall",		3, 3, FEARG_3,	  f_libcall},
     {"libcallnr",	3, 3, FEARG_3,	  f_libcallnr},
-    {"line",		1, 1, FEARG_1,	  f_line},
+    {"line",		1, 2, FEARG_1,	  f_line},
     {"line2byte",	1, 1, FEARG_1,	  f_line2byte},
     {"lispindent",	1, 1, FEARG_1,	  f_lispindent},
     {"list2str",	1, 2, FEARG_1,	  f_list2str},
@@ -1154,14 +1154,18 @@ tv_get_lnum(typval_T *argvars)
 {
     typval_T	rettv;
     linenr_T	lnum;
+    int		save_type;
 
     lnum = (linenr_T)tv_get_number_chk(&argvars[0], NULL);
     if (lnum == 0)  /* no valid number, try using line() */
     {
 	rettv.v_type = VAR_NUMBER;
+	save_type = argvars[1].v_type;
+	argvars[1].v_type = VAR_UNKNOWN;
 	f_line(argvars, &rettv);
 	lnum = (linenr_T)rettv.vval.v_number;
 	clear_tv(&rettv);
+	argvars[1].v_type = save_type;
     }
     return lnum;
 }
@@ -6658,16 +6662,40 @@ f_libcallnr(typval_T *argvars, typval_T 
 }
 
 /*
- * "line(string)" function
+ * "line(string, [winid])" function
  */
     static void
 f_line(typval_T *argvars, typval_T *rettv)
 {
     linenr_T	lnum = 0;
-    pos_T	*fp;
+    pos_T	*fp = NULL;
     int		fnum;
-
-    fp = var2fpos(&argvars[0], TRUE, &fnum);
+    int		id;
+    tabpage_T	*tp;
+    win_T	*wp;
+    win_T	*save_curwin;
+    tabpage_T	*save_curtab;
+
+    if (argvars[1].v_type != VAR_UNKNOWN)
+    {
+	// use window specified in the second argument
+	id = (int)tv_get_number(&argvars[1]);
+	wp = win_id2wp_tp(id, &tp);
+	if (wp != NULL && tp != NULL)
+	{
+	    if (switch_win_noblock(&save_curwin, &save_curtab, wp, tp, TRUE)
+									 == OK)
+	    {
+		check_cursor();
+		fp = var2fpos(&argvars[0], TRUE, &fnum);
+	    }
+	    restore_win_noblock(save_curwin, save_curtab, TRUE);
+	}
+    }
+    else
+	// use current window
+	fp = var2fpos(&argvars[0], TRUE, &fnum);
+
     if (fp != NULL)
 	lnum = fp->lnum;
     rettv->vval.v_number = lnum;
--- a/src/testdir/test_popupwin.vim
+++ b/src/testdir/test_popupwin.vim
@@ -346,6 +346,10 @@ func Test_popup_firstline()
   redraw
   call assert_equal(11, popup_getoptions(winid).firstline)
   call assert_equal(11, popup_getpos(winid).firstline)
+  " check line() works with popup window
+  call assert_equal(11, line('.', winid))
+  call assert_equal(50, line('$', winid))
+  call assert_equal(0, line('$', 123456))
 
   " Normal command changes what is displayed but not "firstline"
   call win_execute(winid, "normal! \<c-y>")
--- a/src/version.c
+++ b/src/version.c
@@ -762,6 +762,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1967,
+/**/
     1966,
 /**/
     1965,