vim-patch:8.1.0307: there is no good way to get the window layout

Problem:    There is no good way to get the window layout.
Solution:   Add the winlayout() function. (Yegappan Lakshmanan)
0f6b4f06de
This commit is contained in:
Jan Edmund Lazo
2019-05-25 21:59:33 -04:00
parent 08aa9b0023
commit f60af8694b
5 changed files with 105 additions and 0 deletions

View File

@@ -2377,6 +2377,7 @@ win_screenpos({nr}) List get screen position of window {nr}
winbufnr({nr}) Number buffer number of window {nr} winbufnr({nr}) Number buffer number of window {nr}
wincol() Number window column of the cursor wincol() Number window column of the cursor
winheight({nr}) Number height of window {nr} winheight({nr}) Number height of window {nr}
winlayout([{tabnr}]) List layout of windows in tab {tabnr}
winline() Number window line of the cursor winline() Number window line of the cursor
winnr([{expr}]) Number number of current window winnr([{expr}]) Number number of current window
winrestcmd() String returns command to restore window sizes winrestcmd() String returns command to restore window sizes
@@ -8537,6 +8538,35 @@ winheight({nr}) *winheight()*
This excludes any window toolbar line. This excludes any window toolbar line.
Examples: > Examples: >
:echo "The current window has " . winheight(0) . " lines." :echo "The current window has " . winheight(0) . " lines."
<
winlayout([{tabnr}]) *winlayout()*
The result is a nested List containing the layout of windows
in a tabpage.
Without {tabnr} use the current tabpage, otherwise the tabpage
with number {tabnr}. If the tabpage {tabnr} is not found,
returns an empty list.
For a leaf window, it returns:
['leaf', {winid}]
For horizontally split windows, which form a column, it
returns:
['col', [{nested list of windows}]]
For vertically split windows, which form a row, it returns:
['row', [{nested list of windows}]]
Example: >
" Only one window in the tab page
:echo winlayout()
['leaf', 1000]
" Two horizontally split windows
:echo winlayout()
['col', [['leaf', 1000], ['leaf', 1001]]]
" Three horizontally split windows, with two
" vertically split windows in the middle window
:echo winlayout(2)
['col', [['leaf', 1002], ['row', ['leaf', 1003],
['leaf', 1001]]], ['leaf', 1000]]
< <
*winline()* *winline()*
winline() The result is a Number, which is the screen line of the cursor winline() The result is a Number, which is the screen line of the cursor

View File

@@ -17872,6 +17872,25 @@ static void f_winheight(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} }
} }
// "winlayout()" function
static void f_winlayout(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tabpage_T *tp;
tv_list_alloc_ret(rettv, 2);
if (argvars[0].v_type == VAR_UNKNOWN) {
tp = curtab;
} else {
tp = find_tabpage((int)tv_get_number(&argvars[0]));
if (tp == NULL) {
return;
}
}
get_framelayout(tp->tp_topframe, rettv->vval.v_list, true);
}
/* /*
* "winline()" function * "winline()" function
*/ */

View File

@@ -352,6 +352,7 @@ return {
winbufnr={args=1}, winbufnr={args=1},
wincol={}, wincol={},
winheight={args=1}, winheight={args=1},
winlayout={args={0, 1}},
winline={}, winline={},
winnr={args={0, 1}}, winnr={args={0, 1}},
winrestcmd={}, winrestcmd={},

View File

@@ -101,3 +101,23 @@ func Test_win_getid_curtab()
call assert_equal(win_getid(1), win_getid(1, 1)) call assert_equal(win_getid(1), win_getid(1, 1))
tabclose! tabclose!
endfunc endfunc
func Test_winlayout()
let w1 = win_getid()
call assert_equal(['leaf', w1], winlayout())
split
let w2 = win_getid()
call assert_equal(['col', [['leaf', w2], ['leaf', w1]]], winlayout())
split
let w3 = win_getid()
call assert_equal(['col', [['leaf', w3], ['leaf', w2], ['leaf', w1]]], winlayout())
2wincmd w
vsplit
let w4 = win_getid()
call assert_equal(['col', [['leaf', w3], ['row', [['leaf', w4], ['leaf', w2]]], ['leaf', w1]]], winlayout())
only!
endfunc

View File

@@ -6658,6 +6658,41 @@ void win_findbuf(typval_T *argvars, list_T *list)
} }
} }
// Get the layout of the given tab page for winlayout().
void get_framelayout(const frame_T *fr, list_T *l, bool outer)
{
list_T *fr_list;
if (fr == NULL) {
return;
}
if (outer) {
// outermost call from f_winlayout()
fr_list = l;
} else {
fr_list = tv_list_alloc(2);
tv_list_append_list(l, fr_list);
}
if (fr->fr_layout == FR_LEAF) {
if (fr->fr_win != NULL) {
tv_list_append_string(fr_list, "leaf", -1);
tv_list_append_number(fr_list, fr->fr_win->handle);
}
} else {
tv_list_append_string(fr_list, fr->fr_layout == FR_ROW ? "row" : "col", -1);
list_T *const win_list = tv_list_alloc(kListLenUnknown);
tv_list_append_list(fr_list, win_list);
const frame_T *child = fr->fr_child;
while (child != NULL) {
get_framelayout(child, win_list, false);
child = child->fr_next;
}
}
}
void win_ui_flush_positions(void) void win_ui_flush_positions(void)
{ {
FOR_ALL_TAB_WINDOWS(tp, wp) { FOR_ALL_TAB_WINDOWS(tp, wp) {