0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

patch 8.2.4052: not easy to resize a window from a plugin

Problem:    Not easy to resize a window from a plugin.
Solution:   Add win_move_separator() and win_move_statusline() functions.
            (Daniel Steinberg, closes #9486)
This commit is contained in:
Daniel Steinberg 2022-01-10 13:36:34 +00:00 committed by Bram Moolenaar
parent b06cfcf5a3
commit ee63031b57
7 changed files with 189 additions and 0 deletions

View File

@ -695,6 +695,8 @@ win_gettype([{nr}]) String type of window {nr}
win_gotoid({expr}) Number go to window with ID {expr}
win_id2tabwin({expr}) List get tab and window nr from window ID
win_id2win({expr}) Number get window nr from window ID
win_move_separator({nr}) Number move window vertical separator
win_move_statusline({nr}) Number move window status line
win_screenpos({nr}) List get screen position of window {nr}
win_splitmove({nr}, {target} [, {options}])
Number move window {nr} to split of {target}
@ -9567,6 +9569,35 @@ win_id2win({expr}) *win_id2win()*
Can also be used as a |method|: >
GetWinid()->win_id2win()
win_move_separator({nr}, {offset}) *win_move_separator()*
Move window {nr}'s vertical separator (i.e., the right border)
by {offset} columns, as if being dragged by the mouse. {nr}
can be a window number or |window-ID|. A positive {offset}
moves right and a negative {offset} moves left. Moving a
window's vertical separator will change the width of the
window and the width of other windows adjacent to the vertical
separator. The magnitude of movement may be smaller than
specified (e.g., as a consequence of maintaining
'winminwidth'). Returns TRUE if the window can be found and
FALSE otherwise.
Can also be used as a |method|: >
GetWinnr()->win_move_separator(offset)
win_move_statusline({nr}, {offset}) *win_move_statusline()*
Move window {nr}'s status line (i.e., the bottom border) by
{offset} rows, as if being dragged by the mouse. {nr} can be a
window number or |window-ID|. A positive {offset} moves down
and a negative {offset} moves up. Moving a window's status
line will change the height of the window and the height of
other windows adjacent to the status line. The magnitude of
movement may be smaller than specified (e.g., as a consequence
of maintaining 'winminheight'). Returns TRUE if the window can
be found and FALSE otherwise.
Can also be used as a |method|: >
GetWinnr()->win_move_statusline(offset)
win_screenpos({nr}) *win_screenpos()*
Return the screen position of window {nr} as a list with two
numbers: [row, col]. The first window always has position

View File

@ -963,6 +963,8 @@ Buffers, windows and the argument list:
win_gotoid() go to window with ID
win_id2tabwin() get tab and window nr from window ID
win_id2win() get window nr from window ID
win_move_separator() move window vertical separator
win_move_statusline() move window status line
win_splitmove() move window to a split of another window
getbufinfo() get a list with buffer information
gettabinfo() get a list with tab page information

View File

@ -2398,6 +2398,10 @@ static funcentry_T global_functions[] =
ret_list_number, f_win_id2tabwin},
{"win_id2win", 1, 1, FEARG_1, arg1_number,
ret_number, f_win_id2win},
{"win_move_separator", 2, 2, FEARG_1, arg2_number,
ret_number_bool, f_win_move_separator},
{"win_move_statusline", 2, 2, FEARG_1, arg2_number,
ret_number_bool, f_win_move_statusline},
{"win_screenpos", 1, 1, FEARG_1, arg1_number,
ret_list_number, f_win_screenpos},
{"win_splitmove", 2, 3, FEARG_1, arg3_number_number_dict,

View File

@ -835,6 +835,56 @@ f_win_id2win(typval_T *argvars, typval_T *rettv)
rettv->vval.v_number = win_id2win(argvars);
}
/*
* "win_move_separator()" function
*/
void
f_win_move_separator(typval_T *argvars, typval_T *rettv)
{
win_T *wp;
int offset;
rettv->vval.v_number = FALSE;
if (in_vim9script()
&& (check_for_number_arg(argvars, 0) == FAIL
|| check_for_number_arg(argvars, 1) == FAIL))
return;
wp = find_win_by_nr_or_id(&argvars[0]);
if (wp == NULL || win_valid_popup(wp))
return;
offset = (int)tv_get_number(&argvars[1]);
win_drag_vsep_line(wp, offset);
rettv->vval.v_number = TRUE;
}
/*
* "win_move_statusline()" function
*/
void
f_win_move_statusline(typval_T *argvars, typval_T *rettv)
{
win_T *wp;
int offset;
rettv->vval.v_number = FALSE;
if (in_vim9script()
&& (check_for_number_arg(argvars, 0) == FAIL
|| check_for_number_arg(argvars, 1) == FAIL))
return;
wp = find_win_by_nr_or_id(&argvars[0]);
if (wp == NULL || win_valid_popup(wp))
return;
offset = (int)tv_get_number(&argvars[1]);
win_drag_status_line(wp, offset);
rettv->vval.v_number = TRUE;
}
/*
* "win_screenpos()" function
*/

