diff options
author | Björn Linse <bjorn.linse@gmail.com> | 2019-01-25 18:44:29 +0100 |
---|---|---|
committer | Björn Linse <bjorn.linse@gmail.com> | 2019-01-27 12:07:06 +0100 |
commit | 2ab70cb55c80b17fb4100dd7f2d056131c02b08b (patch) | |
tree | e3a4cc06776b51d1ec4e9733d377452d0158b4c3 | |
parent | 80b75bc99aeb6ecc40e59343ec527443d882e8ec (diff) | |
download | rneovim-2ab70cb55c80b17fb4100dd7f2d056131c02b08b.tar.gz rneovim-2ab70cb55c80b17fb4100dd7f2d056131c02b08b.tar.bz2 rneovim-2ab70cb55c80b17fb4100dd7f2d056131c02b08b.zip |
window/ui: reorganize size variables, fix terminal window size with multigrid.
wp->w_height_inner now contains the "inner" size, regardless if the
window has been drawn yet or not. It should be used instead of
wp->w_grid.Rows, for stuff that is not directly related to accessing
the allocated grid memory, such like cursor movement and terminal size
-rw-r--r-- | src/nvim/buffer_defs.h | 4 | ||||
-rw-r--r-- | src/nvim/charset.c | 24 | ||||
-rw-r--r-- | src/nvim/cursor.c | 8 | ||||
-rw-r--r-- | src/nvim/edit.c | 8 | ||||
-rw-r--r-- | src/nvim/eval.c | 4 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 6 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 6 | ||||
-rw-r--r-- | src/nvim/getchar.c | 6 | ||||
-rw-r--r-- | src/nvim/grid_defs.h | 8 | ||||
-rw-r--r-- | src/nvim/indent.c | 2 | ||||
-rw-r--r-- | src/nvim/misc1.c | 12 | ||||
-rw-r--r-- | src/nvim/mouse.c | 18 | ||||
-rw-r--r-- | src/nvim/move.c | 126 | ||||
-rw-r--r-- | src/nvim/normal.c | 30 | ||||
-rw-r--r-- | src/nvim/screen.c | 21 | ||||
-rw-r--r-- | src/nvim/screen.h | 3 | ||||
-rw-r--r-- | src/nvim/search.c | 2 | ||||
-rw-r--r-- | src/nvim/terminal.c | 4 | ||||
-rw-r--r-- | src/nvim/ui.c | 8 | ||||
-rw-r--r-- | src/nvim/window.c | 144 | ||||
-rw-r--r-- | test/functional/terminal/helpers.lua | 6 | ||||
-rw-r--r-- | test/functional/terminal/window_spec.lua | 98 |
22 files changed, 321 insertions, 227 deletions
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 05688790c2..85043a2a35 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -1034,6 +1034,10 @@ struct window_S { int w_width; /* Width of window, excluding separation. */ int w_vsep_width; /* Number of separator columns (0 or 1). */ + int w_height_inner; + int w_width_inner; + int w_height_request; + int w_width_request; /* * === start of cached values ==== */ diff --git a/src/nvim/charset.c b/src/nvim/charset.c index c220c4e347..4b192e7e94 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1022,12 +1022,12 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he && vim_isbreak(c) && !vim_isbreak((int)s[1]) && wp->w_p_wrap - && (wp->w_grid.Columns != 0)) { + && (wp->w_width_inner != 0)) { // Count all characters from first non-blank after a blank up to next // non-blank after a blank. numberextra = win_col_off(wp); col2 = col; - colmax = (colnr_T)(wp->w_grid.Columns - numberextra - col_adj); + colmax = (colnr_T)(wp->w_width_inner - numberextra - col_adj); if (col >= colmax) { colmax += col_adj; @@ -1076,9 +1076,9 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he numberextra = numberwidth; col += numberextra + mb_added; - if (col >= (colnr_T)wp->w_grid.Columns) { - col -= wp->w_grid.Columns; - numberextra = wp->w_grid.Columns - (numberextra - win_col_off2(wp)); + if (col >= (colnr_T)wp->w_width_inner) { + col -= wp->w_width_inner; + numberextra = wp->w_width_inner - (numberextra - win_col_off2(wp)); if (col >= numberextra && numberextra > 0) { col %= numberextra; } @@ -1097,17 +1097,17 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he numberwidth -= win_col_off2(wp); } - if (col == 0 || (col + size + sbrlen > (colnr_T)wp->w_grid.Columns)) { + if (col == 0 || (col + size + sbrlen > (colnr_T)wp->w_width_inner)) { added = 0; if (*p_sbr != NUL) { - if (size + sbrlen + numberwidth > (colnr_T)wp->w_grid.Columns) { + if (size + sbrlen + numberwidth > (colnr_T)wp->w_width_inner) { // Calculate effective window width. - int width = (colnr_T)wp->w_grid.Columns - sbrlen - numberwidth; - int prev_width = col ? ((colnr_T)wp->w_grid.Columns - (sbrlen + col)) + int width = (colnr_T)wp->w_width_inner - sbrlen - numberwidth; + int prev_width = col ? ((colnr_T)wp->w_width_inner - (sbrlen + col)) : 0; if (width == 0) { - width = (colnr_T)wp->w_grid.Columns; + width = (colnr_T)wp->w_width_inner; } added += ((size - prev_width) / width) * vim_strsize(p_sbr); if ((size - prev_width) % width) { @@ -1176,11 +1176,11 @@ bool in_win_border(win_T *wp, colnr_T vcol) int width1; // width of first line (after line number) int width2; // width of further lines - if (wp->w_grid.Columns == 0) { + if (wp->w_width_inner == 0) { // there is no border return false; } - width1 = wp->w_grid.Columns - win_col_off(wp); + width1 = wp->w_width_inner - win_col_off(wp); if ((int)vcol < width1 - 1) { return false; diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c index 6c1bd01ff5..bc14761877 100644 --- a/src/nvim/cursor.c +++ b/src/nvim/cursor.c @@ -121,11 +121,11 @@ static int coladvance2( --curwin->w_curswant; } } else { - int width = curwin->w_grid.Columns - win_col_off(curwin); + int width = curwin->w_width_inner - win_col_off(curwin); if (finetune && curwin->w_p_wrap - && curwin->w_grid.Columns != 0 + && curwin->w_width_inner != 0 && wcol >= (colnr_T)width) { csize = linetabsize(line); if (csize > 0) @@ -230,7 +230,7 @@ static int coladvance2( int b = (int)wcol - (int)col; // The difference between wcol and col is used to set coladd. - if (b > 0 && b < (MAXCOL - 2 * curwin->w_grid.Columns)) { + if (b > 0 && b < (MAXCOL - 2 * curwin->w_width_inner)) { pos->coladd = b; } @@ -444,7 +444,7 @@ bool leftcol_changed(void) bool retval = false; changed_cline_bef_curs(); - lastcol = curwin->w_leftcol + curwin->w_grid.Columns - curwin_col_off() - 1; + lastcol = curwin->w_leftcol + curwin->w_width_inner - curwin_col_off() - 1; validate_virtcol(); /* diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 90507cd0a5..bb16e2ae4d 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -566,7 +566,7 @@ static int insert_check(VimState *state) if (curwin->w_wcol < s->mincol - curbuf->b_p_ts && curwin->w_wrow == curwin->w_winrow - + curwin->w_grid.Rows - 1 - p_so + + curwin->w_height_inner - 1 - p_so && (curwin->w_cursor.lnum != curwin->w_topline || curwin->w_topfill > 0)) { if (curwin->w_topfill > 0) { @@ -5868,7 +5868,7 @@ static void check_auto_format( /* * Find out textwidth to be used for formatting: * if 'textwidth' option is set, use it - * else if 'wrapmargin' option is set, use curwin->w_grid.Columns-'wrapmargin' + * else if 'wrapmargin' option is set, use curwin->w_width_inner-'wrapmargin' * if invalid value, use 0. * Set default to window width (maximum 79) for "gq" operator. */ @@ -5883,7 +5883,7 @@ comp_textwidth ( if (textwidth == 0 && curbuf->b_p_wm) { /* The width is the window width minus 'wrapmargin' minus all the * things that add to the margin. */ - textwidth = curwin->w_grid.Columns - curbuf->b_p_wm; + textwidth = curwin->w_width_inner - curbuf->b_p_wm; if (cmdwin_type != 0) { textwidth -= 1; } @@ -5899,7 +5899,7 @@ comp_textwidth ( if (textwidth < 0) textwidth = 0; if (ff && textwidth == 0) { - textwidth = curwin->w_grid.Columns - 1; + textwidth = curwin->w_width_inner - 1; if (textwidth > 79) { textwidth = 79; } diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 1c6fb5d2f8..dcb583ce8a 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -16796,10 +16796,10 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } - uint16_t term_width = MAX(0, curwin->w_grid.Columns - win_col_off(curwin)); + uint16_t term_width = MAX(0, curwin->w_width_inner - win_col_off(curwin)); Channel *chan = channel_job_start(argv, on_stdout, on_stderr, on_exit, true, false, false, cwd, - term_width, curwin->w_grid.Rows, + term_width, curwin->w_height_inner, xstrdup("xterm-256color"), &rettv->vval.v_number); if (rettv->vval.v_number <= 0) { diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index c574ac10e9..fe17314b8d 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -257,7 +257,7 @@ void ex_align(exarg_T *eap) if (width <= 0) width = curbuf->b_p_tw; if (width == 0 && curbuf->b_p_wm > 0) { - width = curwin->w_grid.Columns - curbuf->b_p_wm; + width = curwin->w_width_inner - curbuf->b_p_wm; } if (width <= 0) { width = 80; @@ -2872,11 +2872,11 @@ void ex_z(exarg_T *eap) // Vi compatible: ":z!" uses display height, without a count uses // 'scroll' if (eap->forceit) { - bigness = curwin->w_grid.Rows; + bigness = curwin->w_height_inner; } else if (ONE_WINDOW) { bigness = curwin->w_p_scr * 2; } else { - bigness = curwin->w_grid.Rows - 3; + bigness = curwin->w_height_inner - 3; } if (bigness < 1) { bigness = 1; diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index ae618bfc61..02d96603b7 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -9201,7 +9201,7 @@ static int ses_winsizes(FILE *fd, int restore_size, win_T *tab_firstwin) && (fprintf(fd, "exe '%dresize ' . ((&lines * %" PRId64 " + %" PRId64 ") / %" PRId64 ")", - n, (int64_t)wp->w_grid.Rows, + n, (int64_t)wp->w_height, (int64_t)Rows / 2, (int64_t)Rows) < 0 || put_eol(fd) == FAIL)) { return FAIL; @@ -9469,8 +9469,8 @@ put_view( " * winheight(0) + %" PRId64 ") / %" PRId64 ")", (int64_t)wp->w_cursor.lnum, (int64_t)(wp->w_cursor.lnum - wp->w_topline), - (int64_t)(wp->w_grid.Rows / 2), - (int64_t)wp->w_grid.Rows) < 0 + (int64_t)(wp->w_height_inner / 2), + (int64_t)wp->w_height_inner) < 0 || put_eol(fd) == FAIL || put_line(fd, "if s:l < 1 | let s:l = 1 | endif") == FAIL || put_line(fd, "exe s:l") == FAIL diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index be3e7bb676..b24acb5ebb 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -2123,8 +2123,8 @@ static int vgetorpeek(int advance) ++col; } curwin->w_wrow = curwin->w_cline_row - + curwin->w_wcol / curwin->w_grid.Columns; - curwin->w_wcol %= curwin->w_grid.Columns; + + curwin->w_wcol / curwin->w_width_inner; + curwin->w_wcol %= curwin->w_width_inner; curwin->w_wcol += curwin_col_off(); col = 0; /* no correction needed */ } else { @@ -2133,7 +2133,7 @@ static int vgetorpeek(int advance) } } else if (curwin->w_p_wrap && curwin->w_wrow) { curwin->w_wrow--; - curwin->w_wcol = curwin->w_grid.Columns - 1; + curwin->w_wcol = curwin->w_width_inner - 1; col = curwin->w_cursor.col - 1; } if (col > 0 && curwin->w_wcol > 0) { diff --git a/src/nvim/grid_defs.h b/src/nvim/grid_defs.h index 37d85ead0c..cf9e550f48 100644 --- a/src/nvim/grid_defs.h +++ b/src/nvim/grid_defs.h @@ -48,12 +48,8 @@ typedef struct { // offsets for the grid relative to the global screen int row_offset; int col_offset; - - // grid size requested by the UI. Used for window grids only. - int requested_rows; - int requested_cols; - - int was_resized; } ScreenGrid; +#define SCREEN_GRID_INIT { 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0 } + #endif // NVIM_GRID_DEFS_H diff --git a/src/nvim/indent.c b/src/nvim/indent.c index 19456da45c..9305e85f38 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -473,7 +473,7 @@ int get_breakindent_win(win_T *wp, char_u *line) static varnumber_T prev_tick = 0; // Changedtick of cached value. int bri = 0; // window width minus window margin space, i.e. what rests for text - const int eff_wwidth = wp->w_grid.Columns + const int eff_wwidth = wp->w_width_inner - ((wp->w_p_nu || wp->w_p_rnu) && (vim_strchr(p_cpo, CPO_NUMCOL) == NULL) ? number_width(wp) + 1 : 0); diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index a66ded13f1..7f19bdf145 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -1251,7 +1251,7 @@ int plines_win_nofill( return 1; } - if (wp->w_grid.Columns == 0) { + if (wp->w_width_inner == 0) { return 1; } @@ -1261,8 +1261,8 @@ int plines_win_nofill( } const int lines = plines_win_nofold(wp, lnum); - if (winheight && lines > wp->w_grid.Rows) { - return wp->w_grid.Rows; + if (winheight && lines > wp->w_height_inner) { + return wp->w_height_inner; } return lines; } @@ -1292,7 +1292,7 @@ int plines_win_nofold(win_T *wp, linenr_T lnum) /* * Add column offset for 'number', 'relativenumber' and 'foldcolumn'. */ - width = wp->w_grid.Columns - win_col_off(wp); + width = wp->w_width_inner - win_col_off(wp); if (width <= 0 || col > 32000) { return 32000; // bigger than the number of screen columns } @@ -1318,7 +1318,7 @@ int plines_win_col(win_T *wp, linenr_T lnum, long column) if (!wp->w_p_wrap) return lines + 1; - if (wp->w_grid.Columns == 0) { + if (wp->w_width_inner == 0) { return lines + 1; } @@ -1341,7 +1341,7 @@ int plines_win_col(win_T *wp, linenr_T lnum, long column) } // Add column offset for 'number', 'relativenumber', 'foldcolumn', etc. - int width = wp->w_grid.Columns - win_col_off(wp); + int width = wp->w_width_inner - win_col_off(wp); if (width <= 0) { return 9999; } diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 22f5497f1e..6b282ffbbf 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -164,7 +164,7 @@ retnomove: || (!on_status_line && !on_sep_line && (wp->w_p_rl - ? col < wp->w_grid.Columns - wp->w_p_fdc + ? col < wp->w_width_inner - wp->w_p_fdc : col >= wp->w_p_fdc + (cmdwin_type == 0 && wp == curwin ? 0 : 1)) && (flags & MOUSE_MAY_STOP_VIS)))) { @@ -258,7 +258,7 @@ retnomove: ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP); redraw_later(VALID); row = 0; - } else if (row >= curwin->w_grid.Rows) { + } else if (row >= curwin->w_height_inner) { count = 0; for (first = true; curwin->w_topline < curbuf->b_ml.ml_line_count; ) { if (curwin->w_topfill > 0) { @@ -267,7 +267,7 @@ retnomove: count += plines(curwin->w_topline); } - if (!first && count > row - curwin->w_grid.Rows + 1) { + if (!first && count > row - curwin->w_height_inner + 1) { break; } first = false; @@ -289,7 +289,7 @@ retnomove: redraw_later(VALID); curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP); - row = curwin->w_grid.Rows - 1; + row = curwin->w_height_inner - 1; } else if (row == 0) { // When dragging the mouse, while the text has been scrolled up as // far as it goes, moving the mouse in the top line should scroll @@ -304,7 +304,7 @@ retnomove: } // Check for position outside of the fold column. - if (curwin->w_p_rl ? col < curwin->w_grid.Columns - curwin->w_p_fdc : + if (curwin->w_p_rl ? col < curwin->w_width_inner - curwin->w_p_fdc : col >= curwin->w_p_fdc + (cmdwin_type == 0 ? 0 : 1)) { mouse_char = ' '; } @@ -371,7 +371,7 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump) int count; if (win->w_p_rl) { - col = win->w_grid.Columns - 1 - col; + col = win->w_width_inner - 1 - col; } lnum = win->w_topline; @@ -409,7 +409,7 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump) off = win_col_off(win) - win_col_off2(win); if (col < off) col = off; - col += row * (win->w_grid.Columns - off); + col += row * (win->w_width_inner - off); // add skip column (for long wrapping line) col += win->w_skipcol; } @@ -622,7 +622,7 @@ bool mouse_scroll_horiz(int dir) int step = 6; if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) { - step = curwin->w_grid.Columns; + step = curwin->w_width_inner; } int leftcol = curwin->w_leftcol + (dir == MSCR_RIGHT ? -step : +step); @@ -674,7 +674,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col) // Find the offset where scanning should begin. int offset = wp->w_leftcol; if (row > 0) { - offset += row * (wp->w_grid.Columns - win_col_off(wp) - win_col_off2(wp) - + offset += row * (wp->w_width_inner - win_col_off(wp) - win_col_off2(wp) - wp->w_leftcol + wp->w_skipcol); } diff --git a/src/nvim/move.c b/src/nvim/move.c index 07b355e603..44ca10d11b 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -83,7 +83,7 @@ static void comp_botline(win_T *wp) redraw_for_cursorline(wp); wp->w_valid |= (VALID_CROW|VALID_CHEIGHT); } - if (done + n > wp->w_grid.Rows) { + if (done + n > wp->w_height_inner) { break; } done += n; @@ -150,12 +150,9 @@ void update_topline(void) bool check_botline = false; long save_so = p_so; - // need to have w_grid.Rows/Columns updated - win_grid_alloc(curwin); - // If there is no valid screen and when the window height is zero just use // the cursor line. - if (!screen_valid(true) || curwin->w_grid.Rows == 0) { + if (!screen_valid(true) || curwin->w_height_inner == 0) { curwin->w_topline = curwin->w_cursor.lnum; curwin->w_botline = curwin->w_topline; curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP; @@ -204,7 +201,7 @@ void update_topline(void) check_topline = true; if (check_topline) { - int halfheight = curwin->w_grid.Rows / 2 - 1; + int halfheight = curwin->w_height_inner / 2 - 1; if (halfheight < 2) { halfheight = 2; } @@ -297,7 +294,7 @@ void update_topline(void) lnum >= curwin->w_botline - p_so; lnum--) { line_count++; // stop at end of file or when we know we are far off - if (lnum <= 0 || line_count > curwin->w_grid.Rows + 1) { + if (lnum <= 0 || line_count > curwin->w_height_inner + 1) { break; } (void)hasFolding(lnum, &lnum, NULL); @@ -305,7 +302,7 @@ void update_topline(void) } else line_count = curwin->w_cursor.lnum - curwin->w_botline + 1 + p_so; - if (line_count <= curwin->w_grid.Rows + 1) { + if (line_count <= curwin->w_height_inner + 1) { scroll_cursor_bot(scrolljump_value(), false); } else { scroll_cursor_halfway(false); @@ -353,7 +350,7 @@ void update_topline_win(win_T* win) */ static int scrolljump_value(void) { - long result = p_sj >= 0 ? p_sj : (curwin->w_grid.Rows * -p_sj) / 100; + long result = p_sj >= 0 ? p_sj : (curwin->w_height_inner * -p_sj) / 100; assert(result <= INT_MAX); return (int)result; } @@ -529,7 +526,6 @@ int cursor_valid(void) */ void validate_cursor(void) { - win_grid_alloc(curwin); // we need to have w_grid.Rows/Columns updated check_cursor_moved(curwin); if ((curwin->w_valid & (VALID_WCOL|VALID_WROW)) != (VALID_WCOL|VALID_WROW)) curs_columns(true); @@ -668,13 +664,13 @@ void validate_cursor_col(void) colnr_T col = curwin->w_virtcol; colnr_T off = curwin_col_off(); col += off; - int width = curwin->w_grid.Columns - off + curwin_col_off2(); + int width = curwin->w_width_inner - off + curwin_col_off2(); // long line wrapping, adjust curwin->w_wrow - if (curwin->w_p_wrap && col >= (colnr_T)curwin->w_grid.Columns + if (curwin->w_p_wrap && col >= (colnr_T)curwin->w_width_inner && width > 0) { // use same formula as what is used in curs_columns() - col -= ((col - curwin->w_grid.Columns) / width + 1) * width; + col -= ((col - curwin->w_width_inner) / width + 1) * width; } if (col > (int)curwin->w_leftcol) { col -= curwin->w_leftcol; @@ -769,20 +765,20 @@ void curs_columns( */ curwin->w_wrow = curwin->w_cline_row; - int textwidth = curwin->w_grid.Columns - extra; + int textwidth = curwin->w_width_inner - extra; if (textwidth <= 0) { // No room for text, put cursor in last char of window. - curwin->w_wcol = curwin->w_grid.Columns - 1; - curwin->w_wrow = curwin->w_grid.Rows - 1; + curwin->w_wcol = curwin->w_width_inner - 1; + curwin->w_wrow = curwin->w_height_inner - 1; } else if (curwin->w_p_wrap - && curwin->w_grid.Columns != 0 + && curwin->w_width_inner != 0 ) { width = textwidth + curwin_col_off2(); // long line wrapping, adjust curwin->w_wrow - if (curwin->w_wcol >= curwin->w_grid.Columns) { + if (curwin->w_wcol >= curwin->w_width_inner) { // this same formula is used in validate_cursor_col() - n = (curwin->w_wcol - curwin->w_grid.Columns) / width + 1; + n = (curwin->w_wcol - curwin->w_width_inner) / width + 1; curwin->w_wcol -= n * width; curwin->w_wrow += n; @@ -809,7 +805,7 @@ void curs_columns( assert(p_siso <= INT_MAX); int off_left = startcol - curwin->w_leftcol - (int)p_siso; int off_right = - endcol - curwin->w_leftcol - curwin->w_grid.Columns + (int)p_siso + 1; + endcol - curwin->w_leftcol - curwin->w_width_inner + (int)p_siso + 1; if (off_left < 0 || off_right > 0) { int diff = (off_left < 0) ? -off_left: off_right; @@ -852,16 +848,16 @@ void curs_columns( prev_skipcol = curwin->w_skipcol; int p_lines = 0; - if ((curwin->w_wrow >= curwin->w_grid.Rows + if ((curwin->w_wrow >= curwin->w_height_inner || ((prev_skipcol > 0 - || curwin->w_wrow + p_so >= curwin->w_grid.Rows) + || curwin->w_wrow + p_so >= curwin->w_height_inner) && (p_lines = plines_win_nofill(curwin, curwin->w_cursor.lnum, false)) - 1 - >= curwin->w_grid.Rows)) - && curwin->w_grid.Rows != 0 + >= curwin->w_height_inner)) + && curwin->w_height_inner != 0 && curwin->w_cursor.lnum == curwin->w_topline && width > 0 - && curwin->w_grid.Columns != 0 + && curwin->w_width_inner != 0 ) { /* Cursor past end of screen. Happens with a single line that does * not fit on screen. Find a skipcol to show the text around the @@ -883,21 +879,21 @@ void curs_columns( } else n = p_lines; - if ((colnr_T)n >= curwin->w_grid.Rows + curwin->w_skipcol / width) { + if ((colnr_T)n >= curwin->w_height_inner + curwin->w_skipcol / width) { extra += 2; } if (extra == 3 || p_lines < p_so * 2) { // not enough room for 'scrolloff', put cursor in the middle n = curwin->w_virtcol / width; - if (n > curwin->w_grid.Rows / 2) { - n -= curwin->w_grid.Rows / 2; + if (n > curwin->w_height_inner / 2) { + n -= curwin->w_height_inner / 2; } else { n = 0; } // don't skip more than necessary - if (n > p_lines - curwin->w_grid.Rows + 1) { - n = p_lines - curwin->w_grid.Rows + 1; + if (n > p_lines - curwin->w_height_inner + 1) { + n = p_lines - curwin->w_height_inner + 1; } curwin->w_skipcol = n * width; } else if (extra == 1) { @@ -912,7 +908,7 @@ void curs_columns( } } else if (extra == 2) { // less then 'scrolloff' lines below, increase skipcol - endcol = (n - curwin->w_grid.Rows + 1) * width; + endcol = (n - curwin->w_height_inner + 1) * width; while (endcol > curwin->w_virtcol) { endcol -= width; } @@ -922,9 +918,9 @@ void curs_columns( } curwin->w_wrow -= curwin->w_skipcol / width; - if (curwin->w_wrow >= curwin->w_grid.Rows) { + if (curwin->w_wrow >= curwin->w_height_inner) { // small window, make sure cursor is in it - extra = curwin->w_wrow - curwin->w_grid.Rows + 1; + extra = curwin->w_wrow - curwin->w_height_inner + 1; curwin->w_skipcol += extra * width; curwin->w_wrow -= extra; } @@ -966,7 +962,7 @@ scrolldown ( validate_cursor(); /* w_wrow needs to be valid */ while (line_count-- > 0) { if (curwin->w_topfill < diff_check(curwin, curwin->w_topline) - && curwin->w_topfill < curwin->w_grid.Rows - 1) { + && curwin->w_topfill < curwin->w_height_inner - 1) { curwin->w_topfill++; done++; } else { @@ -1001,15 +997,15 @@ scrolldown ( */ int wrow = curwin->w_wrow; if (curwin->w_p_wrap - && curwin->w_grid.Columns != 0 + && curwin->w_width_inner != 0 ) { validate_virtcol(); validate_cheight(); wrow += curwin->w_cline_height - 1 - - curwin->w_virtcol / curwin->w_grid.Columns; + curwin->w_virtcol / curwin->w_width_inner; } bool moved = false; - while (wrow >= curwin->w_grid.Rows && curwin->w_cursor.lnum > 1) { + while (wrow >= curwin->w_height_inner && curwin->w_cursor.lnum > 1) { linenr_T first; if (hasFolding(curwin->w_cursor.lnum, &first, NULL)) { --wrow; @@ -1094,12 +1090,12 @@ check_topfill ( { if (wp->w_topfill > 0) { int n = plines_win_nofill(wp, wp->w_topline, true); - if (wp->w_topfill + n > wp->w_grid.Rows) { + if (wp->w_topfill + n > wp->w_height_inner) { if (down && wp->w_topline > 1) { --wp->w_topline; wp->w_topfill = 0; } else { - wp->w_topfill = wp->w_grid.Rows - n; + wp->w_topfill = wp->w_height_inner - n; if (wp->w_topfill < 0) { wp->w_topfill = 0; } @@ -1115,12 +1111,12 @@ check_topfill ( static void max_topfill(void) { int n = plines_nofill(curwin->w_topline); - if (n >= curwin->w_grid.Rows) { + if (n >= curwin->w_height_inner) { curwin->w_topfill = 0; } else { curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline); - if (curwin->w_topfill + n > curwin->w_grid.Rows) { - curwin->w_topfill = curwin->w_grid.Rows - n; + if (curwin->w_topfill + n > curwin->w_height_inner) { + curwin->w_topfill = curwin->w_height_inner - n; } } } @@ -1152,14 +1148,14 @@ void scrolldown_clamp(void) else end_row += plines_nofill(curwin->w_topline - 1); if (curwin->w_p_wrap - && curwin->w_grid.Columns != 0 + && curwin->w_width_inner != 0 ) { validate_cheight(); validate_virtcol(); end_row += curwin->w_cline_height - 1 - - curwin->w_virtcol / curwin->w_grid.Columns; + curwin->w_virtcol / curwin->w_width_inner; } - if (end_row < curwin->w_grid.Rows - p_so) { + if (end_row < curwin->w_height_inner - p_so) { if (can_fill) { ++curwin->w_topfill; check_topfill(curwin, true); @@ -1194,10 +1190,10 @@ void scrollup_clamp(void) int start_row = curwin->w_wrow - plines_nofill(curwin->w_topline) - curwin->w_topfill; if (curwin->w_p_wrap - && curwin->w_grid.Columns != 0 + && curwin->w_width_inner != 0 ) { validate_virtcol(); - start_row -= curwin->w_virtcol / curwin->w_grid.Columns; + start_row -= curwin->w_virtcol / curwin->w_width_inner; } if (start_row >= p_so) { if (curwin->w_topfill > 0) @@ -1351,7 +1347,7 @@ void scroll_cursor_top(int min_scroll, int always) else used += plines(bot); } - if (used > curwin->w_grid.Rows) { + if (used > curwin->w_height_inner) { break; } if (top < curwin->w_topline) { @@ -1376,7 +1372,7 @@ void scroll_cursor_top(int min_scroll, int always) * This makes sure we get the same position when using "k" and "j" * in a small window. */ - if (used > curwin->w_grid.Rows) { + if (used > curwin->w_height_inner) { scroll_cursor_halfway(false); } else { /* @@ -1413,7 +1409,7 @@ void set_empty_rows(win_T *wp, int used) if (used == 0) { wp->w_empty_rows = 0; // single line that doesn't fit } else { - wp->w_empty_rows = wp->w_grid.Rows - used; + wp->w_empty_rows = wp->w_height_inner - used; if (wp->w_botline <= wp->w_buffer->b_ml.ml_line_count) { wp->w_filler_rows = diff_check_fill(wp, wp->w_botline); if (wp->w_empty_rows > wp->w_filler_rows) @@ -1456,7 +1452,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) curwin->w_topline = loff.lnum) { loff.lnum = curwin->w_topline; topline_back(&loff); - if (loff.height == MAXCOL || used + loff.height > curwin->w_grid.Rows) { + if (loff.height == MAXCOL || used + loff.height > curwin->w_height_inner) { break; } used += loff.height; @@ -1520,7 +1516,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) } else { used += loff.height; } - if (used > curwin->w_grid.Rows) { + if (used > curwin->w_height_inner) { break; } if (loff.lnum >= curwin->w_botline @@ -1539,7 +1535,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) /* Add one line below */ botline_forw(&boff); used += boff.height; - if (used > curwin->w_grid.Rows) { + if (used > curwin->w_height_inner) { break; } if (extra < ( @@ -1566,7 +1562,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) if (scrolled <= 0) { line_count = 0; // more than a screenfull, don't scroll but redraw - } else if (used > curwin->w_grid.Rows) { + } else if (used > curwin->w_height_inner) { line_count = used; // scroll minimal number of lines } else { @@ -1587,7 +1583,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) * Scroll up if the cursor is off the bottom of the screen a bit. * Otherwise put it at 1/2 of the screen. */ - if (line_count >= curwin->w_grid.Rows && line_count > min_scroll) { + if (line_count >= curwin->w_height_inner && line_count > min_scroll) { scroll_cursor_halfway(false); } else { scrollup(line_count, true); @@ -1630,7 +1626,7 @@ void scroll_cursor_halfway(int atend) if (boff.lnum < curbuf->b_ml.ml_line_count) { botline_forw(&boff); used += boff.height; - if (used > curwin->w_grid.Rows) { + if (used > curwin->w_height_inner) { break; } below += boff.height; @@ -1647,7 +1643,7 @@ void scroll_cursor_halfway(int atend) used = MAXCOL; else used += loff.height; - if (used > curwin->w_grid.Rows) { + if (used > curwin->w_height_inner) { break; } above += loff.height; @@ -1658,7 +1654,7 @@ void scroll_cursor_halfway(int atend) if (!hasFolding(topline, &curwin->w_topline, NULL)) curwin->w_topline = topline; curwin->w_topfill = topfill; - if (old_topline > curwin->w_topline + curwin->w_grid.Rows) { + if (old_topline > curwin->w_topline + curwin->w_height_inner) { curwin->w_botfill = false; } check_topfill(curwin, false); @@ -1687,7 +1683,7 @@ void cursor_correct(void) } if (curwin->w_topline == 1) { above_wanted = 0; - int max_off = curwin->w_grid.Rows / 2; + int max_off = curwin->w_height_inner / 2; if (below_wanted > max_off) { below_wanted = max_off; } @@ -1697,7 +1693,7 @@ void cursor_correct(void) && mouse_dragging == 0 ) { below_wanted = 0; - int max_off = (curwin->w_grid.Rows - 1) / 2; + int max_off = (curwin->w_height_inner - 1) / 2; if (above_wanted > max_off) { above_wanted = max_off; } @@ -1871,7 +1867,7 @@ int onepage(Direction dir, long count) /* Find the line just above the new topline to get the right line * at the bottom of the window. */ n = 0; - while (n <= curwin->w_grid.Rows && loff.lnum >= 1) { + while (n <= curwin->w_height_inner && loff.lnum >= 1) { topline_back(&loff); if (loff.height == MAXCOL) n = MAXCOL; @@ -1962,7 +1958,7 @@ int onepage(Direction dir, long count) */ static void get_scroll_overlap(lineoff_T *lp, int dir) { - int min_height = curwin->w_grid.Rows - 2; + int min_height = curwin->w_height_inner - 2; if (lp->fill > 0) lp->height = 1; @@ -2017,12 +2013,12 @@ void halfpage(bool flag, linenr_T Prenum) int i; if (Prenum) { - curwin->w_p_scr = (Prenum > curwin->w_grid.Rows) ? curwin->w_grid.Rows + curwin->w_p_scr = (Prenum > curwin->w_height_inner) ? curwin->w_height_inner : Prenum; } assert(curwin->w_p_scr <= INT_MAX); - int n = curwin->w_p_scr <= curwin->w_grid.Rows ? (int)curwin->w_p_scr - : curwin->w_grid.Rows; + int n = curwin->w_p_scr <= curwin->w_height_inner ? (int)curwin->w_p_scr + : curwin->w_height_inner; update_topline(); validate_botline(); diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 844e748681..44e6ab46f1 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -3875,14 +3875,14 @@ static bool nv_screengo(oparg_T *oap, int dir, long dist) col_off1 = curwin_col_off(); col_off2 = col_off1 - curwin_col_off2(); - width1 = curwin->w_grid.Columns - col_off1; - width2 = curwin->w_grid.Columns - col_off2; + width1 = curwin->w_width_inner - col_off1; + width2 = curwin->w_width_inner - col_off2; if (width2 == 0) { width2 = 1; // Avoid divide by zero. } - if (curwin->w_grid.Columns != 0) { + if (curwin->w_width_inner != 0) { // Instead of sticking at the last character of the buffer line we // try to stick in the last column of the screen. if (curwin->w_curswant == MAXCOL) { @@ -4226,7 +4226,7 @@ dozet: /* "zH" - scroll screen right half-page */ case 'H': - cap->count1 *= curwin->w_grid.Columns / 2; + cap->count1 *= curwin->w_width_inner / 2; FALLTHROUGH; /* "zh" - scroll screen to the right */ @@ -4242,7 +4242,7 @@ dozet: break; // "zL" - scroll screen left half-page - case 'L': cap->count1 *= curwin->w_grid.Columns / 2; + case 'L': cap->count1 *= curwin->w_width_inner / 2; FALLTHROUGH; /* "zl" - scroll screen to the left */ @@ -4278,7 +4278,7 @@ dozet: col = 0; /* like the cursor is in col 0 */ else getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col); - n = curwin->w_grid.Columns - curwin_col_off(); + n = curwin->w_width_inner - curwin_col_off(); if (col + l_p_siso < n) { col = 0; } else { @@ -4989,7 +4989,7 @@ static void nv_scroll(cmdarg_T *cap) used -= diff_check_fill(curwin, curwin->w_topline) - curwin->w_topfill; validate_botline(); // make sure w_empty_rows is valid - half = (curwin->w_grid.Rows - curwin->w_empty_rows + 1) / 2; + half = (curwin->w_height_inner - curwin->w_empty_rows + 1) / 2; for (n = 0; curwin->w_topline + n < curbuf->b_ml.ml_line_count; n++) { // Count half he number of filler lines to be "below this // line" and half to be "above the next line". @@ -5004,7 +5004,7 @@ static void nv_scroll(cmdarg_T *cap) if (hasFolding(curwin->w_topline + n, NULL, &lnum)) n = lnum - curwin->w_topline; } - if (n > 0 && used > curwin->w_grid.Rows) { + if (n > 0 && used > curwin->w_height_inner) { n--; } } else { // (cap->cmdchar == 'H') @@ -6716,9 +6716,9 @@ static void nv_g_cmd(cmdarg_T *cap) oap->motion_type = kMTCharWise; oap->inclusive = false; if (curwin->w_p_wrap - && curwin->w_grid.Columns != 0 + && curwin->w_width_inner != 0 ) { - int width1 = curwin->w_grid.Columns - curwin_col_off(); + int width1 = curwin->w_width_inner - curwin_col_off(); int width2 = width1 + curwin_col_off2(); validate_virtcol(); @@ -6731,7 +6731,7 @@ static void nv_g_cmd(cmdarg_T *cap) * 'relativenumber' is on and lines are wrapping the middle can be more * to the left. */ if (cap->nchar == 'm') { - i += (curwin->w_grid.Columns - curwin_col_off() + i += (curwin->w_width_inner - curwin_col_off() + ((curwin->w_p_wrap && i > 0) ? curwin_col_off2() : 0)) / 2; } @@ -6778,11 +6778,11 @@ static void nv_g_cmd(cmdarg_T *cap) oap->motion_type = kMTCharWise; oap->inclusive = true; if (curwin->w_p_wrap - && curwin->w_grid.Columns != 0 + && curwin->w_width_inner != 0 ) { curwin->w_curswant = MAXCOL; /* so we stay at the end */ if (cap->count1 == 1) { - int width1 = curwin->w_grid.Columns - col_off; + int width1 = curwin->w_width_inner - col_off; int width2 = width1 + curwin_col_off2(); validate_virtcol(); @@ -6808,7 +6808,7 @@ static void nv_g_cmd(cmdarg_T *cap) } else if (nv_screengo(oap, FORWARD, cap->count1 - 1) == false) clearopbeep(oap); } else { - i = curwin->w_leftcol + curwin->w_grid.Columns - col_off - 1; + i = curwin->w_leftcol + curwin->w_width_inner - col_off - 1; coladvance((colnr_T)i); /* Make sure we stick in this column. */ @@ -7918,7 +7918,7 @@ static void get_op_vcol( colnr_T end; if (VIsual_mode != Ctrl_V - || (!initial && oap->end.col < curwin->w_grid.Columns)) { + || (!initial && oap->end.col < curwin->w_width_inner)) { return; } diff --git a/src/nvim/screen.c b/src/nvim/screen.c index d5a48cebf9..bb69a13db0 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -5898,15 +5898,8 @@ void win_grid_alloc(win_T *wp) { ScreenGrid *grid = &wp->w_grid; - int rows = grid->requested_rows; - if (rows == 0) { - rows = wp->w_height; - } - - int columns = grid->requested_cols; - if (columns == 0) { - columns = wp->w_width; - } + int rows = wp->w_height_inner; + int cols = wp->w_width_inner; // TODO(bfredl): floating windows should force this to true bool want_allocation = ui_is_external(kUIMultigrid); @@ -5919,9 +5912,9 @@ void win_grid_alloc(win_T *wp) int was_resized = false; if ((has_allocation != want_allocation) || grid->Rows != rows - || grid->Columns != columns) { + || grid->Columns != cols) { if (want_allocation) { - grid_alloc(grid, rows, columns, true); + grid_alloc(grid, rows, cols, true); win_free_lsize(wp); win_alloc_lines(wp); } else { @@ -5929,7 +5922,7 @@ void win_grid_alloc(win_T *wp) // Only keep track of the size and offset of the window. grid_free(grid); grid->Rows = rows; - grid->Columns = columns; + grid->Columns = cols; } was_resized = true; } @@ -6233,7 +6226,7 @@ void setcursor(void) if (curwin->w_p_rl) { // With 'rightleft' set and the cursor on a double-wide character, // position it on the leftmost column. - col = curwin->w_grid.Columns - curwin->w_wcol + col = curwin->w_width_inner - curwin->w_wcol - ((utf_ptr2cells(get_cursor_pos_ptr()) == 2 && vim_isprintc(gchar_cursor())) ? 2 : 1); } @@ -7086,7 +7079,7 @@ int number_width(win_T *wp) if (wp->w_p_rnu && !wp->w_p_nu) { // cursor line shows "0" - lnum = wp->w_grid.Rows; + lnum = wp->w_height_inner; } else { // cursor line shows absolute line number lnum = wp->w_buffer->b_ml.ml_line_count; diff --git a/src/nvim/screen.h b/src/nvim/screen.h index 109541ef07..61ed98247d 100644 --- a/src/nvim/screen.h +++ b/src/nvim/screen.h @@ -28,8 +28,7 @@ /// /// Note: before the screen is initialized and when out of memory these can be /// NULL. -EXTERN ScreenGrid default_grid INIT(= { 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0, - 0, 0, 0 }); +EXTERN ScreenGrid default_grid INIT(= SCREEN_GRID_INIT); #define DEFAULT_GRID_HANDLE 1 // handle for the default_grid diff --git a/src/nvim/search.c b/src/nvim/search.c index cf0f1ea287..5f0ff96f95 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -2168,7 +2168,7 @@ showmatch( } if (curwin->w_p_wrap || (vcol >= curwin->w_leftcol - && vcol < curwin->w_leftcol + curwin->w_grid.Columns)) { + && vcol < curwin->w_leftcol + curwin->w_width_inner)) { mpos = *lpos; // save the pos, update_screen() may change it save_cursor = curwin->w_cursor; save_so = p_so; diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 489e39f784..e2e3bc5f30 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -351,9 +351,9 @@ void terminal_check_size(Terminal *term) if (wp->w_buffer && wp->w_buffer->terminal == term) { window_seen = true; const uint16_t win_width = - (uint16_t)(MAX(0, wp->w_width - win_col_off(wp))); + (uint16_t)(MAX(0, wp->w_width_inner - win_col_off(wp))); width = MAX(width, win_width); - height = (uint16_t)MAX(height, wp->w_height); + height = (uint16_t)MAX(height, wp->w_height_inner); } } diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 73d45d8192..ec0cfb6caa 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -452,8 +452,8 @@ void ui_grid_resize(handle_T grid_handle, int width, int height, Error *error) return; } - wp->w_grid.requested_rows = (int)height; - wp->w_grid.requested_cols = (int)width; - win_inner_width_changed(wp); - redraw_win_later(wp, SOME_VALID); + // non-positive indicates no request + wp->w_height_request = (int)MAX(height,0); + wp->w_width_request = (int)MAX(width,0); + win_set_inner_size(wp); } diff --git a/src/nvim/window.c b/src/nvim/window.c index f88b36615a..36d780a661 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -3025,8 +3025,10 @@ static void new_frame(win_T *wp) void win_init_size(void) { firstwin->w_height = ROWS_AVAIL; + firstwin->w_height_inner = firstwin->w_height; topframe->fr_height = ROWS_AVAIL; firstwin->w_width = Columns; + firstwin->w_width_inner = firstwin->w_width; topframe->fr_width = Columns; } @@ -4123,8 +4125,10 @@ static void frame_remove(frame_T *frp) void win_alloc_lines(win_T *wp) { wp->w_lines_valid = 0; - assert(wp->w_grid.Rows >= 0); - wp->w_lines = xcalloc(MAX(wp->w_grid.Rows + 1, Rows), sizeof(wline_T)); + assert(wp->w_height_inner >= 0); + // TODO(bfredl) :this should work, add call to win_set_inner_size? + // wp->w_lines = xcalloc(wp->w_height_inner+1, sizeof(wline_T)); + wp->w_lines = xcalloc(MAX(wp->w_height_inner + 1, Rows), sizeof(wline_T)); } /* @@ -4876,9 +4880,9 @@ void win_drag_vsep_line(win_T *dragwin, int offset) // Has no effect when the window is less than two lines. void set_fraction(win_T *wp) { - if (wp->w_height > 1) { - wp->w_fraction = ((long)wp->w_wrow * FRACTION_MULT + wp->w_height / 2) - / (long)wp->w_height; + if (wp->w_height_inner > 1) { + wp->w_fraction = ((long)wp->w_wrow * FRACTION_MULT + wp->w_height_inner / 2) + / (long)wp->w_height_inner; } } @@ -4889,46 +4893,25 @@ void set_fraction(win_T *wp) */ void win_new_height(win_T *wp, int height) { - int prev_height = wp->w_height; - - /* Don't want a negative height. Happens when splitting a tiny window. - * Will equalize heights soon to fix it. */ - if (height < 0) + // Don't want a negative height. Happens when splitting a tiny window. + // Will equalize heights soon to fix it. + if (height < 0) { height = 0; - if (wp->w_height == height) - return; /* nothing to do */ - - if (wp->w_height > 0) { - if (wp == curwin) { - // w_wrow needs to be valid. When setting 'laststatus' this may - // call win_new_height() recursively. - validate_cursor(); - } - if (wp->w_height != prev_height) { // -V547 - return; // Recursive call already changed the size, bail out. - } - if (wp->w_wrow != wp->w_prev_fraction_row) { - set_fraction(wp); - } } - - wp->w_height = height; - wp->w_skipcol = 0; - - // There is no point in adjusting the scroll position when exiting. Some - // values might be invalid. - if (!exiting) { - scroll_to_fraction(wp, prev_height); + if (wp->w_height == height) { + return; // nothing to do } + wp->w_height = height; wp->w_pos_changed = true; + win_set_inner_size(wp); } void scroll_to_fraction(win_T *wp, int prev_height) { linenr_T lnum; int sline, line_size; - int height = wp->w_height; + int height = wp->w_height_inner; /* Don't change w_topline when height is zero. Don't set w_topline when * 'scrollbind' is set and this isn't the current window. */ @@ -4951,8 +4934,8 @@ void scroll_to_fraction(win_T *wp, int prev_height) // Make sure the whole cursor line is visible, if possible. const int rows = plines_win(wp, lnum, false); - if (sline > wp->w_height - rows) { - sline = wp->w_height - rows; + if (sline > wp->w_height_inner - rows) { + sline = wp->w_height_inner - rows; wp->w_wrow -= rows - line_size; } } @@ -4964,14 +4947,14 @@ void scroll_to_fraction(win_T *wp, int prev_height) * room use w_skipcol; */ wp->w_wrow = line_size; - if (wp->w_wrow >= wp->w_height - && (wp->w_width - win_col_off(wp)) > 0) { - wp->w_skipcol += wp->w_width - win_col_off(wp); - --wp->w_wrow; - while (wp->w_wrow >= wp->w_height) { - wp->w_skipcol += wp->w_width - win_col_off(wp) + if (wp->w_wrow >= wp->w_height_inner + && (wp->w_width_inner - win_col_off(wp)) > 0) { + wp->w_skipcol += wp->w_width_inner - win_col_off(wp); + wp->w_wrow--; + while (wp->w_wrow >= wp->w_height_inner) { + wp->w_skipcol += wp->w_width_inner - win_col_off(wp) + win_col_off2(wp); - --wp->w_wrow; + wp->w_wrow--; } } set_topline(wp, lnum); @@ -5024,22 +5007,58 @@ void scroll_to_fraction(win_T *wp, int prev_height) redraw_win_later(wp, SOME_VALID); wp->w_redr_status = TRUE; invalidate_botline_win(wp); - - if (wp->w_buffer->terminal) { - terminal_check_size(wp->w_buffer->terminal); - // TODO: terminal should this itself: - redraw_win_later(wp, NOT_VALID); - } } -void win_inner_width_changed(win_T *wp) +void win_set_inner_size(win_T *wp) { - wp->w_lines_valid = 0; - changed_line_abv_curs_win(wp); - invalidate_botline_win(wp); - if (wp == curwin) { - update_topline(); - curs_columns(TRUE); /* validate w_wrow */ + int width = wp->w_width_request; + if (width == 0) { + width = wp->w_width; + } + + int prev_height = wp->w_height_inner; + int height = wp->w_height_request; + if (height == 0) { + height = wp->w_height; + } + + if (height != prev_height) { + if (height > 0) { + if (wp == curwin) { + // w_wrow needs to be valid. When setting 'laststatus' this may + // call win_new_height() recursively. + validate_cursor(); + } + if (wp->w_height_inner != prev_height) { // -V547 + return; // Recursive call already changed the size, bail out. + } + if (wp->w_wrow != wp->w_prev_fraction_row) { + set_fraction(wp); + } + } + wp->w_height_inner = height; + wp->w_skipcol = 0; + + // There is no point in adjusting the scroll position when exiting. Some + // values might be invalid. + if (!exiting) { + scroll_to_fraction(wp, prev_height); + } + } + + if (width != wp->w_width_inner) { + wp->w_width_inner = width; + wp->w_lines_valid = 0; + changed_line_abv_curs_win(wp); + invalidate_botline_win(wp); + if (wp == curwin) { + update_topline(); + curs_columns(true); // validate w_wrow + } + } + + if (wp->w_buffer->terminal) { + terminal_check_size(wp->w_buffer->terminal); } } @@ -5047,22 +5066,11 @@ void win_inner_width_changed(win_T *wp) void win_new_width(win_T *wp, int width) { wp->w_width = width; - // TODO(bfredl): refactor this. There should be some variable - // wp->w_inner_width which always contains the final actual width. - // Alternatively use wp->w_width for this and introduce wp->w_outer_width. - // Then use this to fix terminal_check_size. - if (!ui_is_external(kUIMultigrid) || wp->w_grid.requested_cols == 0) { - win_inner_width_changed(wp); - } + win_set_inner_size(wp); redraw_win_later(wp, NOT_VALID); wp->w_redr_status = TRUE; - if (wp->w_buffer->terminal) { - if (wp->w_height != 0) { - terminal_check_size(wp->w_buffer->terminal); - } - } wp->w_pos_changed = true; } diff --git a/test/functional/terminal/helpers.lua b/test/functional/terminal/helpers.lua index 7de0152de0..18f0b9e4c1 100644 --- a/test/functional/terminal/helpers.lua +++ b/test/functional/terminal/helpers.lua @@ -33,7 +33,7 @@ local function disable_mouse() feed_termcode('[?1002l') end local default_command = '["'..nvim_dir..'/tty-test'..'"]' -local function screen_setup(extra_rows, command, cols) +local function screen_setup(extra_rows, command, cols, opts) extra_rows = extra_rows and extra_rows or 0 command = command and command or default_command cols = cols and cols or 50 @@ -55,7 +55,7 @@ local function screen_setup(extra_rows, command, cols) [10] = {foreground = 121}, -- "Press ENTER" in embedded :terminal session. }) - screen:attach({rgb=false}) + screen:attach(opts or {rgb=false}) feed_command('enew | call termopen('..command..')') nvim('input', '<CR>') @@ -69,7 +69,7 @@ local function screen_setup(extra_rows, command, cols) -- tty-test puts the terminal into raw mode and echoes input. Tests work by -- feeding termcodes to control the display and asserting by screen:expect. - if command == default_command then + if command == default_command and opts == nil then -- Wait for "tty ready" to be printed before each test or the terminal may -- still be in canonical mode (will echo characters for example). local empty_line = (' '):rep(cols) diff --git a/test/functional/terminal/window_spec.lua b/test/functional/terminal/window_spec.lua index 842a81872e..242377f9bd 100644 --- a/test/functional/terminal/window_spec.lua +++ b/test/functional/terminal/window_spec.lua @@ -124,3 +124,101 @@ describe('terminal window', function() end) end) +describe('terminal window with multigrid', function() + local screen + + before_each(function() + clear() + screen = thelpers.screen_setup(0,nil,50,{ext_multigrid=true}) + end) + + it('resizes to requested size', function() + screen:expect([[ + ## grid 1 + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + {3:-- TERMINAL --} | + ## grid 2 + tty ready | + {1: } | + | + | + | + | + ]]) + + screen:try_resize_grid(2, 20, 10) + if iswin() then + screen:expect{any="rows: 10, cols: 20"} + else + screen:expect([[ + ## grid 1 + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + {3:-- TERMINAL --} | + ## grid 2 + tty ready | + rows: 10, cols: 20 | + {1: } | + | + | + | + | + | + | + | + ]]) + end + + screen:try_resize_grid(2, 70, 3) + if iswin() then + screen:expect{any="rows: 3, cols: 70"} + else + screen:expect([[ + ## grid 1 + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + {3:-- TERMINAL --} | + ## grid 2 + rows: 10, cols: 20 | + rows: 3, cols: 70 | + {1: } | + ]]) + end + + screen:try_resize_grid(2, 0, 0) + if iswin() then + screen:expect{any="rows: 6, cols: 50"} + else + screen:expect([[ + ## grid 1 + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + {3:-- TERMINAL --} | + ## grid 2 + tty ready | + rows: 10, cols: 20 | + rows: 3, cols: 70 | + rows: 6, cols: 50 | + {1: } | + | + ]]) + end + end) +end) |