]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.1.0307: there is no good way to get the window layout v8.1.0307
authorBram Moolenaar <Bram@vim.org>
Tue, 21 Aug 2018 14:56:34 +0000 (16:56 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 21 Aug 2018 14:56:34 +0000 (16:56 +0200)
Problem:    There is no good way to get the window layout.
Solution:   Add the winlayout() function. (Yegappan Lakshmanan)

runtime/doc/eval.txt
src/evalfunc.c
src/proto/window.pro
src/testdir/test_window_id.vim
src/version.c
src/window.c

index 53ee2094e378f5bdec3e425a34a06a6bc62b8061..821cbbca9ba547d9a5caf3277e7c73f98b70fbcd 100644 (file)
@@ -2497,6 +2497,7 @@ win_screenpos({nr})               List    get screen position of window {nr}
 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,6 +9088,35 @@ winheight({nr})                                          *winheight()*
                This excludes any window toolbar line.
                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
index 2bebdd1c62db076235173bfea0f529c866b47402..5e7c013979e7a0ee4b34cd8de20efd3a714cf946 100644 (file)
@@ -463,6 +463,7 @@ static void f_win_screenpos(typval_T *argvars, typval_T *rettv);
 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,6 +953,7 @@ static struct fst
     {"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},
@@ -13742,6 +13744,29 @@ f_winheight(typval_T *argvars, typval_T *rettv)
        rettv->vval.v_number = wp->w_height;
 }
 
+/*
+ * "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
  */
index 7ed8042f7b7b73ea47330ac4e301c6149ab1350a..c31e59969bafc063cbd16604405f6aba33a5f7a3 100644 (file)
@@ -94,4 +94,5 @@ void win_id2tabwin(typval_T *argvars, list_T *list);
 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 : */
index b3b506d04d8c7141ced16ecd2ac6d886594bb3ad..d10d831650da81f48fcdb6da35db4675dffa85bb 100644 (file)
@@ -101,3 +101,23 @@ func Test_win_getid_curtab()
   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
index 5f03975c94f7199d7d9a5c49425d227011167e54..bad2b33242ed964d11828293edec0304689b13b8 100644 (file)
@@ -794,6 +794,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    307,
 /**/
     306,
 /**/
index e1781d3f46340c941cdc9c113917949b5d81428e..5671cf900e33c2ca7cf736b6a62878c1f83c5fd3 100644 (file)
@@ -7236,4 +7236,53 @@ win_findbuf(typval_T *argvars, list_T *list)
                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