changeset 10000:233289599874 v7.4.2273

commit https://github.com/vim/vim/commit/3056735ae8a366aa7fcb51872520895251858637 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Aug 27 21:25:44 2016 +0200 patch 7.4.2273 Problem: getwininfo() and getbufinfo() are inefficient. Solution: Do not make a copy of all window/buffer-local options. Make it possible to get them with gettabwinvar() or getbufvar().
author Christian Brabandt <cb@256bit.org>
date Sat, 27 Aug 2016 21:30:06 +0200
parents 2c5b2fc3a9f9
children 7b64e4c76677
files runtime/doc/eval.txt src/eval.c src/evalfunc.c src/testdir/test_bufwintabinfo.vim src/version.c
diffstat 5 files changed, 95 insertions(+), 34 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 7.4.  Last change: 2016 Aug 21
+*eval.txt*	For Vim version 7.4.  Last change: 2016 Aug 27
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -4014,26 +4014,31 @@ getbufinfo([{dict}])
 			lnum		current line number in buffer.
 			loaded		TRUE if the buffer is loaded.
 			name		full path to the file in the buffer.
-			options		dictionary of buffer local options.
 			signs		list of signs placed in the buffer.
 					Each list item is a dictionary with
 					the following fields:
 					    id	  sign identifier
 					    lnum  line number
 					    name  sign name
-			variables	dictionary of buffer local variables.
-			windows		list of |window-ID|s with this buffer
+			variables	a reference to the dictionary with
+					buffer-local variables.
+			windows		list of |window-ID|s that display this
+					buffer
 
 		Examples: >
 			for buf in getbufinfo()
 			    echo buf.name
 			endfor
 			for buf in getbufinfo({'buflisted':1})
-			    if buf.options.filetype == 'java'
+			    if buf.changed
 				....
 			    endif
 			endfor
 <
+		To get buffer-local options use: >
+			getbufvar({bufnr}, '&')
+
+<
 							*getbufline()*
 getbufline({expr}, {lnum} [, {end}])
 		Return a |List| with the lines starting from {lnum} to {end}
@@ -4065,6 +4070,10 @@ getbufvar({expr}, {varname} [, {def}])		
 		must be used.
 		When {varname} is empty returns a dictionary with all the
 		buffer-local variables.
+		When {varname} is equal to "&" returns a dictionary with all
+		the buffer-local options.
+		Otherwise, when {varname} starts with "&" returns the value of
+		a buffer-local option.
 		This also works for a global or buffer-local option, but it
 		doesn't work for a global variable, window-local variable or
 		window-local option.
@@ -4532,7 +4541,8 @@ gettabinfo([{arg}])					*gettabinfo()*
 
 		Each List item is a Dictionary with the following entries:
 			tabnr		tab page number.
-			variables	dictionary of tabpage local variables.
+			variables	a reference to the dictionary with
+					tabpage-local variables
 			windows		List of |window-ID|s in the tag page.
 
 gettabvar({tabnr}, {varname} [, {def}])				*gettabvar()*
@@ -4548,10 +4558,12 @@ gettabvar({tabnr}, {varname} [, {def}])	
 gettabwinvar({tabnr}, {winnr}, {varname} [, {def}])		*gettabwinvar()*
 		Get the value of window-local variable {varname} in window
 		{winnr} in tab page {tabnr}.
-		When {varname} starts with "&" get the value of a window-local
-		option.
 		When {varname} is empty a dictionary with all window-local
 		variables is returned.
+		When {varname} is equal to "&" get the values of all
+		window-local options in a Dictionary.
+		Otherwise, when {varname} starts with "&" get the value of a
+		window-local option.
 		Note that {varname} must be the name without "w:".
 		Tabs are numbered starting with one.  For the current tabpage
 		use |getwinvar()|.
@@ -4591,15 +4603,18 @@ getwininfo([{winid}])					*getwininfo()*
 			height		window height
 			loclist		1 if showing a location list
 					{only with the +quickfix feature}
-			options		dictionary of window local options
 			quickfix	1 if quickfix or location list window
 					{only with the +quickfix feature}
 			tabnr		tab page number
-			variables	dictionary of window local variables
+			variables	a reference to the dictionary with
+					window-local variables
 			width		window width
 			winid		|window-ID|
 			winnr		window number
 
+		To obtain all window-local variables use: >
+			gettabwinvar({tabnr}, {winnr}, '&')
+
 getwinvar({winnr}, {varname} [, {def}])				*getwinvar()*
 		Like |gettabwinvar()| for the current tabpage.
 		Examples: >
@@ -5987,6 +6002,16 @@ printf({fmt}, {expr1} ...)				*printf()*
 			cause truncation of a numeric field; if the result of
 			a conversion is wider than the field width, the field
 			is expanded to contain the conversion result.
+			The 'h' modifier indicates the argument is 16 bits.
+			The 'l' modifier indicates the argument is 32 bits.
+			The 'L' modifier indicates the argument is 64 bits.
+			Generally, these modifiers are not useful. They are
+			ignored when type is known from the argument.
+
+		i	alias for d
+		D	alias for ld
+		U	alias for lu
+		O	alias for lo
 
 							*printf-c*
 		c	The Number argument is converted to a byte, and the
@@ -6006,7 +6031,7 @@ printf({fmt}, {expr1} ...)				*printf()*
 			feature works just like 's'.
 
 							*printf-f* *E807*
-		f	The Float argument is converted into a string of the 
+		f F	The Float argument is converted into a string of the 
 			form 123.456.  The precision specifies the number of
 			digits after the decimal point.  When the precision is
 			zero the decimal point is omitted.  When the precision
