Skip to content

Commit

Permalink
patch 7.4.2273
Browse files Browse the repository at this point in the history
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().
  • Loading branch information
brammool committed Aug 27, 2016
1 parent 9f8187c commit 3056735
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 32 deletions.
47 changes: 36 additions & 11 deletions 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
Expand Down Expand Up @@ -4014,25 +4014,30 @@ 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}])
Expand Down Expand Up @@ -4065,6 +4070,10 @@ getbufvar({expr}, {varname} [, {def}]) *getbufvar()*
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.
Expand Down Expand Up @@ -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()*
Expand All @@ -4548,10 +4558,12 @@ gettabvar({tabnr}, {varname} [, {def}]) *gettabvar()*
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()|.
Expand Down Expand Up @@ -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: >
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
18 changes: 16 additions & 2 deletions src/eval.c
Expand Up @@ -8470,9 +8470,23 @@ getwinvar(
|| switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE) == OK)
#endif
{
if (*varname == '&') /* window-local-option */
if (*varname == '&')
{
if (get_option_tv(&varname, rettv, 1) == OK)
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
Expand Down
32 changes: 17 additions & 15 deletions src/evalfunc.c
Expand Up @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -4156,9 +4150,23 @@ f_getbufvar(typval_T *argvars, typval_T *rettv)
save_curbuf = curbuf;
curbuf = buf;

if (*varname == '&') /* buffer-local-option */
if (*varname == '&')
{
if (get_option_tv(&varname, rettv, TRUE) == OK)
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)
Expand Down Expand Up @@ -5112,7 +5120,6 @@ f_gettabwinvar(typval_T *argvars, typval_T *rettv)
get_win_info(win_T *wp, short tpnr, short winnr)
{
dict_T *dict;
dict_T *opts;

dict = dict_alloc();
if (dict == NULL)
Expand All @@ -5131,14 +5138,9 @@ get_win_info(win_T *wp, short tpnr, short winnr)
(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
Expand Down
26 changes: 22 additions & 4 deletions src/testdir/test_bufwintabinfo.vim
Expand Up @@ -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('%')))

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -763,6 +763,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
2273,
/**/
2272,
/**/
Expand Down

0 comments on commit 3056735

Please sign in to comment.