Skip to content

Commit 3056735

Browse files
committed
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().
1 parent 9f8187c commit 3056735

File tree

5 files changed

+93
-32
lines changed

5 files changed

+93
-32
lines changed

runtime/doc/eval.txt

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*eval.txt* For Vim version 7.4. Last change: 2016 Aug 21
1+
*eval.txt* For Vim version 7.4. Last change: 2016 Aug 27
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -4014,25 +4014,30 @@ getbufinfo([{dict}])
40144014
lnum current line number in buffer.
40154015
loaded TRUE if the buffer is loaded.
40164016
name full path to the file in the buffer.
4017-
options dictionary of buffer local options.
40184017
signs list of signs placed in the buffer.
40194018
Each list item is a dictionary with
40204019
the following fields:
40214020
id sign identifier
40224021
lnum line number
40234022
name sign name
4024-
variables dictionary of buffer local variables.
4025-
windows list of |window-ID|s with this buffer
4023+
variables a reference to the dictionary with
4024+
buffer-local variables.
4025+
windows list of |window-ID|s that display this
4026+
buffer
40264027

40274028
Examples: >
40284029
for buf in getbufinfo()
40294030
echo buf.name
40304031
endfor
40314032
for buf in getbufinfo({'buflisted':1})
4032-
if buf.options.filetype == 'java'
4033+
if buf.changed
40334034
....
40344035
endif
40354036
endfor
4037+
<
4038+
To get buffer-local options use: >
4039+
getbufvar({bufnr}, '&')
4040+
40364041
<
40374042
*getbufline()*
40384043
getbufline({expr}, {lnum} [, {end}])
@@ -4065,6 +4070,10 @@ getbufvar({expr}, {varname} [, {def}]) *getbufvar()*
40654070
must be used.
40664071
When {varname} is empty returns a dictionary with all the
40674072
buffer-local variables.
4073+
When {varname} is equal to "&" returns a dictionary with all
4074+
the buffer-local options.
4075+
Otherwise, when {varname} starts with "&" returns the value of
4076+
a buffer-local option.
40684077
This also works for a global or buffer-local option, but it
40694078
doesn't work for a global variable, window-local variable or
40704079
window-local option.
@@ -4532,7 +4541,8 @@ gettabinfo([{arg}]) *gettabinfo()*
45324541

45334542
Each List item is a Dictionary with the following entries:
45344543
tabnr tab page number.
4535-
variables dictionary of tabpage local variables.
4544+
variables a reference to the dictionary with
4545+
tabpage-local variables
45364546
windows List of |window-ID|s in the tag page.
45374547

45384548
gettabvar({tabnr}, {varname} [, {def}]) *gettabvar()*
@@ -4548,10 +4558,12 @@ gettabvar({tabnr}, {varname} [, {def}]) *gettabvar()*
45484558
gettabwinvar({tabnr}, {winnr}, {varname} [, {def}]) *gettabwinvar()*
45494559
Get the value of window-local variable {varname} in window
45504560
{winnr} in tab page {tabnr}.
4551-
When {varname} starts with "&" get the value of a window-local
4552-
option.
45534561
When {varname} is empty a dictionary with all window-local
45544562
variables is returned.
4563+
When {varname} is equal to "&" get the values of all
4564+
window-local options in a Dictionary.
4565+
Otherwise, when {varname} starts with "&" get the value of a
4566+
window-local option.
45554567
Note that {varname} must be the name without "w:".
45564568
Tabs are numbered starting with one. For the current tabpage
45574569
use |getwinvar()|.
@@ -4591,15 +4603,18 @@ getwininfo([{winid}]) *getwininfo()*
45914603
height window height
45924604
loclist 1 if showing a location list
45934605
{only with the +quickfix feature}
4594-
options dictionary of window local options
45954606
quickfix 1 if quickfix or location list window
45964607
{only with the +quickfix feature}
45974608
tabnr tab page number
4598-
variables dictionary of window local variables
4609+
variables a reference to the dictionary with
4610+
window-local variables
45994611
width window width
46004612
winid |window-ID|
46014613
winnr window number
46024614

