aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/window.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:31:31 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:31:31 +0000
commit9243becbedbb6a1592208051f8fa2b090dcc5e7d (patch)
tree607c2a862ec3f4399b8766383f6f8e04c4aa43b4 /src/nvim/window.c
parent9e40b6e9e1bc67f2d856adb837ee64dd0e25b717 (diff)
parent3c48d3c83fc21dbc0841f9210f04bdb073d73cd1 (diff)
downloadrneovim-usermarks.tar.gz
rneovim-usermarks.tar.bz2
rneovim-usermarks.zip
Merge remote-tracking branch 'upstream/master' into usermarksusermarks
Diffstat (limited to 'src/nvim/window.c')
-rw-r--r--src/nvim/window.c2420
1 files changed, 1200 insertions, 1220 deletions
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 68c5b42e30..05f84b5a91 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -2,21 +2,34 @@
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include <assert.h>
+#include <ctype.h>
#include <inttypes.h>
+#include <limits.h>
#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "klib/kvec.h"
+#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
-#include "nvim/api/vim.h"
#include "nvim/arglist.h"
#include "nvim/ascii.h"
+#include "nvim/autocmd.h"
#include "nvim/buffer.h"
+#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/decoration.h"
#include "nvim/diff.h"
#include "nvim/drawscreen.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
+#include "nvim/eval/typval.h"
+#include "nvim/eval/typval_defs.h"
#include "nvim/eval/vars.h"
+#include "nvim/eval/window.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
@@ -27,15 +40,19 @@
#include "nvim/fold.h"
#include "nvim/garray.h"
#include "nvim/getchar.h"
+#include "nvim/gettext.h"
#include "nvim/globals.h"
#include "nvim/grid.h"
#include "nvim/hashtab.h"
-#include "nvim/highlight.h"
+#include "nvim/keycodes.h"
+#include "nvim/macros.h"
#include "nvim/main.h"
-#include "nvim/mapping.h"
+#include "nvim/map.h"
+#include "nvim/mapping.h" // IWYU pragma: keep (langmap_adjust_mb)
#include "nvim/mark.h"
#include "nvim/match.h"
-#include "nvim/memline.h"
+#include "nvim/mbyte.h"
+#include "nvim/memline_defs.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/mouse.h"
@@ -44,16 +61,19 @@
#include "nvim/option.h"
#include "nvim/optionstr.h"
#include "nvim/os/os.h"
-#include "nvim/os_unix.h"
+#include "nvim/os/os_defs.h"
#include "nvim/path.h"
#include "nvim/plines.h"
+#include "nvim/pos.h"
#include "nvim/quickfix.h"
-#include "nvim/regexp.h"
+#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/state.h"
+#include "nvim/statusline.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/terminal.h"
+#include "nvim/types.h"
#include "nvim/ui.h"
#include "nvim/ui_compositor.h"
#include "nvim/undo.h"
@@ -125,15 +145,10 @@ win_T *prevwin_curwin(void)
/// @param xchar extra char from ":wincmd gx" or NUL
void do_window(int nchar, long Prenum, int xchar)
{
- long Prenum1;
- win_T *wp;
- char *ptr;
- linenr_T lnum = -1;
int type = FIND_DEFINE;
- size_t len;
char cbuf[40];
- Prenum1 = Prenum == 0 ? 1 : Prenum;
+ long Prenum1 = Prenum == 0 ? 1 : Prenum;
#define CHECK_CMDWIN \
do { \
@@ -215,7 +230,7 @@ newwindow:
case Ctrl_Q:
case 'q':
reset_VIsual_and_resel(); // stop Visual mode
- cmd_with_count("quit", (char_u *)cbuf, sizeof(cbuf), Prenum);
+ cmd_with_count("quit", cbuf, sizeof(cbuf), Prenum);
do_cmdline_cmd(cbuf);
break;
@@ -223,7 +238,7 @@ newwindow:
case Ctrl_C:
case 'c':
reset_VIsual_and_resel(); // stop Visual mode
- cmd_with_count("close", (char_u *)cbuf, sizeof(cbuf), Prenum);
+ cmd_with_count("close", cbuf, sizeof(cbuf), Prenum);
do_cmdline_cmd(cbuf);
break;
@@ -236,8 +251,8 @@ newwindow:
break;
// cursor to preview window
- case 'P':
- wp = NULL;
+ case 'P': {
+ win_T *wp = NULL;
FOR_ALL_WINDOWS_IN_TAB(wp2, curtab) {
if (wp2->w_p_pvw) {
wp = wp2;
@@ -250,13 +265,14 @@ newwindow:
win_goto(wp);
}
break;
+ }
// close all but current window
case Ctrl_O:
case 'o':
CHECK_CMDWIN;
reset_VIsual_and_resel(); // stop Visual mode
- cmd_with_count("only", (char_u *)cbuf, sizeof(cbuf), Prenum);
+ cmd_with_count("only", cbuf, sizeof(cbuf), Prenum);
do_cmdline_cmd(cbuf);
break;
@@ -269,13 +285,13 @@ newwindow:
if (ONE_WINDOW && Prenum != 1) { // just one window
beep_flush();
} else {
+ win_T *wp;
if (Prenum) { // go to specified window
for (wp = firstwin; --Prenum > 0;) {
if (wp->w_next == NULL) {
break;
- } else {
- wp = wp->w_next;
}
+ wp = wp->w_next;
}
} else {
if (nchar == 'W') { // go to previous window
@@ -346,7 +362,7 @@ newwindow:
// First create a new tab with the window, then go back to
// the old tab and close the window there.
- wp = curwin;
+ win_T *wp = curwin;
if (win_new_tabpage((int)Prenum, NULL) == OK
&& valid_tabpage(oldtab)) {
newtab = curtab;
@@ -417,10 +433,12 @@ newwindow:
| ((nchar == 'H' || nchar == 'K') ? WSP_TOP : WSP_BOT));
break;
- // make all windows the same height
- case '=':
- win_equal(NULL, false, 'b');
+ // make all windows the same width and/or height
+ case '=': {
+ int mod = cmdmod.cmod_split & (WSP_VERT | WSP_HOR);
+ win_equal(NULL, false, mod == WSP_VERT ? 'v' : mod == WSP_HOR ? 'h' : 'b');
break;
+ }
// increase current window height
case '+':
@@ -479,16 +497,18 @@ newwindow:
// Execute the command right here, required when
// "wincmd ]" was used in a function.
do_nv_ident(Ctrl_RSB, NUL);
+ postponed_split = 0;
break;
// edit file name under cursor in a new window
case 'f':
case 'F':
- case Ctrl_F:
+ case Ctrl_F: {
wingotofile:
CHECK_CMDWIN;
- ptr = (char *)grab_file_name(Prenum1, &lnum);
+ linenr_T lnum = -1;
+ char *ptr = grab_file_name(Prenum1, &lnum);
if (ptr != NULL) {
tabpage_T *oldtab = curtab;
win_T *oldwin = curwin;
@@ -508,6 +528,7 @@ wingotofile:
xfree(ptr);
}
break;
+ }
// Go to the first occurrence of the identifier under cursor along path in a
// new window -- webb
@@ -516,8 +537,10 @@ wingotofile:
type = FIND_ANY;
FALLTHROUGH;
case 'd': // Go to definition, using 'define'
- case Ctrl_D:
+ case Ctrl_D: {
CHECK_CMDWIN;
+ size_t len;
+ char *ptr;
if ((len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0) {
break;
}
@@ -525,11 +548,12 @@ wingotofile:
// Make a copy, if the line was changed it will be freed.
ptr = xstrnsave(ptr, len);
- find_pattern_in_path((char_u *)ptr, 0, len, true, Prenum == 0,
+ find_pattern_in_path(ptr, 0, len, true, Prenum == 0,
type, Prenum1, ACTION_SPLIT, 1, MAXLNUM);
xfree(ptr);
curwin->w_set_curswant = true;
break;
+ }
// Quickfix window only: view the result under the cursor in a new split.
case K_KENTER:
@@ -552,6 +576,7 @@ wingotofile:
no_mapping--;
allow_keys--;
(void)add_to_showcmd(xchar);
+
switch (xchar) {
case '}':
xchar = Ctrl_RSB;
@@ -573,6 +598,7 @@ wingotofile:
// Execute the command right here, required when
// "wincmd g}" was used in a function.
do_nv_ident('g', xchar);
+ postponed_split = 0;
break;
case 'f': // CTRL-W gf: "gf" in a new tab page
@@ -580,6 +606,7 @@ wingotofile:
cmdmod.cmod_tab = tabpage_index(curtab) + 1;
nchar = xchar;
goto wingotofile;
+
case 't': // CTRL-W gt: go to next tab page
goto_tabpage((int)Prenum);
break;
@@ -622,12 +649,12 @@ wingotofile:
}
}
-static void cmd_with_count(char *cmd, char_u *bufp, size_t bufsize, int64_t Prenum)
+static void cmd_with_count(char *cmd, char *bufp, size_t bufsize, int64_t Prenum)
{
- size_t len = STRLCPY(bufp, cmd, bufsize);
+ size_t len = xstrlcpy(bufp, cmd, bufsize);
if (Prenum > 0 && len < bufsize) {
- vim_snprintf((char *)bufp + len, bufsize - len, "%" PRId64, Prenum);
+ vim_snprintf(bufp + len, bufsize - len, "%" PRId64, Prenum);
}
}
@@ -635,11 +662,13 @@ void win_set_buf(Window window, Buffer buffer, bool noautocmd, Error *err)
{
win_T *win = find_window_by_handle(window, err);
buf_T *buf = find_buffer_by_handle(buffer, err);
- tabpage_T *tab = win_find_tabpage(win);
if (!win || !buf) {
return;
}
+
+ tabpage_T *tab = win_find_tabpage(win);
+
if (noautocmd) {
block_autocmds();
}
@@ -712,7 +741,7 @@ win_T *win_new_float(win_T *wp, bool last, FloatConfig fconfig, Error *err)
win_config_float(wp, fconfig);
win_set_inner_size(wp, true);
wp->w_pos_changed = true;
- redraw_later(wp, VALID);
+ redraw_later(wp, UPD_VALID);
return wp;
}
@@ -727,38 +756,44 @@ void win_set_minimal_style(win_T *wp)
// Hide EOB region: use " " fillchar and cleared highlighting
if (wp->w_p_fcs_chars.eob != ' ') {
- char_u *old = wp->w_p_fcs;
+ char *old = wp->w_p_fcs;
wp->w_p_fcs = ((*old == NUL)
- ? (char_u *)xstrdup("eob: ")
- : concat_str(old, (char_u *)",eob: "));
+ ? xstrdup("eob: ")
+ : concat_str(old, ",eob: "));
free_string_option(old);
}
// TODO(bfredl): this could use a highlight namespace directly,
- // and avoid pecularities around window options
- char_u *old = wp->w_p_winhl;
+ // and avoid peculiarities around window options
+ char *old = wp->w_p_winhl;
wp->w_p_winhl = ((*old == NUL)
- ? (char_u *)xstrdup("EndOfBuffer:")
- : concat_str(old, (char_u *)",EndOfBuffer:"));
+ ? xstrdup("EndOfBuffer:")
+ : concat_str(old, ",EndOfBuffer:"));
free_string_option(old);
parse_winhl_opt(wp);
// signcolumn: use 'auto'
- if (wp->w_p_scl[0] != 'a' || STRLEN(wp->w_p_scl) >= 8) {
+ if (wp->w_p_scl[0] != 'a' || strlen(wp->w_p_scl) >= 8) {
free_string_option(wp->w_p_scl);
- wp->w_p_scl = (char_u *)xstrdup("auto");
+ wp->w_p_scl = xstrdup("auto");
}
// foldcolumn: use '0'
if (wp->w_p_fdc[0] != '0') {
free_string_option(wp->w_p_fdc);
- wp->w_p_fdc = (char_u *)xstrdup("0");
+ wp->w_p_fdc = xstrdup("0");
}
// colorcolumn: cleared
if (wp->w_p_cc != NULL && *wp->w_p_cc != NUL) {
free_string_option(wp->w_p_cc);
- wp->w_p_cc = (char_u *)xstrdup("");
+ wp->w_p_cc = xstrdup("");
+ }
+
+ // statuscolumn: cleared
+ if (wp->w_p_stc != NULL && *wp->w_p_stc != NUL) {
+ free_string_option(wp->w_p_stc);
+ wp->w_p_stc = xstrdup("");
}
}
@@ -772,13 +807,22 @@ void win_config_float(win_T *wp, FloatConfig fconfig)
fconfig.row += curwin->w_wrow;
fconfig.col += curwin->w_wcol;
fconfig.window = curwin->handle;
+ } else if (fconfig.relative == kFloatRelativeMouse) {
+ int row = mouse_row, col = mouse_col, grid = mouse_grid;
+ win_T *mouse_win = mouse_find_win(&grid, &row, &col);
+ if (mouse_win != NULL) {
+ fconfig.relative = kFloatRelativeWindow;
+ fconfig.row += row;
+ fconfig.col += col;
+ fconfig.window = mouse_win->handle;
+ }
}
bool change_external = fconfig.external != wp->w_float_config.external;
bool change_border = (fconfig.border != wp->w_float_config.border
|| memcmp(fconfig.border_hl_ids,
wp->w_float_config.border_hl_ids,
- sizeof fconfig.border_hl_ids));
+ sizeof fconfig.border_hl_ids) != 0);
wp->w_float_config = fconfig;
@@ -797,12 +841,12 @@ void win_config_float(win_T *wp, FloatConfig fconfig)
}
win_set_inner_size(wp, true);
- must_redraw = MAX(must_redraw, VALID);
+ must_redraw = MAX(must_redraw, UPD_VALID);
wp->w_pos_changed = true;
if (change_external || change_border) {
wp->w_hl_needs_update = true;
- redraw_later(wp, NOT_VALID);
+ redraw_later(wp, UPD_NOT_VALID);
}
// compute initial position
@@ -819,16 +863,16 @@ void win_config_float(win_T *wp, FloatConfig fconfig)
grid_adjust(&grid, &row_off, &col_off);
row += row_off;
col += col_off;
+ if (wp->w_float_config.bufpos.lnum >= 0) {
+ pos_T pos = { wp->w_float_config.bufpos.lnum + 1,
+ wp->w_float_config.bufpos.col, 0 };
+ int trow, tcol, tcolc, tcole;
+ textpos2screenpos(parent, &pos, &trow, &tcol, &tcolc, &tcole, true);
+ row += trow - 1;
+ col += tcol - 1;
+ }
}
api_clear_error(&dummy);
- if (wp->w_float_config.bufpos.lnum >= 0) {
- pos_T pos = { wp->w_float_config.bufpos.lnum + 1,
- wp->w_float_config.bufpos.col, 0 };
- int trow, tcol, tcolc, tcole;
- textpos2screenpos(wp, &pos, &trow, &tcol, &tcolc, &tcole, true);
- row += trow - 1;
- col += tcol - 1;
- }
wp->w_winrow = row;
wp->w_wincol = col;
} else {
@@ -839,7 +883,7 @@ void win_config_float(win_T *wp, FloatConfig fconfig)
// changing border style while keeping border only requires redrawing border
if (fconfig.border) {
wp->w_redr_border = true;
- redraw_later(wp, VALID);
+ redraw_later(wp, UPD_VALID);
}
}
@@ -864,13 +908,13 @@ int win_fdccol_count(win_T *wp)
const int fdccol = fdc[4] == ':' ? fdc[5] - '0' : 1;
int needed_fdccols = getDeepestNesting(wp);
return MIN(fdccol, needed_fdccols);
- } else {
- return fdc[0] - '0';
}
+ return fdc[0] - '0';
}
-void ui_ext_win_position(win_T *wp)
+void ui_ext_win_position(win_T *wp, bool validate)
{
+ wp->w_pos_changed = false;
if (!wp->w_floating) {
ui_call_win_pos(wp->w_grid_alloc.handle, wp->handle, wp->w_winrow,
wp->w_wincol, wp->w_width, wp->w_height);
@@ -908,6 +952,11 @@ void ui_ext_win_position(win_T *wp)
grid->handle, row, col, c.focusable,
wp->w_grid_alloc.zindex);
} else {
+ bool valid = (wp->w_redr_type == 0);
+ if (!valid && !validate) {
+ wp->w_pos_changed = true;
+ return;
+ }
// TODO(bfredl): ideally, compositor should work like any multigrid UI
// and use standard win_pos events.
bool east = c.anchor & kFloatAnchorEast;
@@ -921,14 +970,13 @@ void ui_ext_win_position(win_T *wp)
comp_col = MAX(MIN(comp_col, Columns - wp->w_width_outer), 0);
wp->w_winrow = comp_row;
wp->w_wincol = comp_col;
- bool valid = (wp->w_redr_type == 0);
ui_comp_put_grid(&wp->w_grid_alloc, comp_row, comp_col,
wp->w_height_outer, wp->w_width_outer, valid, false);
ui_check_cursor_grid(wp->w_grid_alloc.handle);
wp->w_grid_alloc.focusable = wp->w_float_config.focusable;
if (!valid) {
wp->w_grid_alloc.valid = false;
- redraw_later(wp, NOT_VALID);
+ redraw_later(wp, UPD_NOT_VALID);
}
}
} else {
@@ -968,21 +1016,19 @@ static int check_split_disallowed(void)
return OK;
}
-/*
- * split the current window, implements CTRL-W s and :split
- *
- * "size" is the height or width for the new window, 0 to use half of current
- * height or width.
- *
- * "flags":
- * WSP_ROOM: require enough room for new window
- * WSP_VERT: vertical split.
- * 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
- *
- * return FAIL for failure, OK otherwise
- */
+// split the current window, implements CTRL-W s and :split
+//
+// "size" is the height or width for the new window, 0 to use half of current
+// height or width.
+//
+// "flags":
+// WSP_ROOM: require enough room for new window
+// WSP_VERT: vertical split.
+// 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
+//
+// return FAIL for failure, OK otherwise
int win_split(int size, int flags)
{
if (check_split_disallowed() == FAIL) {
@@ -1012,35 +1058,20 @@ int win_split(int size, int flags)
return win_split_ins(size, flags, NULL, 0);
}
-/*
- * 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
- */
+// 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)
{
win_T *wp = new_wp;
- win_T *oldwin;
- int new_size = size;
- int i;
- int need_status = 0;
- bool do_equal = false;
- int needed;
- int available;
- int oldwin_height = 0;
- int layout;
- frame_T *frp, *curfrp, *frp2, *prevfrp;
- int before;
- int minheight;
- int wmh1;
- bool did_set_fraction = false;
- // aucmd_win should always remain floating
- if (new_wp != NULL && new_wp == aucmd_win) {
+ // aucmd_win[] should always remain floating
+ if (new_wp != NULL && is_aucmd_win(new_wp)) {
return FAIL;
}
+ win_T *oldwin;
if (flags & WSP_TOP) {
oldwin = firstwin;
} else if (flags & WSP_BOT || curwin->w_floating) {
@@ -1050,6 +1081,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
oldwin = curwin;
}
+ int need_status = 0;
+ int new_size = size;
bool new_in_layout = (new_wp == NULL || new_wp->w_floating);
// add a status line when p_ls == 1 and splitting the first window
@@ -1061,32 +1094,33 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
need_status = STATUS_HEIGHT;
}
- if (flags & WSP_VERT) {
- int wmw1;
- int minwidth;
-
- layout = FR_ROW;
+ bool do_equal = false;
+ int oldwin_height = 0;
+ const int layout = flags & WSP_VERT ? FR_ROW : FR_COL;
+ bool did_set_fraction = false;
- /*
- * Check if we are able to split the current window and compute its
- * width.
- */
+ if (flags & WSP_VERT) {
+ // Check if we are able to split the current window and compute its
+ // width.
// Current window requires at least 1 space.
- wmw1 = (p_wmw == 0 ? 1 : (int)p_wmw);
- needed = wmw1 + 1;
+ int wmw1 = (p_wmw == 0 ? 1 : (int)p_wmw);
+ int needed = wmw1 + 1;
if (flags & WSP_ROOM) {
needed += (int)p_wiw - wmw1;
}
+ int minwidth;
+ int available;
if (flags & (WSP_BOT | WSP_TOP)) {
minwidth = frame_minwidth(topframe, NOWIN);
available = topframe->fr_width;
needed += minwidth;
} else if (p_ea) {
minwidth = frame_minwidth(oldwin->w_frame, NOWIN);
- prevfrp = oldwin->w_frame;
- for (frp = oldwin->w_frame->fr_parent; frp != NULL;
+ frame_T *prevfrp = oldwin->w_frame;
+ for (frame_T *frp = oldwin->w_frame->fr_parent; frp != NULL;
frp = frp->fr_parent) {
if (frp->fr_layout == FR_ROW) {
+ frame_T *frp2;
FOR_ALL_FRAMES(frp2, frp->fr_child) {
if (frp2 != prevfrp) {
minwidth += frame_minwidth(frp2, NOWIN);
@@ -1132,7 +1166,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
// is wider than one of the split windows.
if (!do_equal && p_ea && size == 0 && *p_ead != 'v'
&& oldwin->w_frame->fr_parent != NULL) {
- frp = oldwin->w_frame->fr_parent->fr_child;
+ frame_T *frp = oldwin->w_frame->fr_parent->fr_child;
while (frp != NULL) {
if (frp->fr_win != oldwin && frp->fr_win != NULL
&& (frp->fr_win->w_width > new_size
@@ -1145,27 +1179,28 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
}
}
} else {
- layout = FR_COL;
-
// Check if we are able to split the current window and compute its height.
// Current window requires at least 1 space plus space for the window bar.
- wmh1 = MAX((int)p_wmh, 1) + oldwin->w_winbar_height;
- needed = wmh1 + STATUS_HEIGHT;
+ int wmh1 = MAX((int)p_wmh, 1) + oldwin->w_winbar_height;
+ int needed = wmh1 + STATUS_HEIGHT;
if (flags & WSP_ROOM) {
needed += (int)p_wh - wmh1 + oldwin->w_winbar_height;
}
if (p_ch < 1) {
needed += 1; // Adjust for cmdheight=0.
}
+ int minheight;
+ int available;
if (flags & (WSP_BOT | WSP_TOP)) {
minheight = frame_minheight(topframe, NOWIN) + need_status;
available = topframe->fr_height;
needed += minheight;
} else if (p_ea) {
minheight = frame_minheight(oldwin->w_frame, NOWIN) + need_status;
- prevfrp = oldwin->w_frame;
- for (frp = oldwin->w_frame->fr_parent; frp != NULL; frp = frp->fr_parent) {
+ frame_T *prevfrp = oldwin->w_frame;
+ for (frame_T *frp = oldwin->w_frame->fr_parent; frp != NULL; frp = frp->fr_parent) {
if (frp->fr_layout == FR_COL) {
+ frame_T *frp2;
FOR_ALL_FRAMES(frp2, frp->fr_child) {
if (frp2 != prevfrp) {
minheight += frame_minheight(frp2, NOWIN);
@@ -1228,7 +1263,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
if (!do_equal && p_ea && size == 0
&& *p_ead != 'h'
&& oldwin->w_frame->fr_parent != NULL) {
- frp = oldwin->w_frame->fr_parent->fr_child;
+ frame_T *frp = oldwin->w_frame->fr_parent->fr_child;
while (frp != NULL) {
if (frp->fr_win != oldwin && frp->fr_win != NULL
&& (frp->fr_win->w_height > new_size
@@ -1241,9 +1276,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
}
}
- /*
- * allocate new window structure and link it in the window list
- */
+ // allocate new window structure and link it in the window list
if ((flags & WSP_TOP) == 0
&& ((flags & WSP_BOT)
|| (flags & WSP_BELOW)
@@ -1280,9 +1313,10 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
CLEAR_FIELD(wp->w_border_adj);
}
- /*
- * Reorganise the tree of frames to insert the new window.
- */
+ int before;
+ 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)) {
@@ -1299,9 +1333,9 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
} else {
curfrp = oldwin->w_frame;
if (flags & WSP_BELOW) {
- before = FALSE;
+ before = false;
} else if (flags & WSP_ABOVE) {
- before = TRUE;
+ before = true;
} else if (flags & WSP_VERT) {
before = !p_spr;
} else {
@@ -1310,7 +1344,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
}
if (curfrp->fr_parent == NULL || curfrp->fr_parent->fr_layout != layout) {
// Need to create a new frame in the tree to make a branch.
- frp = xcalloc(1, sizeof(frame_T));
+ frame_T *frp = xcalloc(1, sizeof(frame_T));
*frp = *curfrp;
curfrp->fr_layout = (char)layout;
frp->fr_parent = curfrp;
@@ -1328,6 +1362,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
}
}
+ frame_T *frp;
if (new_wp == NULL) {
frp = wp->w_frame;
} else {
@@ -1474,8 +1509,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
// Both windows need redrawing. Update all status lines, in case they
// show something related to the window count or position.
- redraw_later(wp, NOT_VALID);
- redraw_later(oldwin, NOT_VALID);
+ redraw_later(wp, UPD_NOT_VALID);
+ redraw_later(oldwin, UPD_NOT_VALID);
status_redraw_all();
if (need_status) {
@@ -1487,13 +1522,15 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
msg_col = 0; // put position back at start of line
}
- /*
- * equalize the window sizes.
- */
+ // equalize the window sizes.
if (do_equal || dir != 0) {
win_equal(wp, true, (flags & WSP_VERT) ? (dir == 'v' ? 'b' : 'h') : (dir == 'h' ? 'b' : 'v'));
+ } else if (*p_spk != 'c' && !is_aucmd_win(wp)) {
+ win_fix_scroll(false);
}
+ int i;
+
// Don't change the window height/width to 'winheight' / 'winwidth' if a
// size was given.
if (flags & WSP_VERT) {
@@ -1525,17 +1562,13 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
return OK;
}
-/*
- * Initialize window "newp" from window "oldp".
- * Used when splitting a window and when creating a new tab page.
- * The windows will both edit the same buffer.
- * WSP_NEWLOC may be specified in flags to prevent the location list from
- * being copied.
- */
+// Initialize window "newp" from window "oldp".
+// Used when splitting a window and when creating a new tab page.
+// The windows will both edit the same buffer.
+// WSP_NEWLOC may be specified in flags to prevent the location list from
+// being copied.
static void win_init(win_T *newp, win_T *oldp, int flags)
{
- int i;
-
newp->w_buffer = oldp->w_buffer;
newp->w_s = &(oldp->w_buffer->b_s);
oldp->w_buffer->b_nwindows++;
@@ -1565,15 +1598,21 @@ static void win_init(win_T *newp, win_T *oldp, int flags)
newp->w_prevdir = (oldp->w_prevdir == NULL)
? NULL : xstrdup(oldp->w_prevdir);
+ if (*p_spk != 'c') {
+ newp->w_botline = oldp->w_botline;
+ newp->w_prev_height = oldp->w_height;
+ newp->w_prev_winrow = oldp->w_winrow;
+ }
+
// copy tagstack and folds
- for (i = 0; i < oldp->w_tagstacklen; i++) {
+ for (int i = 0; i < oldp->w_tagstacklen; i++) {
taggy_T *tag = &newp->w_tagstack[i];
*tag = oldp->w_tagstack[i];
if (tag->tagname != NULL) {
- tag->tagname = vim_strsave(tag->tagname);
+ tag->tagname = xstrdup(tag->tagname);
}
if (tag->user_data != NULL) {
- tag->user_data = vim_strsave(tag->user_data);
+ tag->user_data = xstrdup(tag->user_data);
}
}
newp->w_tagstackidx = oldp->w_tagstackidx;
@@ -1589,15 +1628,13 @@ static void win_init(win_T *newp, win_T *oldp, int flags)
newp->w_winbar_height = oldp->w_winbar_height;
}
-/*
- * Initialize window "newp" from window "old".
- * Only the essential things are copied.
- */
+// Initialize window "newp" from window "old".
+// Only the essential things are copied.
static void win_init_some(win_T *newp, win_T *oldp)
{
// Use the same argument list.
newp->w_alist = oldp->w_alist;
- ++newp->w_alist->al_refcount;
+ newp->w_alist->al_refcount++;
newp->w_arg_idx = oldp->w_arg_idx;
// copy options from existing window
@@ -1627,11 +1664,20 @@ bool win_valid_floating(const win_T *win)
/// @param win window to check
bool win_valid(const win_T *win) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
+ return tabpage_win_valid(curtab, win);
+}
+
+/// Check if "win" is a pointer to an existing window in tabpage "tp".
+///
+/// @param win window to check
+static bool tabpage_win_valid(const tabpage_T *tp, const win_T *win)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
if (win == NULL) {
return false;
}
- FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
if (wp == win) {
return true;
}
@@ -1669,9 +1715,7 @@ bool win_valid_any_tab(win_T *win) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
return false;
}
-/*
- * Return the number of windows.
- */
+// Return the number of windows.
int win_count(void)
{
int count = 0;
@@ -1692,7 +1736,6 @@ int win_count(void)
int make_windows(int count, bool vertical)
{
int maxcount;
- int todo;
if (vertical) {
// Each window needs at least 'winminwidth' lines and a separator column.
@@ -1722,8 +1765,10 @@ int make_windows(int count, bool vertical)
// when putting the buffers in the windows.
block_autocmds();
+ int todo;
+
// todo is number of windows left to create
- for (todo = count - 1; todo > 0; --todo) {
+ for (todo = count - 1; todo > 0; todo--) {
if (vertical) {
if (win_split(curwin->w_width - (curwin->w_width - todo)
/ (todo + 1) - 1, WSP_VERT | WSP_ABOVE) == FAIL) {
@@ -1744,17 +1789,9 @@ int make_windows(int count, bool vertical)
return count - todo;
}
-/*
- * Exchange current and next window
- */
+// Exchange current and next window
static void win_exchange(long Prenum)
{
- frame_T *frp;
- frame_T *frp2;
- win_T *wp;
- win_T *wp2;
- int temp;
-
if (curwin->w_floating) {
emsg(e_floatexchange);
return;
@@ -1766,9 +1803,9 @@ static void win_exchange(long Prenum)
return;
}
- /*
- * find window to exchange with
- */
+ frame_T *frp;
+
+ // find window to exchange with
if (Prenum) {
frp = curwin->w_frame->fr_parent->fr_child;
while (frp != NULL && --Prenum > 0) {
@@ -1785,18 +1822,16 @@ static void win_exchange(long Prenum)
if (frp == NULL || frp->fr_win == NULL || frp->fr_win == curwin) {
return;
}
- wp = frp->fr_win;
-
- /*
- * 1. remove curwin from the list. Remember after which window it was in wp2
- * 2. insert curwin before wp in the list
- * if wp != wp2
- * 3. remove wp from the list
- * 4. insert wp after wp2
- * 5. exchange the status line height, winbar height, hsep height and vsep width.
- */
- wp2 = curwin->w_prev;
- frp2 = curwin->w_frame->fr_prev;
+ win_T *wp = frp->fr_win;
+
+ // 1. remove curwin from the list. Remember after which window it was in wp2
+ // 2. insert curwin before wp in the list
+ // if wp != wp2
+ // 3. remove wp from the list
+ // 4. insert wp after wp2
+ // 5. exchange the status line height, winbar height, hsep height and vsep width.
+ win_T *wp2 = curwin->w_prev;
+ frame_T *frp2 = curwin->w_frame->fr_prev;
if (wp->w_prev != curwin) {
win_remove(curwin, NULL);
frame_remove(curwin->w_frame);
@@ -1813,7 +1848,7 @@ static void win_exchange(long Prenum)
frame_append(frp2, wp->w_frame);
}
}
- temp = curwin->w_status_height;
+ int temp = curwin->w_status_height;
curwin->w_status_height = wp->w_status_height;
wp->w_status_height = temp;
temp = curwin->w_vsep_width;
@@ -1837,19 +1872,14 @@ static void win_exchange(long Prenum)
}
win_enter(wp, true);
- redraw_later(curwin, NOT_VALID);
- redraw_later(wp, NOT_VALID);
+ redraw_later(curwin, UPD_NOT_VALID);
+ redraw_later(wp, UPD_NOT_VALID);
}
// rotate windows: if upwards true the second window becomes the first one
// if upwards false the first window becomes the second one
static void win_rotate(bool upwards, int count)
{
- win_T *wp1;
- win_T *wp2;
- frame_T *frp;
- int n;
-
if (curwin->w_floating) {
emsg(e_floatexchange);
return;
@@ -1862,6 +1892,7 @@ static void win_rotate(bool upwards, int count)
}
// Check if all frames in this row/col have one window.
+ frame_T *frp;
FOR_ALL_FRAMES(frp, curwin->w_frame->fr_parent->fr_child) {
if (frp->fr_win == NULL) {
emsg(_("E443: Cannot rotate when another window is split"));
@@ -1869,6 +1900,9 @@ static void win_rotate(bool upwards, int count)
}
}
+ win_T *wp1;
+ win_T *wp2;
+
while (count--) {
if (upwards) { // first window becomes last window
// remove first window/frame from the list
@@ -1901,7 +1935,7 @@ static void win_rotate(bool upwards, int count)
}
// exchange status height, winbar height, hsep height and vsep width of old and new last window
- n = wp2->w_status_height;
+ int n = wp2->w_status_height;
wp2->w_status_height = wp1->w_status_height;
wp1->w_status_height = n;
n = wp2->w_hsep_height;
@@ -1922,12 +1956,10 @@ static void win_rotate(bool upwards, int count)
wp1->w_pos_changed = true;
wp2->w_pos_changed = true;
- redraw_all_later(NOT_VALID);
+ redraw_all_later(UPD_NOT_VALID);
}
-/*
- * Move the current window to the very top/bottom/left/right of the screen.
- */
+// Move the current window to the very top/bottom/left/right of the screen.
static void win_totop(int size, int flags)
{
int dir = 0;
@@ -1937,7 +1969,7 @@ static void win_totop(int size, int flags)
beep_flush();
return;
}
- if (curwin == aucmd_win) {
+ if (is_aucmd_win(curwin)) {
return;
}
if (check_split_disallowed() == FAIL) {
@@ -1971,14 +2003,10 @@ static void win_totop(int size, int flags)
}
}
-/*
- * Move window "win1" to below/right of "win2" and make "win1" the current
- * window. Only works within the same frame!
- */
+// Move window "win1" to below/right of "win2" and make "win1" the current
+// window. Only works within the same frame!
void win_move_after(win_T *win1, win_T *win2)
{
- int height;
-
// check if the arguments are reasonable
if (win1 == win2) {
return;
@@ -1994,7 +2022,7 @@ void win_move_after(win_T *win1, win_T *win2)
// may need to move the status line, window bar, horizontal or vertical separator of the last
// window
if (win1 == lastwin) {
- height = win1->w_prev->w_status_height;
+ int height = win1->w_prev->w_status_height;
win1->w_prev->w_status_height = win1->w_status_height;
win1->w_status_height = height;
@@ -2011,7 +2039,7 @@ void win_move_after(win_T *win1, win_T *win2)
win1->w_frame->fr_width += 1;
}
} else if (win2 == lastwin) {
- height = win1->w_status_height;
+ int height = win1->w_status_height;
win1->w_status_height = win2->w_status_height;
win2-&