Hi all,
I am attaching a patch to add the neighbor window information to the
getwininfo() function. It returns the window ID of the windows above,
right, below and left of the specified window. If a neighbor window
is not present, then it is set to 0.
- 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..bc6b9dd57 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -4836,10 +4836,13 @@ 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}
+ neighbors list of neighbor window IDs. The list
+ contains the window IDs of the above,
+ right, below and left windows. If a
+ neighbor window is not found in a
+ particular direction, it is set to 0.
quickfix 1 if quickfix or location list window
{only with the +quickfix feature}
terminal 1 if a terminal window
@@ -4848,6 +4851,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
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 0300efea4..8c561dc8a 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -5266,9 +5266,10 @@ f_gettabwinvar(typval_T *argvars, typval_T *rettv)
* Returns information about a window as a dictionary.
*/
static dict_T *
-get_win_info(win_T *wp, short tpnr, short winnr)
+get_win_info(tabpage_T *tp, win_T *wp, short tpnr, short winnr)
{
dict_T *dict;
+ list_T *l;
dict = dict_alloc();
if (dict == NULL)
@@ -5292,6 +5293,13 @@ get_win_info(win_T *wp, short tpnr, short winnr)
dict_add_nr_str(dict, "loclist",
(bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL), NULL);
#endif
+ /* Add neighbor window information */
+ l = list_alloc();
+ if (l != NULL)
+ {
+ win_get_neighbors(tp, wp, l);
+ dict_add_list(dict, "neighbors", l);
+ }
/* Add a reference to window variables */
dict_add_dict(dict, "variables", wp->w_vars);
@@ -5332,7 +5340,7 @@ f_getwininfo(typval_T *argvars, typval_T *rettv)
winnr++;
if (wparg != NULL && wp != wparg)
continue;
- d = get_win_info(wp, tabnr, winnr);
+ d = get_win_info(tp, wp, tabnr, winnr);
if (d != NULL)
list_append_dict(rettv->vval.v_list, d);
if (wparg != NULL)
diff --git a/src/proto/window.pro b/src/proto/window.pro
index e53123c55..759ade399 100644
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -37,6 +37,7 @@ void tabpage_move(int nr);
void win_goto(win_T *wp);
win_T *win_find_nr(int winnr);
tabpage_T *win_find_tabpage(win_T *win);
+void win_get_neighbors(tabpage_T *tp, win_T *wp, list_T *neighbors);
void win_enter(win_T *wp, int undo_sync);
win_T *buf_jump_open_win(buf_T *buf);
win_T *buf_jump_open_tab(buf_T *buf);
diff --git a/src/testdir/test_bufwintabinfo.vim
b/src/testdir/test_bufwintabinfo.vim
index 31b465002..2dde2d9fa 100644
--- a/src/testdir/test_bufwintabinfo.vim
+++ b/src/testdir/test_bufwintabinfo.vim
@@ -120,3 +120,23 @@ function Test_get_win_options()
set foldlevel=0
endif
endfunc
+
+" Test for window neighbors
+func Test_win_neighbors()
+ enew | only
+ call assert_equal([0, 0, 0, 0], getwininfo()[0].neighbors)
+ let w1 = win_getid()
+ botright new
+ let w2 = win_getid()
+ botright new
+ let w3 = win_getid()
+ vert topleft new
+ let w4 = win_getid()
+ vert botright new
+ let w5 = win_getid()
+ call assert_equal([0, w5, w2, w4], getwininfo(w1)[0].neighbors)
+ call assert_equal([w1, w5, w3, w4], getwininfo(w2)[0].neighbors)
+ call assert_equal([w2, w5, 0, w4], getwininfo(w3)[0].neighbors)
+ call assert_equal([0, w1, 0, 0], getwininfo(w4)[0].neighbors)
+ call assert_equal([0, 0, 0, w1], getwininfo(w5)[0].neighbors)
+endfunc
diff --git a/src/window.c b/src/window.c
index a58fbbd7b..127f682ab 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4188,18 +4188,19 @@ win_find_tabpage(win_T *win)
#endif
/*
- * Move to window above or below "count" times.
+ * Get the above or below neighbor window of the specified window.
+ * up - TRUE for the above neighbor
+ * count - nth neighbor window
+ * Returns the specified window if the neighbor is not found.
*/
- static void
-win_goto_ver(
- int up, /* TRUE to go to win above */
- long count)
+ static win_T *
+win_vert_neighbor(tabpage_T *tp, win_T *wp, int up, long count)
{
frame_T *fr;
frame_T *nfr;
frame_T *foundfr;
- foundfr = curwin->w_frame;
+ foundfr = wp->w_frame;
while (count--)
{
/*
@@ -4209,7 +4210,7 @@ win_goto_ver(
fr = foundfr;
for (;;)
{
- if (fr == topframe)
+ if (fr == tp->tp_topframe)
goto end;
if (up)
nfr = fr->fr_prev;
@@ -4236,7 +4237,7 @@ win_goto_ver(
/* Find the frame at the cursor row. */
while (fr->fr_next != NULL
&& frame2win(fr)->w_wincol + fr->fr_width
- <= curwin->w_wincol + curwin->w_wcol)
+ <= wp->w_wincol + wp->w_wcol)
fr = fr->fr_next;
}
if (nfr->fr_layout == FR_COL && up)
@@ -4246,23 +4247,38 @@ win_goto_ver(
}
}
end:
- if (foundfr != NULL)
- win_goto(foundfr->fr_win);
+ return foundfr != NULL ? foundfr->fr_win : NULL;
}
/*
- * Move to left or right window.
+ * Move to window above or below "count" times.
*/
static void
-win_goto_hor(
- int left, /* TRUE to go to left win */
+win_goto_ver(
+ int up, /* TRUE to go to win above */
long count)
+{
+ win_T *win;
+
+ win = win_vert_neighbor(curtab, curwin, up, count);
+ if (win != NULL)
+ win_goto(win);
+}
+
+/*
+ * Get the left or right neighbor window of the specified window.
+ * left - TRUE for the left neighbor
+ * count - nth neighbor window
+ * Returns the specified window if the neighbor is not found.
+ */
+ static win_T *
+win_horz_neighbor(tabpage_T *tp, win_T * wp, int left, long count)
{
frame_T *fr;
frame_T *nfr;
frame_T *foundfr;
- foundfr = curwin->w_frame;
+ foundfr = wp->w_frame;
while (count--)
{
/*
@@ -4272,7 +4288,7 @@ win_goto_hor(
fr = foundfr;
for (;;)
{
- if (fr == topframe)
+ if (fr == tp->tp_topframe)
goto end;
if (left)
nfr = fr->fr_prev;
@@ -4299,7 +4315,7 @@ win_goto_hor(
/* Find the frame at the cursor row. */
while (fr->fr_next != NULL
&& frame2win(fr)->w_winrow + fr->fr_height
- <= curwin->w_winrow + curwin->w_wrow)
+ <= wp->w_winrow + wp->w_wrow)
fr = fr->fr_next;
}
if (nfr->fr_layout == FR_ROW && left)
@@ -4309,8 +4325,44 @@ win_goto_hor(
}
}
end:
- if (foundfr != NULL)
- win_goto(foundfr->fr_win);
+ return foundfr != NULL ? foundfr->fr_win : NULL;
+}
+
+/*
+ * Move to left or right window.
+ */
+ static void
+win_goto_hor(
+ int left, /* TRUE to go to left win */
+ long count)
+{
+ win_T *win;
+
+ win = win_horz_neighbor(curtab, curwin, left, count);
+ if (win != NULL)
+ win_goto(win);
+}
+
+ void
+win_get_neighbors(tabpage_T *tp, win_T *wp, list_T *neighbors)
+{
+ win_T *win;
+
+ /* North neighbor */
+ win = win_vert_neighbor(tp, wp, TRUE, 1);
+ list_append_number(neighbors, (win != NULL && win != wp) ? win->w_id : 0);
+
+ /* East neighbor */
+ win = win_horz_neighbor(tp, wp, FALSE, 1);
+ list_append_number(neighbors, (win != NULL && win != wp) ? win->w_id : 0);
+
+ /* South neighbor */
+ win = win_vert_neighbor(tp, wp, FALSE, 1);
+ list_append_number(neighbors, (win != NULL && win != wp) ? win->w_id : 0);
+
+ /* West neighbor */
+ win = win_horz_neighbor(tp, wp, TRUE, 1);
+ list_append_number(neighbors, (win != NULL && win != wp) ? win->w_id : 0);
}
/*