mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 8.1.1140: not easy to find out what neighbors a window has
Problem: Not easy to find out what neighbors a window has. Solution: Add more arguments to winnr(). (Yegappan Lakshmanan, closes #3993)
This commit is contained in:
@@ -10198,17 +10198,30 @@ winline() The result is a Number, which is the screen line of the cursor
|
||||
*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 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
|
||||
|
@@ -13982,6 +13982,8 @@ get_winnr(tabpage_T *tp, typval_T *argvar)
|
||||
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 */
|
||||
@@ -13994,6 +13996,32 @@ get_winnr(tabpage_T *tp, typval_T *argvar)
|
||||
nr = 0;
|
||||
}
|
||||
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;
|
||||
|
@@ -37,6 +37,8 @@ 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);
|
||||
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);
|
||||
|
@@ -743,4 +743,49 @@ func Test_relative_cursor_second_line_after_resize()
|
||||
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
|
||||
|
@@ -771,6 +771,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1140,
|
||||
/**/
|
||||
1139,
|
||||
/**/
|
||||
|
66
src/window.c
66
src/window.c
@@ -4218,18 +4218,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)
|
||||
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--)
|
||||
{
|
||||
/*
|
||||
@@ -4239,7 +4240,7 @@ win_goto_ver(
|
||||
fr = foundfr;
|
||||
for (;;)
|
||||
{
|
||||
if (fr == topframe)
|
||||
if (fr == tp->tp_topframe)
|
||||
goto end;
|
||||
if (up)
|
||||
nfr = fr->fr_prev;
|
||||
@@ -4266,7 +4267,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)
|
||||
@@ -4276,23 +4277,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.
|
||||
*/
|
||||
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--)
|
||||
{
|
||||
/*
|
||||
@@ -4302,7 +4318,7 @@ win_goto_hor(
|
||||
fr = foundfr;
|
||||
for (;;)
|
||||
{
|
||||
if (fr == topframe)
|
||||
if (fr == tp->tp_topframe)
|
||||
goto end;
|
||||
if (left)
|
||||
nfr = fr->fr_prev;
|
||||
@@ -4329,7 +4345,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)
|
||||
@@ -4339,8 +4355,22 @@ 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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user