1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
|
To: vim_dev@googlegroups.com
Subject: Patch 8.1.0307
Fcc: outbox
From: Bram Moolenaar <Bram@moolenaar.net>
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 ///
|