mirror of
https://github.com/neovim/neovim.git
synced 2025-09-29 14:38:32 +00:00
feat(api): make nvim_open_win support non-floating windows (#25550)
Adds support to `nvim_open_win` and `nvim_win_set_config` for creating and manipulating split (non-floating) windows.
This commit is contained in:
@@ -713,7 +713,7 @@ void win_set_buf(win_T *win, buf_T *buf, bool noautocmd, Error *err)
|
||||
}
|
||||
|
||||
switchwin_T switchwin;
|
||||
if (switch_win_noblock(&switchwin, win, tab, false) == FAIL) {
|
||||
if (switch_win_noblock(&switchwin, win, tab, true) == FAIL) {
|
||||
api_set_error(err,
|
||||
kErrorTypeException,
|
||||
"Failed to switch to window %d",
|
||||
@@ -733,7 +733,7 @@ void win_set_buf(win_T *win, buf_T *buf, bool noautocmd, Error *err)
|
||||
// So do it now.
|
||||
validate_cursor();
|
||||
|
||||
restore_win_noblock(&switchwin, false);
|
||||
restore_win_noblock(&switchwin, true);
|
||||
if (noautocmd) {
|
||||
unblock_autocmds();
|
||||
}
|
||||
@@ -928,6 +928,7 @@ static int check_split_disallowed(void)
|
||||
// WSP_TOP: open window at the top-left of the screen (help window).
|
||||
// WSP_BOT: open window at the bottom-right of the screen (quickfix window).
|
||||
// WSP_HELP: creating the help window, keep layout snapshot
|
||||
// WSP_NOENTER: do not enter the new window or trigger WinNew autocommands
|
||||
//
|
||||
// return FAIL for failure, OK otherwise
|
||||
int win_split(int size, int flags)
|
||||
@@ -956,20 +957,20 @@ int win_split(int size, int flags)
|
||||
clear_snapshot(curtab, SNAP_HELP_IDX);
|
||||
}
|
||||
|
||||
return win_split_ins(size, flags, NULL, 0);
|
||||
return win_split_ins(size, flags, NULL, 0) == NULL ? FAIL : OK;
|
||||
}
|
||||
|
||||
/// When "new_wp" is NULL: split the current window in two.
|
||||
/// When "new_wp" is not NULL: insert this window at the far
|
||||
/// top/left/right/bottom.
|
||||
/// @return FAIL for failure, OK otherwise
|
||||
int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
/// @return NULL for failure, or pointer to new window
|
||||
win_T *win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
{
|
||||
win_T *wp = new_wp;
|
||||
|
||||
// aucmd_win[] should always remain floating
|
||||
if (new_wp != NULL && is_aucmd_win(new_wp)) {
|
||||
return FAIL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
win_T *oldwin;
|
||||
@@ -985,22 +986,24 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
int need_status = 0;
|
||||
int new_size = size;
|
||||
bool new_in_layout = (new_wp == NULL || new_wp->w_floating);
|
||||
bool vertical = flags & WSP_VERT;
|
||||
bool toplevel = flags & (WSP_TOP | WSP_BOT);
|
||||
|
||||
// add a status line when p_ls == 1 and splitting the first window
|
||||
if (one_nonfloat() && p_ls == 1 && oldwin->w_status_height == 0) {
|
||||
if (oldwin->w_height <= p_wmh && new_in_layout) {
|
||||
emsg(_(e_noroom));
|
||||
return FAIL;
|
||||
return NULL;
|
||||
}
|
||||
need_status = STATUS_HEIGHT;
|
||||
}
|
||||
|
||||
bool do_equal = false;
|
||||
int oldwin_height = 0;
|
||||
const int layout = flags & WSP_VERT ? FR_ROW : FR_COL;
|
||||
const int layout = vertical ? FR_ROW : FR_COL;
|
||||
bool did_set_fraction = false;
|
||||
|
||||
if (flags & WSP_VERT) {
|
||||
if (vertical) {
|
||||
// Check if we are able to split the current window and compute its
|
||||
// width.
|
||||
// Current window requires at least 1 space.
|
||||
@@ -1011,7 +1014,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
}
|
||||
int minwidth;
|
||||
int available;
|
||||
if (flags & (WSP_BOT | WSP_TOP)) {
|
||||
if (toplevel) {
|
||||
minwidth = frame_minwidth(topframe, NOWIN);
|
||||
available = topframe->fr_width;
|
||||
needed += minwidth;
|
||||
@@ -1039,7 +1042,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
}
|
||||
if (available < needed && new_in_layout) {
|
||||
emsg(_(e_noroom));
|
||||
return FAIL;
|
||||
return NULL;
|
||||
}
|
||||
if (new_size == 0) {
|
||||
new_size = oldwin->w_width / 2;
|
||||
@@ -1092,7 +1095,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
}
|
||||
int minheight;
|
||||
int available;
|
||||
if (flags & (WSP_BOT | WSP_TOP)) {
|
||||
if (toplevel) {
|
||||
minheight = frame_minheight(topframe, NOWIN) + need_status;
|
||||
available = topframe->fr_height;
|
||||
needed += minheight;
|
||||
@@ -1119,7 +1122,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
}
|
||||
if (available < needed && new_in_layout) {
|
||||
emsg(_(e_noroom));
|
||||
return FAIL;
|
||||
return NULL;
|
||||
}
|
||||
oldwin_height = oldwin->w_height;
|
||||
if (need_status) {
|
||||
@@ -1182,7 +1185,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
&& ((flags & WSP_BOT)
|
||||
|| (flags & WSP_BELOW)
|
||||
|| (!(flags & WSP_ABOVE)
|
||||
&& ((flags & WSP_VERT) ? p_spr : p_sb)))) {
|
||||
&& (vertical ? p_spr : p_sb)))) {
|
||||
// new window below/right of current one
|
||||
if (new_wp == NULL) {
|
||||
wp = win_alloc(oldwin, false);
|
||||
@@ -1199,7 +1202,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
|
||||
if (new_wp == NULL) {
|
||||
if (wp == NULL) {
|
||||
return FAIL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
new_frame(wp);
|
||||
@@ -1218,9 +1221,9 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
frame_T *curfrp;
|
||||
|
||||
// Reorganise the tree of frames to insert the new window.
|
||||
if (flags & (WSP_TOP | WSP_BOT)) {
|
||||
if ((topframe->fr_layout == FR_COL && (flags & WSP_VERT) == 0)
|
||||
|| (topframe->fr_layout == FR_ROW && (flags & WSP_VERT) != 0)) {
|
||||
if (toplevel) {
|
||||
if ((topframe->fr_layout == FR_COL && !vertical)
|
||||
|| (topframe->fr_layout == FR_ROW && vertical)) {
|
||||
curfrp = topframe->fr_child;
|
||||
if (flags & WSP_BOT) {
|
||||
while (curfrp->fr_next != NULL) {
|
||||
@@ -1237,7 +1240,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
before = false;
|
||||
} else if (flags & WSP_ABOVE) {
|
||||
before = true;
|
||||
} else if (flags & WSP_VERT) {
|
||||
} else if (vertical) {
|
||||
before = !p_spr;
|
||||
} else {
|
||||
before = !p_sb;
|
||||
@@ -1285,14 +1288,14 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
}
|
||||
wp->w_fraction = oldwin->w_fraction;
|
||||
|
||||
if (flags & WSP_VERT) {
|
||||
if (vertical) {
|
||||
wp->w_p_scr = curwin->w_p_scr;
|
||||
|
||||
if (need_status) {
|
||||
win_new_height(oldwin, oldwin->w_height - 1);
|
||||
oldwin->w_status_height = need_status;
|
||||
}
|
||||
if (flags & (WSP_TOP | WSP_BOT)) {
|
||||
if (toplevel) {
|
||||
// set height and row of new window to full height
|
||||
wp->w_winrow = tabline_height();
|
||||
win_new_height(wp, curfrp->fr_height - (p_ls == 1 || p_ls == 2));
|
||||
@@ -1316,7 +1319,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
wp->w_vsep_width = oldwin->w_vsep_width;
|
||||
oldwin->w_vsep_width = 1;
|
||||
}
|
||||
if (flags & (WSP_TOP | WSP_BOT)) {
|
||||
if (toplevel) {
|
||||
if (flags & WSP_BOT) {
|
||||
frame_add_vsep(curfrp);
|
||||
}
|
||||
@@ -1338,7 +1341,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
} else {
|
||||
const bool is_stl_global = global_stl_height() > 0;
|
||||
// width and column of new window is same as current window
|
||||
if (flags & (WSP_TOP | WSP_BOT)) {
|
||||
if (toplevel) {
|
||||
wp->w_wincol = 0;
|
||||
win_new_width(wp, Columns);
|
||||
wp->w_vsep_width = 0;
|
||||
@@ -1359,7 +1362,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
wp->w_hsep_height = oldwin->w_hsep_height;
|
||||
oldwin->w_hsep_height = is_stl_global ? 1 : 0;
|
||||
}
|
||||
if (flags & (WSP_TOP | WSP_BOT)) {
|
||||
if (toplevel) {
|
||||
int new_fr_height = curfrp->fr_height - new_size;
|
||||
if (is_stl_global) {
|
||||
if (flags & WSP_BOT) {
|
||||
@@ -1405,7 +1408,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
frame_fix_height(oldwin);
|
||||
}
|
||||
|
||||
if (flags & (WSP_TOP | WSP_BOT)) {
|
||||
if (toplevel) {
|
||||
win_comp_pos();
|
||||
}
|
||||
|
||||
@@ -1426,7 +1429,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
|
||||
// equalize the window sizes.
|
||||
if (do_equal || dir != 0) {
|
||||
win_equal(wp, true, (flags & WSP_VERT) ? (dir == 'v' ? 'b' : 'h') : (dir == 'h' ? 'b' : 'v'));
|
||||
win_equal(wp, true, vertical ? (dir == 'v' ? 'b' : 'h') : (dir == 'h' ? 'b' : 'v'));
|
||||
} else if (!is_aucmd_win(wp)) {
|
||||
win_fix_scroll(false);
|
||||
}
|
||||
@@ -1447,10 +1450,12 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
}
|
||||
}
|
||||
|
||||
// make the new window the current window
|
||||
win_enter_ext(wp, WEE_TRIGGER_NEW_AUTOCMDS | WEE_TRIGGER_ENTER_AUTOCMDS
|
||||
| WEE_TRIGGER_LEAVE_AUTOCMDS);
|
||||
if (flags & WSP_VERT) {
|
||||
if (!(flags & WSP_NOENTER)) {
|
||||
// make the new window the current window
|
||||
win_enter_ext(wp, WEE_TRIGGER_NEW_AUTOCMDS | WEE_TRIGGER_ENTER_AUTOCMDS
|
||||
| WEE_TRIGGER_LEAVE_AUTOCMDS);
|
||||
}
|
||||
if (vertical) {
|
||||
p_wiw = i;
|
||||
} else {
|
||||
p_wh = i;
|
||||
@@ -1461,7 +1466,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
|
||||
oldwin->w_pos_changed = true;
|
||||
}
|
||||
|
||||
return OK;
|
||||
return wp;
|
||||
}
|
||||
|
||||
// Initialize window "newp" from window "oldp".
|
||||
|
Reference in New Issue
Block a user