vim-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().

3056735ae8
This commit is contained in:
James McCoy 2016-12-12 23:01:53 -05:00
parent 03ed7e1eba
commit fe03ce23bf
No known key found for this signature in database
GPG Key ID: DFE691AE331BA3DB
4 changed files with 86 additions and 30 deletions

View File

@ -1,4 +1,4 @@
*eval.txt* For Vim version 7.4. Last change: 2016 Jun 04 *eval.txt* For Vim version 7.4. Last change: 2016 Aug 27
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@ -3625,25 +3625,30 @@ getbufinfo([{dict}])
lnum current line number in buffer. lnum current line number in buffer.
loaded TRUE if the buffer is loaded. loaded TRUE if the buffer is loaded.
name full path to the file in the buffer. name full path to the file in the buffer.
options dictionary of buffer local options.
signs list of signs placed in the buffer. signs list of signs placed in the buffer.
Each list item is a dictionary with Each list item is a dictionary with
the following fields: the following fields:
id sign identifier id sign identifier
lnum line number lnum line number
name sign name name sign name
variables dictionary of buffer local variables. variables a reference to the dictionary with
windows list of window IDs with this buffer buffer-local variables.
windows list of |window-ID|s that display this
buffer
Examples: > Examples: >
for buf in getbufinfo() for buf in getbufinfo()
echo buf.name echo buf.name
endfor endfor
for buf in getbufinfo({'buflisted':1}) for buf in getbufinfo({'buflisted':1})
if buf.options.filetype == 'java' if buf.changed
.... ....
endif endif
endfor endfor
<
To get buffer-local options use: >
getbufvar({bufnr}, '&')
< <
*getbufline()* *getbufline()*
getbufline({expr}, {lnum} [, {end}]) getbufline({expr}, {lnum} [, {end}])
@ -3676,6 +3681,10 @@ getbufvar({expr}, {varname} [, {def}]) *getbufvar()*
must be used. must be used.
When {varname} is empty returns a dictionary with all the When {varname} is empty returns a dictionary with all the
buffer-local variables. 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 This also works for a global or buffer-local option, but it
doesn't work for a global variable, window-local variable or doesn't work for a global variable, window-local variable or
window-local option. window-local option.
@ -4111,8 +4120,9 @@ gettabinfo([{arg}]) *gettabinfo()*
Each List item is a Dictionary with the following entries: Each List item is a Dictionary with the following entries:
nr tab page number. nr tab page number.
variables a reference to the dictionary with
tabpage-local variables
windows List of window IDs in the tag page. windows List of window IDs in the tag page.
variables dictionary of tabpage local variables.
gettabvar({tabnr}, {varname} [, {def}]) *gettabvar()* gettabvar({tabnr}, {varname} [, {def}]) *gettabvar()*
Get the value of a tab-local variable {varname} in tab page Get the value of a tab-local variable {varname} in tab page
@ -4127,10 +4137,12 @@ gettabvar({tabnr}, {varname} [, {def}]) *gettabvar()*
gettabwinvar({tabnr}, {winnr}, {varname} [, {def}]) *gettabwinvar()* gettabwinvar({tabnr}, {winnr}, {varname} [, {def}]) *gettabwinvar()*
Get the value of window-local variable {varname} in window Get the value of window-local variable {varname} in window
{winnr} in tab page {tabnr}. {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 When {varname} is empty a dictionary with all window-local
variables is returned. 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:". Note that {varname} must be the name without "w:".
Tabs are numbered starting with one. For the current tabpage Tabs are numbered starting with one. For the current tabpage
use |getwinvar()|. use |getwinvar()|.
@ -4170,13 +4182,16 @@ getwininfo([{winid}]) *getwininfo()*
height window height height window height
loclist 1 if showing a location list loclist 1 if showing a location list
nr window number nr window number
options dictionary of window local options
quickfix 1 if quickfix or location list window quickfix 1 if quickfix or location list window
tpnr tab page number tpnr tab page number
variables dictionary of window local variables variables a reference to the dictionary with
window-local variables
width window width width window width
winid window ID winid window ID
To obtain all window-local variables use: >
gettabwinvar({tabnr}, {winnr}, '&')
getwinvar({winnr}, {varname} [, {def}]) *getwinvar()* getwinvar({winnr}, {varname} [, {def}]) *getwinvar()*
Like |gettabwinvar()| for the current tabpage. Like |gettabwinvar()| for the current tabpage.
Examples: > Examples: >
@ -5544,6 +5559,16 @@ printf({fmt}, {expr1} ...) *printf()*
numeric field; if the result of a conversion is wider numeric field; if the result of a conversion is wider
than the field width, the field is expanded to contain than the field width, the field is expanded to contain
the conversion result. 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* *printf-c*
c The Number argument is converted to a byte, and the c The Number argument is converted to a byte, and the
@ -5560,7 +5585,7 @@ printf({fmt}, {expr1} ...) *printf()*
feature works just like 's'. feature works just like 's'.
*printf-f* *E807* *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 form 123.456. The precision specifies the number of
digits after the decimal point. When the precision is digits after the decimal point. When the precision is
zero the decimal point is omitted. When the precision zero the decimal point is omitted. When the precision

View File

@ -9883,12 +9883,6 @@ static dict_T *get_buffer_info(buf_T *buf)
// Get a reference to buffer variables // Get a reference to buffer variables
dict_add_dict(dict, "variables", buf->b_vars); dict_add_dict(dict, "variables", buf->b_vars);
// Copy buffer options
dict_T *opts = get_winbuf_options(true);
if (opts != NULL) {
dict_add_dict(dict, "options", opts);
}
// List of windows displaying this buffer // List of windows displaying this buffer
list_T *windows = list_alloc(); list_T *windows = list_alloc();
FOR_ALL_TAB_WINDOWS(tp, wp) { FOR_ALL_TAB_WINDOWS(tp, wp) {
@ -10056,8 +10050,20 @@ static void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
curbuf = buf; curbuf = buf;
if (*varname == '&') { /* buffer-local-option */ if (*varname == '&') { /* buffer-local-option */
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; done = TRUE;
}
} else if (STRCMP(varname, "changedtick") == 0) { } else if (STRCMP(varname, "changedtick") == 0) {
rettv->v_type = VAR_NUMBER; rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = curbuf->b_changedtick; rettv->vval.v_number = curbuf->b_changedtick;
@ -10904,15 +10910,9 @@ static dict_T *get_win_info(win_T *wp, short tpnr, short winnr)
(bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL), (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL),
NULL); NULL);
// Make a reference to window variables // Add a reference to window variables
dict_add_dict(dict, "variables", wp->w_vars); dict_add_dict(dict, "variables", wp->w_vars);
// Copy window options
dict_T *opts = get_winbuf_options(false);
if (opts != NULL) {
dict_add_dict(dict, "options", opts);
}
return dict; return dict;
} }
@ -11072,8 +11072,19 @@ getwinvar (
bool need_switch_win = tp != curtab || win != curwin; bool need_switch_win = tp != curtab || win != curwin;
if (!need_switch_win if (!need_switch_win
|| switch_win(&oldcurwin, &oldtabpage, win, tp, true) == OK) { || switch_win(&oldcurwin, &oldtabpage, win, tp, true) == OK) {
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; done = true;
} }
} else { } else {

View File

@ -18,7 +18,6 @@ function Test_getbufwintabinfo()
let b:editor = 'vim' let b:editor = 'vim'
let l = getbufinfo('%') let l = getbufinfo('%')
call assert_equal(bufnr('%'), l[0].bufnr) 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_equal('vim', l[0].variables.editor)
call assert_notequal(-1, index(l[0].windows, bufwinid('%'))) call assert_notequal(-1, index(l[0].windows, bufwinid('%')))
@ -49,7 +48,6 @@ function Test_getbufwintabinfo()
call assert_equal(winbufnr(2), winlist[1].bufnr) call assert_equal(winbufnr(2), winlist[1].bufnr)
call assert_equal(winheight(2), winlist[1].height) call assert_equal(winheight(2), winlist[1].height)
call assert_equal(1, winlist[2].winnr) call assert_equal(1, winlist[2].winnr)
call assert_equal('auto', winlist[0].options.signcolumn)
call assert_equal(2, winlist[3].tabnr) call assert_equal(2, winlist[3].tabnr)
call assert_equal('green', winlist[2].variables.signal) call assert_equal('green', winlist[2].variables.signal)
call assert_equal(winwidth(1), winlist[0].width) call assert_equal(winwidth(1), winlist[0].width)
@ -81,3 +79,25 @@ function Test_getbufwintabinfo()
call assert_false(winlist[2].loclist) call assert_false(winlist[2].loclist)
wincmd t | only wincmd t | only
endfunction 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

View File

@ -167,7 +167,7 @@ static int included_patches[] = {
// 2276, // 2276,
// 2275, // 2275,
2274, 2274,
// 2273, 2273,
2272, 2272,
// 2271 NA // 2271 NA
// 2270 NA // 2270 NA