aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/window.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-11-29 21:52:58 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-11-29 21:52:58 +0000
commit931bffbda3668ddc609fc1da8f9eb576b170aa52 (patch)
treed8c1843a95da5ea0bb4acc09f7e37843d9995c86 /src/nvim/window.c
parent142d9041391780ac15b89886a54015fdc5c73995 (diff)
parent4a8bf24ac690004aedf5540fa440e788459e5e34 (diff)
downloadrneovim-userreg.tar.gz
rneovim-userreg.tar.bz2
rneovim-userreg.zip
Merge remote-tracking branch 'upstream/master' into userreguserreg
Diffstat (limited to 'src/nvim/window.c')
-rw-r--r--src/nvim/window.c859
1 files changed, 386 insertions, 473 deletions
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 05f84b5a91..bcf245ef93 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -1,12 +1,8 @@
-// This is an open source non-commercial project. Dear PVS-Studio, please check
-// 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>
@@ -15,7 +11,7 @@
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
#include "nvim/arglist.h"
-#include "nvim/ascii.h"
+#include "nvim/ascii_defs.h"
#include "nvim/autocmd.h"
#include "nvim/buffer.h"
#include "nvim/buffer_defs.h"
@@ -27,7 +23,6 @@
#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"
@@ -38,6 +33,7 @@
#include "nvim/file_search.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
+#include "nvim/func_attr.h"
#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/gettext.h"
@@ -45,40 +41,39 @@
#include "nvim/grid.h"
#include "nvim/hashtab.h"
#include "nvim/keycodes.h"
-#include "nvim/macros.h"
+#include "nvim/macros_defs.h"
#include "nvim/main.h"
-#include "nvim/map.h"
+#include "nvim/map_defs.h"
#include "nvim/mapping.h" // IWYU pragma: keep (langmap_adjust_mb)
#include "nvim/mark.h"
#include "nvim/match.h"
#include "nvim/mbyte.h"
-#include "nvim/memline_defs.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/mouse.h"
#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/option.h"
-#include "nvim/optionstr.h"
-#include "nvim/os/os.h"
-#include "nvim/os/os_defs.h"
+#include "nvim/option_defs.h"
+#include "nvim/option_vars.h"
+#include "nvim/os/fs.h"
#include "nvim/path.h"
#include "nvim/plines.h"
-#include "nvim/pos.h"
+#include "nvim/pos_defs.h"
#include "nvim/quickfix.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/types_defs.h"
#include "nvim/ui.h"
#include "nvim/ui_compositor.h"
#include "nvim/undo.h"
-#include "nvim/vim.h"
+#include "nvim/vim_defs.h"
#include "nvim/window.h"
+#include "nvim/winfloat.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "window.c.generated.h"
@@ -97,7 +92,7 @@ typedef enum {
WEE_TRIGGER_LEAVE_AUTOCMDS = 0x10,
} wee_flags_T;
-static char e_cannot_split_window_when_closing_buffer[]
+static const char e_cannot_split_window_when_closing_buffer[]
= N_("E1159: Cannot split a window when closing the buffer");
static char *m_onlyone = N_("Already only one window");
@@ -140,15 +135,41 @@ win_T *prevwin_curwin(void)
return is_in_cmdwin() && prevwin != NULL ? prevwin : curwin;
}
+/// If the 'switchbuf' option contains "useopen" or "usetab", then try to jump
+/// to a window containing "buf".
+/// Returns the pointer to the window that was jumped to or NULL.
+win_T *swbuf_goto_win_with_buf(buf_T *buf)
+{
+ win_T *wp = NULL;
+
+ if (buf == NULL) {
+ return wp;
+ }
+
+ // If 'switchbuf' contains "useopen": jump to first window in the current
+ // tab page containing "buf" if one exists.
+ if (swb_flags & SWB_USEOPEN) {
+ wp = buf_jump_open_win(buf);
+ }
+
+ // If 'switchbuf' contains "usetab": jump to first window in any tab page
+ // containing "buf" if one exists.
+ if (wp == NULL && (swb_flags & SWB_USETAB)) {
+ wp = buf_jump_open_tab(buf);
+ }
+
+ return wp;
+}
+
/// all CTRL-W window commands are handled here, called from normal_cmd().
///
/// @param xchar extra char from ":wincmd gx" or NUL
-void do_window(int nchar, long Prenum, int xchar)
+void do_window(int nchar, int Prenum, int xchar)
{
int type = FIND_DEFINE;
char cbuf[40];
- long Prenum1 = Prenum == 0 ? 1 : Prenum;
+ int Prenum1 = Prenum == 0 ? 1 : Prenum;
#define CHECK_CMDWIN \
do { \
@@ -170,7 +191,7 @@ void do_window(int nchar, long Prenum, int xchar)
if (bt_quickfix(curbuf)) {
goto newwindow;
}
- (void)win_split((int)Prenum, 0);
+ (void)win_split(Prenum, 0);
break;
// split current window in two parts, vertically
@@ -183,7 +204,7 @@ void do_window(int nchar, long Prenum, int xchar)
if (bt_quickfix(curbuf)) {
goto newwindow;
}
- (void)win_split((int)Prenum, WSP_VERT);
+ (void)win_split(Prenum, WSP_VERT);
break;
// split current window and edit alternate file
@@ -192,7 +213,7 @@ void do_window(int nchar, long Prenum, int xchar)
CHECK_CMDWIN;
reset_VIsual_and_resel(); // stop Visual mode
- if (buflist_findnr(Prenum == 0 ? curwin->w_alt_fnum : (int)Prenum) == NULL) {
+ if (buflist_findnr(Prenum == 0 ? curwin->w_alt_fnum : Prenum) == NULL) {
if (Prenum == 0) {
emsg(_(e_noalt));
} else {
@@ -202,8 +223,8 @@ void do_window(int nchar, long Prenum, int xchar)
}
if (!curbuf_locked() && win_split(0, 0) == OK) {
- (void)buflist_getfile(Prenum == 0 ? curwin->w_alt_fnum : (int)Prenum,
- (linenr_T)0, GETF_ALT, false);
+ (void)buflist_getfile(Prenum == 0 ? curwin->w_alt_fnum : Prenum,
+ 0, GETF_ALT, false);
}
break;
@@ -355,17 +376,16 @@ newwindow:
case 'T':
CHECK_CMDWIN;
if (one_window(curwin)) {
- msg(_(m_onlyone));
+ msg(_(m_onlyone), 0);
} else {
tabpage_T *oldtab = curtab;
- tabpage_T *newtab;
// First create a new tab with the window, then go back to
// the old tab and close the window there.
win_T *wp = curwin;
- if (win_new_tabpage((int)Prenum, NULL) == OK
+ if (win_new_tabpage(Prenum, NULL) == OK
&& valid_tabpage(oldtab)) {
- newtab = curtab;
+ tabpage_T *newtab = curtab;
goto_tabpage_tp(oldtab, true, true);
if (curwin == wp) {
win_close(curwin, false, false);
@@ -412,14 +432,14 @@ newwindow:
case 'r':
CHECK_CMDWIN;
reset_VIsual_and_resel(); // stop Visual mode
- win_rotate(false, (int)Prenum1); // downwards
+ win_rotate(false, Prenum1); // downwards
break;
// rotate windows upwards
case 'R':
CHECK_CMDWIN;
reset_VIsual_and_resel(); // stop Visual mode
- win_rotate(true, (int)Prenum1); // upwards
+ win_rotate(true, Prenum1); // upwards
break;
// move window to the very top/bottom/left/right
@@ -428,7 +448,7 @@ newwindow:
case 'H':
case 'L':
CHECK_CMDWIN;
- win_totop((int)Prenum,
+ win_totop(Prenum,
((nchar == 'H' || nchar == 'L') ? WSP_VERT : 0)
| ((nchar == 'H' || nchar == 'K') ? WSP_TOP : WSP_BOT));
break;
@@ -442,40 +462,40 @@ newwindow:
// increase current window height
case '+':
- win_setheight(curwin->w_height + (int)Prenum1);
+ win_setheight(curwin->w_height + Prenum1);
break;
// decrease current window height
case '-':
- win_setheight(curwin->w_height - (int)Prenum1);
+ win_setheight(curwin->w_height - Prenum1);
break;
// set current window height
case Ctrl__:
case '_':
- win_setheight(Prenum ? (int)Prenum : Rows - 1);
+ win_setheight(Prenum ? Prenum : Rows - 1);
break;
// increase current window width
case '>':
- win_setwidth(curwin->w_width + (int)Prenum1);
+ win_setwidth(curwin->w_width + Prenum1);
break;
// decrease current window width
case '<':
- win_setwidth(curwin->w_width - (int)Prenum1);
+ win_setwidth(curwin->w_width - Prenum1);
break;
// set current window width
case '|':
- win_setwidth(Prenum != 0 ? (int)Prenum : Columns);
+ win_setwidth(Prenum != 0 ? Prenum : Columns);
break;
// jump to tag and split window if tag exists (in preview window)
case '}':
CHECK_CMDWIN;
if (Prenum) {
- g_do_tagpreview = (int)Prenum;
+ g_do_tagpreview = Prenum;
} else {
g_do_tagpreview = (int)p_pvh;
}
@@ -485,7 +505,7 @@ newwindow:
CHECK_CMDWIN;
// Keep visual mode, can select words to use as a tag.
if (Prenum) {
- postponed_split = (int)Prenum;
+ postponed_split = Prenum;
} else {
postponed_split = -1;
}
@@ -506,6 +526,9 @@ newwindow:
case Ctrl_F: {
wingotofile:
CHECK_CMDWIN;
+ if (check_text_or_curbuf_locked(NULL)) {
+ break;
+ }
linenr_T lnum = -1;
char *ptr = grab_file_name(Prenum1, &lnum);
@@ -513,18 +536,31 @@ wingotofile:
tabpage_T *oldtab = curtab;
win_T *oldwin = curwin;
setpcmark();
- if (win_split(0, 0) == OK) {
+
+ // If 'switchbuf' is set to 'useopen' or 'usetab' and the
+ // file is already opened in a window, then jump to it.
+ win_T *wp = NULL;
+ if ((swb_flags & (SWB_USEOPEN | SWB_USETAB))
+ && cmdmod.cmod_tab == 0) {
+ wp = swbuf_goto_win_with_buf(buflist_findname_exp(ptr));
+ }
+
+ if (wp == NULL && win_split(0, 0) == OK) {
RESET_BINDING(curwin);
if (do_ecmd(0, ptr, NULL, NULL, ECMD_LASTL, ECMD_HIDE, NULL) == FAIL) {
// Failed to open the file, close the window opened for it.
win_close(curwin, false, false);
goto_tabpage_win(oldtab, oldwin);
- } else if (nchar == 'F' && lnum >= 0) {
- curwin->w_cursor.lnum = lnum;
- check_cursor_lnum();
- beginline(BL_SOL | BL_FIX);
+ } else {
+ wp = curwin;
}
}
+
+ if (wp != NULL && nchar == 'F' && lnum >= 0) {
+ curwin->w_cursor.lnum = lnum;
+ check_cursor_lnum(curwin);
+ beginline(BL_SOL | BL_FIX);
+ }
xfree(ptr);
}
break;
@@ -546,7 +582,7 @@ wingotofile:
}
// Make a copy, if the line was changed it will be freed.
- ptr = xstrnsave(ptr, len);
+ ptr = xmemdupz(ptr, len);
find_pattern_in_path(ptr, 0, len, true, Prenum == 0,
type, Prenum1, ACTION_SPLIT, 1, MAXLNUM);
@@ -581,7 +617,7 @@ wingotofile:
case '}':
xchar = Ctrl_RSB;
if (Prenum) {
- g_do_tagpreview = (int)Prenum;
+ g_do_tagpreview = Prenum;
} else {
g_do_tagpreview = (int)p_pvh;
}
@@ -590,7 +626,7 @@ wingotofile:
case Ctrl_RSB:
// Keep visual mode, can select words to use as a tag.
if (Prenum) {
- postponed_split = (int)Prenum;
+ postponed_split = Prenum;
} else {
postponed_split = -1;
}
@@ -608,11 +644,11 @@ wingotofile:
goto wingotofile;
case 't': // CTRL-W gt: go to next tab page
- goto_tabpage((int)Prenum);
+ goto_tabpage(Prenum);
break;
case 'T': // CTRL-W gT: go to previous tab page
- goto_tabpage(-(int)Prenum1);
+ goto_tabpage(-Prenum1);
break;
case TAB: // CTRL-W g<Tab>: go to last used tab page
@@ -658,17 +694,13 @@ static void cmd_with_count(char *cmd, char *bufp, size_t bufsize, int64_t Prenum
}
}
-void win_set_buf(Window window, Buffer buffer, bool noautocmd, Error *err)
+void win_set_buf(win_T *win, buf_T *buf, bool noautocmd, Error *err)
+ FUNC_ATTR_NONNULL_ALL
{
- win_T *win = find_window_by_handle(window, err);
- buf_T *buf = find_buffer_by_handle(buffer, err);
-
- if (!win || !buf) {
- return;
- }
-
tabpage_T *tab = win_find_tabpage(win);
+ // no redrawing and don't set the window title
+ RedrawingDisabled++;
if (noautocmd) {
block_autocmds();
}
@@ -678,7 +710,7 @@ void win_set_buf(Window window, Buffer buffer, bool noautocmd, Error *err)
api_set_error(err,
kErrorTypeException,
"Failed to switch to window %d",
- window);
+ win->handle);
}
try_start();
@@ -687,7 +719,7 @@ void win_set_buf(Window window, Buffer buffer, bool noautocmd, Error *err)
api_set_error(err,
kErrorTypeException,
"Failed to set buffer %d",
- buffer);
+ buf->handle);
}
// If window is not current, state logic will not validate its cursor.
@@ -698,210 +730,13 @@ void win_set_buf(Window window, Buffer buffer, bool noautocmd, Error *err)
if (noautocmd) {
unblock_autocmds();
}
-}
-
-/// Create a new float.
-///
-/// @param wp if NULL, allocate a new window, otherwise turn existing window into a float.
-/// It must then already belong to the current tabpage!
-/// @param last make the window the last one in the window list.
-/// Only used when allocating the autocommand window.
-/// @param config must already have been validated!
-win_T *win_new_float(win_T *wp, bool last, FloatConfig fconfig, Error *err)
-{
- if (wp == NULL) {
- wp = win_alloc(last ? lastwin : lastwin_nofloating(), false);
- win_init(wp, curwin, 0);
- } else {
- assert(!last);
- assert(!wp->w_floating);
- if (firstwin == wp && lastwin_nofloating() == wp) {
- // last non-float
- api_set_error(err, kErrorTypeException,
- "Cannot change last window into float");
- return NULL;
- } else if (!win_valid(wp)) {
- api_set_error(err, kErrorTypeException,
- "Cannot change window from different tabpage into float");
- return NULL;
- }
- int dir;
- winframe_remove(wp, &dir, NULL);
- XFREE_CLEAR(wp->w_frame);
- (void)win_comp_pos(); // recompute window positions
- win_remove(wp, NULL);
- win_append(lastwin_nofloating(), wp);
- }
- wp->w_floating = true;
- wp->w_status_height = 0;
- wp->w_winbar_height = 0;
- wp->w_hsep_height = 0;
- wp->w_vsep_width = 0;
-
- win_config_float(wp, fconfig);
- win_set_inner_size(wp, true);
- wp->w_pos_changed = true;
- redraw_later(wp, UPD_VALID);
- return wp;
-}
-
-void win_set_minimal_style(win_T *wp)
-{
- wp->w_p_nu = false;
- wp->w_p_rnu = false;
- wp->w_p_cul = false;
- wp->w_p_cuc = false;
- wp->w_p_spell = false;
- wp->w_p_list = false;
-
- // Hide EOB region: use " " fillchar and cleared highlighting
- if (wp->w_p_fcs_chars.eob != ' ') {
- char *old = wp->w_p_fcs;
- wp->w_p_fcs = ((*old == NUL)
- ? xstrdup("eob: ")
- : concat_str(old, ",eob: "));
- free_string_option(old);
- }
-
- // TODO(bfredl): this could use a highlight namespace directly,
- // and avoid peculiarities around window options
- char *old = wp->w_p_winhl;
- wp->w_p_winhl = ((*old == NUL)
- ? 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) {
- free_string_option(wp->w_p_scl);
- 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 = 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 = 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("");
- }
-}
-
-void win_config_float(win_T *wp, FloatConfig fconfig)
-{
- wp->w_width = MAX(fconfig.width, 1);
- wp->w_height = MAX(fconfig.height, 1);
-
- if (fconfig.relative == kFloatRelativeCursor) {
- fconfig.relative = kFloatRelativeWindow;
- 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) != 0);
-
- wp->w_float_config = fconfig;
-
- bool has_border = wp->w_floating && wp->w_float_config.border;
- for (int i = 0; i < 4; i++) {
- int new_adj = has_border && wp->w_float_config.border_chars[2 * i + 1][0];
- if (new_adj != wp->w_border_adj[i]) {
- change_border = true;
- wp->w_border_adj[i] = new_adj;
- }
- }
-
- if (!ui_has(kUIMultigrid)) {
- wp->w_height = MIN(wp->w_height, Rows - 1 - win_border_height(wp));
- wp->w_width = MIN(wp->w_width, Columns - win_border_width(wp));
- }
-
- win_set_inner_size(wp, true);
- 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, UPD_NOT_VALID);
- }
-
- // compute initial position
- if (wp->w_float_config.relative == kFloatRelativeWindow) {
- int row = (int)wp->w_float_config.row;
- int col = (int)wp->w_float_config.col;
- Error dummy = ERROR_INIT;
- win_T *parent = find_window_by_handle(wp->w_float_config.window, &dummy);
- if (parent) {
- row += parent->w_winrow;
- col += parent->w_wincol;
- ScreenGrid *grid = &parent->w_grid;
- int row_off = 0, col_off = 0;
- 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);
- wp->w_winrow = row;
- wp->w_wincol = col;
- } else {
- wp->w_winrow = (int)fconfig.row;
- wp->w_wincol = (int)fconfig.col;
- }
-
- // changing border style while keeping border only requires redrawing border
- if (fconfig.border) {
- wp->w_redr_border = true;
- redraw_later(wp, UPD_VALID);
- }
-}
-
-void win_check_anchored_floats(win_T *win)
-{
- for (win_T *wp = lastwin; wp && wp->w_floating; wp = wp->w_prev) {
- // float might be anchored to moved window
- if (wp->w_float_config.relative == kFloatRelativeWindow
- && wp->w_float_config.window == win->handle) {
- wp->w_pos_changed = true;
- }
- }
+ RedrawingDisabled--;
}
/// Return the number of fold columns to display
int win_fdccol_count(win_T *wp)
{
- const char *fdc = (const char *)wp->w_p_fdc;
+ const char *fdc = wp->w_p_fdc;
// auto:<NUM>
if (strncmp(fdc, "auto", 4) == 0) {
@@ -928,7 +763,13 @@ void ui_ext_win_position(win_T *wp, bool validate)
if (c.relative == kFloatRelativeWindow) {
Error dummy = ERROR_INIT;
win_T *win = find_window_by_handle(c.window, &dummy);
- if (win) {
+ api_clear_error(&dummy);
+ if (win != NULL) {
+ // When a floating window is anchored to another window,
+ // update the position of its anchored window first.
+ if (win->w_pos_changed && win->w_grid_alloc.chars != NULL && win_valid(win)) {
+ ui_ext_win_position(win, validate);
+ }
grid = &win->w_grid;
int row_off = 0, col_off = 0;
grid_adjust(&grid, &row_off, &col_off);
@@ -942,15 +783,18 @@ void ui_ext_win_position(win_T *wp, bool validate)
col += tcol - 1;
}
}
- api_clear_error(&dummy);
}
wp->w_grid_alloc.zindex = wp->w_float_config.zindex;
if (ui_has(kUIMultigrid)) {
String anchor = cstr_as_string((char *)float_anchor_str[c.anchor]);
- ui_call_win_float_pos(wp->w_grid_alloc.handle, wp->handle, anchor,
- grid->handle, row, col, c.focusable,
- wp->w_grid_alloc.zindex);
+ if (!c.hide) {
+ ui_call_win_float_pos(wp->w_grid_alloc.handle, wp->handle, anchor,
+ grid->handle, row, col, c.focusable,
+ wp->w_grid_alloc.zindex);
+ } else {
+ ui_call_win_hide(wp->w_grid_alloc.handle);
+ }
} else {
bool valid = (wp->w_redr_type == 0);
if (!valid && !validate) {
@@ -967,16 +811,23 @@ void ui_ext_win_position(win_T *wp, bool validate)
comp_row += grid->comp_row;
comp_col += grid->comp_col;
comp_row = MAX(MIN(comp_row, Rows - wp->w_height_outer - (p_ch > 0 ? 1 : 0)), 0);
- comp_col = MAX(MIN(comp_col, Columns - wp->w_width_outer), 0);
+ if (!c.fixed || east) {
+ comp_col = MAX(MIN(comp_col, Columns - wp->w_width_outer), 0);
+ }
wp->w_winrow = comp_row;
wp->w_wincol = comp_col;
- 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, UPD_NOT_VALID);
+
+ if (!c.hide) {
+ 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, UPD_NOT_VALID);
+ }
+ } else {
+ ui_comp_remove_grid(&wp->w_grid_alloc);
}
}
} else {
@@ -986,22 +837,63 @@ void ui_ext_win_position(win_T *wp, bool validate)
void ui_ext_win_viewport(win_T *wp)
{
- if ((wp == curwin || ui_has(kUIMultigrid)) && wp->w_viewport_invalid) {
- int botline = wp->w_botline;
- int line_count = wp->w_buffer->b_ml.ml_line_count;
- if (botline == line_count + 1 && wp->w_empty_rows == 0) {
+ // NOTE: The win_viewport command is delayed until the next flush when there are pending updates.
+ // This ensures that the updates and the viewport are sent together.
+ if ((wp == curwin || ui_has(kUIMultigrid)) && wp->w_viewport_invalid && wp->w_redr_type == 0) {
+ const linenr_T line_count = wp->w_buffer->b_ml.ml_line_count;
+ // Avoid ml_get errors when producing "scroll_delta".
+ const linenr_T cur_topline = MIN(wp->w_topline, line_count);
+ const linenr_T cur_botline = MIN(wp->w_botline, line_count);
+ int64_t delta = 0;
+ linenr_T last_topline = wp->w_viewport_last_topline;
+ linenr_T last_botline = wp->w_viewport_last_botline;
+ int last_topfill = wp->w_viewport_last_topfill;
+ int64_t last_skipcol = wp->w_viewport_last_skipcol;
+ if (last_topline > line_count) {
+ delta -= last_topline - line_count;
+ last_topline = line_count;
+ last_topfill = 0;
+ last_skipcol = MAXCOL;
+ }
+ last_botline = MIN(last_botline, line_count);
+ if (cur_topline < last_topline
+ || (cur_topline == last_topline && wp->w_skipcol < last_skipcol)) {
+ if (last_topline > 0 && cur_botline < last_topline) {
+ // Scrolling too many lines: only give an approximate "scroll_delta".
+ delta -= win_text_height(wp, cur_topline, wp->w_skipcol, cur_botline, 0, NULL);
+ delta -= last_topline - cur_botline;
+ } else {
+ delta -= win_text_height(wp, cur_topline, wp->w_skipcol, last_topline, last_skipcol, NULL);
+ }
+ } else if (cur_topline > last_topline
+ || (cur_topline == last_topline && wp->w_skipcol > last_skipcol)) {
+ if (last_botline > 0 && cur_topline > last_botline) {
+ // Scrolling too many lines: only give an approximate "scroll_delta".
+ delta += win_text_height(wp, last_topline, last_skipcol, last_botline, 0, NULL);
+ delta += cur_topline - last_botline;
+ } else {
+ delta += win_text_height(wp, last_topline, last_skipcol, cur_topline, wp->w_skipcol, NULL);
+ }
+ }
+ delta += last_topfill;
+ delta -= wp->w_topfill;
+ linenr_T ev_botline = wp->w_botline;
+ if (ev_botline == line_count + 1 && wp->w_empty_rows == 0) {
// TODO(bfredl): The might be more cases to consider, like how does this
// interact with incomplete final line? Diff filler lines?
- botline = wp->w_buffer->b_ml.ml_line_count;
+ ev_botline = line_count;
}
- ui_call_win_viewport(wp->w_grid_alloc.handle, wp->handle, wp->w_topline - 1,
- botline, wp->w_cursor.lnum - 1, wp->w_cursor.col,
- line_count);
+ ui_call_win_viewport(wp->w_grid_alloc.handle, wp->handle, wp->w_topline - 1, ev_botline,
+ wp->w_cursor.lnum - 1, wp->w_cursor.col, line_count, delta);
wp->w_viewport_invalid = false;
+ wp->w_viewport_last_topline = wp->w_topline;
+ wp->w_viewport_last_botline = wp->w_botline;
+ wp->w_viewport_last_topfill = wp->w_topfill;
+ wp->w_viewport_last_skipcol = wp->w_skipcol;
}
}
-/// If "split_disallowed" is set given an error and return FAIL.
+/// If "split_disallowed" is set give an error and return FAIL.
/// Otherwise return OK.
static int check_split_disallowed(void)
{
@@ -1058,10 +950,10 @@ 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;
@@ -1435,7 +1327,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
frame_fix_width(oldwin);
frame_fix_width(wp);
} else {
- bool is_stl_global = global_stl_height() > 0;
+ 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)) {
wp->w_wincol = 0;
@@ -1451,6 +1343,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
// "new_size" of the current window goes to the new window, use
// one row for the status line
win_new_height(wp, new_size);
+ const int old_status_height = oldwin->w_status_height;
if (before) {
wp->w_hsep_height = is_stl_global ? 1 : 0;
} else {
@@ -1459,15 +1352,19 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
}
if (flags & (WSP_TOP | WSP_BOT)) {
int new_fr_height = curfrp->fr_height - new_size;
-
- if (!((flags & WSP_BOT) && p_ls == 0) && !is_stl_global) {
- new_fr_height -= STATUS_HEIGHT;
- } else if (is_stl_global) {
+ if (is_stl_global) {
if (flags & WSP_BOT) {
frame_add_hsep(curfrp);
} else {
new_fr_height -= 1;
}
+ } else {
+ if (!((flags & WSP_BOT) && p_ls == 0)) {
+ new_fr_height -= STATUS_HEIGHT;
+ }
+ if (flags & WSP_BOT) {
+ frame_add_statusline(curfrp);
+ }
}
frame_new_height(curfrp, new_fr_height, flags & WSP_TOP, false);
} else {
@@ -1476,7 +1373,6 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
if (before) { // new window above current one
wp->w_winrow = oldwin->w_winrow;
-
if (is_stl_global) {
wp->w_status_height = 0;
oldwin->w_winrow += wp->w_height + 1;
@@ -1490,15 +1386,12 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
wp->w_status_height = 0;
} else {
wp->w_winrow = oldwin->w_winrow + oldwin->w_height + STATUS_HEIGHT;
- wp->w_status_height = oldwin->w_status_height;
+ wp->w_status_height = old_status_height;
if (!(flags & WSP_BOT)) {
oldwin->w_status_height = STATUS_HEIGHT;
}
}
}
- if ((flags & WSP_BOT) && !is_stl_global) {
- frame_add_statusline(curfrp);
- }
frame_fix_height(wp);
frame_fix_height(oldwin);
}
@@ -1525,7 +1418,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'));
- } else if (*p_spk != 'c' && !is_aucmd_win(wp)) {
+ } else if (!is_aucmd_win(wp)) {
win_fix_scroll(false);
}
@@ -1567,7 +1460,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
// 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)
+void win_init(win_T *newp, win_T *oldp, int flags)
{
newp->w_buffer = oldp->w_buffer;
newp->w_s = &(oldp->w_buffer->b_s);
@@ -1599,6 +1492,9 @@ static void win_init(win_T *newp, win_T *oldp, int flags)
? NULL : xstrdup(oldp->w_prevdir);
if (*p_spk != 'c') {
+ if (*p_spk == 't') {
+ newp->w_skipcol = oldp->w_skipcol;
+ }
newp->w_botline = oldp->w_botline;
newp->w_prev_height = oldp->w_height;
newp->w_prev_winrow = oldp->w_winrow;
@@ -1641,24 +1537,6 @@ static void win_init_some(win_T *newp, win_T *oldp)
win_copy_options(oldp, newp);
}
-/// Return true if "win" is floating window in the current tab page.
-///
-/// @param win window to check
-bool win_valid_floating(const win_T *win)
- FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
-{
- if (win == NULL) {
- return false;
- }
-
- FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
- if (wp == win) {
- return wp->w_floating;
- }
- }
- return false;
-}
-
/// Check if "win" is a pointer to an existing window in the current tabpage.
///
/// @param win window to check
@@ -1790,7 +1668,7 @@ int make_windows(int count, bool vertical)
}
// Exchange current and next window
-static void win_exchange(long Prenum)
+static void win_exchange(int Prenum)
{
if (curwin->w_floating) {
emsg(e_floatexchange);
@@ -1802,6 +1680,10 @@ static void win_exchange(long Prenum)
beep_flush();
return;
}
+ if (text_or_buf_locked()) {
+ beep_flush();
+ return;
+ }
frame_T *frp;
@@ -1900,8 +1782,8 @@ static void win_rotate(bool upwards, int count)
}
}
- win_T *wp1;
- win_T *wp2;
+ win_T *wp1 = NULL;
+ win_T *wp2 = NULL;
while (count--) {
if (upwards) { // first window becomes last window
@@ -2115,7 +1997,7 @@ void win_equal(win_T *next_curwin, bool current, int dir)
win_equal_rec(next_curwin == NULL ? curwin : next_curwin, current,
topframe, dir, 0, tabline_height(),
Columns, topframe->fr_height);
- if (*p_spk != 'c' && !is_aucmd_win(next_curwin)) {
+ if (!is_aucmd_win(next_curwin)) {
win_fix_scroll(true);
}
}
@@ -2258,6 +2140,9 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
}
if (hnc) { // add next_curwin size
next_curwin_size -= (int)p_wiw - (m - n);
+ if (next_curwin_size < 0) {
+ next_curwin_size = 0;
+ }
new_size += next_curwin_size;
room -= new_size - next_curwin_size;
} else {
@@ -2407,7 +2292,7 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
}
}
-static void leaving_window(win_T *const win)
+void leaving_window(win_T *const win)
FUNC_ATTR_NONNULL_ALL
{
// Only matters for a prompt window.
@@ -2585,6 +2470,23 @@ static bool can_close_floating_windows(void)
return true;
}
+/// @return true if, considering the cmdwin, `win` is safe to close.
+/// If false and `win` is the cmdwin, it is closed; otherwise, `err` is set.
+bool can_close_in_cmdwin(win_T *win, Error *err)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (cmdwin_type != 0) {
+ if (win == curwin) {
+ cmdwin_result = Ctrl_C;
+ return false;
+ } else if (win == cmdwin_old_curwin) {
+ api_set_error(err, kErrorTypeException, "%s", e_cmdwin);
+ return false;
+ }
+ }
+ return true;
+}
+
/// Close the possibly last window in a tab page.
///
/// @param win window to close
@@ -2599,6 +2501,7 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf, tabpage_T *prev
if (!ONE_WINDOW) {
return false;
}
+
buf_T *old_curbuf = curbuf;
Terminal *term = win->w_buffer ? win->w_buffer->terminal : NULL;
@@ -2636,10 +2539,11 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf, tabpage_T *prev
return true;
}
-/// Close the buffer of "win" and unload it if "free_buf" is true.
+/// Close the buffer of "win" and unload it if "action" is DOBUF_UNLOAD.
+/// "action" can also be zero (do nothing).
/// "abort_if_last" is passed to close_buffer(): abort closing if all other
/// windows are closed.
-static void win_close_buffer(win_T *win, bool free_buf, bool abort_if_last)
+static void win_close_buffer(win_T *win, int action, bool abort_if_last)
{
// Free independent synblock before the buffer is freed.
if (win->w_buffer != NULL) {
@@ -2658,7 +2562,7 @@ static void win_close_buffer(win_T *win, bool free_buf, bool abort_if_last)
bufref_T bufref;
set_bufref(&bufref, curbuf);
win->w_closing = true;
- close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, abort_if_last, true);
+ close_buffer(win, win->w_buffer, action, abort_if_last, true);
if (win_valid_any_tab(win)) {
win->w_closing = false;
}
@@ -2756,6 +2660,9 @@ int win_close(win_T *win, bool free_buf, bool force)
reset_VIsual_and_resel(); // stop Visual mode
other_buffer = true;
+ if (!win_valid(win)) {
+ return FAIL;
+ }
win->w_closing = true;
apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf);
if (!win_valid(win)) {
@@ -2788,7 +2695,7 @@ int win_close(win_T *win, bool free_buf, bool force)
return OK;
}
- win_close_buffer(win, free_buf, true);
+ win_close_buffer(win, free_buf ? DOBUF_UNLOAD : 0, true);
if (only_one_window() && win_valid(win) && win->w_buffer == NULL
&& (last_window(win) || curtab != prev_curtab
@@ -2872,7 +2779,7 @@ int win_close(win_T *win, bool free_buf, bool force)
if (wp->w_p_pvw || bt_quickfix(wp->w_buffer)) {
// If the cursor goes to the preview or the quickfix window, try
// finding another window to go to.
- for (;;) {
+ while (true) {
if (wp->w_next == NULL) {
wp = firstwin;
} else {
@@ -2907,9 +2814,7 @@ int win_close(win_T *win, bool free_buf, bool force)
win_equal(curwin, curwin->w_frame->fr_parent == win_frame, dir);
} else {
(void)win_comp_pos();
- if (*p_spk != 'c') {
- win_fix_scroll(false);
- }
+ win_fix_scroll(false);
}
}
@@ -3326,20 +3231,20 @@ static frame_T *win_altframe(win_T *win, tabpage_T *tp)
// By default the next window will get the space that was abandoned by this
// window
frame_T *target_fr = frp->fr_next;
- frame_T *other_fr = frp->fr_prev;
+ frame_T *other_fr = frp->fr_prev;
// If this is part of a column of windows and 'splitbelow' is true then the
// previous window will get the space.
if (frp->fr_parent != NULL && frp->fr_parent->fr_layout == FR_COL && p_sb) {
target_fr = frp->fr_prev;
- other_fr = frp->fr_next;
+ other_fr = frp->fr_next;
}
// If this is part of a row of windows, and 'splitright' is true then the
// previous window will get the space.
if (frp->fr_parent != NULL && frp->fr_parent->fr_layout == FR_ROW && p_spr) {
target_fr = frp->fr_prev;
- other_fr = frp->fr_next;
+ other_fr = frp->fr_next;
}
// If 'wfh' or 'wfw' is set for the target and not for the alternate
@@ -3576,12 +3481,7 @@ static void frame_add_statusline(frame_T *frp)
{
if (frp->fr_layout == FR_LEAF) {
win_T *wp = frp->fr_win;
- if (wp->w_status_height == 0) {
- if (wp->w_height - STATUS_HEIGHT >= 0) { // don't make it negative
- wp->w_height -= STATUS_HEIGHT;
- }
- wp->w_status_height = STATUS_HEIGHT;
- }
+ wp->w_status_height = STATUS_HEIGHT;
} else if (frp->fr_layout == FR_ROW) {
// Handle all the frames in the row.
FOR_ALL_FRAMES(frp, frp->fr_child) {
@@ -3728,12 +3628,7 @@ static void frame_add_hsep(const frame_T *frp)
{
if (frp->fr_layout == FR_LEAF) {
win_T *wp = frp->fr_win;
- if (wp->w_hsep_height == 0) {
- if (wp->w_height > 0) { // don't make it negative
- wp->w_height++;
- }
- wp->w_hsep_height = 1;
- }
+ wp->w_hsep_height = 1;
} else if (frp->fr_layout == FR_ROW) {
// Handle all the frames in the row.
FOR_ALL_FRAMES(frp, frp->fr_child) {
@@ -3870,7 +3765,7 @@ void close_others(int message, int forceit)
if (one_nonfloat() && !lastwin->w_floating) {
if (message
&& !autocmd_busy) {
- msg(_(m_onlyone));
+ msg(_(m_onlyone), 0);
}
return;
}
@@ -3883,6 +3778,12 @@ void close_others(int message, int forceit)
continue;
}
+ // autoccommands messed this one up
+ if (!buf_valid(wp->w_buffer) && win_valid(wp)) {
+ wp->w_buffer = NULL;
+ win_close(wp, false, false);
+ continue;
+ }
// Check if it's allowed to abandon this window
int r = can_abandon(wp->w_buffer, forceit);
if (!win_valid(wp)) { // autocommands messed wp up
@@ -3968,7 +3869,7 @@ static int win_alloc_firstwin(win_T *oldwin)
if (oldwin == NULL) {
// Very first window, need to create an empty buffer for it and
// initialize from scratch.
- curbuf = buflist_new(NULL, NULL, 1L, BLN_LISTED);
+ curbuf = buflist_new(NULL, NULL, 1, BLN_LISTED);
if (curbuf == NULL) {
return FAIL;
}
@@ -4024,7 +3925,7 @@ static tabpage_T *alloc_tabpage(void)
static int last_tp_handle = 0;
tabpage_T *tp = xcalloc(1, sizeof(tabpage_T));
tp->handle = ++last_tp_handle;
- pmap_put(handle_T)(&tabpage_handles, tp->handle, tp);
+ pmap_put(int)(&tabpage_handles, tp->handle, tp);
// Init t: variables.
tp->tp_vars = tv_dict_alloc();
@@ -4037,7 +3938,7 @@ static tabpage_T *alloc_tabpage(void)
void free_tabpage(tabpage_T *tp)
{
- pmap_del(handle_T)(&tabpage_handles, tp->handle);
+ pmap_del(int)(&tabpage_handles, tp->handle, NULL);
diff_clear(tp);
for (int idx = 0; idx < SNAP_COUNT; idx++) {
clear_snapshot(tp, idx);
@@ -4081,7 +3982,7 @@ int win_new_tabpage(int after, char *filename)
}
newtp->tp_localdir = old_curtab->tp_localdir
- ? xstrdup(old_curtab->tp_localdir) : NULL;
+ ? xstrdup(old_curtab->tp_localdir) : NULL;
curtab = newtp;
@@ -4144,12 +4045,17 @@ int may_open_tabpage(void)
{
int n = (cmdmod.cmod_tab == 0) ? postponed_split_tab : cmdmod.cmod_tab;
- if (n != 0) {
- cmdmod.cmod_tab = 0; // reset it to avoid doing it twice
- postponed_split_tab = 0;
- return win_new_tabpage(n, NULL);
+ if (n == 0) {
+ return FAIL;
+ }
+
+ cmdmod.cmod_tab = 0; // reset it to avoid doing it twice
+ postponed_split_tab = 0;
+ int status = win_new_tabpage(n, NULL);
+ if (status == OK) {
+ apply_autocmds(EVENT_TABNEWENTERED, NULL, NULL, false, curbuf);
}
- return FAIL;
+ return status;
}
// Create up to "maxcount" tabpages with empty windows.
@@ -4494,11 +4400,12 @@ void goto_tabpage_tp(tabpage_T *tp, bool trigger_enter_autocmds, bool trigger_le
/// @return true if the tab page is valid, false otherwise.
bool goto_tabpage_lastused(void)
{
- if (valid_tabpage(lastused_tabpage)) {
- goto_tabpage_tp(lastused_tabpage, true, true);
- return true;
+ if (!valid_tabpage(lastused_tabpage)) {
+ return false;
}
- return false;
+
+ goto_tabpage_tp(lastused_tabpage, true, true);
+ return true;
}
// Enter window "wp" in tab page "tp".
@@ -4615,7 +4522,7 @@ tabpage_T *win_find_tabpage(win_T *win)
/// @param count nth neighbor window
///
/// @return found window
-win_T *win_vert_neighbor(tabpage_T *tp, win_T *wp, bool up, long count)
+win_T *win_vert_neighbor(tabpage_T *tp, win_T *wp, bool up, int count)
{
frame_T *foundfr = wp->w_frame;
@@ -4628,7 +4535,7 @@ win_T *win_vert_neighbor(tabpage_T *tp, win_T *wp, bool up, long count)
// First go upwards in the tree of frames until we find an upwards or
// downwards neighbor.
frame_T *fr = foundfr;
- for (;;) {
+ while (true) {
if (fr == tp->tp_topframe) {
goto end;
}
@@ -4644,7 +4551,7 @@ win_T *win_vert_neighbor(tabpage_T *tp, win_T *wp, bool up, long count)
}
// Now go downwards to find the bottom or top frame in it.
- for (;;) {
+ while (true) {
if (nfr->fr_layout == FR_LEAF) {
foundfr = nfr;
break;
@@ -4674,7 +4581,7 @@ end:
///
/// @param up true to go to win above
/// @param count go count times into direction
-static void win_goto_ver(bool up, long count)
+static void win_goto_ver(bool up, int count)
{
win_T *win = win_vert_neighbor(curtab, curwin, up, count);
if (win != NULL) {
@@ -4691,7 +4598,7 @@ static void win_goto_ver(bool up, long count)
/// @param count nth neighbor window
///
/// @return found window
-win_T *win_horz_neighbor(tabpage_T *tp, win_T *wp, bool left, long count)
+win_T *win_horz_neighbor(tabpage_T *tp, win_T *wp, bool left, int count)
{
frame_T *foundfr = wp->w_frame;
@@ -4704,7 +4611,7 @@ win_T *win_horz_neighbor(tabpage_T *tp, win_T *wp, bool left, long count)
// First go upwards in the tree of frames until we find a left or
// right neighbor.
frame_T *fr = foundfr;
- for (;;) {
+ while (true) {
if (fr == tp->tp_topframe) {
goto end;
}
@@ -4720,7 +4627,7 @@ win_T *win_horz_neighbor(tabpage_T *tp, win_T *wp, bool left, long count)
}
// Now go downwards to find the leftmost or rightmost frame in it.
- for (;;) {
+ while (true) {
if (nfr->fr_layout == FR_LEAF) {
foundfr = nfr;
break;
@@ -4750,7 +4657,7 @@ end:
///
/// @param left true to go to left window
/// @param count go count times into direction
-static void win_goto_hor(bool left, long count)
+static void win_goto_hor(bool left, int count)
{
win_T *win = win_horz_neighbor(curtab, curwin, left, count);
if (win != NULL) {
@@ -4811,7 +4718,7 @@ static void win_enter_ext(win_T *const wp, const int flags)
// Might need to scroll the old window before switching, e.g., when the
// cursor was moved.
- if (*p_spk == 'c') {
+ if (*p_spk == 'c' && !curwin_invalid) {
update_topline(curwin);
}
@@ -4833,7 +4740,9 @@ static void win_enter_ext(win_T *const wp, const int flags)
if (*p_spk == 'c') {
changed_line_abv_curs(); // assume cursor position needs updating
} else {
- win_fix_cursor(true);
+ // Make sure the cursor position is valid, either by moving the cursor
+ // or by scrolling the text.
+ win_fix_cursor(get_real_state() & (MODE_NORMAL|MODE_CMDLINE|MODE_TERMINAL));
}
fix_current_dir();
@@ -4848,8 +4757,6 @@ static void win_enter_ext(win_T *const wp, const int flags)
if (other_buffer) {
apply_autocmds(EVENT_BUFENTER, NULL, NULL, false, curbuf);
}
- apply_autocmds(EVENT_CURSORMOVED, NULL, NULL, false, curbuf);
- curwin->w_last_cursormoved = curwin->w_cursor;
}
maketitle();
@@ -4997,7 +4904,7 @@ win_T *buf_jump_open_tab(buf_T *buf)
/// @param hidden allocate a window structure and link it in the window if
// false.
-static win_T *win_alloc(win_T *after, bool hidden)
+win_T *win_alloc(win_T *after, bool hidden)
{
static int last_win_id = LOWEST_WIN_ID - 1;
@@ -5005,7 +4912,7 @@ static win_T *win_alloc(win_T *after, bool hidden)
win_T *new_wp = xcalloc(1, sizeof(win_T));
new_wp->handle = ++last_win_id;
- pmap_put(handle_T)(&window_handles, new_wp->handle, new_wp);
+ pmap_put(int)(&window_handles, new_wp->handle, new_wp);
grid_assign_handle(&new_wp->w_grid_alloc);
@@ -5034,12 +4941,13 @@ static win_T *win_alloc(win_T *after, bool hidden)
new_wp->w_floating = 0;
new_wp->w_float_config = FLOAT_CONFIG_INIT;
new_wp->w_viewport_invalid = true;
+ new_wp->w_viewport_last_topline = 1;
new_wp->w_ns_hl = -1;
// use global option for global-local options
- new_wp->w_p_so = -1;
- new_wp->w_p_siso = -1;
+ new_wp->w_allbuf_opt.wo_so = new_wp->w_p_so = -1;
+ new_wp->w_allbuf_opt.wo_siso = new_wp->w_p_siso = -1;
// We won't calculate w_fraction until resizing the window
new_wp->w_fraction = 0;
@@ -5066,14 +4974,13 @@ void free_wininfo(wininfo_T *wip, buf_T *bp)
/// @param tp tab page "win" is in, NULL for current
static void win_free(win_T *wp, tabpage_T *tp)
{
- pmap_del(handle_T)(&window_handles, wp->handle);
+ pmap_del(int)(&window_handles, wp->handle, NULL);
clearFolding(wp);
// reduce the reference count to the argument list.
alist_unlink(wp->w_alist);
// Don't execute autocommands while the window is halfway being deleted.
- // gui_mch_destroy_scrollbar() may trigger a FocusGained event.
block_autocmds();
clear_winopt(&wp->w_onebuf_opt);
@@ -5145,8 +5052,9 @@ static void win_free(win_T *wp, tabpage_T *tp)
}
}
- // free the border title text
+ // free the border text
clear_virttext(&wp->w_float_config.title_chunks);
+ clear_virttext(&wp->w_float_config.footer_chunks);
clear_matches(wp);
@@ -5263,8 +5171,8 @@ static void frame_remove(frame_T *frp)
void win_new_screensize(void)
{
- static long old_Rows = 0;
- static long old_Columns = 0;
+ static int old_Rows = 0;
+ static int old_Columns = 0;
if (old_Rows != Rows) {
// If 'window' uses the whole screen, keep it using that.
@@ -5306,7 +5214,7 @@ void win_new_screen_rows(void)
compute_cmdrow();
curtab->tp_ch_used = p_ch;
- if (*p_spk != 'c' && !skip_win_fix_scroll) {
+ if (!skip_win_fix_scroll) {
win_fix_scroll(true);
}
}
@@ -5364,7 +5272,7 @@ static dict_T *make_win_info_dict(int width, int height, int topline, int topfil
d->dv_refcount = 1;
// not actually looping, for breaking out on error
- while (1) {
+ while (true) {
typval_T tv = {
.v_lock = VAR_UNLOCKED,
.v_type = VAR_NUMBER,
@@ -5617,8 +5525,9 @@ void win_size_save(garray_T *gap)
{
ga_init(gap, (int)sizeof(int), 1);
ga_grow(gap, win_count() * 2 + 1);
- // first entry is value of 'lines'
- ((int *)gap->ga_data)[gap->ga_len++] = Rows;
+ // first entry is the total lines available for windows
+ ((int *)gap->ga_data)[gap->ga_len++] =
+ (int)ROWS_AVAIL + global_stl_height() - last_stl_height(false);
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
((int *)gap->ga_data)[gap->ga_len++] =
@@ -5628,13 +5537,14 @@ void win_size_save(garray_T *gap)
}
// Restore window sizes, but only if the number of windows is still the same
-// and 'lines' didn't change.
+// and total lines available for windows didn't change.
// Does not free the growarray.
void win_size_restore(garray_T *gap)
FUNC_ATTR_NONNULL_ALL
{
if (win_count() * 2 + 1 == gap->ga_len
- && ((int *)gap->ga_data)[0] == Rows) {
+ && ((int *)gap->ga_data)[0] ==
+ ROWS_AVAIL + global_stl_height() - last_stl_height(false)) {
// The order matters, because frames contain other frames, but it's
// difficult to get right. The easy way out is to do it twice.
for (int j = 0; j < 2; j++) {
@@ -5672,13 +5582,6 @@ int win_comp_pos(void)
return row + global_stl_height();
}
-void win_reconfig_floats(void)
-{
- for (win_T *wp = lastwin; wp && wp->w_floating; wp = wp->w_prev) {
- win_config_float(wp, wp->w_float_config);
- }
-}
-
// Update the position of the windows in frame "topfrp", using the width and
// height of the frames.
// "*row" and "*col" are the top-left position of the frame. They are updated
@@ -5753,9 +5656,7 @@ void win_setheight_win(int height, win_T *win)
msg_row = row;
msg_col = 0;
- if (*p_spk != 'c') {
- win_fix_scroll(true);
- }
+ win_fix_scroll(true);
redraw_all_later(UPD_NOT_VALID);
redraw_cmdline = true;
@@ -6079,7 +5980,7 @@ static void frame_setwidth(frame_T *curfrp, int width)
}
// Check 'winminheight' for a valid value and reduce it if needed.
-void win_setminheight(void)
+const char *did_set_winminheight(optset_T *args FUNC_ATTR_UNUSED)
{
bool first = true;
@@ -6096,10 +5997,11 @@ void win_setminheight(void)
first = false;
}
}
+ return NULL;
}
// Check 'winminwidth' for a valid value and reduce it if needed.
-void win_setminwidth(void)
+const char *did_set_winminwidth(optset_T *args FUNC_ATTR_UNUSED)
{
bool first = true;
@@ -6116,6 +6018,7 @@ void win_setminwidth(void)
first = false;
}
}
+ return NULL;
}
/// Status line of dragwin is dragged "offset" lines down (negative is up).
@@ -6233,9 +6136,7 @@ void win_drag_status_line(win_T *dragwin, int offset)
p_ch = MAX(Rows - cmdline_row, p_ch_was_zero ? 0 : 1);
curtab->tp_ch_used = p_ch;
- if (*p_spk != 'c') {
- win_fix_scroll(true);
- }
+ win_fix_scroll(true);
redraw_all_later(UPD_SOME_VALID);
showmode();
@@ -6340,7 +6241,7 @@ void win_drag_vsep_line(win_T *dragwin, int offset)
redraw_all_later(UPD_NOT_VALID);
}
-#define FRACTION_MULT 16384L
+#define FRACTION_MULT 16384
// Set wp->w_fraction for the current w_wrow and w_height.
// Has no effect when the window is less than two lines.
@@ -6350,45 +6251,56 @@ void set_fraction(win_T *wp)
// When cursor is in the first line the percentage is computed as if
// it's halfway that line. Thus with two lines it is 25%, with three
// lines 17%, etc. Similarly for the last line: 75%, 83%, etc.
- wp->w_fraction = (int)(wp->w_wrow * FRACTION_MULT + FRACTION_MULT / 2) / wp->w_height_inner;
+ wp->w_fraction = (wp->w_wrow * FRACTION_MULT + FRACTION_MULT / 2) / wp->w_height_inner;
}
}
-/// Handle scroll position for 'splitkeep'. Replaces scroll_to_fraction()
-/// call from win_set_inner_size(). Instead we iterate over all windows in a
-/// tabpage and calculate the new scroll position.
-/// TODO(luukvbaal): Ensure this also works with wrapped lines.
-/// Requires topline to be able to be set to a bufferline with some
-/// offset(row-wise scrolling/smoothscroll).
+/// Handle scroll position, depending on 'splitkeep'. Replaces the
+/// scroll_to_fraction() call from win_new_height() if 'splitkeep' is "screen"
+/// or "topline". Instead we iterate over all windows in a tabpage and
+/// calculate the new scroll position.
+/// TODO(vim): Ensure this also works with wrapped lines.
+/// Requires a not fully visible cursor line to be allowed at the bottom of
+/// a window("zb"), probably only when 'smoothscroll' is also set.
void win_fix_scroll(int resize)
{
- linenr_T lnum;
+ if (*p_spk == 'c') {
+ return; // 'splitkeep' is "cursor"
+ }
skip_update_topline = true;
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
// Skip when window height has not changed or when floating.
if (!wp->w_floating && wp->w_height != wp->w_prev_height) {
+ // Cursor position in this window may now be invalid. It is kept
+ // potentially invalid until the window is made the current window.
+ wp->w_do_win_fix_cursor = true;
+
// If window has moved update botline to keep the same screenlines.
if (*p_spk == 's' && wp->w_winrow != wp->w_prev_winrow
&& wp->w_botline - 1 <= wp->w_buffer->b_ml.ml_line_count) {
- lnum = wp->w_cursor.lnum;
int diff = (wp->w_winrow - wp->w_prev_winrow)
+ (wp->w_height - wp->w_prev_height);
+ linenr_T lnum = wp->w_cursor.lnum;
wp->w_cursor.lnum = wp->w_botline - 1;
+
// Add difference in height and row to botline.
if (diff > 0) {
cursor_down_inner(wp, diff);
} else {
cursor_up_inner(wp, -diff);
}
- // Bring the new cursor position to the bottom of the screen.
+
+ // Scroll to put the new cursor position at the bottom of the
+ // screen.
wp->w_fraction = FRACTION_MULT;
scroll_to_fraction(wp, wp->w_prev_height);
wp->w_cursor.lnum = lnum;
} else if (wp == curwin) {
wp->w_valid &= ~VALID_CROW;
}
- invalidate_botline_win(wp);
+
+ invalidate_botline(wp);
validate_botline(wp);
}
wp->w_prev_height = wp->w_height;
@@ -6405,40 +6317,45 @@ void win_fix_scroll(int resize)
/// Make sure the cursor position is valid for 'splitkeep'.
/// If it is not, put the cursor position in the jumplist and move it.
-/// If we are not in normal mode, scroll to make valid instead.
-static void win_fix_cursor(int normal)
+/// If we are not in normal mode ("normal" is false), make it valid by scrolling
+/// instead.
+static void win_fix_cursor(bool normal)
{
win_T *wp = curwin;
- long so = get_scrolloff_value(wp);
- linenr_T nlnum = 0;
- linenr_T lnum = wp->w_cursor.lnum;
- if (wp->w_buffer->b_ml.ml_line_count < wp->w_height
- || skip_win_fix_cursor) {
+ if (skip_win_fix_cursor
+ || !wp->w_do_win_fix_cursor
+ || wp->w_buffer->b_ml.ml_line_count < wp->w_height_inner) {
return;
}
+ wp->w_do_win_fix_cursor = false;
// Determine valid cursor range.
- so = MIN(wp->w_height_inner / 2, so);
+ int so = MIN(wp->w_height_inner / 2, get_scrolloff_value(wp));
+ linenr_T lnum = wp->w_cursor.lnum;
+
wp->w_cursor.lnum = wp->w_topline;
- linenr_T top = cursor_down_inner(wp, so);
+ cursor_down_inner(wp, so);
+ linenr_T top = wp->w_cursor.lnum;
+
wp->w_cursor.lnum = wp->w_botline - 1;
- linenr_T bot = cursor_up_inner(wp, so);
+ cursor_up_inner(wp, so);
+ linenr_T bot = wp->w_cursor.lnum;
+
wp->w_cursor.lnum = lnum;
// Check if cursor position is above or below valid cursor range.
+ linenr_T nlnum = 0;
if (lnum > bot && (wp->w_botline - wp->w_buffer->b_ml.ml_line_count) != 1) {
nlnum = bot;
} else if (lnum < top && wp->w_topline != 1) {
- nlnum = (so == wp->w_height / 2) ? bot : top;
+ nlnum = (so == wp->w_height_inner / 2) ? bot : top;
}
- if (nlnum) { // Cursor is invalid for current scroll position.
- if (normal) {
- // Save to jumplist and set cursor to avoid scrolling.
+ if (nlnum != 0) { // Cursor is invalid for current scroll position.
+ if (normal) { // Save to jumplist and set cursor to avoid scrolling.
setmark('\'');
wp->w_cursor.lnum = nlnum;
- } else {
- // Scroll instead when not in normal mode.
+ } else { // Scroll instead when not in normal mode.
wp->w_fraction = (nlnum == bot) ? FRACTION_MULT : 0;
scroll_to_fraction(wp, wp->w_prev_height);
validate_botline(curwin);
@@ -6485,8 +6402,8 @@ void scroll_to_fraction(win_T *wp, int prev_height)
if (lnum < 1) { // can happen when starting up
lnum = 1;
}
- wp->w_wrow = (int)((long)wp->w_fraction * (long)height - 1L) / FRACTION_MULT;
- int line_size = plines_win_col(wp, lnum, (long)(wp->w_cursor.col)) - 1;
+ wp->w_wrow = (wp->w_fraction * height - 1) / FRACTION_MULT;
+ int line_size = plines_win_col(wp, lnum, wp->w_cursor.col) - 1;
int sline = wp->w_wrow - line_size;
if (sline >= 0) {
@@ -6549,9 +6466,6 @@ void scroll_to_fraction(win_T *wp, int prev_height)
}
if (wp == curwin) {
- if (get_scrolloff_value(wp)) {
- update_topline(wp);
- }
curs_columns(wp, false); // validate w_wrow
}
if (prev_height > 0) {
@@ -6559,7 +6473,7 @@ void scroll_to_fraction(win_T *wp, int prev_height)
}
redraw_later(wp, UPD_SOME_VALID);
- invalidate_botline_win(wp);
+ invalidate_botline(wp);
}
void win_set_inner_size(win_T *wp, bool valid_cursor)
@@ -6582,20 +6496,20 @@ void win_set_inner_size(win_T *wp, bool valid_cursor)
// call win_new_height() recursively.
validate_cursor();
}
- if (wp->w_height_inner != prev_height) { // -V547
+ if (wp->w_height_inner != prev_height) {
return; // Recursive call already changed the size, bail out.
}
if (wp->w_wrow != wp->w_prev_fraction_row) {
set_fraction(wp);
}
}
- wp->w_skipcol = 0;
wp->w_height_inner = height;
win_comp_scroll(wp);
// There is no point in adjusting the scroll position when exiting. Some
// values might be invalid.
if (valid_cursor && !exiting && *p_spk == 'c') {
+ wp->w_skipcol = 0;
scroll_to_fraction(wp, prev_height);
}
redraw_later(wp, UPD_SOME_VALID);
@@ -6606,12 +6520,9 @@ void win_set_inner_size(win_T *wp, bool valid_cursor)
wp->w_lines_valid = 0;
if (valid_cursor) {
changed_line_abv_curs_win(wp);
- invalidate_botline_win(wp);
- if (wp == curwin) {
- skip_update_topline = (*p_spk != 'c');
- update_topline(wp);
+ invalidate_botline(wp);
+ if (wp == curwin && *p_spk == 'c') {
curs_columns(wp, true); // validate w_wrow
- skip_update_topline = false;
}
}
redraw_later(wp, UPD_NOT_VALID);
@@ -6628,27 +6539,18 @@ void win_set_inner_size(win_T *wp, bool valid_cursor)
wp->w_redr_status = true;
}
-static int win_border_height(win_T *wp)
-{
- return wp->w_border_adj[0] + wp->w_border_adj[2];
-}
-
-static int win_border_width(win_T *wp)
-{
- return wp->w_border_adj[1] + wp->w_border_adj[3];
-}
-
/// Set the width of a window.
void win_new_width(win_T *wp, int width)
{
- wp->w_width = width;
+ // Should we give an error if width < 0?
+ wp->w_width = width < 0 ? 0 : width;
wp->w_pos_changed = true;
win_set_inner_size(wp, true);
}
void win_comp_scroll(win_T *wp)
{
- const long old_w_p_scr = wp->w_p_scr;
+ const OptInt old_w_p_scr = wp->w_p_scr;
wp->w_p_scr = wp->w_height_inner / 2;
if (wp->w_p_scr == 0) {
@@ -6744,7 +6646,7 @@ void command_height(void)
static void frame_add_height(frame_T *frp, int n)
{
frame_new_height(frp, frp->fr_height + n, false, false);
- for (;;) {
+ while (true) {
frp = frp->fr_parent;
if (frp == NULL) {
break;
@@ -6756,7 +6658,7 @@ static void frame_add_height(frame_T *frp, int n)
// Get the file name at the cursor.
// If Visual mode is active, use the selected text if it's in one line.
// Returns the name in allocated memory, NULL for failure.
-char *grab_file_name(long count, linenr_T *file_lnum)
+char *grab_file_name(int count, linenr_T *file_lnum)
{
int options = FNAME_MESS | FNAME_EXP | FNAME_REL | FNAME_UNESC;
if (VIsual_active) {
@@ -6769,7 +6671,7 @@ char *grab_file_name(long count, linenr_T *file_lnum)
if (file_lnum != NULL && ptr[len] == ':' && isdigit((uint8_t)ptr[len + 1])) {
char *p = ptr + len + 1;
- *file_lnum = (linenr_T)getdigits_long(&p, false, 0);
+ *file_lnum = getdigits_int32(&p, false, 0);
}
return find_file_name_in_path(ptr, len, options, count, curbuf->b_ffname);
}
@@ -6787,7 +6689,7 @@ char *grab_file_name(long count, linenr_T *file_lnum)
// FNAME_EXP expand to path
// FNAME_HYP check for hypertext link
// FNAME_INCL apply "includeexpr"
-char *file_name_at_cursor(int options, long count, linenr_T *file_lnum)
+char *file_name_at_cursor(int options, int count, linenr_T *file_lnum)
{
return file_name_in_line(get_cursor_line_ptr(),
curwin->w_cursor.col, options, count, curbuf->b_ffname,
@@ -6798,7 +6700,7 @@ char *file_name_at_cursor(int options, long count, linenr_T *file_lnum)
/// @param file_lnum line number after the file name
///
/// @return the name of the file under or after ptr[col]. Otherwise like file_name_at_cursor().
-char *file_name_in_line(char *line, int col, int options, long count, char *rel_fname,
+char *file_name_in_line(char *line, int col, int options, int count, char *rel_fname,
linenr_T *file_lnum)
{
// search forward for what could be the start of a file name
@@ -6818,12 +6720,12 @@ char *file_name_in_line(char *line, int col, int options, long count, char *rel_
bool is_url = false;
// Search backward for first char of the file name.
- // Go one char back to ":" before "//" even when ':' is not in 'isfname'.
+ // Go one char back to ":" before "//", or to the drive letter before ":\" (even if ":"
+ // is not in 'isfname').
while (ptr > line) {
if ((len = (size_t)(utf_head_off(line, ptr - 1))) > 0) {
ptr -= len + 1;
- } else if (vim_isfilec((uint8_t)ptr[-1])
- || ((options & FNAME_HYP) && path_is_url(ptr - 1))) {
+ } else if (vim_isfilec((uint8_t)ptr[-1]) || ((options & FNAME_HYP) && path_is_url(ptr - 1))) {
ptr--;
} else {
break;
@@ -6832,14 +6734,13 @@ char *file_name_in_line(char *line, int col, int options, long count, char *rel_
// Search forward for the last char of the file name.
// Also allow ":/" when ':' is not in 'isfname'.
- len = 0;
+ len = path_has_drive_letter(ptr) ? 2 : 0;
while (vim_isfilec((uint8_t)ptr[len]) || (ptr[len] == '\\' && ptr[len + 1] == ' ')
|| ((options & FNAME_HYP) && path_is_url(ptr + len))
|| (is_url && vim_strchr(":?&=", (uint8_t)ptr[len]) != NULL)) {
// After type:// we also include :, ?, & and = as valid characters, so that
// http://google.com:8080?q=this&that=ok works.
- if ((ptr[len] >= 'A' && ptr[len] <= 'Z')
- || (ptr[len] >= 'a' && ptr[len] <= 'z')) {
+ if ((ptr[len] >= 'A' && ptr[len] <= 'Z') || (ptr[len] >= 'a' && ptr[len] <= 'z')) {
if (in_type && path_is_url(ptr + len + 1)) {
is_url = true;
}
@@ -6897,8 +6798,7 @@ char *file_name_in_line(char *line, int col, int options, long count, char *rel_
void last_status(bool morewin)
{
// Don't make a difference between horizontal or vertical split.
- last_status_rec(topframe, (p_ls == 2 || (p_ls == 1 && (morewin || !one_nonfloat()))),
- global_stl_height() > 0);
+ last_status_rec(topframe, last_stl_height(morewin) > 0, global_stl_height() > 0);
}
// Remove status line from window, replacing it with a horizontal separator if needed.
@@ -7097,6 +6997,14 @@ int global_stl_height(void)
return (p_ls == 3) ? STATUS_HEIGHT : 0;
}
+/// Return the height of the last window's statusline, or the global statusline if set.
+///
+/// @param morewin pretend there are two or more windows if true.
+int last_stl_height(bool morewin)
+{
+ return (p_ls > 1 || (p_ls == 1 && (morewin || !one_nonfloat()))) ? STATUS_HEIGHT : 0;
+}
+
/// Return the minimal number of rows that is needed on the screen to display
/// the current number of windows.
int min_rows(void)
@@ -7193,8 +7101,9 @@ void reset_lnums(void)
{
FOR_ALL_TAB_WINDOWS(tp, wp) {
if (wp->w_buffer == curbuf) {
- // Restore the value if the autocommand didn't change it and it was
- // set.
+ // Restore the value if the autocommand didn't change it and it was set.
+ // Note: This triggers e.g. on BufReadPre, when the buffer is not yet
+ // loaded, so cannot validate the buffer line
if (equalpos(wp->w_save_cursor.w_cursor_corr, wp->w_cursor)
&& wp->w_save_cursor.w_cursor_save.lnum != 0) {
wp->w_cursor = wp->w_save_cursor.w_cursor_save;
@@ -7203,6 +7112,9 @@ void reset_lnums(void)
&& wp->w_save_cursor.w_topline_save != 0) {
wp->w_topline = wp->w_save_cursor.w_topline_save;
}
+ if (wp->w_save_cursor.w_topline_save > wp->w_buffer->b_ml.ml_line_count) {
+ wp->w_valid &= ~VALID_TOPLINE;
+ }
}
}
}
@@ -7250,11 +7162,12 @@ static void clear_snapshot(tabpage_T *tp, int idx)
static void clear_snapshot_rec(frame_T *fr)
{
- if (fr != NULL) {
- clear_snapshot_rec(fr->fr_next);
- clear_snapshot_rec(fr->fr_child);
- xfree(fr);
+ if (fr == NULL) {
+ return;
}
+ clear_snapshot_rec(fr->fr_next);
+ clear_snapshot_rec(fr->fr_child);
+ xfree(fr);
}
/// Traverse a snapshot to find the previous curwin.
@@ -7404,13 +7317,13 @@ static int int_cmp(const void *a, const void *b)
/// Handle setting 'colorcolumn' or 'textwidth' in window "wp".
///
/// @return error message, NULL if it's OK.
-char *check_colorcolumn(win_T *wp)
+const char *check_colorcolumn(win_T *wp)
{
if (wp->w_buffer == NULL) {
return NULL; // buffer was closed
}
- unsigned int count = 0;
+ unsigned count = 0;
int color_cols[256];
for (char *s = wp->w_p_cc; *s != NUL && count < 255;) {
int col;
@@ -7463,7 +7376,7 @@ skip:
qsort(color_cols, count, sizeof(int), int_cmp);
int j = 0;
- for (unsigned int i = 0; i < count; i++) {
+ for (unsigned i = 0; i < count; i++) {
// skip duplicates
if (j == 0 || wp->w_p_cc_cols[j - 1] != color_cols[i]) {
wp->w_p_cc_cols[j++] = color_cols[i];