From fb1edb2f5728d74ae811c6ab32395598cea5609b Mon Sep 17 00:00:00 2001 From: Dundar Göc Date: Fri, 26 Aug 2022 23:11:25 +0200 Subject: refactor: replace char_u with char Work on https://github.com/neovim/neovim/issues/459 --- src/nvim/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 74ea1172ee..c11484d1b8 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -6578,7 +6578,7 @@ char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u * Go one char back to ":" before "//" even when ':' is not in 'isfname'. */ while ((char_u *)ptr > line) { - if ((len = (size_t)(utf_head_off(line, (char_u *)ptr - 1))) > 0) { + if ((len = (size_t)(utf_head_off((char *)line, ptr - 1))) > 0) { ptr -= len + 1; } else if (vim_isfilec(ptr[-1]) || ((options & FNAME_HYP) && path_is_url(ptr - 1))) { ptr--; -- cgit From 49e893f296bca9eef5ff45a3d746c261d055bf10 Mon Sep 17 00:00:00 2001 From: Dundar Göc Date: Fri, 26 Aug 2022 23:11:25 +0200 Subject: refactor: replace char_u with char Work on https://github.com/neovim/neovim/issues/459 --- src/nvim/window.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index c11484d1b8..8ca40cdd35 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -6522,7 +6522,7 @@ char_u *grab_file_name(long count, linenr_T *file_lnum) *file_lnum = (linenr_T)getdigits_long(&p, false, 0); } - return find_file_name_in_path((char_u *)ptr, len, options, count, (char_u *)curbuf->b_ffname); + return (char_u *)find_file_name_in_path(ptr, len, options, count, curbuf->b_ffname); } return file_name_at_cursor(options | FNAME_HYP, count, file_lnum); } @@ -6542,7 +6542,7 @@ char_u *grab_file_name(long count, linenr_T *file_lnum) */ char_u *file_name_at_cursor(int options, long count, linenr_T *file_lnum) { - return file_name_in_line(get_cursor_line_ptr(), + return file_name_in_line((char_u *)get_cursor_line_ptr(), curwin->w_cursor.col, options, count, (char_u *)curbuf->b_ffname, file_lnum); } @@ -6649,7 +6649,7 @@ char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u } } - return find_file_name_in_path((char_u *)ptr, len, options, count, rel_fname); + return (char_u *)find_file_name_in_path(ptr, len, options, count, (char *)rel_fname); } /// Add or remove a status line from window(s), according to the -- cgit From c65b1f3e15662cd14c443e34862237d3dee30977 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 1 Sep 2022 20:18:17 +0800 Subject: vim-patch:9.0.0342: ":wincmd =" equalizes in two directions Problem: ":wincmd =" equalizes in two directions. Solution: Make ":vertical wincmd =" equalize vertically only and ":horizontal wincmd =" equalize horizontally only. https://github.com/vim/vim/commit/21c3a80a7fd6b7fc250ce5dc287963511f54b86f --- src/nvim/window.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index c11484d1b8..c0b73ff837 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -417,10 +417,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 '+': -- cgit From 1ffd527c837fb2465c9659273bbe5447a1352db2 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Fri, 2 Sep 2022 17:39:49 +0100 Subject: refactor: migrate comment style (#20012) Done automatically using the following perl command: perl -pi -0777pe 's#\n\K */\*\n(.+?)\s*\*/\n#join("\n", map { $_ =~ s:^\s*\K \*://:; $_ } split("\n", $1)) . "\n"#sge' src/nvim/**/*.c Co-authored-by: zeertzjq Co-authored-by: zeertzjq --- src/nvim/window.c | 599 ++++++++++++++++++++---------------------------------- 1 file changed, 215 insertions(+), 384 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 6ee3820d95..530cbc0c7b 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -970,21 +970,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) { @@ -1014,12 +1012,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; @@ -1069,10 +1065,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) layout = FR_ROW; - /* - * Check if we are able to split the current window and compute its - * width. - */ + // 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; @@ -1243,9 +1237,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) @@ -1282,9 +1274,7 @@ 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. - */ + // 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)) { @@ -1489,9 +1479,7 @@ 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')); } @@ -1527,13 +1515,11 @@ 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; @@ -1591,10 +1577,8 @@ 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. @@ -1671,9 +1655,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; @@ -1746,9 +1728,7 @@ 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; @@ -1768,9 +1748,7 @@ static void win_exchange(long Prenum) return; } - /* - * find window to exchange with - */ + // find window to exchange with if (Prenum) { frp = curwin->w_frame->fr_parent->fr_child; while (frp != NULL && --Prenum > 0) { @@ -1789,14 +1767,12 @@ static void win_exchange(long Prenum) } 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. - */ + // 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; if (wp->w_prev != curwin) { @@ -1927,9 +1903,7 @@ static void win_rotate(bool upwards, int count) 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; @@ -1973,10 +1947,8 @@ 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; @@ -2146,11 +2118,9 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int totwincount = (n + extra_sep) / ((int)p_wmw + 1); has_next_curwin = frame_has_win(topfr, next_curwin); - /* - * Compute width for "next_curwin" window and room available for - * other windows. - * "m" is the minimal width when counting p_wiw for "next_curwin". - */ + // Compute width for "next_curwin" window and room available for + // other windows. + // "m" is the minimal width when counting p_wiw for "next_curwin". m = frame_minwidth(topfr, next_curwin); room = width - m; if (room < 0) { @@ -2274,11 +2244,9 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int totwincount = get_maximum_wincount(topfr, n + extra_sep); has_next_curwin = frame_has_win(topfr, next_curwin); - /* - * Compute height for "next_curwin" window and room available for - * other windows. - * "m" is the minimal height when counting p_wh for "next_curwin". - */ + // Compute height for "next_curwin" window and room available for + // other windows. + // "m" is the minimal height when counting p_wh for "next_curwin". m = frame_minheight(topfr, next_curwin); room = height - m; if (room < 0) { @@ -2594,14 +2562,12 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf, tabpage_T *prev free_buf = false; } - /* - * Closing the last window in a tab page. First go to another tab - * page and then close the window and the tab page. This avoids that - * curwin and curtab are invalid while we are freeing memory, they may - * be used in GUI events. - * Don't trigger autocommands yet, they may use wrong values, so do - * that below. - */ + // Closing the last window in a tab page. First go to another tab + // page and then close the window and the tab page. This avoids that + // curwin and curtab are invalid while we are freeing memory, they may + // be used in GUI events. + // Don't trigger autocommands yet, they may use wrong values, so do + // that below. goto_tabpage_tp(alt_tabpage(), false, true); redraw_tabline = true; @@ -2745,10 +2711,8 @@ int win_close(win_T *win, bool free_buf, bool force) } } - /* - * Be careful: If autocommands delete the window or cause this window - * to be the last one left, return now. - */ + // Be careful: If autocommands delete the window or cause this window + // to be the last one left, return now. if (wp->w_buffer != curbuf) { reset_VIsual_and_resel(); // stop Visual mode @@ -2860,10 +2824,8 @@ int win_close(win_T *win, bool free_buf, bool force) if (win == curwin) { curwin = wp; 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. - */ + // If the cursor goes to the preview or the quickfix window, try + // finding another window to go to. for (;;) { if (wp->w_next == NULL) { wp = firstwin; @@ -2908,10 +2870,8 @@ int win_close(win_T *win, bool free_buf, bool force) split_disallowed--; - /* - * If last window has a status line now and we don't want one, - * remove the status line. - */ + // If last window has a status line now and we don't want one, + // remove the status line. last_status(false); // After closing the help window, try restoring the window layout from @@ -2955,13 +2915,11 @@ static void do_autocmd_winclosed(win_T *win) recursive = false; } -/* - * Close window "win" in tab page "tp", which is not the current tab page. - * This may be the last window in that tab page and result in closing the tab, - * thus "tp" may become invalid! - * Caller must check if buffer is hidden and whether the tabline needs to be - * updated. - */ +// Close window "win" in tab page "tp", which is not the current tab page. +// This may be the last window in that tab page and result in closing the tab, +// thus "tp" may become invalid! +// Caller must check if buffer is hidden and whether the tabline needs to be +// updated. void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) { int dir; @@ -3138,16 +3096,12 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp) frame_T *frp_close = win->w_frame; win_T *wp; - /* - * If there is only one window there is nothing to remove. - */ + // If there is only one window there is nothing to remove. if (tp == NULL ? ONE_WINDOW : tp->tp_firstwin == tp->tp_lastwin) { return NULL; } - /* - * Remove the window from its frame. - */ + // Remove the window from its frame. frp2 = win_altframe(win, tp); wp = frame2win(frp2); @@ -3334,9 +3288,7 @@ static frame_T *win_altframe(win_T *win, tabpage_T *tp) return target_fr; } -/* - * Return the tabpage that will be used if the current one is closed. - */ +// Return the tabpage that will be used if the current one is closed. static tabpage_T *alt_tabpage(void) { tabpage_T *tp; @@ -3351,9 +3303,7 @@ static tabpage_T *alt_tabpage(void) return tp; } -/* - * Find the left-upper window in frame "frp". - */ +// Find the left-upper window in frame "frp". win_T *frame2win(frame_T *frp) { while (frp->fr_win == NULL) { @@ -3557,10 +3507,8 @@ static bool frame_fixed_width(frame_T *frp) return true; } -/* - * Add a status line to windows at the bottom of "frp". - * Note: Does not check if there is room! - */ +// Add a status line to windows at the bottom of "frp". +// Note: Does not check if there is room! static void frame_add_statusline(frame_T *frp) { win_T *wp; @@ -3748,17 +3696,13 @@ static void frame_add_hsep(const frame_T *frp) } } -/* - * Set frame width from the window it contains. - */ +// Set frame width from the window it contains. static void frame_fix_width(win_T *wp) { wp->w_frame->fr_width = wp->w_width + wp->w_vsep_width; } -/* - * Set frame height from the window it contains. - */ +// Set frame height from the window it contains. static void frame_fix_height(win_T *wp) FUNC_ATTR_NONNULL_ALL { @@ -3913,12 +3857,10 @@ void close_others(int message, int forceit) } } -/* - * Allocate the first window and put an empty buffer in it. - * Called from main(). - * - * Return FAIL when something goes wrong. - */ +// Allocate the first window and put an empty buffer in it. +// Called from main(). +// +// Return FAIL when something goes wrong. int win_alloc_first(void) { if (win_alloc_firstwin(NULL) == FAIL) { @@ -3949,12 +3891,10 @@ void win_alloc_aucmd_win(void) RESET_BINDING(aucmd_win); } -/* - * Allocate the first window or the first window in a new tab page. - * When "oldwin" is NULL create an empty buffer for it. - * When "oldwin" is not NULL copy info from it to the new window. - * Return FAIL when something goes wrong (out of memory). - */ +// Allocate the first window or the first window in a new tab page. +// When "oldwin" is NULL create an empty buffer for it. +// When "oldwin" is not NULL copy info from it to the new window. +// Return FAIL when something goes wrong (out of memory). static int win_alloc_firstwin(win_T *oldwin) { curwin = win_alloc(NULL, false); @@ -3986,9 +3926,7 @@ static int win_alloc_firstwin(win_T *oldwin) return OK; } -/* - * Create a frame for window "wp". - */ +// Create a frame for window "wp". static void new_frame(win_T *wp) { frame_T *frp = xcalloc(1, sizeof(frame_T)); @@ -3998,9 +3936,7 @@ static void new_frame(win_T *wp) frp->fr_win = wp; } -/* - * Initialize the window and frame size to the maximum. - */ +// Initialize the window and frame size to the maximum. void win_init_size(void) { firstwin->w_height = (int)ROWS_AVAIL; @@ -4014,9 +3950,7 @@ void win_init_size(void) topframe->fr_width = Columns; } -/* - * Allocate a new tabpage_T and init the values. - */ +// Allocate a new tabpage_T and init the values. static tabpage_T *alloc_tabpage(void) { static int last_tp_handle = 0; @@ -4138,11 +4072,9 @@ int win_new_tabpage(int after, char_u *filename) return FAIL; } -/* - * Open a new tab page if ":tab cmd" was used. It will edit the same buffer, - * like with ":split". - * Returns OK if a new tab page was created, FAIL otherwise. - */ +// Open a new tab page if ":tab cmd" was used. It will edit the same buffer, +// like with ":split". +// Returns OK if a new tab page was created, FAIL otherwise. int may_open_tabpage(void) { int n = (cmdmod.cmod_tab == 0) ? postponed_split_tab : cmdmod.cmod_tab; @@ -4155,10 +4087,8 @@ int may_open_tabpage(void) return FAIL; } -/* - * Create up to "maxcount" tabpages with empty windows. - * Returns the number of resulting tab pages. - */ +// Create up to "maxcount" tabpages with empty windows. +// Returns the number of resulting tab pages. int make_tabpages(int maxcount) { int count = maxcount; @@ -4169,10 +4099,8 @@ int make_tabpages(int maxcount) count = (int)p_tpm; } - /* - * Don't execute autocommands while creating the tab pages. Must do that - * when putting the buffers in the windows. - */ + // Don't execute autocommands while creating the tab pages. Must do that + // when putting the buffers in the windows. block_autocmds(); for (todo = count - 1; todo > 0; todo--) { @@ -4239,9 +4167,7 @@ void close_tabpage(tabpage_T *tab) free_tabpage(tab); } -/* - * Find tab page "n" (first one is 1). Returns NULL when not found. - */ +// Find tab page "n" (first one is 1). Returns NULL when not found. tabpage_T *find_tabpage(int n) { tabpage_T *tp; @@ -4253,10 +4179,8 @@ tabpage_T *find_tabpage(int n) return tp; } -/* - * Get index of tab page "tp". First one has index 1. - * When not found returns number of tab pages plus one. - */ +// Get index of tab page "tp". First one has index 1. +// When not found returns number of tab pages plus one. int tabpage_index(tabpage_T *ftp) { int i = 1; @@ -4412,10 +4336,8 @@ static void tabpage_check_windows(tabpage_T *old_curtab) } } -/* - * Go to tab page "n". For ":tab N" and "Ngt". - * When "n" is 9999 go to the last tab page. - */ +// Go to tab page "n". For ":tab N" and "Ngt". +// When "n" is 9999 go to the last tab page. void goto_tabpage(int n) { tabpage_T *tp = NULL; // shut up compiler @@ -4504,10 +4426,8 @@ bool goto_tabpage_lastused(void) return false; } -/* - * Enter window "wp" in tab page "tp". - * Also updates the GUI tab. - */ +// Enter window "wp" in tab page "tp". +// Also updates the GUI tab. void goto_tabpage_win(tabpage_T *tp, win_T *wp) { goto_tabpage_tp(tp, true, true); @@ -4570,13 +4490,11 @@ void tabpage_move(int nr) redraw_tabline = true; } -/* - * Go to another window. - * When jumping to another buffer, stop Visual mode. Do this before - * changing windows so we can yank the selection into the '*' register. - * When jumping to another window on the same buffer, adjust its cursor - * position to keep the same Visual area. - */ +// Go to another window. +// When jumping to another buffer, stop Visual mode. Do this before +// changing windows so we can yank the selection into the '*' register. +// When jumping to another window on the same buffer, adjust its cursor +// position to keep the same Visual area. void win_goto(win_T *wp) { win_T *owp = curwin; @@ -4603,9 +4521,7 @@ void win_goto(win_T *wp) } } -/* - * Find the tabpage for window "win". - */ +// Find the tabpage for window "win". tabpage_T *win_find_tabpage(win_T *win) { FOR_ALL_TAB_WINDOWS(tp, wp) { @@ -4638,10 +4554,8 @@ win_T *win_vert_neighbor(tabpage_T *tp, win_T *wp, bool up, long count) } while (count--) { - /* - * First go upwards in the tree of frames until we find an upwards or - * downwards neighbor. - */ + // First go upwards in the tree of frames until we find an upwards or + // downwards neighbor. fr = foundfr; for (;;) { if (fr == tp->tp_topframe) { @@ -4658,9 +4572,7 @@ win_T *win_vert_neighbor(tabpage_T *tp, win_T *wp, bool up, long count) fr = fr->fr_parent; } - /* - * Now go downwards to find the bottom or top frame in it. - */ + // Now go downwards to find the bottom or top frame in it. for (;;) { if (nfr->fr_layout == FR_LEAF) { foundfr = nfr; @@ -4721,10 +4633,8 @@ win_T *win_horz_neighbor(tabpage_T *tp, win_T *wp, bool left, long count) } while (count--) { - /* - * First go upwards in the tree of frames until we find a left or - * right neighbor. - */ + // First go upwards in the tree of frames until we find a left or + // right neighbor. fr = foundfr; for (;;) { if (fr == tp->tp_topframe) { @@ -4741,9 +4651,7 @@ win_T *win_horz_neighbor(tabpage_T *tp, win_T *wp, bool left, long count) fr = fr->fr_parent; } - /* - * Now go downwards to find the leftmost or rightmost frame in it. - */ + // Now go downwards to find the leftmost or rightmost frame in it. for (;;) { if (nfr->fr_layout == FR_LEAF) { foundfr = nfr; @@ -5036,9 +4944,7 @@ static win_T *win_alloc(win_T *after, bool hidden) // initialized yet. gui_create_scrollbar() may trigger a FocusGained // event. block_autocmds(); - /* - * link the window in the window list - */ + // link the window in the window list if (!hidden) { win_append(after, new_wp); } @@ -5202,9 +5108,7 @@ void win_free_grid(win_T *wp, bool reinit) } } -/* - * Append window "wp" in the window list after window "after". - */ +// Append window "wp" in the window list after window "after". void win_append(win_T *after, win_T *wp) { win_T *before; @@ -5250,9 +5154,7 @@ void win_remove(win_T *wp, tabpage_T *tp) } } -/* - * Append frame "frp" in a frame list after frame "after". - */ +// Append frame "frp" in a frame list after frame "after". static void frame_append(frame_T *after, frame_T *frp) { frp->fr_next = after->fr_next; @@ -5263,9 +5165,7 @@ static void frame_append(frame_T *after, frame_T *frp) frp->fr_prev = after; } -/* - * Insert frame "frp" in a frame list before frame "before". - */ +// Insert frame "frp" in a frame list before frame "before". static void frame_insert(frame_T *before, frame_T *frp) { frp->fr_next = before; @@ -5278,9 +5178,7 @@ static void frame_insert(frame_T *before, frame_T *frp) } } -/* - * Remove a frame from a frame list. - */ +// Remove a frame from a frame list. static void frame_remove(frame_T *frp) { if (frp->fr_prev != NULL) { @@ -5390,9 +5288,7 @@ void may_trigger_winscrolled(void) } } -/* - * Save the size of all windows in "gap". - */ +// Save the size of all windows in "gap". void win_size_save(garray_T *gap) { ga_init(gap, (int)sizeof(int), 1); @@ -5459,12 +5355,10 @@ void win_reconfig_floats(void) } } -/* - * 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 - * to the bottom-right position plus one. - */ +// 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 +// to the bottom-right position plus one. static void frame_comp_pos(frame_T *topfrp, int *row, int *col) { win_T *wp; @@ -5500,19 +5394,15 @@ static void frame_comp_pos(frame_T *topfrp, int *row, int *col) } } -/* - * Set current window height and take care of repositioning other windows to - * fit around it. - */ +// Set current window height and take care of repositioning other windows to +// fit around it. void win_setheight(int height) { win_setheight_win(height, curwin); } -/* - * Set the window height of window "win" and take care of repositioning other - * windows to fit around it. - */ +// Set the window height of window "win" and take care of repositioning other +// windows to fit around it. void win_setheight_win(int height, win_T *win) { // Always keep current window at least one line high, even when 'winminheight' is zero. @@ -5547,19 +5437,17 @@ void win_setheight_win(int height, win_T *win) } } -/* - * Set the height of a frame to "height" and take care that all frames and - * windows inside it are resized. Also resize frames on the left and right if - * the are in the same FR_ROW frame. - * - * Strategy: - * If the frame is part of a FR_COL frame, try fitting the frame in that - * frame. If that doesn't work (the FR_COL frame is too small), recursively - * go to containing frames to resize them and make room. - * If the frame is part of a FR_ROW frame, all frames must be resized as well. - * Check for the minimal height of the FR_ROW frame. - * At the top level we can also use change the command line height. - */ +// Set the height of a frame to "height" and take care that all frames and +// windows inside it are resized. Also resize frames on the left and right if +// the are in the same FR_ROW frame. +// +// Strategy: +// If the frame is part of a FR_COL frame, try fitting the frame in that +// frame. If that doesn't work (the FR_COL frame is too small), recursively +// go to containing frames to resize them and make room. +// If the frame is part of a FR_ROW frame, all frames must be resized as well. +// Check for the minimal height of the FR_ROW frame. +// At the top level we can also use change the command line height. static void frame_setheight(frame_T *curfrp, int height) { int room; // total number of lines available @@ -5595,16 +5483,13 @@ static void frame_setheight(frame_T *curfrp, int height) } frame_setheight(curfrp->fr_parent, height); } else { - /* - * Column of frames: try to change only frames in this column. - */ - /* - * Do this twice: - * 1: compute room available, if it's not enough try resizing the - * containing frame. - * 2: compute the room available and adjust the height to it. - * Try not to reduce the height of a window with 'winfixheight' set. - */ + // Column of frames: try to change only frames in this column. + + // Do this twice: + // 1: compute room available, if it's not enough try resizing the + // containing frame. + // 2: compute the room available and adjust the height to it. + // Try not to reduce the height of a window with 'winfixheight' set. for (run = 1; run <= 2; run++) { room = 0; room_reserved = 0; @@ -5642,10 +5527,8 @@ static void frame_setheight(frame_T *curfrp, int height) //NOTREACHED } - /* - * Compute the number of lines we will take from others frames (can be - * negative!). - */ + // Compute the number of lines we will take from others frames (can be + // negative!). take = height - curfrp->fr_height; // If there is not enough room, also reduce the height of a window @@ -5668,16 +5551,12 @@ static void frame_setheight(frame_T *curfrp, int height) topframe->fr_height += room_cmdline; } - /* - * set the current frame to the new height - */ + // set the current frame to the new height frame_new_height(curfrp, height, false, false); - /* - * First take lines from the frames after the current frame. If - * that is not enough, takes lines from frames above the current - * frame. - */ + // First take lines from the frames after the current frame. If + // that is not enough, takes lines from frames above the current + // frame. for (run = 0; run < 2; run++) { if (run == 0) { frp = curfrp->fr_next; // 1st run: start with next window @@ -5718,10 +5597,8 @@ static void frame_setheight(frame_T *curfrp, int height) } } -/* - * Set current window width and take care of repositioning other windows to - * fit around it. - */ +// Set current window width and take care of repositioning other windows to +// fit around it. void win_setwidth(int width) { win_setwidth_win(width, curwin); @@ -5754,13 +5631,11 @@ void win_setwidth_win(int width, win_T *wp) } } -/* - * Set the width of a frame to "width" and take care that all frames and - * windows inside it are resized. Also resize frames above and below if the - * are in the same FR_ROW frame. - * - * Strategy is similar to frame_setheight(). - */ +// Set the width of a frame to "width" and take care that all frames and +// windows inside it are resized. Also resize frames above and below if the +// are in the same FR_ROW frame. +// +// Strategy is similar to frame_setheight(). static void frame_setwidth(frame_T *curfrp, int width) { int room; // total number of lines available @@ -5789,14 +5664,12 @@ static void frame_setwidth(frame_T *curfrp, int width) } frame_setwidth(curfrp->fr_parent, width); } else { - /* - * Row of frames: try to change only frames in this row. - * - * Do this twice: - * 1: compute room available, if it's not enough try resizing the - * containing frame. - * 2: compute the room available and adjust the width to it. - */ + // Row of frames: try to change only frames in this row. + // + // Do this twice: + // 1: compute room available, if it's not enough try resizing the + // containing frame. + // 2: compute the room available and adjust the width to it. for (run = 1; run <= 2; run++) { room = 0; room_reserved = 0; @@ -5823,10 +5696,8 @@ static void frame_setwidth(frame_T *curfrp, int width) + frame_minwidth(curfrp->fr_parent, NOWIN) - (int)p_wmw - 1); } - /* - * Compute the number of lines we will take from others frames (can be - * negative!). - */ + // Compute the number of lines we will take from others frames (can be + // negative!). take = width - curfrp->fr_width; // If there is not enough room, also reduce the width of a window @@ -5840,16 +5711,12 @@ static void frame_setwidth(frame_T *curfrp, int width) room_reserved = 0; } - /* - * set the current frame to the new width - */ + // set the current frame to the new width frame_new_width(curfrp, width, false, false); - /* - * First take lines from the frames right of the current frame. If - * that is not enough, takes lines from frames left of the current - * frame. - */ + // First take lines from the frames right of the current frame. If + // that is not enough, takes lines from frames left of the current + // frame. for (run = 0; run < 2; run++) { if (run == 0) { frp = curfrp->fr_next; // 1st run: start with next window @@ -6016,10 +5883,8 @@ void win_drag_status_line(win_T *dragwin, int offset) return; } - /* - * Grow frame fr by "offset" lines. - * Doesn't happen when dragging the last status line up. - */ + // Grow frame fr by "offset" lines. + // Doesn't happen when dragging the last status line up. if (fr != NULL) { frame_new_height(fr, fr->fr_height + offset, up, false); } @@ -6029,9 +5894,7 @@ void win_drag_status_line(win_T *dragwin, int offset) } else { fr = curfr->fr_next; // next frame gets smaller } - /* - * Now make the other frames smaller. - */ + // Now make the other frames smaller. while (fr != NULL && offset > 0) { n = frame_minheight(fr, NULL); if (fr->fr_height - offset <= n) { @@ -6059,9 +5922,7 @@ void win_drag_status_line(win_T *dragwin, int offset) showmode(); } -/* - * Separator line of dragwin is dragged "offset" lines right (negative is left). - */ +// Separator line of dragwin is dragged "offset" lines right (negative is left). void win_drag_vsep_line(win_T *dragwin, int offset) { frame_T *curfr; @@ -6214,10 +6075,8 @@ void scroll_to_fraction(win_T *wp, int prev_height) && (!wp->w_p_scb || wp == curwin) && (height < wp->w_buffer->b_ml.ml_line_count || wp->w_topline > 1)) { - /* - * Find a value for w_topline that shows the cursor at the same - * relative position in the window as before (more or less). - */ + // Find a value for w_topline that shows the cursor at the same + // relative position in the window as before (more or less). lnum = wp->w_cursor.lnum; if (lnum < 1) { // can happen when starting up lnum = 1; @@ -6237,11 +6096,9 @@ void scroll_to_fraction(win_T *wp, int prev_height) } if (sline < 0) { - /* - * Cursor line would go off top of screen if w_wrow was this high. - * Make cursor line the first line in the window. If not enough - * room use w_skipcol; - */ + // Cursor line would go off top of screen if w_wrow was this high. + // Make cursor line the first line in the window. If not enough + // room use w_skipcol; wp->w_wrow = line_size; if (wp->w_wrow >= wp->w_height_inner && (wp->w_width_inner - win_col_off(wp)) > 0) { @@ -6273,10 +6130,8 @@ void scroll_to_fraction(win_T *wp, int prev_height) } if (sline < 0) { - /* - * Line we want at top would go off top of screen. Use next - * line instead. - */ + // Line we want at top would go off top of screen. Use next + // line instead. (void)hasFoldingWin(wp, lnum, NULL, &lnum, true, NULL); lnum++; wp->w_wrow -= line_size + sline; @@ -6403,9 +6258,7 @@ void win_comp_scroll(win_T *wp) } } -/* - * command_height: called whenever p_ch has been changed - */ +// command_height: called whenever p_ch has been changed void command_height(void) { int h; @@ -6488,10 +6341,8 @@ void command_height(void) } } -/* - * Resize frame "frp" to be "n" lines higher (negative for less high). - * Also resize the frames it is contained in. - */ +// Resize frame "frp" to be "n" lines higher (negative for less high). +// Also resize the frames it is contained in. static void frame_add_height(frame_T *frp, int n) { frame_new_height(frp, frp->fr_height + n, false, false); @@ -6504,11 +6355,9 @@ 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. - */ +// 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_u *grab_file_name(long count, linenr_T *file_lnum) { int options = FNAME_MESS | FNAME_EXP | FNAME_REL | FNAME_UNESC; @@ -6529,19 +6378,17 @@ char_u *grab_file_name(long count, linenr_T *file_lnum) return file_name_at_cursor(options | FNAME_HYP, count, file_lnum); } -/* - * Return the file name under or after the cursor. - * - * The 'path' option is searched if the file name is not absolute. - * The string returned has been alloc'ed and should be freed by the caller. - * NULL is returned if the file name or file is not found. - * - * options: - * FNAME_MESS give error messages - * FNAME_EXP expand to path - * FNAME_HYP check for hypertext link - * FNAME_INCL apply "includeexpr" - */ +// Return the file name under or after the cursor. +// +// The 'path' option is searched if the file name is not absolute. +// The string returned has been alloc'ed and should be freed by the caller. +// NULL is returned if the file name or file is not found. +// +// options: +// FNAME_MESS give error messages +// FNAME_EXP expand to path +// FNAME_HYP check for hypertext link +// FNAME_INCL apply "includeexpr" char_u *file_name_at_cursor(int options, long count, linenr_T *file_lnum) { return file_name_in_line((char_u *)get_cursor_line_ptr(), @@ -6561,9 +6408,7 @@ char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u bool in_type = true; bool is_url = false; - /* - * search forward for what could be the start of a file name - */ + // search forward for what could be the start of a file name ptr = (char *)line + col; while (*ptr != NUL && !vim_isfilec(*ptr)) { MB_PTR_ADV(ptr); @@ -6575,10 +6420,8 @@ char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u return NULL; } - /* - * Search backward for first char of the file name. - * Go one char back to ":" before "//" even when ':' is not in 'isfname'. - */ + // Search backward for first char of the file name. + // Go one char back to ":" before "//" even when ':' is not in 'isfname'. while ((char_u *)ptr > line) { if ((len = (size_t)(utf_head_off((char *)line, ptr - 1))) > 0) { ptr -= len + 1; @@ -6589,10 +6432,8 @@ char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u } } - /* - * Search forward for the last char of the file name. - * Also allow ":/" when ':' is not in 'isfname'. - */ + // Search forward for the last char of the file name. + // Also allow ":/" when ':' is not in 'isfname'. len = 0; while (vim_isfilec(ptr[len]) || (ptr[len] == '\\' && ptr[len + 1] == ' ') || ((options & FNAME_HYP) && path_is_url(ptr + len)) @@ -6615,10 +6456,8 @@ char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u len += (size_t)(utfc_ptr2len(ptr + len)); } - /* - * If there is trailing punctuation, remove it. - * But don't remove "..", could be a directory name. - */ + // If there is trailing punctuation, remove it. + // But don't remove "..", could be a directory name. if (len > 2 && vim_strchr(".,:;!", ptr[len - 1]) != NULL && ptr[len - 2] != '.') { len--; @@ -6972,21 +6811,17 @@ void reset_lnums(void) } } -/* - * A snapshot of the window sizes, to restore them after closing the help - * window. - * Only these fields are used: - * fr_layout - * fr_width - * fr_height - * fr_next - * fr_child - * fr_win (only valid for the old curwin, NULL otherwise) - */ +// A snapshot of the window sizes, to restore them after closing the help +// window. +// Only these fields are used: +// fr_layout +// fr_width +// fr_height +// fr_next +// fr_child +// fr_win (only valid for the old curwin, NULL otherwise) -/* - * Create a snapshot of the current frame sizes. - */ +// Create a snapshot of the current frame sizes. void make_snapshot(int idx) { clear_snapshot(curtab, idx); @@ -7010,9 +6845,7 @@ static void make_snapshot_rec(frame_T *fr, frame_T **frp) } } -/* - * Remove any existing snapshot. - */ +// Remove any existing snapshot. static void clear_snapshot(tabpage_T *tp, int idx) { clear_snapshot_rec(tp->tp_snapshot[idx]); @@ -7097,11 +6930,9 @@ static int check_snapshot_rec(frame_T *sn, frame_T *fr) return OK; } -/* - * Copy the size of snapshot frame "sn" to frame "fr". Do the same for all - * following frames and children. - * Returns a pointer to the old current window, or NULL. - */ +// Copy the size of snapshot frame "sn" to frame "fr". Do the same for all +// following frames and children. +// Returns a pointer to the old current window, or NULL. static win_T *restore_snapshot_rec(frame_T *sn, frame_T *fr) { win_T *wp = NULL; -- cgit From 12afc344deb2df3973904fe55813d700da985dbf Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Tue, 6 Sep 2022 16:23:00 +0200 Subject: refactor: migrate comment style 2 #20080 --- src/nvim/window.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 530cbc0c7b..ca97ae6184 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2048,7 +2048,7 @@ static int get_maximum_wincount(frame_T *fr, int height) } /// Make all windows the same height. -///'next_curwin' will soon be the current window, make sure it has enough rows. +/// 'next_curwin' will soon be the current window, make sure it has enough rows. /// /// @param next_curwin pointer to current window to be or NULL /// @param current do only frame with current window @@ -5524,7 +5524,7 @@ static void frame_setheight(frame_T *curfrp, int height) } frame_setheight(curfrp->fr_parent, height + frame_minheight(curfrp->fr_parent, NOWIN) - (int)p_wmh - 1); - //NOTREACHED + // NOTREACHED } // Compute the number of lines we will take from others frames (can be -- cgit From 87e037e26cfd53c3c34ac9029a8833023af60a56 Mon Sep 17 00:00:00 2001 From: Shougo Date: Tue, 6 Sep 2022 23:33:25 +0900 Subject: fix(cmdheight=0): various issues part3 #19816 And fixed in https://github.com/neovim/neovim/pull/19801 regression. Fix #19834 Fix #19184 --- src/nvim/window.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index ca97ae6184..a6cc53080b 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -6270,12 +6270,6 @@ void command_height(void) // p_ch was changed in another tab page. curtab->tp_ch_used = p_ch; - // If the space for the command line is already more than 'cmdheight' there - // is nothing to do (window size must have decreased). - if (p_ch > old_p_ch && cmdline_row <= Rows - p_ch) { - return; - } - // If cmdline_row is smaller than what it is supposed to be for 'cmdheight' // then set old_p_ch to what it would be, so that the windows get resized // properly for the new value. -- cgit From ead524656dc1664622f80509a983519a190ca48a Mon Sep 17 00:00:00 2001 From: luukvbaal <31730729+luukvbaal@users.noreply.github.com> Date: Wed, 7 Sep 2022 18:08:00 +0200 Subject: vim-patch:9.0.0403: 'equalalways' may be off when 'laststatus' is zero (#20109) Problem: 'equalalways' may be off when 'laststatus' is zero. Solution: call last_status() before win_equal(). (Luuk van Baal, closes https://github.com/vim/vim/pull/11070) https://github.com/vim/vim/commit/fd7e60a33ddd83a82da4eb6267f1c12fa926f32b --- src/nvim/window.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index a6cc53080b..63a6eb9fb6 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2849,6 +2849,11 @@ int win_close(win_T *win, bool free_buf, bool force) check_cursor(); } + // If last window has a status line now and we don't want one, + // remove the status line. Do this before win_equal(), because + // it may change the height of a window. + last_status(false); + if (!was_floating) { if (!curwin->w_floating && p_ea && (*p_ead == 'b' || *p_ead == dir)) { // If the frame of the closed window contains the new current window, @@ -2870,10 +2875,6 @@ int win_close(win_T *win, bool free_buf, bool force) split_disallowed--; - // If last window has a status line now and we don't want one, - // remove the status line. - last_status(false); - // After closing the help window, try restoring the window layout from // before it was opened. if (help_window) { -- cgit From 3ff46544c9872b4161fd098569c30b55fe3abd36 Mon Sep 17 00:00:00 2001 From: Dundar Göc Date: Fri, 26 Aug 2022 23:11:25 +0200 Subject: refactor: replace char_u with char Work on https://github.com/neovim/neovim/issues/459 --- src/nvim/window.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 63a6eb9fb6..f6301457f3 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -746,7 +746,7 @@ void win_set_minimal_style(win_T *wp) 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 = xstrdup("auto"); } @@ -6467,10 +6467,10 @@ char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u // Also accept " line 999" with and without the same translation as // used in last_set_msg(). p = ptr + len; - if (STRNCMP(p, line_english, STRLEN(line_english)) == 0) { - p += STRLEN(line_english); - } else if (STRNCMP(p, line_transl, STRLEN(line_transl)) == 0) { - p += STRLEN(line_transl); + if (STRNCMP(p, line_english, strlen(line_english)) == 0) { + p += strlen(line_english); + } else if (STRNCMP(p, line_transl, strlen(line_transl)) == 0) { + p += strlen(line_transl); } else { p = skipwhite(p); } -- cgit From 708bd686516b420c2b65f4bc4d2c58fe43fb945e Mon Sep 17 00:00:00 2001 From: bfredl Date: Tue, 13 Sep 2022 12:56:30 +0200 Subject: feat(ui): use msg_grid based implementation for cmdheight=0 --- src/nvim/window.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index f6301457f3..2ccbdc10ea 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -6193,8 +6193,7 @@ void win_set_inner_size(win_T *wp, bool valid_cursor) // There is no point in adjusting the scroll position when exiting. Some // values might be invalid. - // Skip scroll_to_fraction() when 'cmdheight' was set to one from zero. - if (!exiting && !made_cmdheight_nonzero && valid_cursor) { + if (!exiting && valid_cursor) { scroll_to_fraction(wp, prev_height); } redraw_later(wp, UPD_NOT_VALID); // UPD_SOME_VALID?? -- cgit From 00cfc1dcebd1c81dd0d8c111740782e86cf2e385 Mon Sep 17 00:00:00 2001 From: bfredl Date: Fri, 16 Sep 2022 19:21:32 +0200 Subject: fix(redraw): avoid unnecessary redraws and glitches with floats+messages fixes #20106 fixes #20229 --- src/nvim/window.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 2ccbdc10ea..cc20a5fcec 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -871,8 +871,9 @@ int win_fdccol_count(win_T *wp) } } -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); @@ -910,6 +911,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; @@ -923,7 +929,6 @@ 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); @@ -2849,12 +2854,12 @@ int win_close(win_T *win, bool free_buf, bool force) check_cursor(); } - // If last window has a status line now and we don't want one, - // remove the status line. Do this before win_equal(), because - // it may change the height of a window. - last_status(false); - if (!was_floating) { + // If last window has a status line now and we don't want one, + // remove the status line. Do this before win_equal(), because + // it may change the height of a window. + last_status(false); + if (!curwin->w_floating && p_ea && (*p_ead == 'b' || *p_ead == dir)) { // If the frame of the closed window contains the new current window, // only resize that frame. Otherwise resize all windows. @@ -2898,7 +2903,10 @@ int win_close(win_T *win, bool free_buf, bool force) } curwin->w_pos_changed = true; - redraw_all_later(UPD_NOT_VALID); + if (!was_floating) { + // TODO(bfredl): how about no? + redraw_all_later(UPD_NOT_VALID); + } return OK; } @@ -5413,7 +5421,7 @@ void win_setheight_win(int height, win_T *win) if (win->w_floating) { win->w_float_config.height = height; win_config_float(win, win->w_float_config); - redraw_later(win, UPD_NOT_VALID); + redraw_later(win, UPD_VALID); } else { frame_setheight(win->w_frame, height + win->w_hsep_height + win->w_status_height); @@ -6059,6 +6067,9 @@ void win_new_height(win_T *wp, int height) wp->w_height = height; wp->w_pos_changed = true; win_set_inner_size(wp, true); + if (wp->w_status_height) { + wp->w_redr_status = true; + } } void scroll_to_fraction(win_T *wp, int prev_height) @@ -6196,7 +6207,7 @@ void win_set_inner_size(win_T *wp, bool valid_cursor) if (!exiting && valid_cursor) { scroll_to_fraction(wp, prev_height); } - redraw_later(wp, UPD_NOT_VALID); // UPD_SOME_VALID?? + redraw_later(wp, UPD_SOME_VALID); } if (width != wp->w_width_inner) { @@ -6608,7 +6619,6 @@ static void last_status_rec(frame_T *fr, bool statusline, bool is_stl_global) wp->w_hsep_height = 0; comp_col(); } - redraw_all_later(UPD_SOME_VALID); } else { // For a column or row frame, recursively call this function for all child frames FOR_ALL_FRAMES(fp, fr->fr_child) { @@ -7336,16 +7346,16 @@ void get_framelayout(const frame_T *fr, list_T *l, bool outer) } } -void win_ui_flush(void) +void win_ui_flush(bool validate) { FOR_ALL_TAB_WINDOWS(tp, wp) { if (wp->w_pos_changed && wp->w_grid_alloc.chars != NULL) { if (tp == curtab) { - ui_ext_win_position(wp); + ui_ext_win_position(wp, validate); } else { ui_call_win_hide(wp->w_grid_alloc.handle); + wp->w_pos_changed = false; } - wp->w_pos_changed = false; } if (tp == curtab) { ui_ext_win_viewport(wp); -- cgit From 2083c1771ad2de44c8e085062a0777e694b0fd4d Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 22 Sep 2022 20:25:34 +0800 Subject: fix(window): close floats first when closing buffer in other tab (#20284) --- src/nvim/window.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index cc20a5fcec..236663dfea 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2464,7 +2464,8 @@ void close_windows(buf_T *buf, bool keep_curwin) for (tp = first_tabpage; tp != NULL; tp = nexttp) { nexttp = tp->tp_next; if (tp != curtab) { - FOR_ALL_WINDOWS_IN_TAB(wp, tp) { + // Start from tp_lastwin to close floating windows with the same buffer first. + for (win_T *wp = tp->tp_lastwin; wp != NULL; wp = wp->w_prev) { if (wp->w_buffer == buf && !(wp->w_closing || wp->w_buffer->b_locked > 0)) { win_close_othertab(wp, false, tp); -- cgit From c28f00b101148d17a640fe2a186b23fbe230fbf3 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 23 Sep 2022 07:14:32 +0800 Subject: vim-patch:9.0.0550: crash when closing a tabpage and buffer is NULL Problem: Crash when closing a tabpage and buffer is NULL. Solution: Adjust how autocommands are triggered when closing a window. (closes vim/vim#11198, closes vim/vim#11197) https://github.com/vim/vim/commit/62de54b48d6354d4622ec0b21ffa4cf3cf312505 --- src/nvim/window.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 236663dfea..22c1b77570 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2439,7 +2439,6 @@ void curwin_init(void) void close_windows(buf_T *buf, bool keep_curwin) { tabpage_T *tp, *nexttp; - int h = tabline_height(); RedrawingDisabled++; @@ -2480,11 +2479,6 @@ void close_windows(buf_T *buf, bool keep_curwin) } RedrawingDisabled--; - - redraw_tabline = true; - if (h != tabline_height()) { - win_new_screen_rows(); - } } /// Check that the specified window is the last one. @@ -2575,7 +2569,6 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf, tabpage_T *prev // Don't trigger autocommands yet, they may use wrong values, so do // that below. goto_tabpage_tp(alt_tabpage(), false, true); - redraw_tabline = true; // save index for tabclosed event char_u prev_idx[NUMBUFLEN]; @@ -2584,12 +2577,7 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf, tabpage_T *prev // Safety check: Autocommands may have closed the window when jumping // to the other tab page. if (valid_tabpage(prev_curtab) && prev_curtab->tp_firstwin == win) { - int h = tabline_height(); - win_close_othertab(win, free_buf, prev_curtab); - if (h != tabline_height()) { - win_new_screen_rows(); - } } entering_window(curwin); @@ -2793,7 +2781,10 @@ int win_close(win_T *win, bool free_buf, bool force) if (curtab != prev_curtab && win_valid_any_tab(win) && win->w_buffer == NULL) { // Need to close the window anyway, since the buffer is NULL. + // Don't trigger autocmds with a NULL buffer. + block_autocmds(); win_close_othertab(win, false, prev_curtab); + unblock_autocmds(); return FAIL; } @@ -2990,6 +2981,8 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) vim_snprintf(prev_idx, NUMBUFLEN, "%i", tabpage_index(tp)); } + int h = tabline_height(); + if (tp == first_tabpage) { first_tabpage = tp->tp_next; } else { @@ -3004,6 +2997,10 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) ptp->tp_next = tp->tp_next; } free_tp = true; + redraw_tabline = true; + if (h != tabline_height()) { + win_new_screen_rows(); + } if (has_event(EVENT_TABCLOSED)) { apply_autocmds(EVENT_TABCLOSED, prev_idx, prev_idx, false, win->w_buffer); -- cgit From e6c214033a4fadf60faf99e95f8e9787e3c5e630 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 28 Sep 2022 06:22:11 +0800 Subject: fix(window): fix equalization with cmdheight=0 (#20369) --- src/nvim/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 22c1b77570..5523c3df8b 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2239,7 +2239,7 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int // Compute maximum number of windows vertically in this frame. n = frame_minheight(topfr, NOWIN); // add one for the bottom window if it doesn't have a statusline or separator - if (row + height == cmdline_row && p_ls == 0) { + if (row + height >= cmdline_row && p_ls == 0) { extra_sep = STATUS_HEIGHT; } else if (global_stl_height() > 0) { extra_sep = 1; -- cgit From df646572c53f55268a5dbb61628d7c3b302d5663 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Fri, 30 Sep 2022 09:53:52 +0200 Subject: docs: fix typos (#20394) Co-authored-by: Raphael Co-authored-by: smjonas Co-authored-by: zeertzjq --- src/nvim/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 5523c3df8b..adcf9cdd56 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -737,7 +737,7 @@ void win_set_minimal_style(win_T *wp) } // TODO(bfredl): this could use a highlight namespace directly, - // and avoid pecularities around window options + // and avoid peculiarities around window options char_u *old = (char_u *)wp->w_p_winhl; wp->w_p_winhl = ((*old == NUL) ? xstrdup("EndOfBuffer:") -- cgit From cb310d2901a0eb63721ac5930daaadee91929208 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 1 Oct 2022 21:59:53 +0800 Subject: vim-patch:9.0.0622: matchaddpos() can get slow when adding many matches Problem: matchaddpos() can get slow when adding many matches. Solution: Update the next available match ID when manually picking an ID and remove check if the available ID can be used. (idea by Rick Howe) https://github.com/vim/vim/commit/9f573a8df02d9f699a43d2afbd1d2841d700b9ad --- src/nvim/window.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index adcf9cdd56..c3806e10ff 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -4981,8 +4981,7 @@ static win_T *win_alloc(win_T *after, bool hidden) foldInitWin(new_wp); unblock_autocmds(); - new_wp->w_match_head = NULL; - new_wp->w_next_match_id = 4; + new_wp->w_next_match_id = 1000; // up to 1000 can be picked by the user return new_wp; } -- cgit From 7746f641b89d1d80b2121980f83ae1f322c30e89 Mon Sep 17 00:00:00 2001 From: bfredl Date: Tue, 4 Oct 2022 11:28:30 +0200 Subject: fix(options): no matter what is said, 'cmdheight' is tab-local (susy baka) --- src/nvim/window.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index c3806e10ff..c0edef7abc 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -3865,13 +3865,12 @@ void close_others(int message, int forceit) } // Allocate the first window and put an empty buffer in it. -// Called from main(). -// -// Return FAIL when something goes wrong. -int win_alloc_first(void) +// Only called from main(). +void win_alloc_first(void) { if (win_alloc_firstwin(NULL) == FAIL) { - return FAIL; + // allocating first buffer before any autocmds should not fail. + abort(); } first_tabpage = alloc_tabpage(); @@ -3880,8 +3879,6 @@ int win_alloc_first(void) curtab->tp_firstwin = firstwin; curtab->tp_lastwin = lastwin; curtab->tp_curwin = curwin; - - return OK; } // Init `aucmd_win`. This can only be done after the first window -- cgit From bc64aa435b84bb3a43501e101c51507c75fbd349 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 6 Oct 2022 09:03:49 +0800 Subject: vim-patch:9.0.0665: setting 'cmdheight' has no effect if last window was resized (#20500) Problem: Setting 'cmdheight' has no effect if last window was resized. Solution: Do apply 'cmdheight' when told to. Use the frame height instead of the cmdline_row. (closes vim/vim#11286) https://github.com/vim/vim/commit/0816f473ab2f6cf7d8311c0f97371cada7f20d18 --- src/nvim/window.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index c0edef7abc..242ff1fb12 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -6263,7 +6263,7 @@ void win_comp_scroll(win_T *wp) } } -// command_height: called whenever p_ch has been changed +/// command_height: called whenever p_ch has been changed. void command_height(void) { int h; @@ -6275,6 +6275,9 @@ void command_height(void) // p_ch was changed in another tab page. curtab->tp_ch_used = p_ch; + // Update cmdline_row to what it should be: just below the last window. + cmdline_row = topframe->fr_height; + // If cmdline_row is smaller than what it is supposed to be for 'cmdheight' // then set old_p_ch to what it would be, so that the windows get resized // properly for the new value. -- cgit From 5acf52e19b1f9920fe95b55588eff256a439d816 Mon Sep 17 00:00:00 2001 From: luukvbaal <31730729+luukvbaal@users.noreply.github.com> Date: Thu, 6 Oct 2022 08:57:52 +0200 Subject: feat(window/ui): add splitkeep option (#19243) vim-patch:9.0.0445: when opening/closing window text moves up/down Problem: When opening/closing window text moves up/down. Solution: Add the 'splitscroll' option. When off text will keep its position as much as possible. https://github.com/vim/vim/commit/29ab524358ba429bcf6811710afc97a978641f0b vim-patch:9.0.0455: a few problems with 'splitscroll' Problem: A few problems with 'splitscroll'. Solution: Fix 'splitscroll' problems. (Luuk van Baal, closes vim/vim#11117) https://github.com/vim/vim/commit/5ed391708a62b4ebaa84dd23e32a416e5c3383d9 vim-patch:9.0.0461: 'scroll' is not always updated Problem: 'scroll' is not always updated. Solution: Call win_init_size() at the right place. https://github.com/vim/vim/commit/470a14140bc06f1653edf26ab0b3c9b801080353 vim-patch:9.0.0465: cursor moves when cmdwin is closed when 'splitscroll' is off Problem: Cursor moves when cmdwin is closed when 'splitscroll' is off. Solution: Temporarily set 'splitscroll' when jumping back to the original window. (closes vim/vim#11128) https://github.com/vim/vim/commit/e697d488901b6321ddaad68b553f0a434c97d849 vim-patch:9.0.0469: cursor moves if cmdwin is closed when 'splitscroll' is off Problem: Cursor moves if cmdwin is closed when 'splitscroll' is off. Solution: Skip win_fix_cursor if called when cmdwin is open or closing. (Luuk van Baal, closes vim/vim#11134) https://github.com/vim/vim/commit/3735f11050616652525bf80b4fbcb2b3bfeab113 vim-patch:9.0.0478: test for 'splitscroll' takes too much time Problem: Test for 'splitscroll' takes too much time. Solution: Only test some of the combinations. (Luuk van Baal, closes vim/vim#11139) https://github.com/vim/vim/commit/594f9e09cd68e6277b8aa08094405bc642c5792a vim-patch:9.0.0486: text scrolled with 'nosplitscroll', autocmd win and help Problem: Text scrolled with 'nosplitscroll', autocmd win opened and help window closed. Solution: Skip win_fix_scroll() in more situations. (Luuk van Baal, closes vim/vim#11150) https://github.com/vim/vim/commit/d5bc762dea1fd32fa04342f8149f95ccfc3b9709 vim-patch:9.0.0505: various problems with 'nosplitscroll' Problem: Various problems with 'nosplitscroll'. Solution: Fix 'nosplitscroll' problems. (Luuk van Baal, closes vim/vim#11166) https://github.com/vim/vim/commit/faf1d412f5e3665021500b528c0e7301eb02bf0b vim-patch:9.0.0555: scrolling with 'nosplitscroll' in callback changing curwin Problem: Scrolling with 'nosplitscroll' in callback changing curwin. Solution: Invalidate w_cline_row in the right place. (Luuk van Baal, closes vim/vim#11185) https://github.com/vim/vim/commit/20e58561abc4116f3bfbafaef242d886dd77b303 vim-patch:9.0.0603: with 'nosplitscroll' folds are not handled correctly Problem: With 'nosplitscroll' folds are not handled correctly. Solution: Take care of closed folds when moving the cursor. (Luuk van Baal, closes vim/vim#11234) https://github.com/vim/vim/commit/7c1cbb6cd437c6e0c3ccc05840cc931108b4a60a vim-patch:9.0.0605: dump file missing Problem: Dump file missing. Solution: Add the missing dump file. (issue vim/vim#11234) https://github.com/vim/vim/commit/439a2ba1749463718b6ce1e1375b68c7b7cff808 vim-patch:9.0.0647: the 'splitscroll' option is not a good name Problem: The 'splitscroll' option is not a good name. Solution: Rename 'splitscroll' to 'splitkeep' and make it a string option, also supporting "topline". (Luuk van Baal, closes vim/vim#11258) https://github.com/vim/vim/commit/13ece2ae1d09009d3fb8acf858c288e7848ecdac vim-patch:9.0.0667: ml_get error when 'splitkeep' is "screen" Problem: ml_get error when 'splitkeep' is "screen". (Marius Gedminas) Solution: Check the botline is not too large. (Luuk van Baal, closes vim/vim#11293, closes vim/vim#11292) https://github.com/vim/vim/commit/346823d3e5668b99d2c2fd920e7f215e21ad3ea7 --- src/nvim/window.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 142 insertions(+), 5 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 242ff1fb12..ecd713013f 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -1487,6 +1487,8 @@ 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' && wp != aucmd_win) { + win_fix_scroll(false); } // Don't change the window height/width to 'winheight' / 'winwidth' if a @@ -1558,6 +1560,12 @@ 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++) { taggy_T *tag = &newp->w_tagstack[i]; @@ -2066,6 +2074,9 @@ 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' && next_curwin != aucmd_win) { + win_fix_scroll(true); + } } /// Set a frame to a new position and height, spreading the available room @@ -2858,6 +2869,9 @@ 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); + } } } @@ -3944,6 +3958,7 @@ static void new_frame(win_T *wp) void win_init_size(void) { firstwin->w_height = (int)ROWS_AVAIL; + firstwin->w_prev_height = (int)ROWS_AVAIL; firstwin->w_height_inner = firstwin->w_height - firstwin->w_winbar_height; firstwin->w_height_outer = firstwin->w_height; firstwin->w_winrow_off = firstwin->w_winbar_height; @@ -4050,6 +4065,7 @@ int win_new_tabpage(int after, char_u *filename) win_init_size(); firstwin->w_winrow = tabline_height(); + firstwin->w_prev_winrow = firstwin->w_winrow; win_comp_scroll(curwin); newtp->tp_topframe = topframe; @@ -4407,6 +4423,7 @@ void goto_tabpage_tp(tabpage_T *tp, bool trigger_enter_autocmds, bool trigger_le // Don't repeat a message in another tab page. set_keep_msg(NULL, 0); + skip_win_fix_scroll = true; if (tp != curtab && leave_tabpage(tp->tp_curwin->w_buffer, trigger_leave_autocmds) == OK) { if (valid_tabpage(tp)) { @@ -4417,6 +4434,7 @@ void goto_tabpage_tp(tabpage_T *tp, bool trigger_enter_autocmds, bool trigger_le trigger_leave_autocmds); } } + skip_win_fix_scroll = false; } /// Go to the last accessed tab page, if there is one. @@ -4747,7 +4765,9 @@ 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. - update_topline(curwin); + if (*p_spk == 'c') { + update_topline(curwin); + } // may have to copy the buffer options when 'cpo' contains 'S' if (wp->w_buffer != curbuf) { @@ -4764,7 +4784,11 @@ static void win_enter_ext(win_T *const wp, const int flags) if (!virtual_active()) { curwin->w_cursor.coladd = 0; } - changed_line_abv_curs(); // assume cursor position needs updating + if (*p_spk == 'c') { + changed_line_abv_curs(); // assume cursor position needs updating + } else { + win_fix_cursor(true); + } fix_current_dir(); @@ -5238,6 +5262,10 @@ void win_new_screen_rows(void) win_reconfig_floats(); // The size of floats might change compute_cmdrow(); curtab->tp_ch_used = p_ch; + + if (*p_spk != 'c' && !skip_win_fix_scroll) { + win_fix_scroll(true); + } } /// Called from win_new_screensize() after Columns changed. @@ -5435,6 +5463,11 @@ void win_setheight_win(int height, win_T *win) curtab->tp_ch_used = p_ch; msg_row = row; msg_col = 0; + + if (*p_spk != 'c') { + win_fix_scroll(true); + } + redraw_all_later(UPD_NOT_VALID); redraw_cmdline = true; } @@ -5921,6 +5954,11 @@ void win_drag_status_line(win_T *dragwin, int offset) cmdline_row = row; 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); + } + redraw_all_later(UPD_SOME_VALID); showmode(); } @@ -6043,6 +6081,99 @@ void set_fraction(win_T *wp) } } +/// 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). +void win_fix_scroll(int resize) +{ + linenr_T lnum; + + 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) { + // 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); + 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. + 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); + validate_botline(wp); + } + win_comp_scroll(wp); + wp->w_prev_height = wp->w_height; + wp->w_prev_winrow = wp->w_winrow; + } + skip_update_topline = false; + // Ensure cursor is valid when not in normal mode or when resized. + if (!(get_real_state() & (MODE_NORMAL|MODE_CMDLINE|MODE_TERMINAL))) { + win_fix_cursor(false); + } else if (resize) { + win_fix_cursor(true); + } +} + +/// 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) +{ + 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) { + return; + } + + // Determine valid cursor range. + so = MIN(wp->w_height_inner / 2, so); + wp->w_cursor.lnum = wp->w_topline; + linenr_T top = cursor_down_inner(wp, so); + wp->w_cursor.lnum = wp->w_botline - 1; + linenr_T bot = cursor_up_inner(wp, so); + wp->w_cursor.lnum = lnum; + // Check if cursor position is above or below valid cursor range. + 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; + } + + if (nlnum) { // 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. + wp->w_fraction = (nlnum == bot) ? FRACTION_MULT : 0; + scroll_to_fraction(wp, wp->w_prev_height); + validate_botline(curwin); + } + } +} + // Set the height of a window. // "height" excludes any window toolbar. // This takes care of the things inside the window, not what happens to the @@ -6181,7 +6312,7 @@ void win_set_inner_size(win_T *wp, bool valid_cursor) if (height != prev_height) { if (height > 0 && valid_cursor) { - if (wp == curwin) { + if (wp == curwin && *p_spk == 'c') { // w_wrow needs to be valid. When setting 'laststatus' this may // call win_new_height() recursively. validate_cursor(); @@ -6198,7 +6329,7 @@ void win_set_inner_size(win_T *wp, bool valid_cursor) // There is no point in adjusting the scroll position when exiting. Some // values might be invalid. - if (!exiting && valid_cursor) { + if (valid_cursor && !exiting && *p_spk == 'c') { scroll_to_fraction(wp, prev_height); } redraw_later(wp, UPD_SOME_VALID); @@ -6211,8 +6342,10 @@ void win_set_inner_size(win_T *wp, bool valid_cursor) changed_line_abv_curs_win(wp); invalidate_botline_win(wp); if (wp == curwin) { + skip_update_topline = (*p_spk != 'c'); update_topline(wp); curs_columns(wp, true); // validate w_wrow + skip_update_topline = false; } } redraw_later(wp, UPD_NOT_VALID); @@ -6252,7 +6385,7 @@ void win_comp_scroll(win_T *wp) { const long old_w_p_scr = wp->w_p_scr; - wp->w_p_scr = wp->w_height / 2; + wp->w_p_scr = wp->w_height_inner / 2; if (wp->w_p_scr == 0) { wp->w_p_scr = 1; } @@ -6606,6 +6739,10 @@ static void last_status_rec(frame_T *fr, bool statusline, bool is_stl_global) } comp_col(); } + // Set prev_height when difference is due to 'laststatus'. + if (abs(wp->w_height - wp->w_prev_height) == 1) { + wp->w_prev_height = wp->w_height; + } } else if (wp->w_status_height != 0 && is_stl_global) { // If statusline is global and the window has a statusline, replace it with a horizontal // separator -- cgit From 25dea99ce54de6a8c4369e28e0db82e1af669f24 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 6 Oct 2022 20:03:59 +0800 Subject: vim-patch:9.0.0670: no space for command line when there is a tabline (#20512) Problem: No space for command line when there is a tabline. Solution: Correct computation of where the command line should be. (closes vim/vim#11295) https://github.com/vim/vim/commit/c9f5f73206272ccad0aa536854debc5f9781978a --- src/nvim/window.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index ecd713013f..5993df64cd 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -4300,7 +4300,7 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, bool trigger_enter_a // When cmdheight is changed in a tab page with '-', cmdline_row is // changed but p_ch and tp_ch_used are not changed. Thus we also need to // check cmdline_row. - if ((row < cmdline_row) && (cmdline_row <= Rows - p_ch)) { + if (row < cmdline_row && cmdline_row <= Rows - p_ch) { clear_cmdline = true; } @@ -6409,7 +6409,7 @@ void command_height(void) curtab->tp_ch_used = p_ch; // Update cmdline_row to what it should be: just below the last window. - cmdline_row = topframe->fr_height; + cmdline_row = topframe->fr_height + tabline_height(); // If cmdline_row is smaller than what it is supposed to be for 'cmdheight' // then set old_p_ch to what it would be, so that the windows get resized -- cgit From d191070913dc195309926a91f97008defd877a71 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 7 Oct 2022 08:52:51 +0800 Subject: fix(ui): setting 'cmdheight' with global statusline (#20515) --- src/nvim/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 5993df64cd..b505350892 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -6409,7 +6409,7 @@ void command_height(void) curtab->tp_ch_used = p_ch; // Update cmdline_row to what it should be: just below the last window. - cmdline_row = topframe->fr_height + tabline_height(); + cmdline_row = topframe->fr_height + tabline_height() + global_stl_height(); // If cmdline_row is smaller than what it is supposed to be for 'cmdheight' // then set old_p_ch to what it would be, so that the windows get resized -- cgit From cfdb4cbada8c65aa57e69776bcc0f7b8b298317a Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 7 Oct 2022 09:43:16 +0800 Subject: fix: find multibyte file name in line (#20519) And remove unnecessary unsigned casts in fold marker comparison. --- src/nvim/window.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index b505350892..d7ca718c68 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -6545,7 +6545,7 @@ char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u // search forward for what could be the start of a file name ptr = (char *)line + col; - while (*ptr != NUL && !vim_isfilec(*ptr)) { + while (*ptr != NUL && !vim_isfilec((uint8_t)(*ptr))) { MB_PTR_ADV(ptr); } if (*ptr == NUL) { // nothing found @@ -6560,7 +6560,8 @@ char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u while ((char_u *)ptr > line) { if ((len = (size_t)(utf_head_off((char *)line, ptr - 1))) > 0) { ptr -= len + 1; - } else if (vim_isfilec(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; @@ -6570,7 +6571,7 @@ char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u // Search forward for the last char of the file name. // Also allow ":/" when ':' is not in 'isfname'. len = 0; - while (vim_isfilec(ptr[len]) || (ptr[len] == '\\' && ptr[len + 1] == ' ') + while (vim_isfilec((uint8_t)ptr[len]) || (ptr[len] == '\\' && ptr[len + 1] == ' ') || ((options & FNAME_HYP) && path_is_url(ptr + len)) || (is_url && vim_strchr(":?&=", ptr[len]) != NULL)) { // After type:// we also include :, ?, & and = as valid characters, so that -- cgit From 3b562535c323292637a53d36d9bd341feea2f2c6 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 12 Oct 2022 07:47:28 +0800 Subject: vim-patch:8.2.4523: when gvim is started maximized the 'window' option isn't set Problem: When gvim is started maximized the 'window' option isn't set properly. (Christian J. Robinson) Solution: Check if 'windows' was already set or not. (Ken Takata, closes vim/vim#9904) https://github.com/vim/vim/commit/6ca883dd8a585a85acdf9303b434211ea91872a7 --- src/nvim/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index d7ca718c68..d99d22af12 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5226,7 +5226,7 @@ void win_new_screensize(void) if (old_Rows != Rows) { // If 'window' uses the whole screen, keep it using that. // Don't change it when set with "-w size" on the command line. - if (p_window == old_Rows - 1 || (old_Rows == 0 && p_window == 0)) { + if (p_window == old_Rows - 1 || (old_Rows == 0 && !option_was_set("window"))) { p_window = Rows - 1; } old_Rows = Rows; -- cgit From 0ef6aaa3a73d5089bf53e804364950c81784574c Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Wed, 12 Oct 2022 14:53:40 +0100 Subject: refactor: clint (#20600) --- src/nvim/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index d99d22af12..c18f8ca6a3 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2583,7 +2583,7 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf, tabpage_T *prev // save index for tabclosed event char_u prev_idx[NUMBUFLEN]; - sprintf((char *)prev_idx, "%i", tabpage_index(prev_curtab)); + snprintf((char *)prev_idx, NUMBUFLEN, "%i", tabpage_index(prev_curtab)); // Safety check: Autocommands may have closed the window when jumping // to the other tab page. -- cgit From cd1e0bb87dc71d51d9e8da097f5822c37e909335 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 13 Oct 2022 10:13:17 +0800 Subject: vim-patch:8.2.4462: not enough testing for quickfix code Problem: Not enough testing for quickfix code. Solution: Add more tests. Fix uncovered problem. (Yegappan Lakshmanan, closes vim/vim#9839) https://github.com/vim/vim/commit/9c9be05b17ececb1515a2f41a4dedbf848d3d8b6 Omit Test_helpgrep_vim9_restore_cpo(). Cherry-pick test_quickfix.vim change from patch 8.2.0644. --- src/nvim/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index c18f8ca6a3..ed64062a55 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -4913,7 +4913,7 @@ win_T *buf_jump_open_win(buf_T *buf) } /// Jump to the first open window in any tab page that contains buffer "buf", -/// if one exists. +/// if one exists. First search in the windows present in the current tab page. /// @return the found window, or NULL. win_T *buf_jump_open_tab(buf_T *buf) { -- cgit From 0578c67767a9cbaeaab167092a7bdb389f556ee4 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 14 Oct 2022 07:29:58 +0800 Subject: vim-patch:9.0.0747: too many #ifdefs (#20641) Problem: Too many #ifdefs. Solution: Gradudate the +cmdline_info feature. (Martin Tournoij, closes vim/vim#11330) https://github.com/vim/vim/commit/ba43e76fcd5b2da57dbaa4d9a555793fe8ac344e --- src/nvim/window.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index ed64062a55..002d95ac2a 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -554,6 +554,7 @@ wingotofile: no_mapping--; allow_keys--; (void)add_to_showcmd(xchar); + switch (xchar) { case '}': xchar = Ctrl_RSB; -- cgit From 46eabe1ac1f70d0d7b199cb7e505b275b2f01bff Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Sun, 16 Oct 2022 22:34:14 +0200 Subject: fix: 'scroll' is not set correctly for floats with 'splitkeep' vim-patch:9.0.0780: 'scroll' value computed in unexpected location Problem: 'scroll' value computed in unexpected location. Solution: Compute 'scroll' when the window height is changed. (Luuk van Baal, closes vim/vim#11387) https://github.com/vim/vim/commit/a1a46da87d91cfbf46866627b3e66a757145e8c3 --- src/nvim/window.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 002d95ac2a..7c246191a5 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -6119,7 +6119,6 @@ void win_fix_scroll(int resize) invalidate_botline_win(wp); validate_botline(wp); } - win_comp_scroll(wp); wp->w_prev_height = wp->w_height; wp->w_prev_winrow = wp->w_winrow; } @@ -6292,7 +6291,6 @@ void scroll_to_fraction(win_T *wp, int prev_height) wp->w_prev_fraction_row = wp->w_wrow; } - win_comp_scroll(wp); redraw_later(wp, UPD_SOME_VALID); wp->w_redr_status = true; invalidate_botline_win(wp); @@ -6327,6 +6325,7 @@ void win_set_inner_size(win_T *wp, bool valid_cursor) } 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. -- cgit From a5a5e273233ec6738fa6cda2a6618009646c4c47 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Tue, 18 Oct 2022 23:06:10 +0100 Subject: refactor(window.c): reduce scope of locals (#20301) --- src/nvim/window.c | 551 +++++++++++++++++++++++------------------------------- 1 file changed, 234 insertions(+), 317 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 7c246191a5..0e6bb7822a 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -125,15 +125,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 { \ @@ -236,8 +231,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,6 +245,7 @@ newwindow: win_goto(wp); } break; + } // close all but current window case Ctrl_O: @@ -269,6 +265,7 @@ 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) { @@ -346,7 +343,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; @@ -486,11 +483,12 @@ newwindow: // 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 = (char *)grab_file_name(Prenum1, &lnum); if (ptr != NULL) { tabpage_T *oldtab = curtab; win_T *oldwin = curwin; @@ -510,6 +508,7 @@ wingotofile: xfree(ptr); } break; + } // Go to the first occurrence of the identifier under cursor along path in a // new window -- webb @@ -518,8 +517,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; } @@ -532,6 +533,7 @@ wingotofile: xfree(ptr); curwin->w_set_curswant = true; break; + } // Quickfix window only: view the result under the cursor in a new split. case K_KENTER: @@ -638,11 +640,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(); } @@ -1025,26 +1029,13 @@ int win_split(int size, int flags) 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) { return FAIL; } + win_T *oldwin; if (flags & WSP_TOP) { oldwin = firstwin; } else if (flags & WSP_BOT || curwin->w_floating) { @@ -1054,6 +1045,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 @@ -1065,30 +1058,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; + 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); @@ -1134,7 +1130,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 @@ -1147,27 +1143,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); @@ -1230,7 +1227,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 @@ -1280,6 +1277,9 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) CLEAR_FIELD(wp->w_border_adj); } + 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) @@ -1308,7 +1308,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; @@ -1326,6 +1326,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 { @@ -1492,6 +1493,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) 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) { @@ -1530,8 +1533,6 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) // 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++; @@ -1568,7 +1569,7 @@ static void win_init(win_T *newp, win_T *oldp, int flags) } // 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) { @@ -1690,7 +1691,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. @@ -1720,6 +1720,8 @@ 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--) { if (vertical) { @@ -1745,12 +1747,6 @@ int make_windows(int count, bool vertical) // 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; @@ -1762,6 +1758,8 @@ static void win_exchange(long Prenum) return; } + frame_T *frp; + // find window to exchange with if (Prenum) { frp = curwin->w_frame->fr_parent->fr_child; @@ -1779,7 +1777,7 @@ static void win_exchange(long Prenum) if (frp == NULL || frp->fr_win == NULL || frp->fr_win == curwin) { return; } - wp = frp->fr_win; + 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 @@ -1787,8 +1785,8 @@ static void win_exchange(long Prenum) // 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 *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); @@ -1805,7 +1803,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,11 +1835,6 @@ static void win_exchange(long Prenum) // 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; @@ -1854,6 +1847,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")); @@ -1861,6 +1855,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 @@ -1893,7 +1890,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; @@ -1965,8 +1962,6 @@ static void win_totop(int size, int flags) // 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; @@ -1982,7 +1977,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; @@ -1999,7 +1994,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->w_status_height = height; @@ -2096,15 +2091,11 @@ void win_equal(win_T *next_curwin, bool current, int dir) static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int dir, int col, int row, int width, int height) { - int n, m; int extra_sep = 0; - int wincount, totwincount = 0; - frame_T *fr; + int totwincount = 0; int next_curwin_size = 0; int room = 0; - int new_size; int has_next_curwin = 0; - bool hnc; if (topfr->fr_layout == FR_LEAF) { // Set the width/height of this frame. @@ -2125,7 +2116,7 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int if (dir != 'v') { // equalize frame widths // Compute the maximum number of windows horizontally in this // frame. - n = frame_minwidth(topfr, NOWIN); + int n = frame_minwidth(topfr, NOWIN); // add one for the rightmost window, it doesn't have a separator if (col + width == Columns) { extra_sep = 1; @@ -2138,13 +2129,14 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int // Compute width for "next_curwin" window and room available for // other windows. // "m" is the minimal width when counting p_wiw for "next_curwin". - m = frame_minwidth(topfr, next_curwin); + int m = frame_minwidth(topfr, next_curwin); room = width - m; if (room < 0) { next_curwin_size = (int)p_wiw + room; room = 0; } else { next_curwin_size = -1; + frame_T *fr; FOR_ALL_FRAMES(fr, topfr->fr_child) { if (!frame_fixed_width(fr)) { continue; @@ -2152,7 +2144,7 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int // If 'winfixwidth' set keep the window width if possible. // Watch out for this window being the next_curwin. n = frame_minwidth(fr, NOWIN); - new_size = fr->fr_width; + int new_size = fr->fr_width; if (frame_has_win(fr, next_curwin)) { room += (int)p_wiw - (int)p_wmw; next_curwin_size = 0; @@ -2193,8 +2185,10 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int } } + frame_T *fr; FOR_ALL_FRAMES(fr, topfr->fr_child) { - wincount = 1; + int wincount = 1; + int new_size; if (fr->fr_next == NULL) { // last frame gets all that remains (avoid roundoff error) new_size = width; @@ -2205,14 +2199,10 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int wincount = 0; // doesn't count as a sizeable window } else { // Compute the maximum number of windows horiz. in "fr". - n = frame_minwidth(fr, NOWIN); + int n = frame_minwidth(fr, NOWIN); wincount = (n + (fr->fr_next == NULL ? extra_sep : 0)) / ((int)p_wmw + 1); - m = frame_minwidth(fr, next_curwin); - if (has_next_curwin) { - hnc = frame_has_win(fr, next_curwin); - } else { - hnc = false; - } + int m = frame_minwidth(fr, next_curwin); + bool hnc = has_next_curwin && frame_has_win(fr, next_curwin); if (hnc) { // don't count next_curwin wincount--; } @@ -2249,7 +2239,7 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int if (dir != 'h') { // equalize frame heights // Compute maximum number of windows vertically in this frame. - n = frame_minheight(topfr, NOWIN); + int n = frame_minheight(topfr, NOWIN); // add one for the bottom window if it doesn't have a statusline or separator if (row + height >= cmdline_row && p_ls == 0) { extra_sep = STATUS_HEIGHT; @@ -2264,7 +2254,7 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int // Compute height for "next_curwin" window and room available for // other windows. // "m" is the minimal height when counting p_wh for "next_curwin". - m = frame_minheight(topfr, next_curwin); + int m = frame_minheight(topfr, next_curwin); room = height - m; if (room < 0) { // The room is less than 'winheight', use all space for the @@ -2273,6 +2263,7 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int room = 0; } else { next_curwin_size = -1; + frame_T *fr; FOR_ALL_FRAMES(fr, topfr->fr_child) { if (!frame_fixed_height(fr)) { continue; @@ -2280,7 +2271,7 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int // If 'winfixheight' set keep the window height if possible. // Watch out for this window being the next_curwin. n = frame_minheight(fr, NOWIN); - new_size = fr->fr_height; + int new_size = fr->fr_height; if (frame_has_win(fr, next_curwin)) { room += (int)p_wh - (int)p_wmh; next_curwin_size = 0; @@ -2321,8 +2312,10 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int } } + frame_T *fr; FOR_ALL_FRAMES(fr, topfr->fr_child) { - wincount = 1; + int new_size; + int wincount = 1; if (fr->fr_next == NULL) { // last frame gets all that remains (avoid roundoff error) new_size = height; @@ -2333,14 +2326,10 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int wincount = 0; // doesn't count as a sizeable window } else { // Compute the maximum number of windows vert. in "fr". - n = frame_minheight(fr, NOWIN); + int n = frame_minheight(fr, NOWIN); wincount = get_maximum_wincount(fr, (n + (fr->fr_next == NULL ? extra_sep : 0))); - m = frame_minheight(fr, next_curwin); - if (has_next_curwin) { - hnc = frame_has_win(fr, next_curwin); - } else { - hnc = false; - } + int m = frame_minheight(fr, next_curwin); + bool hnc = has_next_curwin && frame_has_win(fr, next_curwin); if (hnc) { // don't count next_curwin wincount--; } @@ -2450,8 +2439,6 @@ void curwin_init(void) /// @param keep_curwin don't close `curwin` void close_windows(buf_T *buf, bool keep_curwin) { - tabpage_T *tp, *nexttp; - RedrawingDisabled++; // Start from lastwin to close floating windows with the same buffer first. @@ -2471,8 +2458,10 @@ void close_windows(buf_T *buf, bool keep_curwin) } } + tabpage_T *nexttp; + // Also check windows in other tab pages. - for (tp = first_tabpage; tp != NULL; tp = nexttp) { + for (tabpage_T *tp = first_tabpage; tp != NULL; tp = nexttp) { nexttp = tp->tp_next; if (tp != curtab) { // Start from tp_lastwin to close floating windows with the same buffer first. @@ -2645,11 +2634,6 @@ static void win_close_buffer(win_T *win, bool free_buf, bool abort_if_last) // Returns FAIL when the window was not closed. int win_close(win_T *win, bool free_buf, bool force) { - win_T *wp; - bool other_buffer = false; - bool close_curwin = false; - int dir; - bool help_window = false; tabpage_T *prev_curtab = curtab; frame_T *win_frame = win->w_floating ? NULL : win->w_frame->fr_parent; const bool had_diffmode = win->w_p_diff; @@ -2694,6 +2678,8 @@ int win_close(win_T *win, bool free_buf, bool force) return FAIL; } + bool help_window = false; + // When closing the help window, try restoring a snapshot after closing // the window. Otherwise clear the snapshot, it's now invalid. if (bt_help(win->w_buffer)) { @@ -2702,6 +2688,9 @@ int win_close(win_T *win, bool free_buf, bool force) clear_snapshot(curtab, SNAP_HELP_IDX); } + win_T *wp; + bool other_buffer = false; + if (win == curwin) { leaving_window(curwin); @@ -2816,6 +2805,7 @@ int win_close(win_T *win, bool free_buf, bool force) // Free the memory used for the window and get the window that received // the screen space. + int dir; wp = win_free_mem(win, &dir, NULL); if (help_window) { @@ -2827,6 +2817,8 @@ int win_close(win_T *win, bool free_buf, bool force) } } + bool close_curwin = false; + // Make sure curwin isn't invalid. It can cause severe trouble when // printing an error message. For win_equal() curbuf needs to be valid // too. @@ -2938,10 +2930,6 @@ static void do_autocmd_winclosed(win_T *win) // updated. void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) { - int dir; - tabpage_T *ptp = NULL; - bool free_tp = false; - // Get here with win->w_buffer == NULL when win_close() detects the tab page // changed. if (win->w_closing @@ -2961,6 +2949,8 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, false, true); } + tabpage_T *ptp = NULL; + // Careful: Autocommands may have closed the tab page or made it the // current tab page. for (ptp = first_tabpage; ptp != NULL && ptp != tp; ptp = ptp->tp_next) {} @@ -2989,6 +2979,8 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) } } + bool free_tp = false; + // When closing the last window in a tab page remove the tab page. if (tp->tp_firstwin == tp->tp_lastwin) { char prev_idx[NUMBUFLEN]; @@ -3023,6 +3015,7 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) } // Free the memory used for the window. + int dir; win_free_mem(win, &dir, tp); if (free_tp) { @@ -3038,12 +3031,11 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) /// @return a pointer to the window that got the freed up space. static win_T *win_free_mem(win_T *win, int *dirp, tabpage_T *tp) { - frame_T *frp; win_T *wp; if (!win->w_floating) { // Remove the window and its frame from the tree of frames. - frp = win->w_frame; + frame_T *frp = win->w_frame; wp = winframe_remove(win, dirp, tp); xfree(frp); } else { @@ -3072,8 +3064,6 @@ static win_T *win_free_mem(win_T *win, int *dirp, tabpage_T *tp) #if defined(EXITFREE) void win_free_all(void) { - int dummy; - // avoid an error for switching tabpage with the cmdline window open cmdwin_type = 0; @@ -3084,6 +3074,7 @@ void win_free_all(void) while (lastwin != NULL && lastwin->w_floating) { win_T *wp = lastwin; win_remove(lastwin, NULL); + int dummy; (void)win_free_mem(wp, &dummy, NULL); if (wp == aucmd_win) { aucmd_win = NULL; @@ -3091,11 +3082,13 @@ void win_free_all(void) } if (aucmd_win != NULL) { + int dummy; (void)win_free_mem(aucmd_win, &dummy, NULL); aucmd_win = NULL; } while (firstwin != NULL) { + int dummy; (void)win_free_mem(firstwin, &dummy, NULL); } @@ -3114,18 +3107,16 @@ void win_free_all(void) /// @return a pointer to the window that got the freed up space. win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp) { - frame_T *frp, *frp2, *frp3; - frame_T *frp_close = win->w_frame; - win_T *wp; - // If there is only one window there is nothing to remove. if (tp == NULL ? ONE_WINDOW : tp->tp_firstwin == tp->tp_lastwin) { return NULL; } + frame_T *frp_close = win->w_frame; + // Remove the window from its frame. - frp2 = win_altframe(win, tp); - wp = frame2win(frp2); + frame_T *frp2 = win_altframe(win, tp); + win_T *wp = frame2win(frp2); // Remove this frame from the list of frames. frame_remove(frp_close); @@ -3135,8 +3126,8 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp) // (as close to the closed frame as possible) to distribute the height // to. if (frp2->fr_win != NULL && frp2->fr_win->w_p_wfh) { - frp = frp_close->fr_prev; - frp3 = frp_close->fr_next; + frame_T *frp = frp_close->fr_prev; + frame_T *frp3 = frp_close->fr_next; while (frp != NULL || frp3 != NULL) { if (frp != NULL) { if (!frame_fixed_height(frp)) { @@ -3164,8 +3155,8 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp) // (as close to the closed frame as possible) to distribute the width // to. if (frp2->fr_win != NULL && frp2->fr_win->w_p_wfw) { - frp = frp_close->fr_prev; - frp3 = frp_close->fr_next; + frame_T *frp = frp_close->fr_prev; + frame_T *frp3 = frp_close->fr_next; while (frp != NULL || frp3 != NULL) { if (frp != NULL) { if (!frame_fixed_width(frp)) { @@ -3204,6 +3195,7 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp) // and remove it. frp2->fr_parent->fr_layout = frp2->fr_layout; frp2->fr_parent->fr_child = frp2->fr_child; + frame_T *frp; FOR_ALL_FRAMES(frp, frp2->fr_child) { frp->fr_parent = frp2->fr_parent; } @@ -3229,6 +3221,7 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp) if (frp->fr_prev != NULL) { frp->fr_prev->fr_next = frp->fr_child; } + frame_T *frp3; for (frp3 = frp->fr_child;; frp3 = frp3->fr_next) { frp3->fr_parent = frp2; if (frp3->fr_next == NULL) { @@ -3261,13 +3254,11 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp) /// is left over after "win" is closed. static frame_T *win_altframe(win_T *win, tabpage_T *tp) { - frame_T *frp; - if (tp == NULL ? ONE_WINDOW : tp->tp_firstwin == tp->tp_lastwin) { return alt_tabpage()->tp_curwin->w_frame; } - frp = win->w_frame; + frame_T *frp = win->w_frame; if (frp->fr_prev == NULL) { return frp->fr_next; @@ -3313,14 +3304,13 @@ static frame_T *win_altframe(win_T *win, tabpage_T *tp) // Return the tabpage that will be used if the current one is closed. static tabpage_T *alt_tabpage(void) { - tabpage_T *tp; - // Use the next tab page if possible. if (curtab->tp_next != NULL) { return curtab->tp_next; } // Find the last but one tab page. + tabpage_T *tp; for (tp = first_tabpage; tp->tp_next != curtab; tp = tp->tp_next) {} return tp; } @@ -3358,8 +3348,7 @@ static bool frame_has_win(const frame_T *frp, const win_T *wp) static bool is_bottom_win(win_T *wp) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - frame_T *frp; - for (frp = wp->w_frame; frp->fr_parent != NULL; frp = frp->fr_parent) { + for (frame_T *frp = wp->w_frame; frp->fr_parent != NULL; frp = frp->fr_parent) { if (frp->fr_parent->fr_layout == FR_COL && frp->fr_next != NULL) { return false; } @@ -3375,19 +3364,15 @@ static bool is_bottom_win(win_T *wp) void frame_new_height(frame_T *topfrp, int height, bool topfirst, bool wfh) FUNC_ATTR_NONNULL_ALL { - frame_T *frp; - int extra_lines; - int h; - win_T *wp; - if (topfrp->fr_win != NULL) { // Simple case: just one window. - wp = topfrp->fr_win; + win_T *wp = topfrp->fr_win; if (is_bottom_win(wp)) { wp->w_hsep_height = 0; } win_new_height(wp, height - wp->w_hsep_height - wp->w_status_height); } else if (topfrp->fr_layout == FR_ROW) { + frame_T *frp; do { // All frames in this row get the same new height. FOR_ALL_FRAMES(frp, topfrp->fr_child) { @@ -3403,7 +3388,7 @@ void frame_new_height(frame_T *topfrp, int height, bool topfirst, bool wfh) // Complicated case: Resize a column of frames. Resize the bottom // frame first, frames above that when needed. - frp = topfrp->fr_child; + frame_T *frp = topfrp->fr_child; if (wfh) { // Advance past frames with one window with 'wfh' set. while (frame_fixed_height(frp)) { @@ -3426,11 +3411,11 @@ void frame_new_height(frame_T *topfrp, int height, bool topfirst, bool wfh) } } - extra_lines = height - topfrp->fr_height; + int extra_lines = height - topfrp->fr_height; if (extra_lines < 0) { // reduce height of contained frames, bottom or top frame first while (frp != NULL) { - h = frame_minheight(frp, NULL); + int h = frame_minheight(frp, NULL); if (frp->fr_height + extra_lines < h) { extra_lines += frp->fr_height - h; frame_new_height(frp, h, topfirst, wfh); @@ -3533,10 +3518,8 @@ static bool frame_fixed_width(frame_T *frp) // Note: Does not check if there is room! static void frame_add_statusline(frame_T *frp) { - win_T *wp; - if (frp->fr_layout == FR_LEAF) { - wp = frp->fr_win; + 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; @@ -3564,15 +3547,11 @@ static void frame_add_statusline(frame_T *frp) /// may cause the width not to be set. static void frame_new_width(frame_T *topfrp, int width, bool leftfirst, bool wfw) { - frame_T *frp; - int extra_cols; - int w; - win_T *wp; - if (topfrp->fr_layout == FR_LEAF) { // Simple case: just one window. - wp = topfrp->fr_win; + win_T *wp = topfrp->fr_win; // Find out if there are any windows right of this one. + frame_T *frp; for (frp = topfrp; frp->fr_parent != NULL; frp = frp->fr_parent) { if (frp->fr_parent->fr_layout == FR_ROW && frp->fr_next != NULL) { break; @@ -3583,6 +3562,7 @@ static void frame_new_width(frame_T *topfrp, int width, bool leftfirst, bool wfw } win_new_width(wp, width - wp->w_vsep_width); } else if (topfrp->fr_layout == FR_COL) { + frame_T *frp; do { // All frames in this column get the same new width. FOR_ALL_FRAMES(frp, topfrp->fr_child) { @@ -3598,7 +3578,7 @@ static void frame_new_width(frame_T *topfrp, int width, bool leftfirst, bool wfw // Complicated case: Resize a row of frames. Resize the rightmost // frame first, frames left of it when needed. - frp = topfrp->fr_child; + frame_T *frp = topfrp->fr_child; if (wfw) { // Advance past frames with one window with 'wfw' set. while (frame_fixed_width(frp)) { @@ -3621,11 +3601,11 @@ static void frame_new_width(frame_T *topfrp, int width, bool leftfirst, bool wfw } } - extra_cols = width - topfrp->fr_width; + int extra_cols = width - topfrp->fr_width; if (extra_cols < 0) { // reduce frame width, rightmost frame first while (frp != NULL) { - w = frame_minwidth(frp, NULL); + int w = frame_minwidth(frp, NULL); if (frp->fr_width + extra_cols < w) { extra_cols += frp->fr_width - w; frame_new_width(frp, w, leftfirst, wfw); @@ -3661,10 +3641,8 @@ static void frame_new_width(frame_T *topfrp, int width, bool leftfirst, bool wfw static void frame_add_vsep(const frame_T *frp) FUNC_ATTR_NONNULL_ARG(1) { - win_T *wp; - if (frp->fr_layout == FR_LEAF) { - wp = frp->fr_win; + win_T *wp = frp->fr_win; if (wp->w_vsep_width == 0) { if (wp->w_width > 0) { // don't make it negative wp->w_width--; @@ -3692,10 +3670,8 @@ static void frame_add_vsep(const frame_T *frp) static void frame_add_hsep(const frame_T *frp) FUNC_ATTR_NONNULL_ARG(1) { - win_T *wp; - if (frp->fr_layout == FR_LEAF) { - wp = frp->fr_win; + 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++; @@ -3736,9 +3712,7 @@ static void frame_fix_height(win_T *wp) /// When "next_curwin" is NOWIN, don't use at least one line for the current window. static int frame_minheight(frame_T *topfrp, win_T *next_curwin) { - frame_T *frp; int m; - int n; if (topfrp->fr_win != NULL) { // Combined height of window bar and separator column or status line. @@ -3759,8 +3733,9 @@ static int frame_minheight(frame_T *topfrp, win_T *next_curwin) } else if (topfrp->fr_layout == FR_ROW) { // get the minimal height from each frame in this row m = 0; + frame_T *frp; FOR_ALL_FRAMES(frp, topfrp->fr_child) { - n = frame_minheight(frp, next_curwin); + int n = frame_minheight(frp, next_curwin); if (n > m) { m = n; } @@ -3768,6 +3743,7 @@ static int frame_minheight(frame_T *topfrp, win_T *next_curwin) } else { // Add up the minimal heights for all frames in this column. m = 0; + frame_T *frp; FOR_ALL_FRAMES(frp, topfrp->fr_child) { m += frame_minheight(frp, next_curwin); } @@ -3784,8 +3760,7 @@ static int frame_minheight(frame_T *topfrp, win_T *next_curwin) /// @param next_curwin use p_wh and p_wiw for next_curwin static int frame_minwidth(frame_T *topfrp, win_T *next_curwin) { - frame_T *frp; - int m, n; + int m; if (topfrp->fr_win != NULL) { if (topfrp->fr_win == next_curwin) { @@ -3801,8 +3776,9 @@ static int frame_minwidth(frame_T *topfrp, win_T *next_curwin) } else if (topfrp->fr_layout == FR_COL) { // get the minimal width from each frame in this column m = 0; + frame_T *frp; FOR_ALL_FRAMES(frp, topfrp->fr_child) { - n = frame_minwidth(frp, next_curwin); + int n = frame_minwidth(frp, next_curwin); if (n > m) { m = n; } @@ -3810,6 +3786,7 @@ static int frame_minwidth(frame_T *topfrp, win_T *next_curwin) } else { // Add up the minimal widths for all frames in this row. m = 0; + frame_T *frp; FOR_ALL_FRAMES(frp, topfrp->fr_child) { m += frame_minwidth(frp, next_curwin); } @@ -3827,10 +3804,6 @@ static int frame_minwidth(frame_T *topfrp, win_T *next_curwin) /// @param forceit always hide all other windows void close_others(int message, int forceit) { - win_T *wp; - win_T *nextwp; - int r; - if (curwin->w_floating) { if (message && !autocmd_busy) { emsg(e_floatonly); @@ -3847,14 +3820,15 @@ void close_others(int message, int forceit) } // Be very careful here: autocommands may change the window layout. - for (wp = firstwin; win_valid(wp); wp = nextwp) { + win_T *nextwp; + for (win_T *wp = firstwin; win_valid(wp); wp = nextwp) { nextwp = wp->w_next; if (wp == curwin) { // don't close current window continue; } // Check if it's allowed to abandon this window - r = can_abandon(wp->w_buffer, forceit); + int r = can_abandon(wp->w_buffer, forceit); if (!win_valid(wp)) { // autocommands messed wp up nextwp = firstwin; continue; @@ -3989,11 +3963,9 @@ static tabpage_T *alloc_tabpage(void) void free_tabpage(tabpage_T *tp) { - int idx; - pmap_del(handle_T)(&tabpage_handles, tp->handle); diff_clear(tp); - for (idx = 0; idx < SNAP_COUNT; idx++) { + for (int idx = 0; idx < SNAP_COUNT; idx++) { clear_snapshot(tp, idx); } vars_clear(&tp->tp_vars->dv_hashtab); // free all t: variables @@ -4020,15 +3992,13 @@ void free_tabpage(tabpage_T *tp) int win_new_tabpage(int after, char_u *filename) { tabpage_T *old_curtab = curtab; - tabpage_T *newtp; - int n; if (cmdwin_type != 0) { emsg(_(e_cmdwin)); return FAIL; } - newtp = alloc_tabpage(); + tabpage_T *newtp = alloc_tabpage(); // Remember the current windows in this Tab page. if (leave_tabpage(curbuf, true) == FAIL) { @@ -4053,7 +4023,7 @@ int win_new_tabpage(int after, char_u *filename) if (after > 0) { // Put new tab page before tab page "after". - n = 2; + int n = 2; for (tp = first_tabpage; tp->tp_next != NULL && n < after; tp = tp->tp_next) { n++; @@ -4113,7 +4083,6 @@ int may_open_tabpage(void) int make_tabpages(int maxcount) { int count = maxcount; - int todo; // Limit to 'tabpagemax' tabs. if (count > p_tpm) { @@ -4124,6 +4093,7 @@ int make_tabpages(int maxcount) // when putting the buffers in the windows. block_autocmds(); + int todo; for (todo = count - 1; todo > 0; todo--) { if (win_new_tabpage(0, NULL) == FAIL) { break; @@ -4361,10 +4331,6 @@ static void tabpage_check_windows(tabpage_T *old_curtab) // When "n" is 9999 go to the last tab page. void goto_tabpage(int n) { - tabpage_T *tp = NULL; // shut up compiler - tabpage_T *ttp; - int i; - if (text_locked()) { // Not allowed when editing the command line. text_locked_msg(); @@ -4379,6 +4345,8 @@ void goto_tabpage(int n) return; } + tabpage_T *tp = NULL; // shut up compiler + if (n == 0) { // No count, go to next tab page, wrap around end. if (curtab->tp_next == NULL) { @@ -4389,8 +4357,8 @@ void goto_tabpage(int n) } else if (n < 0) { // "gT": go to previous tab page, wrap around end. "N gT" repeats // this N times. - ttp = curtab; - for (i = n; i < 0; i++) { + tabpage_T *ttp = curtab; + for (int i = n; i < 0; i++) { for (tp = first_tabpage; tp->tp_next != ttp && tp->tp_next != NULL; tp = tp->tp_next) {} ttp = tp; @@ -4462,16 +4430,15 @@ void goto_tabpage_win(tabpage_T *tp, win_T *wp) // Move the current tab page to after tab page "nr". void tabpage_move(int nr) { - int n = 1; - tabpage_T *tp; - tabpage_T *tp_dst; - assert(curtab != NULL); if (first_tabpage->tp_next == NULL) { return; } + int n = 1; + tabpage_T *tp; + for (tp = first_tabpage; tp->tp_next != NULL && n < nr; tp = tp->tp_next) { n++; } @@ -4481,7 +4448,7 @@ void tabpage_move(int nr) return; } - tp_dst = tp; + tabpage_T *tp_dst = tp; // Remove the current tab page from the list of tab pages. if (curtab == first_tabpage) { @@ -4566,20 +4533,17 @@ tabpage_T *win_find_tabpage(win_T *win) /// @return found window win_T *win_vert_neighbor(tabpage_T *tp, win_T *wp, bool up, long count) { - frame_T *fr; - frame_T *nfr; - frame_T *foundfr; - - foundfr = wp->w_frame; + frame_T *foundfr = wp->w_frame; if (wp->w_floating) { return win_valid(prevwin) && !prevwin->w_floating ? prevwin : firstwin; } while (count--) { + frame_T *nfr; // First go upwards in the tree of frames until we find an upwards or // downwards neighbor. - fr = foundfr; + frame_T *fr = foundfr; for (;;) { if (fr == tp->tp_topframe) { goto end; @@ -4645,20 +4609,17 @@ static void win_goto_ver(bool up, long count) /// @return found window win_T *win_horz_neighbor(tabpage_T *tp, win_T *wp, bool left, long count) { - frame_T *fr; - frame_T *nfr; - frame_T *foundfr; - - foundfr = wp->w_frame; + frame_T *foundfr = wp->w_frame; if (wp->w_floating) { return win_valid(prevwin) && !prevwin->w_floating ? prevwin : firstwin; } while (count--) { + frame_T *nfr; // First go upwards in the tree of frames until we find a left or // right neighbor. - fr = foundfr; + frame_T *fr = foundfr; for (;;) { if (fr == tp->tp_topframe) { goto end; @@ -5022,9 +4983,6 @@ 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) { - int i; - wininfo_T *wip; - pmap_del(handle_T)(&window_handles, wp->handle); clearFolding(wp); @@ -5056,7 +5014,7 @@ static void win_free(win_T *wp, tabpage_T *tp) xfree(wp->w_lines); - for (i = 0; i < wp->w_tagstacklen; i++) { + for (int i = 0; i < wp->w_tagstacklen; i++) { xfree(wp->w_tagstack[i].tagname); xfree(wp->w_tagstack[i].user_data); } @@ -5073,7 +5031,7 @@ static void win_free(win_T *wp, tabpage_T *tp) // Remove the window from the b_wininfo lists, it may happen that the // freed memory is re-used for another window. FOR_ALL_BUFFERS(buf) { - for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next) { + for (wininfo_T *wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next) { if (wip->wi_win == wp) { wininfo_T *wip2; @@ -5139,13 +5097,8 @@ void win_free_grid(win_T *wp, bool reinit) // Append window "wp" in the window list after window "after". void win_append(win_T *after, win_T *wp) { - win_T *before; - - if (after == NULL) { // after NULL is in front of the first - before = firstwin; - } else { - before = after->w_next; - } + // after NULL is in front of the first + win_T *before = after == NULL ? firstwin : after->w_next; wp->w_next = before; wp->w_prev = after; @@ -5393,12 +5346,7 @@ void win_reconfig_floats(void) // to the bottom-right position plus one. static void frame_comp_pos(frame_T *topfrp, int *row, int *col) { - win_T *wp; - frame_T *frp; - int startcol; - int startrow; - - wp = topfrp->fr_win; + win_T *wp = topfrp->fr_win; if (wp != NULL) { if (wp->w_winrow != *row || wp->w_wincol != *col) { @@ -5413,8 +5361,9 @@ static void frame_comp_pos(frame_T *topfrp, int *row, int *col) *row += h > topfrp->fr_height ? topfrp->fr_height : h; *col += wp->w_width + wp->w_vsep_width; } else { - startrow = *row; - startcol = *col; + int startrow = *row; + int startcol = *col; + frame_T *frp; FOR_ALL_FRAMES(frp, topfrp->fr_child) { if (topfrp->fr_layout == FR_ROW) { *row = startrow; // all frames are at the same row @@ -5487,14 +5436,6 @@ void win_setheight_win(int height, win_T *win) // At the top level we can also use change the command line height. static void frame_setheight(frame_T *curfrp, int height) { - int room; // total number of lines available - int take; // number of lines taken from other windows - int room_cmdline; // lines available from cmdline - int run; - frame_T *frp; - int h; - int room_reserved; - // If the height already is the desired value, nothing to do. if (curfrp->fr_height == height) { return; @@ -5514,7 +5455,7 @@ static void frame_setheight(frame_T *curfrp, int height) } else if (curfrp->fr_parent->fr_layout == FR_ROW) { // Row of frames: Also need to resize frames left and right of this // one. First check for the minimal height of these. - h = frame_minheight(curfrp->fr_parent, NULL); + int h = frame_minheight(curfrp->fr_parent, NULL); if (height < h) { height = h; } @@ -5522,14 +5463,19 @@ static void frame_setheight(frame_T *curfrp, int height) } else { // Column of frames: try to change only frames in this column. + int room; // total number of lines available + int room_cmdline; // lines available from cmdline + int room_reserved; + // Do this twice: // 1: compute room available, if it's not enough try resizing the // containing frame. // 2: compute the room available and adjust the height to it. // Try not to reduce the height of a window with 'winfixheight' set. - for (run = 1; run <= 2; run++) { + for (int run = 1; run <= 2; run++) { room = 0; room_reserved = 0; + frame_T *frp; FOR_ALL_FRAMES(frp, curfrp->fr_parent->fr_child) { if (frp != curfrp && frp->fr_win != NULL @@ -5566,7 +5512,7 @@ static void frame_setheight(frame_T *curfrp, int height) // Compute the number of lines we will take from others frames (can be // negative!). - take = height - curfrp->fr_height; + int take = height - curfrp->fr_height; // If there is not enough room, also reduce the height of a window // with 'winfixheight' set. @@ -5594,14 +5540,13 @@ static void frame_setheight(frame_T *curfrp, int height) // First take lines from the frames after the current frame. If // that is not enough, takes lines from frames above the current // frame. - for (run = 0; run < 2; run++) { - if (run == 0) { - frp = curfrp->fr_next; // 1st run: start with next window - } else { - frp = curfrp->fr_prev; // 2nd run: start with prev window - } + for (int run = 0; run < 2; run++) { + // 1st run: start with next window + // 2nd run: start with prev window + frame_T *frp = run == 0 ? curfrp->fr_next : curfrp->fr_prev; + while (frp != NULL && take != 0) { - h = frame_minheight(frp, NULL); + int h = frame_minheight(frp, NULL); if (room_reserved > 0 && frp->fr_win != NULL && frp->fr_win->w_p_wfh) { @@ -5675,13 +5620,6 @@ void win_setwidth_win(int width, win_T *wp) // Strategy is similar to frame_setheight(). static void frame_setwidth(frame_T *curfrp, int width) { - int room; // total number of lines available - int take; // number of lines taken from other windows - int run; - frame_T *frp; - int w; - int room_reserved; - // If the width already is the desired value, nothing to do. if (curfrp->fr_width == width) { return; @@ -5695,7 +5633,7 @@ static void frame_setwidth(frame_T *curfrp, int width) if (curfrp->fr_parent->fr_layout == FR_COL) { // Column of frames: Also need to resize frames above and below of // this one. First check for the minimal width of these. - w = frame_minwidth(curfrp->fr_parent, NULL); + int w = frame_minwidth(curfrp->fr_parent, NULL); if (width < w) { width = w; } @@ -5707,9 +5645,13 @@ static void frame_setwidth(frame_T *curfrp, int width) // 1: compute room available, if it's not enough try resizing the // containing frame. // 2: compute the room available and adjust the width to it. - for (run = 1; run <= 2; run++) { + + int room; // total number of lines available + int room_reserved; + for (int run = 1; run <= 2; run++) { room = 0; room_reserved = 0; + frame_T *frp; FOR_ALL_FRAMES(frp, curfrp->fr_parent->fr_child) { if (frp != curfrp && frp->fr_win != NULL @@ -5735,7 +5677,7 @@ static void frame_setwidth(frame_T *curfrp, int width) // Compute the number of lines we will take from others frames (can be // negative!). - take = width - curfrp->fr_width; + int take = width - curfrp->fr_width; // If there is not enough room, also reduce the width of a window // with 'winfixwidth' set. @@ -5754,14 +5696,13 @@ static void frame_setwidth(frame_T *curfrp, int width) // First take lines from the frames right of the current frame. If // that is not enough, takes lines from frames left of the current // frame. - for (run = 0; run < 2; run++) { - if (run == 0) { - frp = curfrp->fr_next; // 1st run: start with next window - } else { - frp = curfrp->fr_prev; // 2nd run: start with prev window - } + for (int run = 0; run < 2; run++) { + // 1st run: start with next window + // 2nd run: start with prev window + frame_T *frp = run == 0 ? curfrp->fr_next : curfrp->fr_prev; + while (frp != NULL && take != 0) { - w = frame_minwidth(frp, NULL); + int w = frame_minwidth(frp, NULL); if (room_reserved > 0 && frp->fr_win != NULL && frp->fr_win->w_p_wfw) { @@ -5837,12 +5778,6 @@ void win_setminwidth(void) /// Status line of dragwin is dragged "offset" lines down (negative is up). void win_drag_status_line(win_T *dragwin, int offset) { - frame_T *curfr; - frame_T *fr; - int room; - int row; - bool up; // if true, drag status line up, otherwise down - int n; static bool p_ch_was_zero = false; // If the user explicitly set 'cmdheight' to zero, then allow for dragging @@ -5851,8 +5786,8 @@ void win_drag_status_line(win_T *dragwin, int offset) p_ch_was_zero = true; } - fr = dragwin->w_frame; - curfr = fr; + frame_T *fr = dragwin->w_frame; + frame_T *curfr = fr; if (fr != topframe) { // more than one window fr = fr->fr_parent; // When the parent frame is not a column of frames, its parent should @@ -5877,8 +5812,10 @@ void win_drag_status_line(win_T *dragwin, int offset) } } - if (offset < 0) { // drag up - up = true; + int room; + const bool up = offset < 0; // if true, drag status line up, otherwise down + + if (up) { // drag up offset = -offset; // sum up the room of the current frame and above it if (fr == curfr) { @@ -5895,7 +5832,6 @@ void win_drag_status_line(win_T *dragwin, int offset) } fr = curfr->fr_next; // put fr at frame that grows } else { // drag down - up = false; // Only dragging the last status line can reduce p_ch. room = Rows - cmdline_row; if (curfr->fr_next != NULL) { @@ -5933,7 +5869,7 @@ void win_drag_status_line(win_T *dragwin, int offset) } // Now make the other frames smaller. while (fr != NULL && offset > 0) { - n = frame_minheight(fr, NULL); + int n = frame_minheight(fr, NULL); if (fr->fr_height - offset <= n) { offset -= fr->fr_height - n; frame_new_height(fr, n, !up, false); @@ -5947,7 +5883,7 @@ void win_drag_status_line(win_T *dragwin, int offset) fr = fr->fr_next; } } - row = win_comp_pos(); + int row = win_comp_pos(); grid_fill(&default_grid, row, cmdline_row, 0, Columns, ' ', ' ', 0); if (msg_grid.chars) { clear_cmdline = true; @@ -5967,17 +5903,11 @@ void win_drag_status_line(win_T *dragwin, int offset) // Separator line of dragwin is dragged "offset" lines right (negative is left). void win_drag_vsep_line(win_T *dragwin, int offset) { - frame_T *curfr; - frame_T *fr; - int room; - bool left; // if true, drag separator line left, otherwise right - int n; - - fr = dragwin->w_frame; + frame_T *fr = dragwin->w_frame; if (fr == topframe) { // only one window (cannot happen?) return; } - curfr = fr; + frame_T *curfr = fr; fr = fr->fr_parent; // When the parent frame is not a row of frames, its parent should be. if (fr->fr_layout != FR_ROW) { @@ -6002,8 +5932,10 @@ void win_drag_vsep_line(win_T *dragwin, int offset) } } - if (offset < 0) { // drag left - left = true; + int room; + const bool left = offset < 0; // if true, drag separator line left, otherwise right + + if (left) { // drag left offset = -offset; // sum up the room of the current frame and left of it room = 0; @@ -6015,7 +5947,6 @@ void win_drag_vsep_line(win_T *dragwin, int offset) } fr = curfr->fr_next; // put fr at frame that grows } else { // drag right - left = false; // sum up the room of frames right of the current one room = 0; FOR_ALL_FRAMES(fr, curfr->fr_next) { @@ -6050,7 +5981,7 @@ void win_drag_vsep_line(win_T *dragwin, int offset) fr = curfr->fr_next; // next frame gets smaller } while (fr != NULL && offset > 0) { - n = frame_minwidth(fr, NULL); + int n = frame_minwidth(fr, NULL); if (fr->fr_width - offset <= n) { offset -= fr->fr_width - n; frame_new_width(fr, n, !left, false); @@ -6199,8 +6130,6 @@ void win_new_height(win_T *wp, int height) void scroll_to_fraction(win_T *wp, int prev_height) { - linenr_T lnum; - int sline, line_size; int height = wp->w_height_inner; // Don't change w_topline in any of these cases: @@ -6214,13 +6143,13 @@ void scroll_to_fraction(win_T *wp, int prev_height) || wp->w_topline > 1)) { // Find a value for w_topline that shows the cursor at the same // relative position in the window as before (more or less). - lnum = wp->w_cursor.lnum; + linenr_T lnum = wp->w_cursor.lnum; if (lnum < 1) { // can happen when starting up lnum = 1; } wp->w_wrow = (int)((long)wp->w_fraction * (long)height - 1L) / FRACTION_MULT; - line_size = plines_win_col(wp, lnum, (long)(wp->w_cursor.col)) - 1; - sline = wp->w_wrow - line_size; + int line_size = plines_win_col(wp, lnum, (long)(wp->w_cursor.col)) - 1; + int sline = wp->w_wrow - line_size; if (sline >= 0) { // Make sure the whole cursor line is visible, if possible. @@ -6399,8 +6328,6 @@ void win_comp_scroll(win_T *wp) /// command_height: called whenever p_ch has been changed. void command_height(void) { - int h; - frame_T *frp; int old_p_ch = (int)curtab->tp_ch_used; // Use the value of p_ch that we remembered. This is needed for when the @@ -6419,7 +6346,7 @@ void command_height(void) } // Find bottom frame with width of screen. - frp = lastwin_nofloating()->w_frame; + frame_T *frp = lastwin_nofloating()->w_frame; while (frp->fr_width != Columns && frp->fr_parent != NULL) { frp = frp->fr_parent; } @@ -6442,7 +6369,7 @@ void command_height(void) cmdline_row = Rows - (int)p_ch; break; } - h = frp->fr_height - frame_minheight(frp, NULL); + int h = frp->fr_height - frame_minheight(frp, NULL); if (h > p_ch - old_p_ch) { h = (int)p_ch - old_p_ch; } @@ -6538,13 +6465,8 @@ char_u *file_name_at_cursor(int options, long count, linenr_T *file_lnum) char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u *rel_fname, linenr_T *file_lnum) { - char *ptr; - size_t len; - bool in_type = true; - bool is_url = false; - // search forward for what could be the start of a file name - ptr = (char *)line + col; + char *ptr = (char *)line + col; while (*ptr != NUL && !vim_isfilec((uint8_t)(*ptr))) { MB_PTR_ADV(ptr); } @@ -6555,6 +6477,10 @@ char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u return NULL; } + size_t len; + bool in_type = true; + 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'. while ((char_u *)ptr > line) { @@ -6600,14 +6526,13 @@ char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u } if (file_lnum != NULL) { - char *p; const char *line_english = " line "; const char *line_transl = _(line_msg); // Get the number after the file name and a separator character. // Also accept " line 999" with and without the same translation as // used in last_set_msg(). - p = ptr + len; + char *p = ptr + len; if (STRNCMP(p, line_english, strlen(line_english)) == 0) { p += strlen(line_english); } else if (STRNCMP(p, line_transl, strlen(line_transl)) == 0) { @@ -6722,11 +6647,8 @@ static bool resize_frame_for_winbar(frame_T *fr) static void last_status_rec(frame_T *fr, bool statusline, bool is_stl_global) { - frame_T *fp; - win_T *wp; - if (fr->fr_layout == FR_LEAF) { - wp = fr->fr_win; + win_T *wp = fr->fr_win; bool is_last = is_bottom_win(wp); if (is_last) { @@ -6756,6 +6678,7 @@ static void last_status_rec(frame_T *fr, bool statusline, bool is_stl_global) } } else { // For a column or row frame, recursively call this function for all child frames + frame_T *fp; FOR_ALL_FRAMES(fp, fr->fr_child) { last_status_rec(fp, statusline, is_stl_global); } @@ -7036,13 +6959,11 @@ static win_T *get_snapshot_curwin(int idx) /// @param close_curwin closing current window void restore_snapshot(int idx, int close_curwin) { - win_T *wp; - if (curtab->tp_snapshot[idx] != NULL && curtab->tp_snapshot[idx]->fr_width == topframe->fr_width && curtab->tp_snapshot[idx]->fr_height == topframe->fr_height && check_snapshot_rec(curtab->tp_snapshot[idx], topframe) == OK) { - wp = restore_snapshot_rec(curtab->tp_snapshot[idx], topframe); + win_T *wp = restore_snapshot_rec(curtab->tp_snapshot[idx], topframe); (void)win_comp_pos(); if (wp != NULL && close_curwin) { win_goto(wp); @@ -7075,7 +6996,6 @@ static int check_snapshot_rec(frame_T *sn, frame_T *fr) static win_T *restore_snapshot_rec(frame_T *sn, frame_T *fr) { win_T *wp = NULL; - win_T *wp2; fr->fr_height = sn->fr_height; fr->fr_width = sn->fr_width; @@ -7085,13 +7005,13 @@ static win_T *restore_snapshot_rec(frame_T *sn, frame_T *fr) wp = sn->fr_win; } if (sn->fr_next != NULL) { - wp2 = restore_snapshot_rec(sn->fr_next, fr->fr_next); + win_T *wp2 = restore_snapshot_rec(sn->fr_next, fr->fr_next); if (wp2 != NULL) { wp = wp2; } } if (sn->fr_child != NULL) { - wp2 = restore_snapshot_rec(sn->fr_child, fr->fr_child); + win_T *wp2 = restore_snapshot_rec(sn->fr_child, fr->fr_child); if (wp2 != NULL) { wp = wp2; } @@ -7260,17 +7180,14 @@ static int int_cmp(const void *a, const void *b) /// @return error message, NULL if it's OK. char *check_colorcolumn(win_T *wp) { - char *s; - int col; - unsigned int count = 0; - int color_cols[256]; - int j = 0; - if (wp->w_buffer == NULL) { return NULL; // buffer was closed } - for (s = wp->w_p_cc; *s != NUL && count < 255;) { + unsigned int count = 0; + int color_cols[256]; + for (char *s = wp->w_p_cc; *s != NUL && count < 255;) { + int col; if (*s == '-' || *s == '+') { // -N and +N: add to 'textwidth' col = (*s == '-') ? -1 : 1; @@ -7319,6 +7236,7 @@ skip: // win_line() qsort(color_cols, count, sizeof(int), int_cmp); + int j = 0; for (unsigned int i = 0; i < count; i++) { // skip duplicates if (j == 0 || wp->w_p_cc_cols[j - 1] != color_cols[i]) { @@ -7390,10 +7308,10 @@ void win_get_tabwin(handle_T id, int *tabnr, int *winnr) void win_id2tabwin(typval_T *const argvars, typval_T *const rettv) { - int winnr = 1; - int tabnr = 1; handle_T id = (handle_T)tv_get_number(&argvars[0]); + int winnr = 1; + int tabnr = 1; win_get_tabwin(id, &tabnr, &winnr); list_T *const list = tv_list_alloc_ret(rettv, 2); @@ -7449,12 +7367,11 @@ void win_findbuf(typval_T *argvars, list_T *list) // Get the layout of the given tab page for winlayout(). void get_framelayout(const frame_T *fr, list_T *l, bool outer) { - list_T *fr_list; - if (fr == NULL) { return; } + list_T *fr_list; if (outer) { // outermost call from f_winlayout() fr_list = l; -- cgit From 784e498c4a9c1f03266ced5ec3f55c3a6c94b80d Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Fri, 21 Oct 2022 14:47:44 +0200 Subject: refactor: clang-tidy fixes to silence clangd warning (#20683) * refactor: readability-uppercase-literal-suffix * refactor: readability-named-parameter * refactor: bugprone-suspicious-string-compare * refactor: google-readability-casting * refactor: readability-redundant-control-flow * refactor: bugprone-too-small-loop-variable * refactor: readability-non-const-parameter * refactor: readability-avoid-const-params-in-decls * refactor: google-readability-todo * refactor: readability-inconsistent-declaration-parameter-name * refactor: bugprone-suspicious-missing-comma * refactor: remove noisy or slow warnings --- src/nvim/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 0e6bb7822a..4812b9ef9d 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -785,7 +785,7 @@ void win_config_float(win_T *wp, FloatConfig fconfig) 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; -- cgit From a600e73007a2cc9ced7eeaeb5f8c05ac454d080e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 1 Nov 2022 07:13:02 +0800 Subject: vim-patch:9.0.0822: crash when dragging the statusline with a mapping Problem: Crash when dragging the statusline with a mapping. Solution: Check for valid window pointer. (issue vim/vim#11427) https://github.com/vim/vim/commit/8ab9ca93eea32b318235384720200771863ecaee Co-authored-by: Bram Moolenaar --- src/nvim/window.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 4812b9ef9d..8c34e4fb6c 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -4195,6 +4195,7 @@ static int leave_tabpage(buf_T *new_curbuf, bool trigger_leave_autocmds) { tabpage_T *tp = curtab; + reset_mouse_got_click(); leaving_window(curwin); reset_VIsual_and_resel(); // stop Visual mode if (trigger_leave_autocmds) { @@ -4392,6 +4393,7 @@ void goto_tabpage_tp(tabpage_T *tp, bool trigger_enter_autocmds, bool trigger_le // Don't repeat a message in another tab page. set_keep_msg(NULL, 0); + reset_mouse_got_click(); skip_win_fix_scroll = true; if (tp != curtab && leave_tabpage(tp->tp_curwin->w_buffer, trigger_leave_autocmds) == OK) { -- cgit From 20bd4d89977005845c070cde9df75496f948fa1e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 1 Nov 2022 10:21:15 +0800 Subject: vim-patch:9.0.0823: mouse drag test fails Problem: Mouse drag test fails. Solution: Only reset the mouse click flag when actually switching to another tab page. Disable test that keeps failing. https://github.com/vim/vim/commit/7a7db047dcb2336de5103e793345eb5a9d125900 Omit test_termcodes.vim change: reverted in patch 9.0.0825. Co-authored-by: Bram Moolenaar --- src/nvim/window.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 8c34e4fb6c..c1ed2b7920 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -4195,7 +4195,6 @@ static int leave_tabpage(buf_T *new_curbuf, bool trigger_leave_autocmds) { tabpage_T *tp = curtab; - reset_mouse_got_click(); leaving_window(curwin); reset_VIsual_and_resel(); // stop Visual mode if (trigger_leave_autocmds) { @@ -4214,6 +4213,8 @@ static int leave_tabpage(buf_T *new_curbuf, bool trigger_leave_autocmds) return FAIL; } } + + reset_mouse_got_click(); tp->tp_curwin = curwin; tp->tp_prevwin = prevwin; tp->tp_firstwin = firstwin; @@ -4276,6 +4277,10 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, bool trigger_enter_a clear_cmdline = true; } + // If there was a click in a window, it won't be usable for a following + // drag. + reset_mouse_got_click(); + // The tabpage line may have appeared or disappeared, may need to resize the frames for that. // When the Vim window was resized or ROWS_AVAIL changed need to update frame sizes too. if (curtab->tp_old_Rows_avail != ROWS_AVAIL || (old_off != firstwin->w_winrow)) { @@ -4393,7 +4398,6 @@ void goto_tabpage_tp(tabpage_T *tp, bool trigger_enter_autocmds, bool trigger_le // Don't repeat a message in another tab page. set_keep_msg(NULL, 0); - reset_mouse_got_click(); skip_win_fix_scroll = true; if (tp != curtab && leave_tabpage(tp->tp_curwin->w_buffer, trigger_leave_autocmds) == OK) { -- cgit From 419ee612e692fb8985342a2091a0d9bf6dfffe46 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 2 Nov 2022 08:04:00 +0800 Subject: vim-patch:9.0.0825: cannot drag an entry in the tabpage line Problem: Cannot drag an entry in the tabpage line. Solution: Clear dragwin instead of got_click. (closes vim/vim#11483, closes vim/vim#11482) https://github.com/vim/vim/commit/8e0ccb6bc21a446e5c6375b7fdf200fb53a129da Omit Test_term_mouse_drag_to_move_tab(): covered by ui/mouse_spec.lua. --- src/nvim/window.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index c1ed2b7920..c755f58c4f 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -4214,7 +4214,7 @@ static int leave_tabpage(buf_T *new_curbuf, bool trigger_leave_autocmds) } } - reset_mouse_got_click(); + reset_dragwin(); tp->tp_curwin = curwin; tp->tp_prevwin = prevwin; tp->tp_firstwin = firstwin; @@ -4279,7 +4279,7 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, bool trigger_enter_a // If there was a click in a window, it won't be usable for a following // drag. - reset_mouse_got_click(); + reset_dragwin(); // The tabpage line may have appeared or disappeared, may need to resize the frames for that. // When the Vim window was resized or ROWS_AVAIL changed need to update frame sizes too. -- cgit From a79d28e4d7939c13f38cf4ce63ff240011bca96d Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 6 Nov 2022 17:58:13 +0800 Subject: vim-patch:9.0.0265: no good reason why the "gf" command isn't in the tiny version (#20964) Problem: No good reason why the "gf" command is not in the tiny version. Solution: Graduate the file_in_path feature. https://github.com/vim/vim/commit/f80f40a55ccff0a4331c5fbd1ac446511f622ed0 Co-authored-by: Bram Moolenaar --- src/nvim/window.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index c755f58c4f..10b366ce23 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -585,6 +585,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; -- cgit From 731cdde28ea8d48cc23ba2752a08c261c87eee92 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sat, 22 Oct 2022 12:36:38 +0200 Subject: refactor: fix clang-tidy warnings Enable and fix bugprone-misplaced-widening-cast warning. Fix some modernize-macro-to-enum and readability-else-after-return warnings, but don't enable them. While the warnings can be useful, they are in general too noisy to enable. --- src/nvim/window.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 10b366ce23..e1ed61ae93 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -270,9 +270,8 @@ newwindow: 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 @@ -872,9 +871,8 @@ 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, bool validate) @@ -4869,12 +4867,11 @@ win_T *buf_jump_open_win(buf_T *buf) if (curwin->w_buffer == buf) { win_enter(curwin, false); return curwin; - } else { - FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if (wp->w_buffer == buf) { - win_enter(wp, false); - return wp; - } + } + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + if (wp->w_buffer == buf) { + win_enter(wp, false); + return wp; } } @@ -6642,12 +6639,11 @@ static bool resize_frame_for_winbar(frame_T *fr) if (fp == NULL || fp == fr) { emsg(_(e_noroom)); return false; - } else { - frame_new_height(fp, fp->fr_height - 1, false, false); - win_new_height(wp, wp->w_height + 1); - frame_fix_height(wp); - (void)win_comp_pos(); } + frame_new_height(fp, fp->fr_height - 1, false, false); + win_new_height(wp, wp->w_height + 1); + frame_fix_height(wp); + (void)win_comp_pos(); return true; } -- cgit From 1af4bd04f9ad157edbfea30642250e854c5cb5d2 Mon Sep 17 00:00:00 2001 From: Raphael Date: Sun, 6 Nov 2022 18:59:43 +0800 Subject: feat(ui): add support to display a title in the border of a float (#20184) add "title" and "title_pos" keys to win config dict. --- src/nvim/window.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 10b366ce23..1cde433b0a 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "nvim/api/private/helpers.h" #include "nvim/api/vim.h" @@ -5066,6 +5067,9 @@ static void win_free(win_T *wp, tabpage_T *tp) } } + // free the border title text + clear_virttext(&wp->w_float_config.title_chunks); + clear_matches(wp); free_jumplist(wp); -- cgit From 69507c0204cfe284e42865c9c89baec0f351b2c1 Mon Sep 17 00:00:00 2001 From: luukvbaal <31730729+luukvbaal@users.noreply.github.com> Date: Thu, 10 Nov 2022 12:05:16 +0100 Subject: refactor: move tabline code to statusline.c (#21008) * refactor: move tabline code to statusline.c Problem: Tabline code is closely related to statusline, but still left over in drawscreen.c and screen.c. Solution: Move it to statusline.c. * refactor: add statusline_defs.h --- src/nvim/window.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 3649e6bc16..de5bcb40ea 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -52,6 +52,7 @@ #include "nvim/regexp.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" @@ -5027,10 +5028,10 @@ static void win_free(win_T *wp, tabpage_T *tp) xfree(wp->w_localdir); xfree(wp->w_prevdir); - stl_clear_click_defs(wp->w_status_click_defs, (long)wp->w_status_click_defs_size); + stl_clear_click_defs(wp->w_status_click_defs, wp->w_status_click_defs_size); xfree(wp->w_status_click_defs); - stl_clear_click_defs(wp->w_winbar_click_defs, (long)wp->w_winbar_click_defs_size); + stl_clear_click_defs(wp->w_winbar_click_defs, wp->w_winbar_click_defs_size); xfree(wp->w_winbar_click_defs); // Remove the window from the b_wininfo lists, it may happen that the @@ -6584,7 +6585,7 @@ static void win_remove_status_line(win_T *wp, bool add_hsep) } comp_col(); - stl_clear_click_defs(wp->w_status_click_defs, (long)wp->w_status_click_defs_size); + stl_clear_click_defs(wp->w_status_click_defs, wp->w_status_click_defs_size); xfree(wp->w_status_click_defs); wp->w_status_click_defs_size = 0; wp->w_status_click_defs = NULL; @@ -6720,7 +6721,7 @@ int set_winbar_win(win_T *wp, bool make_room, bool valid_cursor) if (winbar_height == 0) { // When removing winbar, deallocate the w_winbar_click_defs array - stl_clear_click_defs(wp->w_winbar_click_defs, (long)wp->w_winbar_click_defs_size); + stl_clear_click_defs(wp->w_winbar_click_defs, wp->w_winbar_click_defs_size); xfree(wp->w_winbar_click_defs); wp->w_winbar_click_defs_size = 0; wp->w_winbar_click_defs = NULL; -- cgit From 66360675cf4d091b7460e4a8e1435c13216c1929 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sun, 11 Sep 2022 17:12:44 +0200 Subject: build: allow IWYU to fix includes for all .c files Allow Include What You Use to remove unnecessary includes and only include what is necessary. This helps with reducing compilation times and makes it easier to visualise which dependencies are actually required. Work on https://github.com/neovim/neovim/issues/549, but doesn't close it since this only works fully for .c files and not headers. --- src/nvim/window.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index de5bcb40ea..54ab9a0471 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2,21 +2,30 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include +#include #include +#include #include +#include +#include +#include #include +#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/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/ex_cmds.h" #include "nvim/ex_cmds2.h" @@ -28,15 +37,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" @@ -45,17 +58,18 @@ #include "nvim/option.h" #include "nvim/optionstr.h" #include "nvim/os/os.h" -#include "nvim/os_unix.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" -- cgit From 035d41ac5e5fcbb49eb64b72a924c4d6f89f0579 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 20 Nov 2022 08:38:46 +0800 Subject: vim-patch:partial:9.0.0913: only change in current window triggers the WinScrolled event Problem: Only a change in the current window triggers the WinScrolled event. Solution: Trigger WinScrolled if any window scrolled or changed size. (issue vim/vim#11576) https://github.com/vim/vim/commit/0a60f79fd0c328b47b36279a95282e9f8d9e7512 Skip locking of window layout and E1312. Copy the latest version of all WinScrolled tests from Vim. Note: patch 9.0.0915 is needed for the Lua tests to pass. Co-authored-by: Bram Moolenaar --- src/nvim/window.c | 69 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 22 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 54ab9a0471..4a451975a4 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5263,35 +5263,60 @@ void win_new_screen_cols(void) win_reconfig_floats(); // The size of floats might change } -/// Trigger WinScrolled for "curwin" if needed. +/// Make a snapshot of all the window scroll positions and sizes of the current +/// tab page. +static void snapshot_windows_scroll_size(void) +{ + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + wp->w_last_topline = wp->w_topline; + wp->w_last_leftcol = wp->w_leftcol; + wp->w_last_skipcol = wp->w_skipcol; + wp->w_last_width = wp->w_width; + wp->w_last_height = wp->w_height; + } +} + +static bool did_initial_scroll_size_snapshot = false; + +void may_make_initial_scroll_size_snapshot(void) +{ + if (!did_initial_scroll_size_snapshot) { + did_initial_scroll_size_snapshot = true; + snapshot_windows_scroll_size(); + } +} + +/// Trigger WinScrolled if any window scrolled or changed size. void may_trigger_winscrolled(void) { static bool recursive = false; - if (recursive || !has_event(EVENT_WINSCROLLED)) { + if (recursive + || !has_event(EVENT_WINSCROLLED) + || !did_initial_scroll_size_snapshot) { return; } - win_T *wp = curwin; - if (wp->w_last_topline != wp->w_topline - || wp->w_last_leftcol != wp->w_leftcol - || wp->w_last_skipcol != wp->w_skipcol - || wp->w_last_width != wp->w_width - || wp->w_last_height != wp->w_height) { - char winid[NUMBUFLEN]; - vim_snprintf(winid, sizeof(winid), "%d", wp->handle); - - recursive = true; - apply_autocmds(EVENT_WINSCROLLED, winid, winid, false, wp->w_buffer); - recursive = false; - - // an autocmd may close the window, "wp" may be invalid now - if (win_valid_any_tab(wp)) { - wp->w_last_topline = wp->w_topline; - wp->w_last_leftcol = wp->w_leftcol; - wp->w_last_skipcol = wp->w_skipcol; - wp->w_last_width = wp->w_width; - wp->w_last_height = wp->w_height; + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + if (wp->w_last_topline != wp->w_topline + || wp->w_last_leftcol != wp->w_leftcol + || wp->w_last_skipcol != wp->w_skipcol + || wp->w_last_width != wp->w_width + || wp->w_last_height != wp->w_height) { + // WinScrolled is triggered only once, even when multiple windows + // scrolled or changed size. Store the current values before + // triggering the event, if a scroll or resize happens as a side + // effect then WinScrolled is triggered again later. + snapshot_windows_scroll_size(); + + char winid[NUMBUFLEN]; + vim_snprintf(winid, sizeof(winid), "%d", wp->handle); + + recursive = true; + apply_autocmds(EVENT_WINSCROLLED, winid, winid, false, wp->w_buffer); + recursive = false; + + break; } } } -- cgit From 91c192922da0240be5a8eb4045dae6cd968957e9 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 20 Nov 2022 21:11:57 +0800 Subject: vim-patch:9.0.0915: WinScrolled may trigger immediately when defined Problem: WinScrolled may trigger immediately when defined. Solution: Initialize the fields in all windows. (closes vim/vim#11582) https://github.com/vim/vim/commit/29967732761d1ffb5592db5f5aa7036f5b52abf1 Co-authored-by: Bram Moolenaar --- src/nvim/window.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 4a451975a4..f25e25e905 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -3868,6 +3868,27 @@ void close_others(int message, int forceit) } } +/// Store the relevant window pointers for tab page "tp". To be used before +/// use_tabpage(). +void unuse_tabpage(tabpage_T *tp) +{ + tp->tp_topframe = topframe; + tp->tp_firstwin = firstwin; + tp->tp_lastwin = lastwin; + tp->tp_curwin = curwin; +} + +/// Set the relevant pointers to use tab page "tp". May want to call +/// unuse_tabpage() first. +void use_tabpage(tabpage_T *tp) +{ + curtab = tp; + topframe = curtab->tp_topframe; + firstwin = curtab->tp_firstwin; + lastwin = curtab->tp_lastwin; + curwin = curtab->tp_curwin; +} + // Allocate the first window and put an empty buffer in it. // Only called from main(). void win_alloc_first(void) @@ -3878,11 +3899,8 @@ void win_alloc_first(void) } first_tabpage = alloc_tabpage(); - first_tabpage->tp_topframe = topframe; curtab = first_tabpage; - curtab->tp_firstwin = firstwin; - curtab->tp_lastwin = lastwin; - curtab->tp_curwin = curwin; + unuse_tabpage(first_tabpage); } // Init `aucmd_win`. This can only be done after the first window @@ -4253,10 +4271,7 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, bool trigger_enter_a win_T *next_prevwin = tp->tp_prevwin; tabpage_T *old_curtab = curtab; - curtab = tp; - firstwin = tp->tp_firstwin; - lastwin = tp->tp_lastwin; - topframe = tp->tp_topframe; + use_tabpage(tp); if (old_curtab != curtab) { tabpage_check_windows(old_curtab); @@ -5265,7 +5280,7 @@ void win_new_screen_cols(void) /// Make a snapshot of all the window scroll positions and sizes of the current /// tab page. -static void snapshot_windows_scroll_size(void) +void snapshot_windows_scroll_size(void) { FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { wp->w_last_topline = wp->w_topline; -- cgit From 4571ba4d0a5234408e544c3a98f107688a792f0d Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 23 Nov 2022 09:54:48 +0800 Subject: vim-patch:partial:9.0.0917: the WinScrolled autocommand event is not enough (#21161) Problem: The WinScrolled autocommand event is not enough. Solution: Add WinResized and provide information about what changed. (closes vim/vim#11576) https://github.com/vim/vim/commit/35fc61cb5b5eba8bbb9d8f0700332fbab38f40ca Omit "func_name" comment in tv_dict_extend(): Vim9 script only. Skip layout locking and E1312. Skip list_alloc_with_items() and list_set_item(). Since this overrides remaining changes in patch 9.0.0913, that patch can now be marked as fully ported: vim-patch:9.0.0913: only change in current window triggers the WinScrolled event N/A patches for version.c: vim-patch:9.0.0919: build failure with tiny features Problem: Build failure with tiny features. Solution: Adjust #ifdef's. https://github.com/vim/vim/commit/9c5b7cb4cf67c64648a324e9dfd1e17d793335a4 Co-authored-by: Bram Moolenaar --- src/nvim/window.c | 242 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 222 insertions(+), 20 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index f25e25e905..beb96aaa03 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5301,39 +5301,241 @@ void may_make_initial_scroll_size_snapshot(void) } } -/// Trigger WinScrolled if any window scrolled or changed size. -void may_trigger_winscrolled(void) +/// Create a dictionary with information about size and scroll changes in a +/// window. +/// Returns the dictionary with refcount set to one. +/// Returns NULL on internal error. +static dict_T *make_win_info_dict(int width, int height, int topline, int leftcol, int skipcol) +{ + dict_T *const d = tv_dict_alloc(); + d->dv_refcount = 1; + + // not actually looping, for breaking out on error + while (1) { + typval_T tv = { + .v_lock = VAR_UNLOCKED, + .v_type = VAR_NUMBER, + }; + + tv.vval.v_number = width; + if (tv_dict_add_tv(d, S_LEN("width"), &tv) == FAIL) { + break; + } + tv.vval.v_number = height; + if (tv_dict_add_tv(d, S_LEN("height"), &tv) == FAIL) { + break; + } + tv.vval.v_number = topline; + if (tv_dict_add_tv(d, S_LEN("topline"), &tv) == FAIL) { + break; + } + tv.vval.v_number = leftcol; + if (tv_dict_add_tv(d, S_LEN("leftcol"), &tv) == FAIL) { + break; + } + tv.vval.v_number = skipcol; + if (tv_dict_add_tv(d, S_LEN("skipcol"), &tv) == FAIL) { + break; + } + return d; + } + tv_dict_unref(d); + return NULL; +} + +/// Return values of check_window_scroll_resize(): +enum { + CWSR_SCROLLED = 1, ///< at least one window scrolled + CWSR_RESIZED = 2, ///< at least one window size changed +}; + +/// This function is used for three purposes: +/// 1. Goes over all windows in the current tab page and returns: +/// 0 no scrolling and no size changes found +/// CWSR_SCROLLED at least one window scrolled +/// CWSR_RESIZED at least one window changed size +/// CWSR_SCROLLED + CWSR_RESIZED both +/// "size_count" is set to the nr of windows with size changes. +/// "first_scroll_win" is set to the first window with any relevant changes. +/// "first_size_win" is set to the first window with size changes. +/// +/// 2. When the first three arguments are NULL and "winlist" is not NULL, +/// "winlist" is set to the list of window IDs with size changes. +/// +/// 3. When the first three arguments are NULL and "v_event" is not NULL, +/// information about changed windows is added to "v_event". +static int check_window_scroll_resize(int *size_count, win_T **first_scroll_win, + win_T **first_size_win, list_T *winlist, dict_T *v_event) +{ + int result = 0; + // int listidx = 0; + int tot_width = 0; + int tot_height = 0; + int tot_topline = 0; + int tot_leftcol = 0; + int tot_skipcol = 0; + + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + const bool size_changed = wp->w_last_width != wp->w_width + || wp->w_last_height != wp->w_height; + if (size_changed) { + result |= CWSR_RESIZED; + if (winlist != NULL) { + // Add this window to the list of changed windows. + typval_T tv = { + .v_lock = VAR_UNLOCKED, + .v_type = VAR_NUMBER, + .vval.v_number = wp->handle, + }; + // tv_list_set_item(winlist, listidx++, &tv); + tv_list_append_owned_tv(winlist, tv); + } else if (size_count != NULL) { + (*size_count)++; + if (*first_size_win == NULL) { + *first_size_win = wp; + } + // For WinScrolled the first window with a size change is used + // even when it didn't scroll. + if (*first_scroll_win == NULL) { + *first_scroll_win = wp; + } + } + } + + const bool scroll_changed = wp->w_last_topline != wp->w_topline + || wp->w_last_leftcol != wp->w_leftcol + || wp->w_last_skipcol != wp->w_skipcol; + if (scroll_changed) { + result |= CWSR_SCROLLED; + if (first_scroll_win != NULL && *first_scroll_win == NULL) { + *first_scroll_win = wp; + } + } + + if ((size_changed || scroll_changed) && v_event != NULL) { + // Add info about this window to the v:event dictionary. + int width = wp->w_width - wp->w_last_width; + int height = wp->w_height - wp->w_last_height; + int topline = wp->w_topline - wp->w_last_topline; + int leftcol = wp->w_leftcol - wp->w_last_leftcol; + int skipcol = wp->w_skipcol - wp->w_last_skipcol; + dict_T *d = make_win_info_dict(width, height, + topline, leftcol, skipcol); + if (d == NULL) { + break; + } + char winid[NUMBUFLEN]; + int key_len = vim_snprintf(winid, sizeof(winid), "%d", wp->handle); + if (tv_dict_add_dict(v_event, winid, (size_t)key_len, d) == FAIL) { + tv_dict_unref(d); + break; + } + d->dv_refcount--; + + tot_width += abs(width); + tot_height += abs(height); + tot_topline += abs(topline); + tot_leftcol += abs(leftcol); + tot_skipcol += abs(skipcol); + } + } + + if (v_event != NULL) { + dict_T *alldict = make_win_info_dict(tot_width, tot_height, + tot_topline, tot_leftcol, tot_skipcol); + if (alldict != NULL) { + if (tv_dict_add_dict(v_event, S_LEN("all"), alldict) == FAIL) { + tv_dict_unref(alldict); + } else { + alldict->dv_refcount--; + } + } + } + + return result; +} + +/// Trigger WinScrolled and/or WinResized if any window in the current tab page +/// scrolled or changed size. +void may_trigger_win_scrolled_resized(void) { static bool recursive = false; + const bool do_resize = has_event(EVENT_WINRESIZED); + const bool do_scroll = has_event(EVENT_WINSCROLLED); if (recursive - || !has_event(EVENT_WINSCROLLED) + || !(do_scroll || do_resize) || !did_initial_scroll_size_snapshot) { return; } - FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if (wp->w_last_topline != wp->w_topline - || wp->w_last_leftcol != wp->w_leftcol - || wp->w_last_skipcol != wp->w_skipcol - || wp->w_last_width != wp->w_width - || wp->w_last_height != wp->w_height) { - // WinScrolled is triggered only once, even when multiple windows - // scrolled or changed size. Store the current values before - // triggering the event, if a scroll or resize happens as a side - // effect then WinScrolled is triggered again later. - snapshot_windows_scroll_size(); + int size_count = 0; + win_T *first_scroll_win = NULL, *first_size_win = NULL; + int cwsr = check_window_scroll_resize(&size_count, + &first_scroll_win, &first_size_win, + NULL, NULL); + int trigger_resize = do_resize && size_count > 0; + int trigger_scroll = do_scroll && cwsr != 0; + if (!trigger_resize && !trigger_scroll) { + return; // no relevant changes + } - char winid[NUMBUFLEN]; - vim_snprintf(winid, sizeof(winid), "%d", wp->handle); + list_T *windows_list = NULL; + if (trigger_resize) { + // Create the list for v:event.windows before making the snapshot. + // windows_list = tv_list_alloc_with_items(size_count); + windows_list = tv_list_alloc(size_count); + (void)check_window_scroll_resize(NULL, NULL, NULL, windows_list, NULL); + } - recursive = true; - apply_autocmds(EVENT_WINSCROLLED, winid, winid, false, wp->w_buffer); - recursive = false; + dict_T *scroll_dict = NULL; + if (trigger_scroll) { + // Create the dict with entries for v:event before making the snapshot. + scroll_dict = tv_dict_alloc(); + scroll_dict->dv_refcount = 1; + (void)check_window_scroll_resize(NULL, NULL, NULL, NULL, scroll_dict); + } - break; + // WinScrolled/WinResized are triggered only once, even when multiple + // windows scrolled or changed size. Store the current values before + // triggering the event, if a scroll or resize happens as a side effect + // then WinScrolled/WinResized is triggered for that later. + snapshot_windows_scroll_size(); + + recursive = true; + + // If both are to be triggered do WinResized first. + if (trigger_resize) { + save_v_event_T save_v_event; + dict_T *v_event = get_v_event(&save_v_event); + + if (tv_dict_add_list(v_event, S_LEN("windows"), windows_list) == OK) { + tv_dict_set_keys_readonly(v_event); + + char winid[NUMBUFLEN]; + vim_snprintf(winid, sizeof(winid), "%d", first_size_win->handle); + apply_autocmds(EVENT_WINRESIZED, winid, winid, false, first_size_win->w_buffer); } + restore_v_event(v_event, &save_v_event); } + + if (trigger_scroll) { + save_v_event_T save_v_event; + dict_T *v_event = get_v_event(&save_v_event); + + // Move the entries from scroll_dict to v_event. + tv_dict_extend(v_event, scroll_dict, "move"); + tv_dict_set_keys_readonly(v_event); + tv_dict_unref(scroll_dict); + + char winid[NUMBUFLEN]; + vim_snprintf(winid, sizeof(winid), "%d", first_scroll_win->handle); + apply_autocmds(EVENT_WINSCROLLED, winid, winid, false, first_scroll_win->w_buffer); + + restore_v_event(v_event, &save_v_event); + } + + recursive = false; } // Save the size of all windows in "gap". -- cgit From 27fceca50195957c977b1e718f571fef795ea824 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 23 Nov 2022 20:03:06 +0800 Subject: refactor: maybe suppress a PVS warning --- src/nvim/window.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index beb96aaa03..aacf30712a 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5390,6 +5390,7 @@ static int check_window_scroll_resize(int *size_count, win_T **first_scroll_win, // tv_list_set_item(winlist, listidx++, &tv); tv_list_append_owned_tv(winlist, tv); } else if (size_count != NULL) { + assert(first_size_win != NULL && first_scroll_win != NULL); (*size_count)++; if (*first_size_win == NULL) { *first_size_win = wp; -- cgit From 3b96ccf7d35be90e49029dec76344d3d92ad91dc Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sat, 26 Nov 2022 18:57:46 +0100 Subject: refactor: replace char_u with char Work on https://github.com/neovim/neovim/issues/459 --- src/nvim/window.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index aacf30712a..3d10f89a2c 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -543,7 +543,7 @@ 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; @@ -6799,9 +6799,9 @@ char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u // Also accept " line 999" with and without the same translation as // used in last_set_msg(). char *p = ptr + len; - if (STRNCMP(p, line_english, strlen(line_english)) == 0) { + if (strncmp(p, line_english, strlen(line_english)) == 0) { p += strlen(line_english); - } else if (STRNCMP(p, line_transl, strlen(line_transl)) == 0) { + } else if (strncmp(p, line_transl, strlen(line_transl)) == 0) { p += strlen(line_transl); } else { p = skipwhite(p); -- cgit From 6b18c77a276f95691708fbff72ed75bac9214a2c Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Mon, 28 Nov 2022 23:25:50 +0100 Subject: refactor(ui): statusbar invalidation to win_set_inner_size() Problem: w_redr_status invalidation is duplicated in multiple functions that all call win_set_inner_size(). Solution: Move to win_set_inner_size(). --- src/nvim/window.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 3d10f89a2c..d29a364b4f 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -6389,9 +6389,6 @@ void win_new_height(win_T *wp, int height) wp->w_height = height; wp->w_pos_changed = true; win_set_inner_size(wp, true); - if (wp->w_status_height) { - wp->w_redr_status = true; - } } void scroll_to_fraction(win_T *wp, int prev_height) @@ -6487,7 +6484,6 @@ void scroll_to_fraction(win_T *wp, int prev_height) } redraw_later(wp, UPD_SOME_VALID); - wp->w_redr_status = true; invalidate_botline_win(wp); } @@ -6554,6 +6550,7 @@ void win_set_inner_size(win_T *wp, bool valid_cursor) wp->w_width_outer = (wp->w_width_inner + win_border_width(wp)); wp->w_winrow_off = wp->w_border_adj[0] + wp->w_winbar_height; wp->w_wincol_off = wp->w_border_adj[3]; + wp->w_redr_status = true; } static int win_border_height(win_T *wp) @@ -6570,10 +6567,8 @@ static int win_border_width(win_T *wp) void win_new_width(win_T *wp, int width) { wp->w_width = width; - win_set_inner_size(wp, true); - - wp->w_redr_status = true; wp->w_pos_changed = true; + win_set_inner_size(wp, true); } void win_comp_scroll(win_T *wp) @@ -6974,7 +6969,6 @@ int set_winbar_win(win_T *wp, bool make_room, bool valid_cursor) } wp->w_winbar_height = winbar_height; win_set_inner_size(wp, valid_cursor); - wp->w_redr_status = wp->w_redr_status || winbar_height; if (winbar_height == 0) { // When removing winbar, deallocate the w_winbar_click_defs array -- cgit From 0b79137c59fbe44bded76f123602e552dc6f7b03 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 29 Nov 2022 16:47:29 +0800 Subject: vim-patch:8.1.2001: some source files are too big (#21231) Problem: Some source files are too big. Solution: Move buffer and window related functions to evalbuffer.c and evalwindow.c. (Yegappan Lakshmanan, closes vim/vim#4898) https://github.com/vim/vim/commit/261f346f8154c0ec7094a4a211c653c74e9f7c2e --- src/nvim/window.c | 238 +----------------------------------------------------- 1 file changed, 1 insertion(+), 237 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index d29a364b4f..5dd35537fa 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -27,6 +27,7 @@ #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" @@ -7278,114 +7279,6 @@ static win_T *restore_snapshot_rec(frame_T *sn, frame_T *fr) return wp; } -/// Set "win" to be the curwin and "tp" to be the current tab page. -/// restore_win() MUST be called to undo, also when FAIL is returned. -/// No autocommands will be executed until restore_win() is called. -/// -/// @param no_display if true the display won't be affected, no redraw is -/// triggered, another tabpage access is limited. -/// -/// @return FAIL if switching to "win" failed. -int switch_win(switchwin_T *switchwin, win_T *win, tabpage_T *tp, bool no_display) -{ - block_autocmds(); - return switch_win_noblock(switchwin, win, tp, no_display); -} - -// As switch_win() but without blocking autocommands. -int switch_win_noblock(switchwin_T *switchwin, win_T *win, tabpage_T *tp, bool no_display) -{ - CLEAR_POINTER(switchwin); - switchwin->sw_curwin = curwin; - if (win == curwin) { - switchwin->sw_same_win = true; - } else { - // Disable Visual selection, because redrawing may fail. - switchwin->sw_visual_active = VIsual_active; - VIsual_active = false; - } - - if (tp != NULL) { - switchwin->sw_curtab = curtab; - if (no_display) { - curtab->tp_firstwin = firstwin; - curtab->tp_lastwin = lastwin; - curtab = tp; - firstwin = curtab->tp_firstwin; - lastwin = curtab->tp_lastwin; - } else { - goto_tabpage_tp(tp, false, false); - } - } - if (!win_valid(win)) { - return FAIL; - } - curwin = win; - curbuf = curwin->w_buffer; - return OK; -} - -// Restore current tabpage and window saved by switch_win(), if still valid. -// When "no_display" is true the display won't be affected, no redraw is -// triggered. -void restore_win(switchwin_T *switchwin, bool no_display) -{ - restore_win_noblock(switchwin, no_display); - unblock_autocmds(); -} - -// As restore_win() but without unblocking autocommands. -void restore_win_noblock(switchwin_T *switchwin, bool no_display) -{ - if (switchwin->sw_curtab != NULL && valid_tabpage(switchwin->sw_curtab)) { - if (no_display) { - curtab->tp_firstwin = firstwin; - curtab->tp_lastwin = lastwin; - curtab = switchwin->sw_curtab; - firstwin = curtab->tp_firstwin; - lastwin = curtab->tp_lastwin; - } else { - goto_tabpage_tp(switchwin->sw_curtab, false, false); - } - } - - if (!switchwin->sw_same_win) { - VIsual_active = switchwin->sw_visual_active; - } - - if (win_valid(switchwin->sw_curwin)) { - curwin = switchwin->sw_curwin; - curbuf = curwin->w_buffer; - } -} - -/// Make "buf" the current buffer. -/// -/// restore_buffer() MUST be called to undo. -/// No autocommands will be executed. Use aucmd_prepbuf() if there are any. -void switch_buffer(bufref_T *save_curbuf, buf_T *buf) -{ - block_autocmds(); - set_bufref(save_curbuf, curbuf); - curbuf->b_nwindows--; - curbuf = buf; - curwin->w_buffer = buf; - curbuf->b_nwindows++; -} - -/// Restore the current buffer after using switch_buffer(). -void restore_buffer(bufref_T *save_curbuf) -{ - unblock_autocmds(); - // Check for valid buffer, just in case. - if (bufref_valid(save_curbuf)) { - curbuf->b_nwindows--; - curwin->w_buffer = save_curbuf->br_buf; - curbuf = save_curbuf->br_buf; - curbuf->b_nwindows++; - } -} - /// Check that "topfrp" and its children are at the right height. /// /// @param topfrp top frame pointer @@ -7508,43 +7401,6 @@ skip: return NULL; // no error } -int win_getid(typval_T *argvars) -{ - if (argvars[0].v_type == VAR_UNKNOWN) { - return curwin->handle; - } - int winnr = (int)tv_get_number(&argvars[0]); - win_T *wp; - if (winnr > 0) { - if (argvars[1].v_type == VAR_UNKNOWN) { - wp = firstwin; - } else { - tabpage_T *tp = NULL; - int tabnr = (int)tv_get_number(&argvars[1]); - FOR_ALL_TABS(tp2) { - if (--tabnr == 0) { - tp = tp2; - break; - } - } - if (tp == NULL) { - return -1; - } - if (tp == curtab) { - wp = firstwin; - } else { - wp = tp->tp_firstwin; - } - } - for (; wp != NULL; wp = wp->w_next) { - if (--winnr == 0) { - return wp->handle; - } - } - } - return 0; -} - void win_get_tabwin(handle_T id, int *tabnr, int *winnr) { *tabnr = 0; @@ -7565,98 +7421,6 @@ void win_get_tabwin(handle_T id, int *tabnr, int *winnr) } } -void win_id2tabwin(typval_T *const argvars, typval_T *const rettv) -{ - handle_T id = (handle_T)tv_get_number(&argvars[0]); - - int winnr = 1; - int tabnr = 1; - win_get_tabwin(id, &tabnr, &winnr); - - list_T *const list = tv_list_alloc_ret(rettv, 2); - tv_list_append_number(list, tabnr); - tv_list_append_number(list, winnr); -} - -win_T *win_id2wp(int id) -{ - return win_id2wp_tp(id, NULL); -} - -// Return the window and tab pointer of window "id". -win_T *win_id2wp_tp(int id, tabpage_T **tpp) -{ - FOR_ALL_TAB_WINDOWS(tp, wp) { - if (wp->handle == id) { - if (tpp != NULL) { - *tpp = tp; - } - return wp; - } - } - - return NULL; -} - -int win_id2win(typval_T *argvars) -{ - int nr = 1; - int id = (int)tv_get_number(&argvars[0]); - - FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if (wp->handle == id) { - return nr; - } - nr++; - } - return 0; -} - -void win_findbuf(typval_T *argvars, list_T *list) -{ - int bufnr = (int)tv_get_number(&argvars[0]); - - FOR_ALL_TAB_WINDOWS(tp, wp) { - if (wp->w_buffer->b_fnum == bufnr) { - tv_list_append_number(list, wp->handle); - } - } -} - -// Get the layout of the given tab page for winlayout(). -void get_framelayout(const frame_T *fr, list_T *l, bool outer) -{ - if (fr == NULL) { - return; - } - - list_T *fr_list; - if (outer) { - // outermost call from f_winlayout() - fr_list = l; - } else { - fr_list = tv_list_alloc(2); - tv_list_append_list(l, fr_list); - } - - if (fr->fr_layout == FR_LEAF) { - if (fr->fr_win != NULL) { - tv_list_append_string(fr_list, "leaf", -1); - tv_list_append_number(fr_list, fr->fr_win->handle); - } - } else { - tv_list_append_string(fr_list, fr->fr_layout == FR_ROW ? "row" : "col", -1); - - list_T *const win_list = tv_list_alloc(kListLenUnknown); - tv_list_append_list(fr_list, win_list); - const frame_T *child = fr->fr_child; - while (child != NULL) { - get_framelayout(child, win_list, false); - child = child->fr_next; - } - } -} - void win_ui_flush(bool validate) { FOR_ALL_TAB_WINDOWS(tp, wp) { -- cgit From 3173d07564e7cdf0834099a379f0faf480c76224 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 29 Nov 2022 18:20:11 +0800 Subject: vim-patch:9.0.0965: using one window for executing autocommands is insufficient Problem: Using one window for executing autocommands is insufficient. Solution: Use up to five windows for executing autocommands. https://github.com/vim/vim/commit/e76062c078debed0df818f70e4db14ad7a7cb53a N/A patches for version.c: vim-patch:9.0.0966: some compilers don't allow a declaration after a label Problem: Some compilers don't allow a declaration after a label. Solution: Move the declaration to the start of the block. (John Marriott) https://github.com/vim/vim/commit/f86490ed4fdab213a28f667abd055c023a73d645 Co-authored-by: Bram Moolenaar --- src/nvim/window.c | 54 +++++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 25 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 5dd35537fa..984287cf81 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -1046,8 +1046,8 @@ int 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 && new_wp == aucmd_win) { + // aucmd_win[] should always remain floating + if (new_wp != NULL && is_aucmd_win(new_wp)) { return FAIL; } @@ -1505,7 +1505,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' && wp != aucmd_win) { + } else if (*p_spk != 'c' && !is_aucmd_win(wp)) { win_fix_scroll(false); } @@ -1940,7 +1940,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) { @@ -2086,7 +2086,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' && next_curwin != aucmd_win) { + if (*p_spk != 'c' && !is_aucmd_win(next_curwin)) { win_fix_scroll(true); } } @@ -2459,7 +2459,7 @@ void close_windows(buf_T *buf, bool keep_curwin) // Start from lastwin to close floating windows with the same buffer first. // When the autocommand window is involved win_close() may need to print an error message. - for (win_T *wp = lastwin; wp != NULL && (lastwin == aucmd_win || !one_window(wp));) { + for (win_T *wp = lastwin; wp != NULL && (is_aucmd_win(lastwin) || !one_window(wp));) { if (wp->w_buffer == buf && (!keep_curwin || wp != curwin) && !(wp->w_closing || wp->w_buffer->b_locked > 0)) { if (win_close(wp, false, false) == FAIL) { @@ -2508,14 +2508,14 @@ bool last_window(win_T *win) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT return one_window(win) && first_tabpage->tp_next == NULL; } -/// Check that current tab page contains no more then one window other than `aucmd_win`. -/// @param counted_float counted even if floating, but not if it is `aucmd_win` +/// Check if current tab page contains no more than one window other than `aucmd_win[]`. +/// @param counted_float counted even if floating, but not if it is `aucmd_win[]` bool one_window(win_T *counted_float) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { bool seen_one = false; FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if (wp != aucmd_win && (!wp->w_floating || wp == counted_float)) { + if (!is_aucmd_win(wp) && (!wp->w_floating || wp == counted_float)) { if (seen_one) { return false; } @@ -2545,7 +2545,7 @@ bool last_nonfloat(win_T *wp) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT /// @return true if all floating windows can be closed static bool can_close_floating_windows(void) { - assert(lastwin != aucmd_win); + assert(!is_aucmd_win(lastwin)); for (win_T *wp = lastwin; wp->w_floating; wp = wp->w_prev) { buf_T *buf = wp->w_buffer; int need_hide = (bufIsChanged(buf) && buf->b_nwindows <= 1); @@ -2663,12 +2663,12 @@ int win_close(win_T *win, bool free_buf, bool force) || (win->w_buffer != NULL && win->w_buffer->b_locked > 0)) { return FAIL; // window is already being closed } - if (win == aucmd_win) { + if (is_aucmd_win(win)) { emsg(_(e_autocmd_close)); return FAIL; } if (lastwin->w_floating && one_window(win)) { - if (lastwin == aucmd_win) { + if (is_aucmd_win(lastwin)) { emsg(_("E814: Cannot close window, only autocmd window would remain")); return FAIL; } @@ -3092,15 +3092,19 @@ void win_free_all(void) win_remove(lastwin, NULL); int dummy; (void)win_free_mem(wp, &dummy, NULL); - if (wp == aucmd_win) { - aucmd_win = NULL; + for (int i = 0; i < AUCMD_WIN_COUNT; ++i) { + if (aucmd_win[i].auc_win == wp) { + aucmd_win[i].auc_win_used = false; + } } } - if (aucmd_win != NULL) { - int dummy; - (void)win_free_mem(aucmd_win, &dummy, NULL); - aucmd_win = NULL; + for (int i = 0; i < AUCMD_WIN_COUNT; ++i) { + if (aucmd_win[i].auc_win_used) { + int dummy; + (void)win_free_mem(aucmd_win[i].auc_win, &dummy, NULL); + aucmd_win[i].auc_win_used = false; + } } while (firstwin != NULL) { @@ -3904,18 +3908,18 @@ void win_alloc_first(void) unuse_tabpage(first_tabpage); } -// Init `aucmd_win`. This can only be done after the first window +// Init `aucmd_win[idx]`. This can only be done after the first window // is fully initialized, thus it can't be in win_alloc_first(). -void win_alloc_aucmd_win(void) +void win_alloc_aucmd_win(int idx) { Error err = ERROR_INIT; FloatConfig fconfig = FLOAT_CONFIG_INIT; fconfig.width = Columns; fconfig.height = 5; fconfig.focusable = false; - aucmd_win = win_new_float(NULL, true, fconfig, &err); - aucmd_win->w_buffer->b_nwindows--; - RESET_BINDING(aucmd_win); + aucmd_win[idx].auc_win = win_new_float(NULL, true, fconfig, &err); + aucmd_win[idx].auc_win->w_buffer->b_nwindows--; + RESET_BINDING(aucmd_win[idx].auc_win); } // Allocate the first window or the first window in a new tab page. @@ -5108,7 +5112,7 @@ static void win_free(win_T *wp, tabpage_T *tp) win_free_grid(wp, false); - if (wp != aucmd_win) { + if (win_valid_any_tab(wp)) { win_remove(wp, tp); } if (autocmd_busy) { @@ -7059,7 +7063,7 @@ bool only_one_window(void) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { if (wp->w_buffer != NULL && (!((bt_help(wp->w_buffer) && !bt_help(curbuf)) || wp->w_floating - || wp->w_p_pvw) || wp == curwin) && wp != aucmd_win) { + || wp->w_p_pvw) || wp == curwin) && !is_aucmd_win(wp)) { count++; } } -- cgit From 95f5cf96912727a1ede055211645ac9779f3da44 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 29 Nov 2022 19:02:29 +0800 Subject: vim-patch:9.0.0967: leaking memory from autocmd windows Problem: Leaking memory from autocmd windows. Solution: Free window when auc_win is not NULL. https://github.com/vim/vim/commit/84497cd06f06516f6ce727ea00c47792ce16dc70 Co-authored-by: Bram Moolenaar --- src/nvim/window.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 984287cf81..2927855073 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -3092,18 +3092,18 @@ void win_free_all(void) win_remove(lastwin, NULL); int dummy; (void)win_free_mem(wp, &dummy, NULL); - for (int i = 0; i < AUCMD_WIN_COUNT; ++i) { + for (int i = 0; i < AUCMD_WIN_COUNT; i++) { if (aucmd_win[i].auc_win == wp) { - aucmd_win[i].auc_win_used = false; + aucmd_win[i].auc_win = NULL; } } } - for (int i = 0; i < AUCMD_WIN_COUNT; ++i) { - if (aucmd_win[i].auc_win_used) { + for (int i = 0; i < AUCMD_WIN_COUNT; i++) { + if (aucmd_win[i].auc_win != NULL) { int dummy; (void)win_free_mem(aucmd_win[i].auc_win, &dummy, NULL); - aucmd_win[i].auc_win_used = false; + aucmd_win[i].auc_win = NULL; } } -- cgit From bd2d0edcbf4e98e05edff13f344865fcafac56b5 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 1 Dec 2022 09:05:25 +0800 Subject: fix: clang warnings (#21247) --- src/nvim/window.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 2927855073..e761f7e40b 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2760,6 +2760,7 @@ int win_close(win_T *win, bool free_buf, bool force) if (win->w_floating) { ui_comp_remove_grid(&win->w_grid_alloc); + assert(first_tabpage != NULL); // suppress clang "Dereference of NULL pointer" if (win->w_float_config.external) { for (tabpage_T *tp = first_tabpage; tp != NULL; tp = tp->tp_next) { if (tp == curtab) { -- cgit From 982c0053f4059fb4558ce83a0b8d250be1058980 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 2 Dec 2022 10:30:50 +0800 Subject: fix(float): make closing float in another tab return to correct window --- src/nvim/window.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index e761f7e40b..80c51516b1 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -1643,12 +1643,21 @@ 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; } @@ -3057,10 +3066,18 @@ static win_T *win_free_mem(win_T *win, int *dirp, tabpage_T *tp) xfree(frp); } else { *dirp = 'h'; // Dummy value. - if (win_valid(prevwin) && prevwin != win) { - wp = prevwin; + if (tp == NULL) { + if (win_valid(prevwin) && prevwin != win) { + wp = prevwin; + } else { + wp = firstwin; + } } else { - wp = firstwin; + if (tabpage_win_valid(tp, tp->tp_prevwin) && tp->tp_prevwin != win) { + wp = tp->tp_prevwin; + } else { + wp = tp->tp_firstwin; + } } } win_free(win, tp); @@ -3068,11 +3085,7 @@ static win_T *win_free_mem(win_T *win, int *dirp, tabpage_T *tp) // When deleting the current window of another tab page select a new // current window. if (tp != NULL && win == tp->tp_curwin) { - if (win_valid(tp->tp_prevwin) && tp->tp_prevwin != win) { - tp->tp_curwin = tp->tp_prevwin; - } else { - tp->tp_curwin = tp->tp_firstwin; - } + tp->tp_curwin = wp; } return wp; -- cgit From 47d3d0102fffbfd52b950c521e5d1e443ac7885f Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 2 Dec 2022 10:28:35 +0800 Subject: vim-patch:8.2.1748: closing split window in other tab may cause a crash Problem: Closing split window in other tab may cause a crash. Solution: Set tp_curwin properly. (Rob Pilling, closes vim/vim#7018) https://github.com/vim/vim/commit/f3c51bbff1256a52bdd9ede7887f40062be2628c Co-authored-by: Bram Moolenaar --- src/nvim/window.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 80c51516b1..79a90ab8af 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -3058,6 +3058,7 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) static win_T *win_free_mem(win_T *win, int *dirp, tabpage_T *tp) { win_T *wp; + tabpage_T *win_tp = tp == NULL ? curtab : tp; if (!win->w_floating) { // Remove the window and its frame from the tree of frames. @@ -3082,10 +3083,10 @@ static win_T *win_free_mem(win_T *win, int *dirp, tabpage_T *tp) } win_free(win, tp); - // When deleting the current window of another tab page select a new - // current window. - if (tp != NULL && win == tp->tp_curwin) { - tp->tp_curwin = wp; + // When deleting the current window in the tab, select a new current + // window. + if (win == win_tp->tp_curwin) { + win_tp->tp_curwin = wp; } return wp; -- cgit From 1145a9b2485a4e5072cffe28a958da983cd59e84 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 2 Dec 2022 20:39:24 +0800 Subject: feat(aucmd_win): allow crazy things with hidden buffers (#21250) Problem: Crash when doing crazy things with hidden buffers. Solution: Dynamically allocate the list of autocommand windows. --- src/nvim/window.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 79a90ab8af..1f80f14f26 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -3122,6 +3122,8 @@ void win_free_all(void) } } + kv_destroy(aucmd_win_vec); + while (firstwin != NULL) { int dummy; (void)win_free_mem(firstwin, &dummy, NULL); -- cgit From e120a049f0e6594b317819bbc883d9040729bc93 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 6 Dec 2022 07:26:00 +0800 Subject: fix(float): fix ml_get error with bufpos --- src/nvim/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 1f80f14f26..86c936c734 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -849,7 +849,7 @@ void win_config_float(win_T *wp, FloatConfig fconfig) 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); + textpos2screenpos(parent, &pos, &trow, &tcol, &tcolc, &tcole, true); row += trow - 1; col += tcol - 1; } -- cgit From ed23cd3e50e778604e45e85bc939271a7759ca1f Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 7 Dec 2022 11:36:34 +0800 Subject: fix(float): fix crash with bufpos and non-existent window (#21319) --- src/nvim/window.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 86c936c734..1216bd8dcc 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -843,16 +843,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(parent, &pos, &trow, &tcol, &tcolc, &tcole, true); - row += trow - 1; - col += tcol - 1; - } wp->w_winrow = row; wp->w_wincol = col; } else { -- cgit From f92aab5f704f6e94e80f2fcbab42acc272a66a29 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 7 Dec 2022 18:34:39 +0800 Subject: vim-patch:9.0.1025: WinScrolled is not triggered when filler lines change (#21325) Problem: WinScrolled is not triggered when filler lines change. Solution: Add "topfill" to the values that WinScrolled triggers on. (closes vim/vim#11668) https://github.com/vim/vim/commit/3fc84dc2c7efecd7c14ce341cd777475058936fd Cherry-pick StopVimInTerminal() from patch 9.0.1010. --- src/nvim/window.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 1216bd8dcc..75320bcb7d 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5306,6 +5306,7 @@ void snapshot_windows_scroll_size(void) { FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { wp->w_last_topline = wp->w_topline; + wp->w_last_topfill = wp->w_topfill; wp->w_last_leftcol = wp->w_leftcol; wp->w_last_skipcol = wp->w_skipcol; wp->w_last_width = wp->w_width; @@ -5327,7 +5328,8 @@ void may_make_initial_scroll_size_snapshot(void) /// window. /// Returns the dictionary with refcount set to one. /// Returns NULL on internal error. -static dict_T *make_win_info_dict(int width, int height, int topline, int leftcol, int skipcol) +static dict_T *make_win_info_dict(int width, int height, int topline, int topfill, int leftcol, + int skipcol) { dict_T *const d = tv_dict_alloc(); d->dv_refcount = 1; @@ -5351,6 +5353,10 @@ static dict_T *make_win_info_dict(int width, int height, int topline, int leftco if (tv_dict_add_tv(d, S_LEN("topline"), &tv) == FAIL) { break; } + tv.vval.v_number = topfill; + if (tv_dict_add_tv(d, S_LEN("topfill"), &tv) == FAIL) { + break; + } tv.vval.v_number = leftcol; if (tv_dict_add_tv(d, S_LEN("leftcol"), &tv) == FAIL) { break; @@ -5394,6 +5400,7 @@ static int check_window_scroll_resize(int *size_count, win_T **first_scroll_win, int tot_width = 0; int tot_height = 0; int tot_topline = 0; + int tot_topfill = 0; int tot_leftcol = 0; int tot_skipcol = 0; @@ -5426,6 +5433,7 @@ static int check_window_scroll_resize(int *size_count, win_T **first_scroll_win, } const bool scroll_changed = wp->w_last_topline != wp->w_topline + || wp->w_last_topfill != wp->w_topfill || wp->w_last_leftcol != wp->w_leftcol || wp->w_last_skipcol != wp->w_skipcol; if (scroll_changed) { @@ -5440,10 +5448,11 @@ static int check_window_scroll_resize(int *size_count, win_T **first_scroll_win, int width = wp->w_width - wp->w_last_width; int height = wp->w_height - wp->w_last_height; int topline = wp->w_topline - wp->w_last_topline; + int topfill = wp->w_topfill - wp->w_last_topfill; int leftcol = wp->w_leftcol - wp->w_last_leftcol; int skipcol = wp->w_skipcol - wp->w_last_skipcol; - dict_T *d = make_win_info_dict(width, height, - topline, leftcol, skipcol); + dict_T *d = make_win_info_dict(width, height, topline, + topfill, leftcol, skipcol); if (d == NULL) { break; } @@ -5458,14 +5467,15 @@ static int check_window_scroll_resize(int *size_count, win_T **first_scroll_win, tot_width += abs(width); tot_height += abs(height); tot_topline += abs(topline); + tot_topfill += abs(topfill); tot_leftcol += abs(leftcol); tot_skipcol += abs(skipcol); } } if (v_event != NULL) { - dict_T *alldict = make_win_info_dict(tot_width, tot_height, - tot_topline, tot_leftcol, tot_skipcol); + dict_T *alldict = make_win_info_dict(tot_width, tot_height, tot_topline, + tot_topfill, tot_leftcol, tot_skipcol); if (alldict != NULL) { if (tv_dict_add_dict(v_event, S_LEN("all"), alldict) == FAIL) { tv_dict_unref(alldict); -- cgit From 7faf8a45e8c48d5ab1b6096d6b3e23c84bb3d7c6 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 10 Dec 2022 06:50:03 +0800 Subject: fix(events): skip WinScrolled for newly-created float windows (#21333) Unlike split windows, creating a new floating window does not cause other windows to resize, so it doesn't make much sense to trigger WinScrolled or WinResized when creating a new floating window. --- src/nvim/window.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 75320bcb7d..05694a8b6d 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5405,6 +5405,18 @@ static int check_window_scroll_resize(int *size_count, win_T **first_scroll_win, int tot_skipcol = 0; FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + // Skip floating windows that do not have a snapshot (usually becuase they are newly-created), + // as unlike split windows, creating floating windows do not cause other windows to resize. + if (wp->w_floating && wp->w_last_topline == 0) { + wp->w_last_topline = wp->w_topline; + wp->w_last_topfill = wp->w_topfill; + wp->w_last_leftcol = wp->w_leftcol; + wp->w_last_skipcol = wp->w_skipcol; + wp->w_last_width = wp->w_width; + wp->w_last_height = wp->w_height; + continue; + } + const bool size_changed = wp->w_last_width != wp->w_width || wp->w_last_height != wp->w_height; if (size_changed) { -- cgit From 090048bec9f80c46a6ce6ff05a419b15bc4bf028 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 13 Dec 2022 22:43:54 +0800 Subject: vim-patch:9.0.1051: after a failed CTRL-W ] next command splits window (#21400) Problem: After a failed CTRL-W ] next command splits window. Solution: Reset postponed_split. (Rob Pilling, closes vim/vim#11698) https://github.com/vim/vim/commit/cb94c910706fdd575cc25797d7858e084f1e3524 Co-authored-by: Rob Pilling --- src/nvim/window.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 05694a8b6d..d026f4551a 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -494,6 +494,7 @@ 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 @@ -594,6 +595,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 -- cgit From cd6ec1db068f9f4c1900a00b5392e39e59f0a7cb Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 27 Dec 2022 17:29:05 +0800 Subject: fix(win_close): remove float grid after closing buffer (#21551) It is not safe to remove the float grid when autocommands can still be triggered, as autocommands may use the float grid. --- src/nvim/window.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index d026f4551a..fe771c52c6 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -2764,28 +2764,6 @@ int win_close(win_T *win, bool free_buf, bool force) } } - bool was_floating = win->w_floating; - if (ui_has(kUIMultigrid)) { - ui_call_win_close(win->w_grid_alloc.handle); - } - - if (win->w_floating) { - ui_comp_remove_grid(&win->w_grid_alloc); - assert(first_tabpage != NULL); // suppress clang "Dereference of NULL pointer" - if (win->w_float_config.external) { - for (tabpage_T *tp = first_tabpage; tp != NULL; tp = tp->tp_next) { - if (tp == curtab) { - continue; - } - if (tp->tp_curwin == win) { - // NB: an autocmd can still abort the closing of this window, - // bur carring out this change anyway shouldn't be a catastrophe. - tp->tp_curwin = tp->tp_firstwin; - } - } - } - } - // Fire WinClosed just before starting to free window-related resources. do_autocmd_winclosed(win); // autocmd may have freed the window already. @@ -2831,6 +2809,28 @@ int win_close(win_T *win, bool free_buf, bool force) // let terminal buffers know that this window dimensions may be ignored win->w_closing = true; + bool was_floating = win->w_floating; + if (ui_has(kUIMultigrid)) { + ui_call_win_close(win->w_grid_alloc.handle); + } + + if (win->w_floating) { + ui_comp_remove_grid(&win->w_grid_alloc); + assert(first_tabpage != NULL); // suppress clang "Dereference of NULL pointer" + if (win->w_float_config.external) { + for (tabpage_T *tp = first_tabpage; tp != NULL; tp = tp->tp_next) { + if (tp == curtab) { + continue; + } + if (tp->tp_curwin == win) { + // NB: an autocmd can still abort the closing of this window, + // bur carring out this change anyway shouldn't be a catastrophe. + tp->tp_curwin = tp->tp_firstwin; + } + } + } + } + // Free the memory used for the window and get the window that received // the screen space. int dir; -- cgit From 83472b3808c3cda869471442793ece9e7a0ce261 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 30 Dec 2022 14:41:59 +0800 Subject: vim-patch:8.2.{3773,3774} vim-patch:8.2.3773: wrong window size when a modeline changes 'columns' Problem: Wrong window size when a modeline changes 'columns' and there is more than one tabpage. (Michael Soyka) Solution: Adjust the frames of all tabpages. (closes vim/vim#9315) https://github.com/vim/vim/commit/8a7374f8c4eb4c016270ad908a43af4ddedcbf56 vim-patch:8.2.3774: test for command line height fails Problem: Test for command line height fails. Solution: Use another way to handle window size change. https://github.com/vim/vim/commit/b711814cb64b60ec4918e3e1fb2ca5c50d6e9340 Co-authored-by: Bram Moolenaar --- src/nvim/window.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index fe771c52c6..4c03893173 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -4277,7 +4277,9 @@ static int leave_tabpage(buf_T *new_curbuf, bool trigger_leave_autocmds) tp->tp_firstwin = firstwin; tp->tp_lastwin = lastwin; tp->tp_old_Rows_avail = ROWS_AVAIL; - tp->tp_old_Columns = Columns; + if (tp->tp_old_Columns != -1) { + tp->tp_old_Columns = Columns; + } firstwin = NULL; lastwin = NULL; return OK; @@ -4340,8 +4342,13 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, bool trigger_enter_a if (curtab->tp_old_Rows_avail != ROWS_AVAIL || (old_off != firstwin->w_winrow)) { win_new_screen_rows(); } - if (curtab->tp_old_Columns != Columns && starting == 0) { - win_new_screen_cols(); // update window widths + if (curtab->tp_old_Columns != Columns) { + if (starting == 0) { + win_new_screen_cols(); // update window widths + curtab->tp_old_Columns = Columns; + } else { + curtab->tp_old_Columns = -1; // update window widths later + } } lastused_tabpage = old_curtab; -- cgit From b102bf22c009d3543f71d9d21c1252b54f5d4a54 Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Thu, 29 Dec 2022 03:07:49 +0100 Subject: fix(ui): allow resize commands to set 'cmdheight' to 0 Resolve https://github.com/neovim/neovim/issues/21558 --- src/nvim/window.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index fe771c52c6..5c1c861f45 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5758,8 +5758,8 @@ static void frame_setheight(frame_T *curfrp, int height) if (height > ROWS_AVAIL) { // If height is greater than the available space, try to create space for // the frame by reducing 'cmdheight' if possible, while making sure - // `cmdheight` doesn't go below 1. - height = (int)MIN((p_ch > 0 ? ROWS_AVAIL + (p_ch - 1) : ROWS_AVAIL), height); + // `cmdheight` doesn't go below 1 if it wasn't set to 0 explicitly. + height = (int)MIN(ROWS_AVAIL + p_ch - !p_ch_was_zero, height); } if (height > 0) { frame_new_height(curfrp, height, false, false); @@ -6090,8 +6090,6 @@ void win_setminwidth(void) /// Status line of dragwin is dragged "offset" lines down (negative is up). void win_drag_status_line(win_T *dragwin, int offset) { - static bool p_ch_was_zero = false; - // If the user explicitly set 'cmdheight' to zero, then allow for dragging // the status line making it zero again. if (p_ch == 0) { -- cgit From 936e191fef9865600af211c29ea4959ffbce81dd Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Wed, 4 Jan 2023 00:38:48 +0100 Subject: docs: fix typos (#21427) Co-authored-by: Gustavo Sampaio Co-authored-by: C.D. MacEachern Co-authored-by: Sean Dewar Co-authored-by: Tomas Nemec --- src/nvim/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 57d40ceb42..bb915d2fc5 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5414,7 +5414,7 @@ static int check_window_scroll_resize(int *size_count, win_T **first_scroll_win, int tot_skipcol = 0; FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - // Skip floating windows that do not have a snapshot (usually becuase they are newly-created), + // Skip floating windows that do not have a snapshot (usually because they are newly-created), // as unlike split windows, creating floating windows do not cause other windows to resize. if (wp->w_floating && wp->w_last_topline == 0) { wp->w_last_topline = wp->w_topline; -- cgit From 149209400383c673fdb4fdd1c9a7639139f17936 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Mon, 9 Jan 2023 14:13:06 +0100 Subject: refactor: replace char_u with char 17 - remove STRLCPY (#21235) refactor: replace char_u with char Work on https://github.com/neovim/neovim/issues/459 --- src/nvim/window.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index bb915d2fc5..4e569ce11f 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -648,7 +648,7 @@ wingotofile: 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(bufp + len, bufsize - len, "%" PRId64, Prenum); @@ -4879,7 +4879,7 @@ void fix_current_dir(void) // New directory is either the local directory of the window, tab or NULL. char *new_dir = curwin->w_localdir ? curwin->w_localdir : curtab->tp_localdir; char cwd[MAXPATHL]; - if (os_dirname((char_u *)cwd, MAXPATHL) != OK) { + if (os_dirname(cwd, MAXPATHL) != OK) { cwd[0] = NUL; } -- cgit From 364b131f42509326c912c9b0fef5dfc94ed23b41 Mon Sep 17 00:00:00 2001 From: luukvbaal <31730729+luukvbaal@users.noreply.github.com> Date: Mon, 9 Jan 2023 18:12:06 +0100 Subject: feat(ui): add 'statuscolumn' option Problem: Unable to customize the column next to a window ('gutter'). Solution: Add 'statuscolumn' option that follows the 'statusline' syntax, allowing to customize the status column. Also supporting the %@ click execute function label. Adds new items @C and @s which will print the fold and sign columns. Line numbers and signs can be clicked, highlighted, aligned, transformed, margined etc. --- src/nvim/window.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 4e569ce11f..e836fa50fb 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5094,6 +5094,9 @@ static void win_free(win_T *wp, tabpage_T *tp) stl_clear_click_defs(wp->w_winbar_click_defs, wp->w_winbar_click_defs_size); xfree(wp->w_winbar_click_defs); + stl_clear_click_defs(wp->w_statuscol_click_defs, wp->w_statuscol_click_defs_size); + xfree(wp->w_statuscol_click_defs); + // Remove the window from the b_wininfo lists, it may happen that the // freed memory is re-used for another window. FOR_ALL_BUFFERS(buf) { -- cgit From 87cfe50944ef2c84de98eb6b124fe312eef31313 Mon Sep 17 00:00:00 2001 From: Raphael Date: Tue, 10 Jan 2023 17:36:48 +0800 Subject: fix(ui): set stc to empty in floatwin with minimal style (#21720) fix(ui): set stc to emtpy in floatwin with minimal style --- src/nvim/window.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index e836fa50fb..5c05417dd8 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -786,6 +786,12 @@ void win_set_minimal_style(win_T *wp) 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) -- cgit From 870ca1de52b240926b88f01afa697cd9b119bdac Mon Sep 17 00:00:00 2001 From: Sebastian Lyng Johansen Date: Tue, 10 Jan 2023 11:22:41 +0100 Subject: feat(float): open float relative to mouse #21531 Problem: No easy way to position a LSP hover window relative to mouse. Solution: Introduce another option to the `relative` key in `nvim_open_win()`. With this PR it should be possible to override the handler and do something similar to this https://github.com/neovim/neovim/pull/19481#issuecomment-1193248674 to have hover information displayed from the mouse. Test case: ```lua local util = require('vim.lsp.util') local function make_position_param(window, offset_encoding) window = window or 0 local buf = vim.api.nvim_win_get_buf(window) local row, col local mouse = vim.fn.getmousepos() row = mouse.line col = mouse.column offset_encoding = offset_encoding or util._get_offset_encoding(buf) row = row - 1 local line = vim.api.nvim_buf_get_lines(buf, row, row + 1, true)[1] if not line then return { line = 0, character = 0 } end if #line < col then return { line = 0, character = 0 } end col = util._str_utfindex_enc(line, col, offset_encoding) return { line = row, character = col } end local make_params = function(window, offset_encoding) window = window or 0 local buf = vim.api.nvim_win_get_buf(window) offset_encoding = offset_encoding or util._get_offset_encoding(buf) return { textDocument = util.make_text_document_params(buf), position = make_position_param(window, offset_encoding), } end local hover_timer = nil vim.o.mousemoveevent = true vim.keymap.set({ '', 'i' }, '', function() if hover_timer then hover_timer:close() end hover_timer = vim.defer_fn(function() hover_timer = nil local params = make_params() vim.lsp.buf_request( 0, 'textDocument/hover', params, vim.lsp.with(vim.lsp.handlers.hover, { silent = true, focusable = false, relative = 'mouse', }) ) end, 500) return '' end, { expr = true }) ``` --- src/nvim/window.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 5c05417dd8..37f297909a 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -804,6 +804,15 @@ 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; -- cgit From 1097d239c307a10a87fa995c4cfbe5987939e177 Mon Sep 17 00:00:00 2001 From: luukvbaal <31730729+luukvbaal@users.noreply.github.com> Date: Fri, 13 Jan 2023 04:47:55 +0100 Subject: fix(ui): command line issues with external messages (#21709) * fix: don't truncate external messages * fix: avoid resizing command line with external messages --- src/nvim/window.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/nvim/window.c') diff --git a/src/nvim/window.c b/src/nvim/window.c index 37f297909a..2bcbef14b0 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5780,6 +5780,10 @@ static void frame_setheight(frame_T *curfrp, int height) if (curfrp->fr_parent == NULL) { // topframe: can only change the command line height + // Avoid doing so with external messages. + if (ui_has(kUIMessages)) { + return; + } if (height > ROWS_AVAIL) { // If height is greater than the available space, try to create space for // the frame by reducing 'cmdheight' if possible, while making sure @@ -6115,13 +6119,13 @@ void win_setminwidth(void) /// Status line of dragwin is dragged "offset" lines down (negative is up). void win_drag_status_line(win_T *dragwin, int offset) { - // If the user explicitly set 'cmdheight' to zero, then allow for dragging - // the status line making it zero again. - if (p_ch == 0) { - p_ch_was_zero = true; + frame_T *fr = dragwin->w_frame; + + // Avoid changing command line height with external messages. + if (fr->fr_next == NULL && ui_has(kUIMessages)) { + return; } - frame_T *fr = dragwin->w_frame; frame_T *curfr = fr; if (fr != topframe) { // more than one window fr = fr->fr_parent; -- cgit