View File

@ -18,6 +18,8 @@ void f_win_getid(typval_T *argvars, typval_T *rettv);
void f_win_gotoid(typval_T *argvars, typval_T *rettv);
void f_win_id2tabwin(typval_T *argvars, typval_T *rettv);
void f_win_id2win(typval_T *argvars, typval_T *rettv);
void f_win_move_separator(typval_T *argvars, typval_T *rettv);
void f_win_move_statusline(typval_T *argvars, typval_T *rettv);
void f_win_screenpos(typval_T *argvars, typval_T *rettv);
void f_win_splitmove(typval_T *argvars, typval_T *rettv);
void f_win_gettype(typval_T *argvars, typval_T *rettv);

View File

@ -1395,5 +1395,103 @@ func Test_window_minimal_size()
set winminwidth& winminheight&
endfunc
func Test_win_move_separator()
edit a
leftabove vsplit b
let w = winwidth(0)
" check win_move_separator from left window on left window
call assert_equal(1, winnr())
for offset in range(5)
call assert_true(win_move_separator(0, offset))
call assert_equal(w + offset, winwidth(0))
call assert_true(0->win_move_separator(-offset))
call assert_equal(w, winwidth(0))
endfor
" check win_move_separator from right window on left window number
wincmd l
call assert_notequal(1, winnr())
for offset in range(5)
call assert_true(1->win_move_separator(offset))
call assert_equal(w + offset, winwidth(1))
call assert_true(win_move_separator(1, -offset))
call assert_equal(w, winwidth(1))
endfor
" check win_move_separator from right window on left window ID
let id = win_getid(1)
for offset in range(5)
call assert_true(win_move_separator(id, offset))
call assert_equal(w + offset, winwidth(id))
call assert_true(id->win_move_separator(-offset))
call assert_equal(w, winwidth(id))
endfor
" check that win_move_separator doesn't error with offsets beyond moving
" possibility
call assert_true(win_move_separator(id, 5000))
call assert_true(winwidth(id) > w)
call assert_true(win_move_separator(id, -5000))
call assert_true(winwidth(id) < w)
" check that win_move_separator returns false for an invalid window
wincmd =
let w = winwidth(0)
call assert_false(win_move_separator(-1, 1))
call assert_equal(w, winwidth(0))
" check that win_move_separator returns false for a popup window
let id = popup_create(['hello', 'world'], {})
let w = winwidth(id)
call assert_false(win_move_separator(id, 1))
call assert_equal(w, winwidth(id))
call popup_close(id)
%bwipe!
endfunc
func Test_win_move_statusline()
edit a
leftabove split b
let h = winheight(0)
" check win_move_statusline from top window on top window
call assert_equal(1, winnr())
for offset in range(5)
call assert_true(win_move_statusline(0, offset))
call assert_equal(h + offset, winheight(0))
call assert_true(0->win_move_statusline(-offset))
call assert_equal(h, winheight(0))
endfor
" check win_move_statusline from bottom window on top window number
wincmd j
call assert_notequal(1, winnr())
for offset in range(5)
call assert_true(1->win_move_statusline(offset))
call assert_equal(h + offset, winheight(1))
call assert_true(win_move_statusline(1, -offset))
call assert_equal(h, winheight(1))
endfor
" check win_move_statusline from bottom window on top window ID
let id = win_getid(1)
for offset in range(5)
call assert_true(win_move_statusline(id, offset))
call assert_equal(h + offset, winheight(id))
call assert_true(id->win_move_statusline(-offset))
call assert_equal(h, winheight(id))
endfor
" check that win_move_statusline doesn't error with offsets beyond moving
" possibility
call assert_true(win_move_statusline(id, 5000))
call assert_true(winheight(id) > h)
call assert_true(win_move_statusline(id, -5000))
call assert_true(winheight(id) < h)
" check that win_move_statusline returns false for an invalid window
wincmd =
let h = winheight(0)
call assert_false(win_move_statusline(-1, 1))
call assert_equal(h, winheight(0))
" check that win_move_statusline returns false for a popup window
let id = popup_create(['hello', 'world'], {})
let h = winheight(id)
call assert_false(win_move_statusline(id, 1))
call assert_equal(h, winheight(id))
call popup_close(id)
%bwipe!
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
4052,
/**/
4051,
/**/