Hi Bram,

On Tue, Jan 2, 2018 at 6:18 AM, Bram Moolenaar <[email protected]> wrote:
>
> Yegappan wrote:
>
>> Currently there is no way to determine the layout of the windows on the
>> screen. I needed this while developing a test for the "vert topleft copen"
>> command to check whether the window is opened at the left most part of
>> the screen.
>>
>> What do you think about adding a new winlayout() function that returns
>> the layout of windows in the specified tab page?
>>
>> If there is only one window in the tab page, then this function will return a
>> list with a window identifier.
>>
>> If there is more than one window in the tab page, then this function will
>> return a list where the first item is either "row" (for vertically
>> split windows)
>> or "col" (for horizontally split windows). The second item is a list of
>> window identifiers or additional lists.
>>
>> For example, for two horizontally split windows, this function will return
>> ['col', [1000, 1001]]
>>
>> For two vertically split windows, this function will return ['row',
>> [1000, 1001]]
>>
>> For three horizontally split windows, with two vertically split windows
>> in the middle window, this function will return:
>> ['col', [1002, ['row', [1003, 1001]], 1000]]
>>
>> Do you think this function will be useful?
>
> Yes, this can be useful.  It should already be possible to figure out
> the window position and size, but that doesn't show the hierarchy.
> A nested list of lists seems appropriate.
>

I am attaching a patch that implements the winlayout() function.
Do you think the returned List should also include the position and size
of the windows?

>
> Restoring might work if the same windows are still existing.  E.g. after
> temporary opening a window and closing it.
>

I didn't add the function for restoring the window layout in this patch.

- Yegappan

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index df00dc9e4..f45bab089 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2464,6 +2464,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
@@ -4836,8 +4837,6 @@ getwininfo([{winid}])                                     
*getwininfo()*
                Each List item is a Dictionary with the following entries:
                        bufnr           number of buffer in the window
                        height          window height (excluding winbar)
-                       winbar          1 if the window has a toolbar, 0
-                                       otherwise
                        loclist         1 if showing a location list
                                        {only with the +quickfix feature}
                        quickfix        1 if quickfix or location list window
@@ -4848,6 +4847,8 @@ getwininfo([{winid}])                                     
*getwininfo()*
                        variables       a reference to the dictionary with
                                        window-local variables
                        width           window width
+                       winbar          1 if the window has a toolbar, 0
+                                       otherwise
                        winid           |window-ID|
                        winnr           window number
 
@@ -8713,6 +8714,28 @@ 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 List containing the layout of windows in a
+               tabpage. If there is only one window in the tabpage, returns a
+               list with a window identifier. If there is more than one
+               window in the tabpage, returns a list where the first item is
+               either "row" (for vertically split windows) or "col" (for
+               horizontally split windows) followed by a list of window
+               identifiers or a nested list.  Without {tabnr} use the current
+               tabpage, otherwise the tabpage with number {tabnr}. If the
+               tabpage {tabnr} is not found, returns an empty list.
+               Example: >
+                       " Only one window in the tab page
+                       :echo winlayout()
+                       [1000]
+                       " Two horizontally split windows
+                       :echo winlayout()
+                       ['col', [1000, 1001]]
+                       " Three horizontally split windows, with two
+                       " vertically split windows in the middle window
+                       :echo winlayout(2)
+                       ['col', [1002, ['row', [1003, 1001]], 1000]]
 <
                                                        *winline()*
 winline()      The result is a Number, which is the screen line of the cursor
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 0300efea4..f69062abe 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -445,6 +445,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);
@@ -904,6 +905,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},
@@ -13256,6 +13258,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
  */
diff --git a/src/list.c b/src/list.c
index b593f7171..1dfaa210e 100644
--- a/src/list.c
+++ b/src/list.c
@@ -474,6 +474,27 @@ list_append_dict(list_T *list, dict_T *dict)
     return OK;
 }
 
+/*
+ * Append list2 to list1.
+ * Return FAIL when out of memory.
+ */
+    int
+list_append_list(list1, list2)
+    list_T     *list1;
+    list_T     *list2;
+{
+    listitem_T *li = listitem_alloc();
+
+    if (li == NULL)
+       return FAIL;
+    li->li_tv.v_type = VAR_LIST;
+    li->li_tv.v_lock = 0;
+    li->li_tv.vval.v_list = list2;
+    list_append(list1, li);
+    ++list2->lv_refcount;
+    return OK;
+}
+
 /*
  * Make a copy of "str" and append it as an item to list "l".
  * When "len" >= 0 use "str[len]".
diff --git a/src/proto/list.pro b/src/proto/list.pro
index fe54bab2b..c4fd195f1 100644
--- a/src/proto/list.pro
+++ b/src/proto/list.pro
@@ -21,6 +21,7 @@ long list_idx_of_item(list_T *l, listitem_T *item);
 void list_append(list_T *l, listitem_T *item);
 int list_append_tv(list_T *l, typval_T *tv);
 int list_append_dict(list_T *list, dict_T *dict);
+int list_append_list(list_T *list1, list_T *list2);
 int list_append_string(list_T *l, char_u *str, int len);
 int list_append_number(list_T *l, varnumber_T n);
 int list_insert_tv(list_T *l, typval_T *tv, listitem_T *item);
diff --git a/src/proto/window.pro b/src/proto/window.pro
index e53123c55..43d339e84 100644
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -93,4 +93,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 : */
diff --git a/src/window.c b/src/window.c
index a58fbbd7b..9a17635e8 100644
--- a/src/window.c
+++ b/src/window.c
@@ -7214,4 +7214,54 @@ win_findbuf(typval_T *argvars, list_T *list)
                list_append_number(list, wp->w_id);
 }
 
+/*
+ * Get the layout of the given tab page
+ */
+    void
+get_framelayout(frame_T *fr, list_T *l, int topframe)
+{
+    frame_T    *child;
+
+    if (fr == NULL)
+       return;
+
+    if (fr->fr_layout == FR_LEAF)
+    {
+       if (fr->fr_win != NULL)
+       {
+           list_append_number(l, fr->fr_win->w_id);
+       }
+    }
+    else
+    {
+       list_T *fr_list;
+       list_T *win_list;
+
+       if (topframe)
+           fr_list = l;
+       else
+       {
+           /* Create a new list for every frame */
+           fr_list = list_alloc();
+           if (fr_list == NULL)
+               return;
+           list_append_list(l, fr_list);
+       }
+
+       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

Raspunde prin e-mail lui