4615+
To obtain all window-local variables use: >
4616+
gettabwinvar({tabnr}, {winnr}, '&')
4617+
46034618
getwinvar({winnr}, {varname} [, {def}]) *getwinvar()*
46044619
Like |gettabwinvar()| for the current tabpage.
46054620
Examples: >
@@ -5987,6 +6002,16 @@ printf({fmt}, {expr1} ...) *printf()*
59876002
cause truncation of a numeric field; if the result of
59886003
a conversion is wider than the field width, the field
59896004
is expanded to contain the conversion result.
6005+
The 'h' modifier indicates the argument is 16 bits.
6006+
The 'l' modifier indicates the argument is 32 bits.
6007+
The 'L' modifier indicates the argument is 64 bits.
6008+
Generally, these modifiers are not useful. They are
6009+
ignored when type is known from the argument.
6010+
6011+
i alias for d
6012+
D alias for ld
6013+
U alias for lu
6014+
O alias for lo
59906015

59916016
*printf-c*
59926017
c The Number argument is converted to a byte, and the
@@ -6006,7 +6031,7 @@ printf({fmt}, {expr1} ...) *printf()*
60066031
feature works just like 's'.
60076032

60086033
*printf-f* *E807*
6009-
f The Float argument is converted into a string of the
6034+
f F The Float argument is converted into a string of the
60106035
form 123.456. The precision specifies the number of
60116036
digits after the decimal point. When the precision is
60126037
zero the decimal point is omitted. When the precision

