From 1ef4340f22b915dc7ae2afdb2e88599133a20537 Mon Sep 17 00:00:00 2001 From: "Andy K. Massimino" Date: Thu, 18 Mar 2021 21:51:20 -0400 Subject: vim-patch:8.1.2020: it is not easy to change the window layout Problem: It is not easy to change the window layout. Solution: Add win_splitmove(). (Andy Massimino, closes vim/vim#4561) https://github.com/vim/vim/commit/d20dcb3d011da6111153109f6e46fbd5c7fe9fb6 --- src/nvim/eval/funcs.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 'src/nvim/eval/funcs.c') diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 2b04469af7..6d6b701169 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -3980,6 +3980,85 @@ static void f_win_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) tv_list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_wincol + 1); } +// +// Move the window wp into a new split of targetwin in a given direction +// +static void win_move_into_split(win_T *wp, win_T *targetwin, + int size, int flags) +{ + int dir; + int height = wp->w_height; + win_T *oldwin = curwin; + + if (wp == targetwin) { + return; + } + + // Jump to the target window + if (curwin != targetwin) { + win_goto(targetwin); + } + + // Remove the old window and frame from the tree of frames + (void)winframe_remove(wp, &dir, NULL); + win_remove(wp, NULL); + last_status(false); // may need to remove last status line + (void)win_comp_pos(); // recompute window positions + + // Split a window on the desired side and put the old window there + (void)win_split_ins(size, flags, wp, dir); + + // If splitting horizontally, try to preserve height + if (size == 0 && !(flags & WSP_VERT)) { + win_setheight_win(height, wp); + if (p_ea) { + win_equal(wp, true, 'v'); + } + } + + if (oldwin != curwin) { + win_goto(oldwin); + } +} + +// "win_splitmove()" function +static void f_win_splitmove(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + win_T *wp; + win_T *targetwin; + int flags = 0, size = 0; + + wp = find_win_by_nr_or_id(&argvars[0]); + targetwin = find_win_by_nr_or_id(&argvars[1]); + + if (wp == NULL || targetwin == NULL || wp == targetwin) { + EMSG(_(e_invalwindow)); + rettv->vval.v_number = -1; + return; + } + + if (argvars[2].v_type != VAR_UNKNOWN) { + dict_T *d; + dictitem_T *di; + + if (argvars[2].v_type != VAR_DICT || argvars[2].vval.v_dict == NULL) { + EMSG(_(e_invarg)); + return; + } + + d = argvars[2].vval.v_dict; + if (tv_dict_get_number(d, "vertical")) { + flags |= WSP_VERT; + } + if ((di = tv_dict_find(d, "rightbelow", -1)) != NULL) { + flags |= tv_get_number(&di->di_tv) ? WSP_BELOW : WSP_ABOVE; + } + size = tv_dict_get_number(d, "size"); + } + + win_move_into_split(wp, targetwin, size, flags); +} + // "getwinpos({timeout})" function static void f_getwinpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) { -- cgit From b2ec77007081cf9c63f935115f69c718db248226 Mon Sep 17 00:00:00 2001 From: "Andy K. Massimino" Date: Thu, 18 Mar 2021 22:57:27 -0400 Subject: vim-patch:8.2.0093: win_splitmove() can make Vim hang Problem: win_splitmove() can make Vim hang. Solution: Check windows exists in the current tab page. (closes vim/vim#5444) https://github.com/vim/vim/commit/7b94e77132eabdf0e43abca57e2ffeb961545174 --- src/nvim/eval/funcs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/nvim/eval/funcs.c') diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 6d6b701169..7fb3ccd737 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -4031,7 +4031,8 @@ static void f_win_splitmove(typval_T *argvars, typval_T *rettv, FunPtr fptr) wp = find_win_by_nr_or_id(&argvars[0]); targetwin = find_win_by_nr_or_id(&argvars[1]); - if (wp == NULL || targetwin == NULL || wp == targetwin) { + if (wp == NULL || targetwin == NULL || wp == targetwin + || !win_valid(wp) || !win_valid(targetwin)) { EMSG(_(e_invalwindow)); rettv->vval.v_number = -1; return; -- cgit From 0cec2d39c995f8aaeac95edb0ce463c6fcd19645 Mon Sep 17 00:00:00 2001 From: "Andy K. Massimino" Date: Thu, 18 Mar 2021 22:40:18 -0400 Subject: vim-patch:8.2.0422: crash when passing popup window to win_splitmove() Problem: Crash when passing popup window to win_splitmove(). (john Devin) Solution: Disallow moving a popup window. (closes vim/vim#5816) https://github.com/vim/vim/commit/0f1563ffee4397f5b379517c41b7c9a977fd2e22 Add translated test for 8.2.0422 (popup->floating) --- src/nvim/eval/funcs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/nvim/eval/funcs.c') diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 7fb3ccd737..9edf5c8f7e 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -4032,7 +4032,8 @@ static void f_win_splitmove(typval_T *argvars, typval_T *rettv, FunPtr fptr) targetwin = find_win_by_nr_or_id(&argvars[1]); if (wp == NULL || targetwin == NULL || wp == targetwin - || !win_valid(wp) || !win_valid(targetwin)) { + || !win_valid(wp) || !win_valid(targetwin) + || win_valid_floating(wp) || win_valid_floating(targetwin)) { EMSG(_(e_invalwindow)); rettv->vval.v_number = -1; return; -- cgit