--- a/src/eval.c
+++ b/src/eval.c
@@ -8470,9 +8470,23 @@ getwinvar(
 		  || switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE) == OK)
 #endif
 	{
-	    if (*varname == '&')	/* window-local-option */
-	    {
-		if (get_option_tv(&varname, rettv, 1) == OK)
+	    if (*varname == '&')
+	    {
+		if (varname[1] == NUL)
+		{
+		    /* get all window-local options in a dict */
+		    dict_T	*opts = get_winbuf_options(FALSE);
+
+		    if (opts != NULL)
+		    {
+			rettv->v_type = VAR_DICT;
+			rettv->vval.v_dict = opts;
+			++opts->dv_refcount;
+			done = TRUE;
+		    }
+		}
+		else if (get_option_tv(&varname, rettv, 1) == OK)
+		    /* window-local-option */
 		    done = TRUE;
 	    }
 	    else
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -3921,7 +3921,6 @@ get_buffer_signs(buf_T *buf, list_T *l)
 get_buffer_info(buf_T *buf)
 {
     dict_T	*dict;
-    dict_T	*opts;
     tabpage_T	*tp;
     win_T	*wp;
     list_T	*windows;
@@ -3945,11 +3944,6 @@ get_buffer_info(buf_T *buf)
     /* Get a reference to buffer variables */
     dict_add_dict(dict, "variables", buf->b_vars);
 
-    /* Copy buffer options */
-    opts = get_winbuf_options(TRUE);
-    if (opts != NULL)
-	dict_add_dict(dict, "options", opts);
-
     /* List of windows displaying this buffer */
     windows = list_alloc();
     if (windows != NULL)
@@ -4156,9 +4150,23 @@ f_getbufvar(typval_T *argvars, typval_T 
 	save_curbuf = curbuf;
 	curbuf = buf;
 
-	if (*varname == '&')	/* buffer-local-option */
-	{
-	    if (get_option_tv(&varname, rettv, TRUE) == OK)
+	if (*varname == '&')
+	{
+	    if (varname[1] == NUL)
+	    {
+		/* get all buffer-local options in a dict */
+		dict_T	*opts = get_winbuf_options(TRUE);
+
+		if (opts != NULL)
+		{
+		    rettv->v_type = VAR_DICT;
+		    rettv->vval.v_dict = opts;
+		    ++opts->dv_refcount;
+		    done = TRUE;
+		}
+	    }
+	    else if (get_option_tv(&varname, rettv, TRUE) == OK)
+		/* buffer-local-option */
 		done = TRUE;
 	}
 	else if (STRCMP(varname, "changedtick") == 0)
@@ -5112,7 +5120,6 @@ f_gettabwinvar(typval_T *argvars, typval
 get_win_info(win_T *wp, short tpnr, short winnr)
 {
     dict_T	*dict;
-    dict_T	*opts;
 
     dict = dict_alloc();
     if (dict == NULL)
@@ -5131,14 +5138,9 @@ get_win_info(win_T *wp, short tpnr, shor
 	    (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL), NULL);
 #endif
 
-    /* Make a reference to window variables */
+    /* Add a reference to window variables */
     dict_add_dict(dict, "variables", wp->w_vars);
 
-    /* Copy window options */
-    opts = get_winbuf_options(FALSE);
-    if (opts != NULL)
-	dict_add_dict(dict, "options", opts);
-
     return dict;
 }
 #endif
--- a/src/testdir/test_bufwintabinfo.vim
+++ b/src/testdir/test_bufwintabinfo.vim
@@ -18,7 +18,6 @@ function Test_getbufwintabinfo()
     let b:editor = 'vim'
     let l = getbufinfo('%')
     call assert_equal(bufnr('%'), l[0].bufnr)
-    call assert_equal(8, l[0].options.tabstop)
     call assert_equal('vim', l[0].variables.editor)
     call assert_notequal(-1, index(l[0].windows, bufwinid('%')))
 
@@ -49,9 +48,6 @@ function Test_getbufwintabinfo()
     call assert_equal(winbufnr(2), winlist[1].bufnr)
     call assert_equal(winheight(2), winlist[1].height)
     call assert_equal(1, winlist[2].winnr)
-    if has('signs')
-      call assert_equal('auto', winlist[0].options.signcolumn)
-    endif
     call assert_equal(2, winlist[3].tabnr)
     call assert_equal('green', winlist[2].variables.signal)
     call assert_equal(winwidth(1), winlist[0].width)
@@ -83,3 +79,25 @@ function Test_getbufwintabinfo()
     call assert_false(winlist[2].loclist)
     wincmd t | only
 endfunction
+
+function Test_get_buf_options()
+  let opts = getbufvar(bufnr('%'), '&')
+  call assert_equal(v:t_dict, type(opts))
+  call assert_equal(8, opts.tabstop)
+endfunc
+
+function Test_get_win_options()
+  let opts = getwinvar(1, '&')
+  call assert_equal(v:t_dict, type(opts))
+  call assert_equal(0, opts.linebreak)
+  if has('signs')
+    call assert_equal('auto', opts.signcolumn)
+  endif
+
+  let opts = gettabwinvar(1, 1, '&')
+  call assert_equal(v:t_dict, type(opts))
+  call assert_equal(0, opts.linebreak)
+  if has('signs')
+    call assert_equal('auto', opts.signcolumn)
+  endif
+endfunc
--- a/src/version.c
+++ b/src/version.c
@@ -764,6 +764,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2273,
+/**/
     2272,
 /**/
     2271,