src/eval.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8470,9 +8470,23 @@ getwinvar(
84708470
|| switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE) == OK)
84718471
#endif
84728472
{
8473-
if (*varname == '&') /* window-local-option */
8473+
if (*varname == '&')
84748474
{
8475-
if (get_option_tv(&varname, rettv, 1) == OK)
8475+
if (varname[1] == NUL)
8476+
{
8477+
/* get all window-local options in a dict */
8478+
dict_T *opts = get_winbuf_options(FALSE);
8479+
8480+
if (opts != NULL)
8481+
{
8482+
rettv->v_type = VAR_DICT;
8483+
rettv->vval.v_dict = opts;
8484+
++opts->dv_refcount;
8485+
done = TRUE;
8486+
}
8487+
}
8488+
else if (get_option_tv(&varname, rettv, 1) == OK)
8489+
/* window-local-option */
84768490
done = TRUE;
84778491
}
84788492
else

src/evalfunc.c

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3921,7 +3921,6 @@ get_buffer_signs(buf_T *buf, list_T *l)
39213921
get_buffer_info(buf_T *buf)
39223922
{
39233923
dict_T *dict;
3924-
dict_T *opts;
39253924
tabpage_T *tp;
39263925
win_T *wp;
39273926
list_T *windows;
@@ -3945,11 +3944,6 @@ get_buffer_info(buf_T *buf)
39453944
/* Get a reference to buffer variables */
39463945
dict_add_dict(dict, "variables", buf->b_vars);
39473946

3948-
/* Copy buffer options */
3949-
opts = get_winbuf_options(TRUE);
3950-
if (opts != NULL)
3951-
dict_add_dict(dict, "options", opts);
3952-
39533947
/* List of windows displaying this buffer */
39543948
windows = list_alloc();
39553949
if (windows != NULL)
@@ -4156,9 +4150,23 @@ f_getbufvar(typval_T *argvars, typval_T *rettv)
41564150
save_curbuf = curbuf;
41574151
curbuf = buf;
41584152

4159-
if (*varname == '&') /* buffer-local-option */
4153+
if (*varname == '&')
41604154
{
4161-
if (get_option_tv(&varname, rettv, TRUE) == OK)
4155+
if (varname[1] == NUL)
4156+
{
4157+
/* get all buffer-local options in a dict */
4158+
dict_T *opts = get_winbuf_options(TRUE);
4159+
4160+
if (opts != NULL)
4161+
{
4162+
rettv->v_type = VAR_DICT;
4163+
rettv->vval.v_dict = opts;
4164+
++opts->dv_refcount;
4165+
done = TRUE;
4166+
}
4167+
}
4168+
else if (get_option_tv(&varname, rettv, TRUE) == OK)
4169+
/* buffer-local-option */
41624170
done = TRUE;
41634171
}
41644172
else if (STRCMP(varname, "changedtick") == 0)
@@ -5112,7 +5120,6 @@ f_gettabwinvar(typval_T *argvars, typval_T *rettv)
51125120
get_win_info(win_T *wp, short tpnr, short winnr)
51135121
{
51145122
dict_T *dict;
5115-
dict_T *opts;
51165123

51175124
dict = dict_alloc();
51185125
if (dict == NULL)
@@ -5131,14 +5138,9 @@ get_win_info(win_T *wp, short tpnr, short winnr)
51315138
(bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL), NULL);
51325139
#endif
51335140

5134-
/* Make a reference to window variables */
5141+
/* Add a reference to window variables */
51355142
dict_add_dict(dict, "variables", wp->w_vars);
51365143

5137-
/* Copy window options */
5138-
opts = get_winbuf_options(FALSE);
5139-
if (opts != NULL)
5140-
dict_add_dict(dict, "options", opts);
5141-
51425144
return dict;
51435145
}
51445146
#endif

src/testdir/test_bufwintabinfo.vim

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ function Test_getbufwintabinfo()
1818
let b:editor = 'vim'
1919
let l = getbufinfo('%')
2020
call assert_equal(bufnr('%'), l[0].bufnr)
21-
call assert_equal(8, l[0].options.tabstop)
2221
call assert_equal('vim', l[0].variables.editor)
2322
call assert_notequal(-1, index(l[0].windows, bufwinid('%')))
2423

@@ -49,9 +48,6 @@ function Test_getbufwintabinfo()
4948
call assert_equal(winbufnr(2), winlist[1].bufnr)
5049
call assert_equal(winheight(2), winlist[1].height)
5150
call assert_equal(1, winlist[2].winnr)
52-
if has('signs')
53-
call assert_equal('auto', winlist[0].options.signcolumn)
54-
endif
5551
call assert_equal(2, winlist[3].tabnr)
5652
call assert_equal('green', winlist[2].variables.signal)
5753
call assert_equal(winwidth(1), winlist[0].width)
@@ -83,3 +79,25 @@ function Test_getbufwintabinfo()
8379
call assert_false(winlist[2].loclist)
8480
wincmd t | only
8581
endfunction
82+
83+
function Test_get_buf_options()
84+
let opts = getbufvar(bufnr('%'), '&')
85+
call assert_equal(v:t_dict, type(opts))
86+
call assert_equal(8, opts.tabstop)
87+
endfunc
88+
89+
function Test_get_win_options()
90+
let opts = getwinvar(1, '&')
91+
call assert_equal(v:t_dict, type(opts))
92+
call assert_equal(0, opts.linebreak)
93+
if has('signs')
94+
call assert_equal('auto', opts.signcolumn)
95+
endif
96+
97+
let opts = gettabwinvar(1, 1, '&')
98+
call assert_equal(v:t_dict, type(opts))
99+
call assert_equal(0, opts.linebreak)
100+
if has('signs')
101+
call assert_equal('auto', opts.signcolumn)
102+
endif
103+
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,8 @@ static char *(features[]) =
763763

764764
static int included_patches[] =
765765
{ /* Add new patch number below this line */
766+
/**/
767+
2273,
766768
/**/
767769
2272,
768770
/**/

0 commit comments

Comments
 (0)