diff options
Diffstat (limited to 'src/nvim/window.c')
| -rw-r--r-- | src/nvim/window.c | 428 |
1 files changed, 263 insertions, 165 deletions
diff --git a/src/nvim/window.c b/src/nvim/window.c index 83ddf534cf..6bc082ffb2 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -502,10 +502,11 @@ wingotofile: break; } FloatConfig config = FLOAT_CONFIG_INIT; + config.width = curwin->w_width; + config.height = curwin->w_height; config.external = true; Error err = ERROR_INIT; - if (!win_new_float(curwin, curwin->w_width, curwin->w_height, config, - &err)) { + if (!win_new_float(curwin, config, &err)) { EMSG(err.msg); api_clear_error(&err); beep_flush(); @@ -538,12 +539,9 @@ static void cmd_with_count(char *cmd, char_u *bufp, size_t bufsize, /// float. It must then already belong to the current tabpage! /// /// config must already have been validated! -win_T *win_new_float(win_T *wp, int width, int height, FloatConfig config, - Error *err) +win_T *win_new_float(win_T *wp, FloatConfig fconfig, Error *err) { - bool new = false; if (wp == NULL) { - new = true; wp = win_alloc(lastwin_nofloating(), false); win_init(wp, curwin, 0); } else { @@ -569,29 +567,30 @@ win_T *win_new_float(win_T *wp, int width, int height, FloatConfig config, wp->w_floating = 1; wp->w_status_height = 0; wp->w_vsep_width = 0; - win_config_float(wp, width, height, config); + + // TODO(bfredl): use set_option_to() after merging #9110 ? + wp->w_p_nu = false; + wp->w_allbuf_opt.wo_nu = false; + win_config_float(wp, fconfig); wp->w_pos_changed = true; redraw_win_later(wp, VALID); - if (new) { - win_enter(wp, false); - } return wp; } -void win_config_float(win_T *wp, int width, int height, - FloatConfig config) +void win_config_float(win_T *wp, FloatConfig fconfig) { - wp->w_height = MAX(height, 1); - wp->w_width = MAX(width, 2); + wp->w_width = MAX(fconfig.width, 1); + wp->w_height = MAX(fconfig.height, 1); - if (config.relative == kFloatRelativeCursor) { - config.relative = kFloatRelativeWindow; - config.row += curwin->w_wrow; - config.col += curwin->w_wcol; - config.window = curwin->handle; + if (fconfig.relative == kFloatRelativeCursor) { + fconfig.relative = kFloatRelativeWindow; + fconfig.row += curwin->w_wrow; + fconfig.col += curwin->w_wcol; + fconfig.window = curwin->handle; } - wp->w_float_config = config; + bool change_external = fconfig.external != wp->w_float_config.external; + wp->w_float_config = fconfig; if (!ui_has(kUIMultigrid)) { wp->w_height = MIN(wp->w_height, Rows-1); @@ -601,6 +600,10 @@ void win_config_float(win_T *wp, int width, int height, win_set_inner_size(wp); must_redraw = MAX(must_redraw, VALID); wp->w_pos_changed = true; + if (change_external) { + wp->w_hl_needs_update = true; + redraw_win_later(wp, NOT_VALID); + } } static void ui_ext_win_position(win_T *wp) @@ -610,28 +613,25 @@ static void ui_ext_win_position(win_T *wp) wp->w_wincol, wp->w_width, wp->w_height); return; } - const char *const anchor_str[] = { - "NW", - "NE", - "SW", - "SE" - }; FloatConfig c = wp->w_float_config; if (!c.external) { ScreenGrid *grid = &default_grid; - int row = c.row, col = c.col; + float row = c.row, col = c.col; if (c.relative == kFloatRelativeWindow) { Error dummy = ERROR_INIT; win_T *win = find_window_by_handle(c.window, &dummy); if (win) { grid = &win->w_grid; - screen_adjust_grid(&grid, &row, &col); + int row_off = 0, col_off = 0; + screen_adjust_grid(&grid, &row_off, &col_off); + row += row_off; + col += col_off; } api_clear_error(&dummy); } if (ui_has(kUIMultigrid)) { - String anchor = cstr_to_string(anchor_str[c.anchor]); + String anchor = cstr_to_string(float_anchor_str[c.anchor]); ui_call_win_float_pos(wp->w_grid.handle, wp->handle, anchor, grid->handle, row, col, c.focusable); } else { @@ -640,16 +640,16 @@ static void ui_ext_win_position(win_T *wp) bool east = c.anchor & kFloatAnchorEast; bool south = c.anchor & kFloatAnchorSouth; - row -= (south ? wp->w_height : 0); - col -= (east ? wp->w_width : 0); - row = MAX(MIN(row, Rows-wp->w_height-1), 0); - col = MAX(MIN(col, Columns-wp->w_width), 0); - wp->w_winrow = row; - wp->w_wincol = col; + int comp_row = (int)row - (south ? wp->w_height : 0); + int comp_col = (int)col - (east ? wp->w_width : 0); + comp_row = MAX(MIN(comp_row, Rows-wp->w_height-1), 0); + comp_col = MAX(MIN(comp_col, Columns-wp->w_width), 0); + wp->w_winrow = comp_row; + wp->w_wincol = comp_col; bool valid = (wp->w_redr_type == 0); bool on_top = (curwin == wp) || !curwin->w_floating; - ui_comp_put_grid(&wp->w_grid, row, col, wp->w_height, wp->w_width, - valid, on_top); + ui_comp_put_grid(&wp->w_grid, comp_row, comp_col, wp->w_height, + wp->w_width, valid, on_top); if (!valid) { wp->w_grid.valid = false; redraw_win_later(wp, NOT_VALID); @@ -668,14 +668,14 @@ static bool parse_float_anchor(String anchor, FloatAnchor *out) *out = (FloatAnchor)0; } char *str = anchor.data; - if (!STRICMP(str, "NW")) { - *out = kFloatAnchorNW; - } else if (!STRICMP(str, "NE")) { - *out = kFloatAnchorNE; - } else if (!STRICMP(str, "SW")) { - *out = kFloatAnchorSW; - } else if (!STRICMP(str, "SE")) { - *out = kFloatAnchorSE; + if (striequal(str, "NW")) { + *out = 0; // NW is the default + } else if (striequal(str, "NE")) { + *out = kFloatAnchorEast; + } else if (striequal(str, "SW")) { + *out = kFloatAnchorSouth; + } else if (striequal(str, "SE")) { + *out = kFloatAnchorSouth | kFloatAnchorEast; } else { return false; } @@ -684,15 +684,12 @@ static bool parse_float_anchor(String anchor, FloatAnchor *out) static bool parse_float_relative(String relative, FloatRelative *out) { - if (relative.size == 0) { - *out = (FloatRelative)0; - } char *str = relative.data; - if (!STRICMP(str, "editor")) { + if (striequal(str, "editor")) { *out = kFloatRelativeEditor; - } else if (!STRICMP(str, "win")) { + } else if (striequal(str, "win")) { *out = kFloatRelativeWindow; - } else if (!STRICMP(str, "cursor")) { + } else if (striequal(str, "cursor")) { *out = kFloatRelativeCursor; } else { return false; @@ -700,11 +697,14 @@ static bool parse_float_relative(String relative, FloatRelative *out) return true; } -bool parse_float_config(Dictionary config, FloatConfig *out, bool reconf, +bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf, Error *err) { + // TODO(bfredl): use a get/has_key interface instead and get rid of extra + // flags bool has_row = false, has_col = false, has_relative = false; bool has_external = false, has_window = false; + bool has_width = false, has_height = false; for (size_t i = 0; i < config.size; i++) { char *key = config.items[i].key.data; @@ -712,109 +712,137 @@ bool parse_float_config(Dictionary config, FloatConfig *out, bool reconf, if (!strcmp(key, "row")) { has_row = true; if (val.type == kObjectTypeInteger) { - out->row = val.data.integer; + fconfig->row = val.data.integer; } else if (val.type == kObjectTypeFloat) { - out->row = val.data.floating; + fconfig->row = val.data.floating; } else { api_set_error(err, kErrorTypeValidation, - "'row' option has to be Integer or Float"); + "'row' key must be Integer or Float"); return false; } } else if (!strcmp(key, "col")) { has_col = true; if (val.type == kObjectTypeInteger) { - out->col = val.data.integer; + fconfig->col = val.data.integer; } else if (val.type == kObjectTypeFloat) { - out->col = val.data.floating; + fconfig->col = val.data.floating; + } else { + api_set_error(err, kErrorTypeValidation, + "'col' key must be Integer or Float"); + return false; + } + } else if (strequal(key, "width")) { + has_width = true; + if (val.type == kObjectTypeInteger && val.data.integer > 0) { + fconfig->width = val.data.integer; + } else { + api_set_error(err, kErrorTypeValidation, + "'width' key must be a positive Integer"); + return false; + } + } else if (strequal(key, "height")) { + has_height = true; + if (val.type == kObjectTypeInteger && val.data.integer > 0) { + fconfig->height= val.data.integer; } else { api_set_error(err, kErrorTypeValidation, - "'col' option has to be Integer or Float"); + "'height' key must be a positive Integer"); return false; } } else if (!strcmp(key, "anchor")) { if (val.type != kObjectTypeString) { api_set_error(err, kErrorTypeValidation, - "'anchor' option has to be String"); + "'anchor' key must be String"); return false; } - if (!parse_float_anchor(val.data.string, &out->anchor)) { + if (!parse_float_anchor(val.data.string, &fconfig->anchor)) { api_set_error(err, kErrorTypeValidation, - "Invalid value of 'anchor' option"); + "Invalid value of 'anchor' key"); return false; } } else if (!strcmp(key, "relative")) { - has_relative = true; if (val.type != kObjectTypeString) { api_set_error(err, kErrorTypeValidation, - "'relative' option has to be String"); + "'relative' key must be String"); return false; } - if (!parse_float_relative(val.data.string, &out->relative)) { - api_set_error(err, kErrorTypeValidation, - "Invalid value of 'relative' option"); - return false; + // ignore empty string, to match nvim_win_get_config + if (val.data.string.size > 0) { + has_relative = true; + if (!parse_float_relative(val.data.string, &fconfig->relative)) { + api_set_error(err, kErrorTypeValidation, + "Invalid value of 'relative' key"); + return false; + } } } else if (!strcmp(key, "win")) { has_window = true; if (val.type != kObjectTypeInteger && val.type != kObjectTypeWindow) { api_set_error(err, kErrorTypeValidation, - "'win' option has to be Integer or Window"); + "'win' key must be Integer or Window"); return false; } - out->window = val.data.integer; + fconfig->window = val.data.integer; } else if (!strcmp(key, "external")) { if (val.type == kObjectTypeInteger) { - out->external = val.data.integer; + fconfig->external = val.data.integer; } else if (val.type == kObjectTypeBoolean) { - out->external = val.data.boolean; + fconfig->external = val.data.boolean; } else { api_set_error(err, kErrorTypeValidation, - "'external' option has to be Boolean"); + "'external' key must be Boolean"); return false; } - has_external = out->external; + has_external = fconfig->external; } else if (!strcmp(key, "focusable")) { if (val.type == kObjectTypeInteger) { - out->focusable = val.data.integer; + fconfig->focusable = val.data.integer; } else if (val.type == kObjectTypeBoolean) { - out->focusable = val.data.boolean; + fconfig->focusable = val.data.boolean; } else { api_set_error(err, kErrorTypeValidation, - "'focusable' option has to be Boolean"); + "'focusable' key must be Boolean"); return false; } } else { api_set_error(err, kErrorTypeValidation, - "Invalid options key '%s'", key); + "Invalid key '%s'", key); return false; } } - if (has_window && !(has_relative && out->relative == kFloatRelativeWindow)) { + if (has_window && !(has_relative + && fconfig->relative == kFloatRelativeWindow)) { api_set_error(err, kErrorTypeValidation, - "'win' option is only valid with relative='win'"); + "'win' key is only valid with relative='win'"); return false; } - if ((has_relative && out->relative == kFloatRelativeWindow) - && (!has_window || out->window == 0)) { - out->window = curwin->handle; + if ((has_relative && fconfig->relative == kFloatRelativeWindow) + && (!has_window || fconfig->window == 0)) { + fconfig->window = curwin->handle; } if (has_relative && has_external) { api_set_error(err, kErrorTypeValidation, - "Only one of 'relative' and 'external' should be used"); + "Only one of 'relative' and 'external' must be used"); return false; } else if (!reconf && !has_relative && !has_external) { api_set_error(err, kErrorTypeValidation, "One of 'relative' and 'external' must be used"); return false; } else if (has_relative) { - out->external = false; + fconfig->external = false; } - if (out->external && !ui_has(kUIMultigrid)) { + if (!reconf && !(has_height && has_width)) { + api_set_error(err, kErrorTypeValidation, + "Must specify 'width' and 'height'"); + return false; + } + + if (fconfig->external && !ui_has(kUIMultigrid)) { api_set_error(err, kErrorTypeValidation, "UI doesn't support external windows"); return false; @@ -1121,6 +1149,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) } else if (wp->w_floating) { new_frame(wp); wp->w_floating = false; + // non-floating window doesn't store float config. + wp->w_float_config = FLOAT_CONFIG_INIT; } /* @@ -2265,8 +2295,7 @@ int win_close(win_T *win, bool free_buf) EMSG(_("E813: Cannot close autocmd window")); return FAIL; } - if ((firstwin == aucmd_win || lastwin_nofloating() == aucmd_win) - && one_window()) { + if ((firstwin == aucmd_win || lastwin == aucmd_win) && one_window()) { EMSG(_("E814: Cannot close window, only autocmd window would remain")); return FAIL; } @@ -2299,10 +2328,10 @@ int win_close(win_T *win, bool free_buf) if (!win->w_floating) { wp = frame2win(win_altframe(win, NULL)); } else { - if (win_valid(prevwin)) { + if (win_valid(prevwin) && prevwin != win) { wp = prevwin; } else { - wp = curtab->tp_firstwin; + wp = firstwin; } } @@ -2448,7 +2477,7 @@ int win_close(win_T *win, bool free_buf) } if (!was_floating) { - if (p_ea && (*p_ead == 'b' || *p_ead == dir)) { + 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. win_equal(curwin, curwin->w_frame->fr_parent == win_frame, dir); @@ -2561,15 +2590,12 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) free_tabpage(tp); } -/* - * Free the memory used for a window. - * Returns a pointer to the window that got the freed up space. - */ -static win_T * -win_free_mem ( +// Free the memory used for a window. +// Returns a pointer to the window that got the freed up space. +static win_T *win_free_mem( win_T *win, - int *dirp, /* set to 'v' or 'h' for direction if 'ea' */ - tabpage_T *tp /* tab page "win" is in, NULL for current */ + int *dirp, // set to 'v' or 'h' for direction if 'ea' + tabpage_T *tp // tab page "win" is in, NULL for current ) { frame_T *frp; @@ -2581,18 +2607,20 @@ win_free_mem ( wp = winframe_remove(win, dirp, tp); xfree(frp); } else { - if (win_valid(prevwin)) { + *dirp = 'h'; // Dummy value. + if (win_valid(prevwin) && prevwin != win) { wp = prevwin; } else { - wp = curtab->tp_firstwin; + wp = firstwin; } } 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) + // 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; + } return wp; } @@ -2665,9 +2693,9 @@ winframe_remove ( frp3 = frp_close->fr_next; while (frp != NULL || frp3 != NULL) { if (frp != NULL) { - if (frp->fr_win != NULL && !frp->fr_win->w_p_wfh) { + if (!frame_fixed_height(frp)) { frp2 = frp; - wp = frp->fr_win; + wp = frame2win(frp2); break; } frp = frp->fr_prev; @@ -2694,9 +2722,9 @@ winframe_remove ( frp3 = frp_close->fr_next; while (frp != NULL || frp3 != NULL) { if (frp != NULL) { - if (frp->fr_win != NULL && !frp->fr_win->w_p_wfw) { + if (!frame_fixed_width(frp)) { frp2 = frp; - wp = frp->fr_win; + wp = frame2win(frp2); break; } frp = frp->fr_prev; @@ -3384,16 +3412,18 @@ int win_alloc_first(void) return OK; } -/* - * Init "aucmd_win". This can only be done after the first - * window is fully initialized, thus it can't be in win_alloc_first(). - */ +// Init `aucmd_win`. 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) { - aucmd_win = win_alloc(NULL, TRUE); - win_init_some(aucmd_win, curwin); + Error err = ERROR_INIT; + FloatConfig fconfig = FLOAT_CONFIG_INIT; + fconfig.width = Columns; + fconfig.height = 5; + fconfig.focusable = false; + aucmd_win = win_new_float(NULL, fconfig, &err); + aucmd_win->w_buffer->b_nwindows--; RESET_BINDING(aucmd_win); - new_frame(aucmd_win); } /* @@ -3764,6 +3794,9 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, int trigger_enter_au * the frames for that. When the Vim window was resized need to update * frame sizes too. Use the stored value of p_ch, so that it can be * different for each tab page. */ + if (p_ch != curtab->tp_ch_used) { + clear_cmdline = true; + } p_ch = curtab->tp_ch_used; if (curtab->tp_old_Rows != Rows || (old_off != firstwin->w_winrow )) @@ -3806,7 +3839,7 @@ static void tabpage_check_windows(tabpage_T *old_curtab) for (win_T *wp = firstwin; wp; wp = wp->w_next) { if (wp->w_floating && !wp->w_float_config.external) { - win_config_float(wp, wp->w_width, wp->w_height, wp->w_float_config); + win_config_float(wp, wp->w_float_config); } wp->w_pos_changed = true; } @@ -3818,7 +3851,7 @@ static void tabpage_check_windows(tabpage_T *old_curtab) */ void goto_tabpage(int n) { - tabpage_T *tp; + tabpage_T *tp = NULL; // shut up compiler tabpage_T *ttp; int i; @@ -4006,24 +4039,25 @@ tabpage_T *win_find_tabpage(win_T *win) return NULL; } -/* - * Move to window above or below "count" times. - */ -static void -win_goto_ver ( - int up, /* TRUE to go to win above */ - long count -) +/// Get the above or below neighbor window of the specified window. +/// +/// Returns the specified window if the neighbor is not found. +/// Returns the previous window if the specifiecied window is a floating window. +/// +/// @param up true for the above neighbor +/// @param count nth neighbor window +/// +/// @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 = curwin->w_frame; + foundfr = wp->w_frame; - if (curwin->w_floating) { - win_goto(prevwin); - return; + if (wp->w_floating) { + return win_valid(prevwin) && !prevwin->w_floating ? prevwin : firstwin; } while (count--) { @@ -4033,14 +4067,17 @@ win_goto_ver ( */ fr = foundfr; for (;; ) { - if (fr == topframe) + if (fr == tp->tp_topframe) { goto end; - if (up) + } + if (up) { nfr = fr->fr_prev; - else + } else { nfr = fr->fr_next; - if (fr->fr_parent->fr_layout == FR_COL && nfr != NULL) + } + if (fr->fr_parent->fr_layout == FR_COL && nfr != NULL) { break; + } fr = fr->fr_parent; } @@ -4054,11 +4091,12 @@ win_goto_ver ( } fr = nfr->fr_child; if (nfr->fr_layout == FR_ROW) { - /* Find the frame at the cursor row. */ + // Find the frame at the cursor row. while (fr->fr_next != NULL && frame2win(fr)->w_wincol + fr->fr_width - <= curwin->w_wincol + curwin->w_wcol) + <= wp->w_wincol + wp->w_wcol) { fr = fr->fr_next; + } } if (nfr->fr_layout == FR_COL && up) while (fr->fr_next != NULL) @@ -4067,28 +4105,40 @@ win_goto_ver ( } } end: - if (foundfr != NULL) - win_goto(foundfr->fr_win); + return foundfr != NULL ? foundfr->fr_win : NULL; } -/* - * Move to left or right window. - */ -static void -win_goto_hor ( - int left, /* TRUE to go to left win */ - long count -) +/// Move to window above or below "count" times. +/// +/// @param up true to go to win above +/// @param count go count times into direction +static void win_goto_ver(bool up, long count) +{ + win_T *win = win_vert_neighbor(curtab, curwin, up, count); + if (win != NULL) { + win_goto(win); + } +} + +/// Get the left or right neighbor window of the specified window. +/// +/// Returns the specified window if the neighbor is not found. +/// Returns the previous window if the specifiecied window is a floating window. +/// +/// @param left true for the left neighbor +/// @param count nth neighbor window +/// +/// @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 = curwin->w_frame; + foundfr = wp->w_frame; - if (curwin->w_floating) { - win_goto(prevwin); - return; + if (wp->w_floating) { + return win_valid(prevwin) && !prevwin->w_floating ? prevwin : firstwin; } while (count--) { @@ -4098,14 +4148,17 @@ win_goto_hor ( */ fr = foundfr; for (;; ) { - if (fr == topframe) + if (fr == tp->tp_topframe) { goto end; - if (left) + } + if (left) { nfr = fr->fr_prev; - else + } else { nfr = fr->fr_next; - if (fr->fr_parent->fr_layout == FR_ROW && nfr != NULL) + } + if (fr->fr_parent->fr_layout == FR_ROW && nfr != NULL) { break; + } fr = fr->fr_parent; } @@ -4122,7 +4175,7 @@ win_goto_hor ( /* Find the frame at the cursor row. */ while (fr->fr_next != NULL && frame2win(fr)->w_winrow + fr->fr_height - <= curwin->w_winrow + curwin->w_wrow) + <= wp->w_winrow + wp->w_wrow) fr = fr->fr_next; } if (nfr->fr_layout == FR_ROW && left) @@ -4132,8 +4185,19 @@ win_goto_hor ( } } end: - if (foundfr != NULL) - win_goto(foundfr->fr_win); + return foundfr != NULL ? foundfr->fr_win : NULL; +} + +/// Move to left or right window. +/// +/// @param left true to go to left window +/// @param count go count times into direction +static void win_goto_hor(bool left, long count) +{ + win_T *win = win_horz_neighbor(curtab, curwin, left, count); + if (win != NULL) { + win_goto(win); + } } /* @@ -4242,9 +4306,12 @@ static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid, apply_autocmds(EVENT_WINNEW, NULL, NULL, false, curbuf); } if (trigger_enter_autocmds) { - apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf); - if (other_buffer) - apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf); + apply_autocmds(EVENT_WINENTER, NULL, NULL, false, curbuf); + if (other_buffer) { + apply_autocmds(EVENT_BUFENTER, NULL, NULL, false, curbuf); + } + apply_autocmds(EVENT_CURSORMOVED, NULL, NULL, false, curbuf); + curwin->w_last_cursormoved = curwin->w_cursor; } maketitle(); @@ -4374,6 +4441,7 @@ static win_T *win_alloc(win_T *after, int hidden) new_wp->w_cursor.lnum = 1; new_wp->w_scbind_pos = 1; new_wp->w_floating = 0; + new_wp->w_float_config = FLOAT_CONFIG_INIT; /* We won't calculate w_fraction until resizing the window */ new_wp->w_fraction = 0; @@ -4642,8 +4710,12 @@ void win_size_restore(garray_T *gap) { int i = 0; FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - frame_setwidth(wp->w_frame, ((int *)gap->ga_data)[i++]); - win_setheight_win(((int *)gap->ga_data)[i++], wp); + int width = ((int *)gap->ga_data)[i++]; + int height = ((int *)gap->ga_data)[i++]; + if (!wp->w_floating) { + frame_setwidth(wp->w_frame, width); + win_setheight_win(height, wp); + } } } /* recompute the window positions */ @@ -4666,7 +4738,7 @@ int win_comp_pos(void) // Too often, but when we support anchoring floats to split windows, // this will be needed for (win_T *wp = lastwin; wp && wp->w_floating; wp = wp->w_prev) { - win_config_float(wp, wp->w_width, wp->w_height, wp->w_float_config); + win_config_float(wp, wp->w_float_config); } return row; @@ -4739,7 +4811,8 @@ void win_setheight_win(int height, win_T *win) if (win->w_floating) { if (win->w_float_config.external) { - win_config_float(win, win->w_width, height, win->w_float_config); + win->w_float_config.height = height; + win_config_float(win, win->w_float_config); } else { beep_flush(); return; @@ -4944,7 +5017,8 @@ void win_setwidth_win(int width, win_T *wp) } if (wp->w_floating) { if (wp->w_float_config.external) { - win_config_float(wp, width, wp->w_height, wp->w_float_config); + wp->w_float_config.width = width; + win_config_float(wp, wp->w_float_config); } else { beep_flush(); return; @@ -5770,7 +5844,7 @@ last_status ( { /* Don't make a difference between horizontal or vertical split. */ last_status_rec(topframe, (p_ls == 2 - || (p_ls == 1 && (morewin || !ONE_WINDOW)))); + || (p_ls == 1 && (morewin || !one_window())))); } static void last_status_rec(frame_T *fr, int statusline) @@ -5889,16 +5963,40 @@ void check_lnums(int do_curwin) { FOR_ALL_TAB_WINDOWS(tp, wp) { if ((do_curwin || wp != curwin) && wp->w_buffer == curbuf) { + // save the original cursor position and topline + wp->w_save_cursor.w_cursor_save = wp->w_cursor; + wp->w_save_cursor.w_topline_save = wp->w_topline; + if (wp->w_cursor.lnum > curbuf->b_ml.ml_line_count) { wp->w_cursor.lnum = curbuf->b_ml.ml_line_count; } if (wp->w_topline > curbuf->b_ml.ml_line_count) { wp->w_topline = curbuf->b_ml.ml_line_count; } + + // save the corrected cursor position and topline + wp->w_save_cursor.w_cursor_corr = wp->w_cursor; + wp->w_save_cursor.w_topline_corr = wp->w_topline; } } } +/// Reset cursor and topline to its stored values from check_lnums(). +/// check_lnums() must have been called first! +void reset_lnums(void) +{ + FOR_ALL_TAB_WINDOWS(tp, wp) { + if (wp->w_buffer == curbuf) { + // Restore the value if the autocommand didn't change it. + if (equalpos(wp->w_save_cursor.w_cursor_corr, wp->w_cursor)) { + wp->w_cursor = wp->w_save_cursor.w_cursor_save; + } + if (wp->w_save_cursor.w_topline_corr == wp->w_topline) { + wp->w_topline = wp->w_save_cursor.w_topline_save; + } + } + } +} /* * A snapshot of the window sizes, to restore them after closing the help @@ -6044,7 +6142,7 @@ static win_T *get_snapshot_focus(int idx) } } - return sn->fr_win; + return win_valid(sn->fr_win) ? sn->fr_win : NULL; } /* |
