To: vim_dev@googlegroups.com Subject: Patch 8.1.0307 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.0307 Problem: There is no good way to get the window layout. Solution: Add the winlayout() function. (Yegappan Lakshmanan) Files: runtime/doc/eval.txt, src/evalfunc.c, src/proto/window.pro, src/window.c, src/testdir/test_window_id.vim *** ../vim-8.1.0306/runtime/doc/eval.txt 2018-07-29 15:34:20.864300100 +0200 --- runtime/doc/eval.txt 2018-08-21 16:35:43.299154086 +0200 *************** *** 2497,2502 **** --- 2504,2510 ---- winbufnr({nr}) Number buffer number of window {nr} wincol() Number window column of the cursor winheight({nr}) Number height of window {nr} + winlayout([{tabnr}]) List layout of windows in tab {tabnr} winline() Number window line of the cursor winnr([{expr}]) Number number of current window winrestcmd() String returns command to restore window sizes *************** *** 9087,9092 **** --- 9096,9130 ---- Examples: > :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() The result is a Number, which is the screen line of the cursor in the window. This is counting screen lines from the top of *** ../vim-8.1.0306/src/evalfunc.c 2018-08-11 13:57:16.211969806 +0200 --- src/evalfunc.c 2018-08-21 16:19:29.914566586 +0200 *************** *** 463,468 **** --- 463,469 ---- static void f_winbufnr(typval_T *argvars, typval_T *rettv); static void f_wincol(typval_T *argvars, typval_T *rettv); static void f_winheight(typval_T *argvars, typval_T *rettv); + static void f_winlayout(typval_T *argvars, typval_T *rettv); static void f_winline(typval_T *argvars, typval_T *rettv); static void f_winnr(typval_T *argvars, typval_T *rettv); static void f_winrestcmd(typval_T *argvars, typval_T *rettv); *************** *** 952,957 **** --- 953,959 ---- {"winbufnr", 1, 1, f_winbufnr}, {"wincol", 0, 0, f_wincol}, {"winheight", 1, 1, f_winheight}, + {"winlayout", 0, 1, f_winlayout}, {"winline", 0, 0, f_winline}, {"winnr", 0, 1, f_winnr}, {"winrestcmd", 0, 0, f_winrestcmd}, *************** *** 13743,13748 **** --- 13745,13773 ---- } /* + * "winlayout()" function + */ + static void + f_winlayout(typval_T *argvars, typval_T *rettv) + { + tabpage_T *tp; + + if (rettv_list_alloc(rettv) != OK) + return; + + if (argvars[0].v_type == VAR_UNKNOWN) + tp = curtab; + else + { + tp = find_tabpage((int)get_tv_number(&argvars[0])); + if (tp == NULL) + return; + } + + get_framelayout(tp->tp_topframe, rettv->vval.v_list, TRUE); + } + + /* * "winline()" function */ static void *** ../vim-8.1.0306/src/proto/window.pro 2018-06-12 16:49:26.366028607 +0200 --- src/proto/window.pro 2018-08-21 16:38:15.282101882 +0200 *************** *** 94,97 **** --- 94,98 ---- win_T *win_id2wp(typval_T *argvars); int win_id2win(typval_T *argvars); void win_findbuf(typval_T *argvars, list_T *list); + void get_framelayout(frame_T *fr, list_T *l, int topframe); /* vim: set ft=c : */ *** ../vim-8.1.0306/src/window.c 2018-07-25 22:36:48.991518559 +0200 --- src/window.c 2018-08-21 16:43:30.963948179 +0200 *************** *** 7236,7239 **** --- 7236,7288 ---- list_append_number(list, wp->w_id); } + /* + * Get the layout of the given tab page for winlayout(). + */ + void + get_framelayout(frame_T *fr, list_T *l, int outer) + { + frame_T *child; + list_T *fr_list; + list_T *win_list; + + if (fr == NULL) + return; + + if (outer) + // outermost call from f_winlayout() + fr_list = l; + else + { + fr_list = list_alloc(); + if (fr_list == NULL) + return; + list_append_list(l, fr_list); + } + + if (fr->fr_layout == FR_LEAF) + { + if (fr->fr_win != NULL) + { + list_append_string(fr_list, (char_u *)"leaf", -1); + list_append_number(fr_list, fr->fr_win->w_id); + } + } + else + { + list_append_string(fr_list, + fr->fr_layout == FR_ROW ? (char_u *)"row" : (char_u *)"col", -1); + + win_list = list_alloc(); + if (win_list == NULL) + return; + list_append_list(fr_list, win_list); + child = fr->fr_child; + while (child != NULL) + { + get_framelayout(child, win_list, FALSE); + child = child->fr_next; + } + } + } #endif *** ../vim-8.1.0306/src/testdir/test_window_id.vim 2016-11-13 14:25:47.000000000 +0100 --- src/testdir/test_window_id.vim 2018-08-21 16:47:00.102536647 +0200 *************** *** 101,103 **** --- 101,123 ---- call assert_equal(win_getid(1), win_getid(1, 1)) tabclose! 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 *** ../vim-8.1.0306/src/version.c 2018-08-21 15:12:10.843801621 +0200 --- src/version.c 2018-08-21 16:54:45.515933731 +0200 *************** *** 796,797 **** --- 796,799 ---- { /* Add new patch number below this line */ + /**/ + 307, /**/ -- Friends? I have lots of friends! In fact, I have all episodes ever made. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///