Patch 8.1.1140
Problem: Not easy to find out what neighbors a window has.
Solution: Add more arguments to winnr(). (Yegappan Lakshmanan, closes #3993)
Files: runtime/doc/eval.txt, src/evalfunc.c, src/proto/window.pro,
src/testdir/test_window_cmd.vim, src/window.c
*** ../vim-8.1.1139/runtime/doc/eval.txt 2019-04-06 13:18:06.733335092
+0200
--- runtime/doc/eval.txt 2019-04-08 19:56:34.570615478 +0200
***************
*** 10139,10155 ****
*winnr()*
winnr([{arg}]) The result is a Number, which is the number of the
current
window. The top window has number 1.
! When the optional argument is "$", the number of the
! last window is returned (the window count). >
! let window_count = winnr('$')
! < When the optional argument is "#", the number of the last
! accessed window is returned (where |CTRL-W_p| goes to).
! If there is no previous window or it is in another tab page 0
! is returned.
The number can be used with |CTRL-W_w| and ":wincmd w"
|:wincmd|.
Also see |tabpagewinnr()| and |win_getid()|.
!
*winrestcmd()*
winrestcmd() Returns a sequence of |:resize| commands that should restore
the current window sizes. Only works properly when no windows
--- 10198,10227 ----
*winnr()*
winnr([{arg}]) The result is a Number, which is the number of the
current
window. The top window has number 1.
!
! The optional argument {arg} supports the following values:
! $ the number of the last window (the window
! count).
! # the number of the last accessed window (where
! |CTRL-W_p| goes to). If there is no previous
! window or it is in another tab page 0 is
! returned.
! {N}j the number of the Nth window below the
! current window (where |CTRL-W_j| goes to).
! {N}k the number of the Nth window above the current
! window (where |CTRL-W_k| goes to).
! {N}h the number of the Nth window left of the
! current window (where |CTRL-W_h| goes to).
! {N}l the number of the Nth window right of the
! current window (where |CTRL-W_l| goes to).
The number can be used with |CTRL-W_w| and ":wincmd w"
|:wincmd|.
Also see |tabpagewinnr()| and |win_getid()|.
! Examples: >
! let window_count = winnr('$')
! let prev_window = winnr('#')
! let wnum = winnr('3k')
! <
*winrestcmd()*
winrestcmd() Returns a sequence of |:resize| commands that should restore
the current window sizes. Only works properly when no windows
*** ../vim-8.1.1139/src/evalfunc.c 2019-04-07 14:21:26.230339328 +0200
--- src/evalfunc.c 2019-04-08 19:53:26.131435229 +0200
***************
*** 13982,13987 ****
--- 13982,13989 ----
twin = (tp == curtab) ? curwin : tp->tp_curwin;
if (argvar->v_type != VAR_UNKNOWN)
{
+ int invalid_arg = FALSE;
+
arg = tv_get_string_chk(argvar);
if (arg == NULL)
nr = 0; /* type error; errmsg already given */
***************
*** 13995,14000 ****
--- 13997,14028 ----
}
else
{
+ long count;
+ char_u *endp;
+
+ // Extract the window count (if specified). e.g. winnr('3j')
+ count = strtol((char *)arg, (char **)&endp, 10);
+ if (count <= 0)
+ count = 1; // if count is not specified, default to 1
+ if (endp != NULL && *endp != '\0')
+ {
+ if (STRCMP(endp, "j") == 0)
+ twin = win_vert_neighbor(tp, twin, FALSE, count);
+ else if (STRCMP(endp, "k") == 0)
+ twin = win_vert_neighbor(tp, twin, TRUE, count);
+ else if (STRCMP(endp, "h") == 0)
+ twin = win_horz_neighbor(tp, twin, TRUE, count);
+ else if (STRCMP(endp, "l") == 0)
+ twin = win_horz_neighbor(tp, twin, FALSE, count);
+ else
+ invalid_arg = TRUE;
+ }
+ else
+ invalid_arg = TRUE;
+ }
+
+ if (invalid_arg)
+ {
semsg(_(e_invexpr2), arg);
nr = 0;
}
*** ../vim-8.1.1139/src/proto/window.pro 2019-02-13 22:45:21.512636158
+0100
--- src/proto/window.pro 2019-04-08 19:53:26.131435229 +0200
***************
*** 37,42 ****
--- 37,44 ----
void win_goto(win_T *wp);
win_T *win_find_nr(int winnr);
tabpage_T *win_find_tabpage(win_T *win);
+ win_T *win_vert_neighbor(tabpage_T *tp, win_T *wp, int up, long count);
+ win_T *win_horz_neighbor(tabpage_T *tp, win_T * wp, int left, long count);
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);
*** ../vim-8.1.1139/src/testdir/test_window_cmd.vim 2019-03-04
13:18:15.977053527 +0100
--- src/testdir/test_window_cmd.vim 2019-04-08 19:53:26.131435229 +0200
***************
*** 743,746 ****
--- 743,791 ----
let &so = so_save
endfunc
+ " Tests for the winnr() function
+ func Test_winnr()
+ only | tabonly
+ call assert_equal(1, winnr('j'))
+ call assert_equal(1, winnr('k'))
+ call assert_equal(1, winnr('h'))
+ call assert_equal(1, winnr('l'))
+
+ " create a set of horizontally and vertically split windows
+ leftabove new | wincmd p
+ leftabove new | wincmd p
+ rightbelow new | wincmd p
+ rightbelow new | wincmd p
+ leftabove vnew | wincmd p
+ leftabove vnew | wincmd p
+ rightbelow vnew | wincmd p
+ rightbelow vnew | wincmd p
+
+ call assert_equal(8, winnr('j'))
+ call assert_equal(2, winnr('k'))
+ call assert_equal(4, winnr('h'))
+ call assert_equal(6, winnr('l'))
+ call assert_equal(9, winnr('2j'))
+ call assert_equal(1, winnr('2k'))
+ call assert_equal(3, winnr('2h'))
+ call assert_equal(7, winnr('2l'))
+
+ " Error cases
+ call assert_fails("echo winnr('0.2k')", 'E15:')
+ call assert_equal(2, winnr('-2k'))
+ call assert_fails("echo winnr('-2xj')", 'E15:')
+ call assert_fails("echo winnr('j2j')", 'E15:')
+ call assert_fails("echo winnr('ll')", 'E15:')
+ call assert_fails("echo winnr('5')", 'E15:')
+ call assert_equal(4, winnr('0h'))
+
+ tabnew
+ call assert_equal(8, tabpagewinnr(1, 'j'))
+ call assert_equal(2, tabpagewinnr(1, 'k'))
+ call assert_equal(4, tabpagewinnr(1, 'h'))
+ call assert_equal(6, tabpagewinnr(1, 'l'))
+
+ only | tabonly
+ endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
*** ../vim-8.1.1139/src/window.c 2019-03-30 19:49:03.262806533 +0100
--- src/window.c 2019-04-08 19:58:55.705969739 +0200
***************
*** 4218,4235 ****
#endif
/*
! * Move to window above or below "count" times.
*/
! static void
! win_goto_ver(
! int up, /* TRUE to go to win above */
! long count)
{
frame_T *fr;
frame_T *nfr;
frame_T *foundfr;
! foundfr = curwin->w_frame;
while (count--)
{
/*
--- 4218,4236 ----
#endif
/*
! * 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.
*/
! 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 = wp->w_frame;
while (count--)
{
/*
***************
*** 4239,4245 ****
fr = foundfr;
for (;;)
{
! if (fr == topframe)
goto end;
if (up)
nfr = fr->fr_prev;
--- 4240,4246 ----
fr = foundfr;
for (;;)
{
! if (fr == tp->tp_topframe)
goto end;
if (up)
nfr = fr->fr_prev;
***************
*** 4266,4272 ****
/* 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)
fr = fr->fr_next;
}
if (nfr->fr_layout == FR_COL && up)
--- 4267,4273 ----
/* Find the frame at the cursor row. */
while (fr->fr_next != NULL
&& frame2win(fr)->w_wincol + fr->fr_width
! <= wp->w_wincol + wp->w_wcol)
fr = fr->fr_next;
}
if (nfr->fr_layout == FR_COL && up)
***************
*** 4276,4298 ****
}
}
end:
! if (foundfr != NULL)
! win_goto(foundfr->fr_win);
}
/*
! * Move to left or right window.
*/
static void
! win_goto_hor(
! int left, /* TRUE to go to left win */
long count)
{
frame_T *fr;
frame_T *nfr;
frame_T *foundfr;
! foundfr = curwin->w_frame;
while (count--)
{
/*
--- 4277,4314 ----
}
}
end:
! return foundfr != NULL ? foundfr->fr_win : NULL;
}
/*
! * Move to window above or below "count" times.
*/
static void
! 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.
+ */
+ 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 = wp->w_frame;
while (count--)
{
/*
***************
*** 4302,4308 ****
fr = foundfr;
for (;;)
{
! if (fr == topframe)
goto end;
if (left)
nfr = fr->fr_prev;
--- 4318,4324 ----
fr = foundfr;
for (;;)
{
! if (fr == tp->tp_topframe)
goto end;
if (left)
nfr = fr->fr_prev;
***************
*** 4329,4335 ****
/* 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)
fr = fr->fr_next;
}
if (nfr->fr_layout == FR_ROW && left)
--- 4345,4351 ----
/* Find the frame at the cursor row. */
while (fr->fr_next != NULL
&& frame2win(fr)->w_winrow + fr->fr_height
! <= wp->w_winrow + wp->w_wrow)
fr = fr->fr_next;
}
if (nfr->fr_layout == FR_ROW && left)
***************
*** 4339,4346 ****
}
}
end:
! if (foundfr != NULL)
! win_goto(foundfr->fr_win);
}
/*
--- 4355,4376 ----
}
}
end:
! 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);
}
/*
*** ../vim-8.1.1139/src/version.c 2019-04-08 18:59:50.973019097 +0200
--- src/version.c 2019-04-08 20:00:11.881612574 +0200
***************
*** 773,774 ****
--- 773,776 ----
{ /* Add new patch number below this line */
+ /**/
+ 1140,
/**/
--
hundred-and-one symptoms of being an internet addict:
232. You start conversations with, "Have you gotten an ISDN line?"
/// Bram Moolenaar -- [email protected] -- 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 ///
--
--
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.