aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/buffer.c2
-rw-r--r--src/nvim/api/ui.c5
-rw-r--r--src/nvim/api/vim.c99
-rw-r--r--src/nvim/buffer.c4
-rw-r--r--src/nvim/buffer_defs.h7
-rw-r--r--src/nvim/charset.c24
-rw-r--r--src/nvim/cursor.c8
-rw-r--r--src/nvim/edit.c8
-rw-r--r--src/nvim/eval.c4
-rw-r--r--src/nvim/ex_cmds.c10
-rw-r--r--src/nvim/ex_docmd.c6
-rw-r--r--src/nvim/getchar.c6
-rw-r--r--src/nvim/grid_defs.h8
-rw-r--r--src/nvim/indent.c2
-rw-r--r--src/nvim/memline_defs.h71
-rw-r--r--src/nvim/menu.c55
-rw-r--r--src/nvim/misc1.c12
-rw-r--r--src/nvim/mouse.c18
-rw-r--r--src/nvim/move.c127
-rw-r--r--src/nvim/normal.c30
-rw-r--r--src/nvim/option.c2
-rw-r--r--src/nvim/screen.c105
-rw-r--r--src/nvim/screen.h3
-rw-r--r--src/nvim/search.c2
-rw-r--r--src/nvim/terminal.c37
-rw-r--r--src/nvim/testdir/test_menu.vim23
-rw-r--r--src/nvim/ui.c8
-rw-r--r--src/nvim/window.c164
28 files changed, 427 insertions, 423 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 5df0f0bb47..9cd178eaeb 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -104,7 +104,7 @@ String buffer_get_line(Buffer buffer, Integer index, Error *err)
/// the whole buffer. If so, the first notification will be a
/// `nvim_buf_lines_event`. Otherwise, the first notification will be
/// a `nvim_buf_changedtick_event`
-/// @param opts Optional parameters. Currently not used.
+/// @param opts Optional parameters. Reserved for future use.
/// @param[out] err Details of an error that may have occurred
/// @return False when updates couldn't be enabled because the buffer isn't
/// loaded or `opts` contained an invalid key; otherwise True.
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index 7ba5251c60..bc8a1a941f 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -245,9 +245,8 @@ static void ui_set_option(UI *ui, bool init, String name, Object value,
name.data);
}
-/// Tell nvim to resize a grid. Nvim sends grid_resize event with the
-/// requested grid size is within size limits and with maximum allowed size
-/// otherwise.
+/// Tell Nvim to resize a grid. Triggers a grid_resize event with the requested
+/// grid size or the maximum size if it exceeds size limits.
///
/// On invalid grid handle, fails with error.
///
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 7f62333d88..5b59ff39f4 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -198,9 +198,8 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_csi)
/// @note |keycodes| like <CR> are translated, so "<" is special.
/// To input a literal "<", send <LT>.
///
-/// For mouse events use |nvim_input_mouse()|. For back-compat reasons
-/// this method supports mouse input as "<LeftMouse><col,row>". This
-/// usage is deprecated since API level 6, use the dedicated method instead.
+/// @note For mouse events use |nvim_input_mouse()|. The pseudokey form
+/// "<LeftMouse><col,row>" is deprecated since |api-level| 6.
///
/// @param keys to be typed
/// @return Number of bytes actually written (can be fewer than
@@ -211,7 +210,7 @@ Integer nvim_input(String keys)
return (Integer)input_enqueue(keys);
}
-/// Send mouse event from GUI
+/// Send mouse event from GUI.
///
/// The call is non-blocking. It doesn't wait on any resulting action, but
/// queues the event to be processed soon by the event loop.
@@ -220,20 +219,18 @@ Integer nvim_input(String keys)
/// by calling it multiple times in a loop: the intermediate mouse
/// positions will be ignored. It should be used to implement real-time
/// mouse input in a GUI. The deprecated pseudokey form
-/// ("<LeftMouse><col,row>") in |nvim_input()| has the same limitiation.
+/// ("<LeftMouse><col,row>") of |nvim_input()| has the same limitiation.
///
-/// @param button Which mouse button, one of "left", "right", "middle" or
-/// "wheel".
-/// @param action For ordinary buttons, one of "press", "drag" and "release"
-/// For the wheel, use "up", "down", "left" and "right".
+/// @param button Mouse button: one of "left", "right", "middle", "wheel".
+/// @param action For ordinary buttons, one of "press", "drag", "release".
+/// For the wheel, one of "up", "down", "left", "right".
/// @param modifier String of modifiers each represented by a single char.
/// The same specifiers are used as for a key press, except
/// that the "-" separator is optional, so "C-A-", "c-a"
-/// and "CA" can all be used to specify Ctrl+Alt+click
-/// @param grid For a client using |ui-multigrid| pass in the grid number.
-/// Other clients should pass in 0 (not 1).
-/// @param row row position of mouse (zero-based, like in redraw events)
-/// @param col column position of mouse (zero-based, like in redraw events)
+/// and "CA" can all be used to specify Ctrl+Alt+click.
+/// @param grid Grid number if the client uses |ui-multigrid|, else 0.
+/// @param row Mouse row-position (zero-based, like redraw events)
+/// @param col Mouse column-position (zero-based, like redraw events)
void nvim_input_mouse(String button, String action, String modifier,
Integer grid, Integer row, Integer col, Error *err)
FUNC_API_SINCE(6) FUNC_API_ASYNC
@@ -694,7 +691,7 @@ void nvim_set_current_dir(String dir, Error *err)
try_end(err);
}
-/// Gets the current line
+/// Gets the current line.
///
/// @param[out] err Error details, if any
/// @return Current line string
@@ -704,7 +701,7 @@ String nvim_get_current_line(Error *err)
return buffer_get_line(curbuf->handle, curwin->w_cursor.lnum - 1, err);
}
-/// Sets the current line
+/// Sets the current line.
///
/// @param line Line contents
/// @param[out] err Error details, if any
@@ -714,7 +711,7 @@ void nvim_set_current_line(String line, Error *err)
buffer_set_line(curbuf->handle, curwin->w_cursor.lnum - 1, line, err);
}
-/// Deletes the current line
+/// Deletes the current line.
///
/// @param[out] err Error details, if any
void nvim_del_current_line(Error *err)
@@ -723,7 +720,7 @@ void nvim_del_current_line(Error *err)
buffer_del_line(curbuf->handle, curwin->w_cursor.lnum - 1, err);
}
-/// Gets a global (g:) variable
+/// Gets a global (g:) variable.
///
/// @param name Variable name
/// @param[out] err Error details, if any
@@ -734,7 +731,7 @@ Object nvim_get_var(String name, Error *err)
return dict_get_value(&globvardict, name, err);
}
-/// Sets a global (g:) variable
+/// Sets a global (g:) variable.
///
/// @param name Variable name
/// @param value Variable value
@@ -745,7 +742,7 @@ void nvim_set_var(String name, Object value, Error *err)
dict_set_var(&globvardict, name, value, false, false, err);
}
-/// Removes a global (g:) variable
+/// Removes a global (g:) variable.
///
/// @param name Variable name
/// @param[out] err Error details, if any
@@ -772,7 +769,7 @@ Object vim_del_var(String name, Error *err)
return dict_set_var(&globvardict, name, NIL, true, true, err);
}
-/// Gets a v: variable
+/// Gets a v: variable.
///
/// @param name Variable name
/// @param[out] err Error details, if any
@@ -783,7 +780,7 @@ Object nvim_get_vvar(String name, Error *err)
return dict_get_value(&vimvardict, name, err);
}
-/// Sets a v: variable, if it is not readonly
+/// Sets a v: variable, if it is not readonly.
///
/// @param name Variable name
/// @param value Variable value
@@ -794,7 +791,7 @@ void nvim_set_vvar(String name, Object value, Error *err)
dict_set_var(&vimvardict, name, value, false, false, err);
}
-/// Gets an option value string
+/// Gets an option value string.
///
/// @param name Option name
/// @param[out] err Error details, if any
@@ -805,7 +802,7 @@ Object nvim_get_option(String name, Error *err)
return get_option_from(NULL, SREQ_GLOBAL, name, err);
}
-/// Sets an option value
+/// Sets an option value.
///
/// @param name Option name
/// @param value New option value
@@ -873,7 +870,7 @@ ArrayOf(Buffer) nvim_list_bufs(void)
return rv;
}
-/// Gets the current buffer
+/// Gets the current buffer.
///
/// @return Buffer handle
Buffer nvim_get_current_buf(void)
@@ -882,7 +879,7 @@ Buffer nvim_get_current_buf(void)
return curbuf->handle;
}
-/// Sets the current buffer
+/// Sets the current buffer.
///
/// @param buffer Buffer handle
/// @param[out] err Error details, if any
@@ -905,7 +902,7 @@ void nvim_set_current_buf(Buffer buffer, Error *err)
}
}
-/// Gets the current list of window handles
+/// Gets the current list of window handles.
///
/// @return List of window handles
ArrayOf(Window) nvim_list_wins(void)
@@ -927,7 +924,7 @@ ArrayOf(Window) nvim_list_wins(void)
return rv;
}
-/// Gets the current window
+/// Gets the current window.
///
/// @return Window handle
Window nvim_get_current_win(void)
@@ -936,7 +933,7 @@ Window nvim_get_current_win(void)
return curwin->handle;
}
-/// Sets the current window
+/// Sets the current window.
///
/// @param window Window handle
void nvim_set_current_win(Window window, Error *err)
@@ -958,7 +955,7 @@ void nvim_set_current_win(Window window, Error *err)
}
}
-/// Gets the current list of tabpage handles
+/// Gets the current list of tabpage handles.
///
/// @return List of tabpage handles
ArrayOf(Tabpage) nvim_list_tabpages(void)
@@ -980,7 +977,7 @@ ArrayOf(Tabpage) nvim_list_tabpages(void)
return rv;
}
-/// Gets the current tabpage
+/// Gets the current tabpage.
///
/// @return Tabpage handle
Tabpage nvim_get_current_tabpage(void)
@@ -989,7 +986,7 @@ Tabpage nvim_get_current_tabpage(void)
return curtab->handle;
}
-/// Sets the current tabpage
+/// Sets the current tabpage.
///
/// @param tabpage Tabpage handle
/// @param[out] err Error details, if any
@@ -1012,7 +1009,7 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err)
}
}
-/// Creates a new namespace, or gets an existing one
+/// Creates a new namespace, or gets an existing one.
///
/// Namespaces are used for buffer highlights and virtual text, see
/// |nvim_buf_add_highlight()| and |nvim_buf_set_virtual_text()|.
@@ -1038,7 +1035,7 @@ Integer nvim_create_namespace(String name)
return (Integer)id;
}
-/// Gets existing, non-anonymous namespaces
+/// Gets existing, non-anonymous namespaces.
///
/// @return dict that maps from names to namespace ids.
Dictionary nvim_get_namespaces(void)
@@ -1055,7 +1052,7 @@ Dictionary nvim_get_namespaces(void)
return retval;
}
-/// Subscribes to event broadcasts
+/// Subscribes to event broadcasts.
///
/// @param channel_id Channel id (passed automatically by the dispatcher)
/// @param event Event type string
@@ -1069,7 +1066,7 @@ void nvim_subscribe(uint64_t channel_id, String event)
rpc_subscribe(channel_id, e);
}
-/// Unsubscribes to event broadcasts
+/// Unsubscribes to event broadcasts.
///
/// @param channel_id Channel id (passed automatically by the dispatcher)
/// @param event Event type string
@@ -1379,7 +1376,7 @@ typedef struct {
typedef kvec_withinit_t(ExprASTConvStackItem, 16) ExprASTConvStack;
/// @endcond
-/// Parse a VimL expression
+/// Parse a VimL expression.
///
/// @param[in] expr Expression to parse. Is always treated as a single line.
/// @param[in] flags Flags:
@@ -1860,7 +1857,7 @@ static void write_msg(String message, bool to_err)
// Functions used for testing purposes
-/// Returns object given as argument
+/// Returns object given as argument.
///
/// This API function is used for testing. One should not rely on its presence
/// in plugins.
@@ -1873,7 +1870,7 @@ Object nvim__id(Object obj)
return copy_object(obj);
}
-/// Returns array given as argument
+/// Returns array given as argument.
///
/// This API function is used for testing. One should not rely on its presence
/// in plugins.
@@ -1886,7 +1883,7 @@ Array nvim__id_array(Array arr)
return copy_object(ARRAY_OBJ(arr)).data.array;
}
-/// Returns dictionary given as argument
+/// Returns dictionary given as argument.
///
/// This API function is used for testing. One should not rely on its presence
/// in plugins.
@@ -1899,7 +1896,7 @@ Dictionary nvim__id_dictionary(Dictionary dct)
return copy_object(DICTIONARY_OBJ(dct)).data.dictionary;
}
-/// Returns floating-point value given as argument
+/// Returns floating-point value given as argument.
///
/// This API function is used for testing. One should not rely on its presence
/// in plugins.
@@ -2023,19 +2020,19 @@ Object nvim_get_proc(Integer pid, Error *err)
return rvobj;
}
-/// Selects an item in the completion popupmenu
+/// Selects an item in the completion popupmenu.
///
-/// When insert completion is not active, this API call is silently ignored.
-/// It is mostly useful for an external UI using |ui-popupmenu| for instance
-/// to control the popupmenu with the mouse. But it can also be used in an
-/// insert mode mapping, use <cmd> mapping |:map-cmd| to ensure the mapping
-/// doesn't end completion mode.
+/// If |ins-completion| is not active this API call is silently ignored.
+/// Useful for an external UI using |ui-popupmenu| to control the popupmenu
+/// with the mouse. Can also be used in a mapping; use <cmd> |:map-cmd| to
+/// ensure the mapping doesn't end completion mode.
///
-/// @param item Index of the item to select, starting with zero. Pass in "-1"
-/// to select no item (restore original text).
+/// @param item Index (zero-based) of the item to select. Value of -1 selects
+/// nothing and restores the original text.
/// @param insert Whether the selection should be inserted in the buffer.
-/// @param finish If true, completion will be finished with this item, and the
-/// popupmenu dissmissed. Implies `insert`.
+/// @param finish Finish the completion and dismiss the popupmenu. Implies
+/// `insert`.
+/// @param opts Optional parameters. Reserved for future use.
void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish,
Dictionary opts, Error *err)
FUNC_API_SINCE(6)
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 048fde07e7..7b90cbe4f4 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -1472,6 +1472,10 @@ void set_curbuf(buf_T *buf, int action)
if (old_tw != curbuf->b_p_tw)
check_colorcolumn(curwin);
}
+
+ if (bufref_valid(&prevbufref) && prevbuf->terminal != NULL) {
+ terminal_check_size(prevbuf->terminal);
+ }
}
/*
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 09d22c4233..b3977e0176 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -1063,6 +1063,13 @@ struct window_S {
int w_width; /* Width of window, excluding separation. */
int w_vsep_width; /* Number of separator columns (0 or 1). */
+ // inner size of window, which can be overriden by external UI
+ int w_height_inner;
+ int w_width_inner;
+ // external UI request. If non-zero, the inner size will use this.
+ 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 16e24cc55a..08ecff149c 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 993edec5ef..3980516d32 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -16798,10 +16798,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..abdf411fc3 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;
@@ -2678,6 +2678,10 @@ int do_ecmd(
theend:
+ if (bufref_valid(&old_curbuf) && old_curbuf.br_buf->terminal != NULL) {
+ terminal_check_size(old_curbuf.br_buf->terminal);
+ }
+
if (did_inc_redrawing_disabled) {
RedrawingDisabled--;
}
@@ -2872,11 +2876,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 30962faa23..8e20aa5be4 100644
--- a/src/nvim/indent.c
+++ b/src/nvim/indent.c
@@ -474,7 +474,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/memline_defs.h b/src/nvim/memline_defs.h
index 34a002af5d..edd933b2cd 100644
--- a/src/nvim/memline_defs.h
+++ b/src/nvim/memline_defs.h
@@ -3,54 +3,65 @@
#include "nvim/memfile_defs.h"
-/*
- * When searching for a specific line, we remember what blocks in the tree
- * are the branches leading to that block. This is stored in ml_stack. Each
- * entry is a pointer to info in a block (may be data block or pointer block)
- */
+///
+/// When searching for a specific line, we remember what blocks in the tree
+/// are the branches leading to that block. This is stored in ml_stack. Each
+/// entry is a pointer to info in a block (may be data block or pointer block)
+///
typedef struct info_pointer {
- blocknr_T ip_bnum; /* block number */
- linenr_T ip_low; /* lowest lnum in this block */
- linenr_T ip_high; /* highest lnum in this block */
- int ip_index; /* index for block with current lnum */
-} infoptr_T; /* block/index pair */
+ blocknr_T ip_bnum; // block number
+ linenr_T ip_low; // lowest lnum in this block
+ linenr_T ip_high; // highest lnum in this block
+ int ip_index; // index for block with current lnum
+} infoptr_T; // block/index pair
typedef struct ml_chunksize {
int mlcs_numlines;
long mlcs_totalsize;
} chunksize_T;
-/* Flags when calling ml_updatechunk() */
-
+// Flags when calling ml_updatechunk()
#define ML_CHNK_ADDLINE 1
#define ML_CHNK_DELLINE 2
#define ML_CHNK_UPDLINE 3
-/*
- * the memline structure holds all the information about a memline
- */
+/// memline structure: the contents of a buffer.
+/// Essentially a tree with a branch factor of 128.
+/// Lines are stored at leaf nodes.
+/// Nodes are stored on ml_mfp (memfile_T):
+/// pointer_block: internal nodes
+/// data_block: leaf nodes
+///
+/// Memline also has "chunks" of 800 lines that are separate from the 128-tree
+/// structure, primarily used to speed up line2byte() and byte2line().
+///
+/// Motivation: If you have a file that is 10000 lines long, and you insert
+/// a line at linenr 1000, you don't want to move 9000 lines in
+/// memory. With this structure it is roughly (N * 128) pointer
+/// moves, where N is the height (typically 1-3).
+///
typedef struct memline {
- linenr_T ml_line_count; /* number of lines in the buffer */
+ linenr_T ml_line_count; // number of lines in the buffer
- memfile_T *ml_mfp; /* pointer to associated memfile */
+ memfile_T *ml_mfp; // pointer to associated memfile
-#define ML_EMPTY 1 /* empty buffer */
-#define ML_LINE_DIRTY 2 /* cached line was changed and allocated */
-#define ML_LOCKED_DIRTY 4 /* ml_locked was changed */
-#define ML_LOCKED_POS 8 /* ml_locked needs positive block number */
+#define ML_EMPTY 1 // empty buffer
+#define ML_LINE_DIRTY 2 // cached line was changed and allocated
+#define ML_LOCKED_DIRTY 4 // ml_locked was changed
+#define ML_LOCKED_POS 8 // ml_locked needs positive block number
int ml_flags;
- infoptr_T *ml_stack; /* stack of pointer blocks (array of IPTRs) */
- int ml_stack_top; /* current top of ml_stack */
- int ml_stack_size; /* total number of entries in ml_stack */
+ infoptr_T *ml_stack; // stack of pointer blocks (array of IPTRs)
+ int ml_stack_top; // current top of ml_stack
+ int ml_stack_size; // total number of entries in ml_stack
- linenr_T ml_line_lnum; /* line number of cached line, 0 if not valid */
- char_u *ml_line_ptr; /* pointer to cached line */
+ linenr_T ml_line_lnum; // line number of cached line, 0 if not valid
+ char_u *ml_line_ptr; // pointer to cached line
- bhdr_T *ml_locked; /* block used by last ml_get */
- linenr_T ml_locked_low; /* first line in ml_locked */
- linenr_T ml_locked_high; /* last line in ml_locked */
- int ml_locked_lineadd; /* number of lines inserted in ml_locked */
+ bhdr_T *ml_locked; // block used by last ml_get
+ linenr_T ml_locked_low; // first line in ml_locked
+ linenr_T ml_locked_high; // last line in ml_locked
+ int ml_locked_lineadd; // number of lines inserted in ml_locked
chunksize_T *ml_chunksize;
int ml_numchunks;
int ml_usedchunks;
diff --git a/src/nvim/menu.c b/src/nvim/menu.c
index 1c54db10eb..aea297fce2 100644
--- a/src/nvim/menu.c
+++ b/src/nvim/menu.c
@@ -660,7 +660,8 @@ static void free_menu_string(vimmenu_T *menu, int idx)
///
/// @param[in] menu if null, starts from root_menu
/// @param modes, a choice of \ref MENU_MODES
-/// @return a dict with name/commands
+/// @return dict with name/commands
+/// @see show_menus_recursive
/// @see menu_get
static dict_T *menu_get_recursive(const vimmenu_T *menu, int modes)
{
@@ -715,10 +716,10 @@ static dict_T *menu_get_recursive(const vimmenu_T *menu, int modes)
// visit recursively all children
list_T *const children_list = tv_list_alloc(kListLenMayKnow);
for (menu = menu->children; menu != NULL; menu = menu->next) {
- dict_T *dic = menu_get_recursive(menu, modes);
- if (tv_dict_len(dict) > 0) {
- tv_list_append_dict(children_list, dic);
- }
+ dict_T *d = menu_get_recursive(menu, modes);
+ if (tv_dict_len(d) > 0) {
+ tv_list_append_dict(children_list, d);
+ }
}
tv_dict_add_list(dict, S_LEN("submenus"), children_list);
}
@@ -734,42 +735,51 @@ static dict_T *menu_get_recursive(const vimmenu_T *menu, int modes)
/// @return false if could not find path_name
bool menu_get(char_u *const path_name, int modes, list_T *list)
{
- vimmenu_T *menu;
- menu = find_menu(root_menu, path_name, modes);
+ vimmenu_T *menu = find_menu(root_menu, path_name, modes);
if (!menu) {
return false;
}
for (; menu != NULL; menu = menu->next) {
- dict_T *dict = menu_get_recursive(menu, modes);
- if (dict && tv_dict_len(dict) > 0) {
- tv_list_append_dict(list, dict);
+ dict_T *d = menu_get_recursive(menu, modes);
+ if (d && tv_dict_len(d) > 0) {
+ tv_list_append_dict(list, d);
+ }
+ if (*path_name != NUL) {
+ // If a (non-empty) path query was given, only the first node in the
+ // find_menu() result is relevant. Else we want all nodes.
+ break;
}
}
return true;
}
-/// Find menu matching required name and modes
+/// Find menu matching `name` and `modes`.
///
/// @param menu top menu to start looking from
/// @param name path towards the menu
/// @return menu if \p name is null, found menu or NULL
-vimmenu_T *
-find_menu(vimmenu_T *menu, char_u * name, int modes)
+static vimmenu_T *find_menu(vimmenu_T *menu, char_u *name, int modes)
{
char_u *p;
while (*name) {
+ // find the end of one dot-separated name and put a NUL at the dot
p = menu_name_skip(name);
while (menu != NULL) {
if (menu_name_equal(name, menu)) {
- /* Found menu */
+ // Found menu
if (*p != NUL && menu->children == NULL) {
- EMSG(_(e_notsubmenu));
- return NULL;
- } else if ((menu->modes & modes) == 0x0) {
- EMSG(_(e_othermode));
- return NULL;
+ if (*p != NUL) {
+ EMSG(_(e_notsubmenu));
+ return NULL;
+ } else if ((menu->modes & modes) == 0x0) {
+ EMSG(_(e_othermode));
+ return NULL;
+ }
+ }
+ if (*p == NUL) { // found a full match
+ return menu;
}
break;
}
@@ -780,6 +790,7 @@ find_menu(vimmenu_T *menu, char_u * name, int modes)
EMSG2(_(e_nomenu), name);
return NULL;
}
+ // Found a match, search the sub-menu.
name = p;
menu = menu->children;
}
@@ -1235,7 +1246,7 @@ static char_u *popup_mode_name(char_u *name, int idx)
///
/// @return a pointer to allocated memory.
static char_u *menu_text(const char_u *str, int *mnemonic, char_u **actext)
- FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
FUNC_ATTR_NONNULL_ARG(1)
{
char_u *p;
@@ -1520,7 +1531,7 @@ static char_u *menutrans_lookup(char_u *name, int len)
char_u *dname;
for (int i = 0; i < menutrans_ga.ga_len; i++) {
- if (STRNCMP(name, tp[i].from, len) == 0 && tp[i].from[len] == NUL) {
+ if (STRNICMP(name, tp[i].from, len) == 0 && tp[i].from[len] == NUL) {
return tp[i].to;
}
}
@@ -1531,7 +1542,7 @@ static char_u *menutrans_lookup(char_u *name, int len)
dname = menu_text(name, NULL, NULL);
name[len] = c;
for (int i = 0; i < menutrans_ga.ga_len; i++) {
- if (STRCMP(dname, tp[i].from_noamp) == 0) {
+ if (STRICMP(dname, tp[i].from_noamp) == 0) {
xfree(dname);
return tp[i].to;
}
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c
index ef4562f4e9..e752910a4b 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;
}
@@ -1291,7 +1291,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
}
@@ -1317,7 +1317,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 48fd765e1b..50dba92eca 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..610fd04ebc 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,8 @@ 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 +1517,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 +1536,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 +1563,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 +1584,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 +1627,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 +1644,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 +1655,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 +1684,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 +1694,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 +1868,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 +1959,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 +2014,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/option.c b/src/nvim/option.c
index d8e5b78e80..c57e6649bb 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -4356,7 +4356,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
} else if (pp == &curbuf->b_p_scbk || pp == &p_scbk) {
if (curbuf->terminal) {
// Force the scrollback to take effect.
- terminal_resize(curbuf->terminal, UINT16_MAX, UINT16_MAX);
+ terminal_check_size(curbuf->terminal);
}
} else if (pp == &curwin->w_p_nuw) {
curwin->w_nrwidth_line_count = 0;
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 29a71fc0e1..2038fb4d2c 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -324,7 +324,7 @@ void update_screen(int type)
wp->w_redr_status = true;
}
}
- } else if (msg_scrolled > default_grid.Rows - 5) { // clearing is faster
+ } else if (msg_scrolled > Rows - 5) { // clearing is faster
type = CLEAR;
} else if (type != CLEAR) {
check_for_delay(false);
@@ -629,9 +629,7 @@ static void win_update(win_T *wp)
wp->w_nrwidth = i;
if (buf->terminal) {
- terminal_resize(buf->terminal,
- (uint16_t)(MAX(0, wp->w_grid.Columns - win_col_off(wp))),
- (uint16_t)wp->w_grid.Rows);
+ terminal_check_size(buf->terminal);
}
} else if (buf->b_mod_set
&& buf->b_mod_xlines != 0
@@ -4661,8 +4659,7 @@ win_redr_status_matches (
if (matches == NULL) /* interrupted completion? */
return;
- buf = xmalloc(has_mbyte ? default_grid.Columns * MB_MAXBYTES + 1
- : default_grid.Columns + 1);
+ buf = xmalloc(Columns * MB_MAXBYTES + 1);
if (match == -1) { /* don't show match but original text */
match = 0;
@@ -4683,13 +4680,13 @@ win_redr_status_matches (
if (first_match > 0)
clen += 2;
// jumping right, put match at the left
- if ((long)clen > default_grid.Columns) {
+ if ((long)clen > Columns) {
first_match = match;
/* if showing the last match, we can add some on the left */
clen = 2;
for (i = match; i < num_matches; ++i) {
clen += status_match_len(xp, L_MATCH(i)) + 2;
- if ((long)clen >= default_grid.Columns) {
+ if ((long)clen >= Columns) {
break;
}
}
@@ -4700,7 +4697,7 @@ win_redr_status_matches (
if (add_left)
while (first_match > 0) {
clen += status_match_len(xp, L_MATCH(first_match - 1)) + 2;
- if ((long)clen >= default_grid.Columns) {
+ if ((long)clen >= Columns) {
break;
}
first_match--;
@@ -4718,8 +4715,7 @@ win_redr_status_matches (
clen = len;
i = first_match;
- while ((long)(clen + status_match_len(xp, L_MATCH(i)) + 2)
- < default_grid.Columns) {
+ while ((long)(clen + status_match_len(xp, L_MATCH(i)) + 2) < Columns) {
if (i == match) {
selstart = buf + len;
selstart_col = clen;
@@ -4770,7 +4766,7 @@ win_redr_status_matches (
if (msg_scrolled > 0) {
/* Put the wildmenu just above the command line. If there is
* no room, scroll the screen one line up. */
- if (cmdline_row == default_grid.Rows - 1) {
+ if (cmdline_row == Rows - 1) {
grid_del_lines(&default_grid, 0, 1, (int)Rows, 0, (int)Columns);
msg_scrolled++;
} else {
@@ -4799,7 +4795,7 @@ win_redr_status_matches (
grid_puts(&default_grid, selstart, row, selstart_col, HL_ATTR(HLF_WM));
}
- grid_fill(&default_grid, row, row + 1, clen, (int)default_grid.Columns,
+ grid_fill(&default_grid, row, row + 1, clen, (int)Columns,
fillchar, fillchar, attr);
}
@@ -5065,7 +5061,7 @@ win_redr_custom (
row = 0;
fillchar = ' ';
attr = HL_ATTR(HLF_TPF);
- maxwidth = default_grid.Columns;
+ maxwidth = Columns;
use_sandbox = was_set_insecurely((char_u *)"tabline", 0);
} else {
row = W_ENDROW(wp);
@@ -5084,13 +5080,13 @@ win_redr_custom (
if (*stl++ != '(')
stl = p_ruf;
}
- col = ru_col - (default_grid.Columns - wp->w_width);
+ col = ru_col - (Columns - wp->w_width);
if (col < (wp->w_width + 1) / 2) {
col = (wp->w_width + 1) / 2;
}
maxwidth = wp->w_width - col;
if (!wp->w_status_height) {
- row = default_grid.Rows - 1;
+ row = Rows - 1;
maxwidth--; // writing in last column may cause scrolling
fillchar = ' ';
attr = 0;
@@ -5184,7 +5180,7 @@ win_redr_custom (
p = (char_u *) tabtab[n].start;
cur_click_def = tabtab[n].def;
}
- while (col < default_grid.Columns) {
+ while (col < Columns) {
tab_page_click_defs[col++] = cur_click_def;
}
}
@@ -5883,7 +5879,7 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col,
}
// TODO(bfredl): The relevant caller should do this
- if (row == default_grid.Rows - 1) { // overwritten the command line
+ if (row == Rows - 1) { // overwritten the command line
redraw_cmdline = true;
if (start_col == 0 && end_col == Columns
&& c1 == ' ' && c2 == ' ' && attr == 0) {
@@ -5934,15 +5930,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);
@@ -5952,20 +5941,24 @@ void win_grid_alloc(win_T *wp)
grid_invalidate(grid);
}
+ if (grid->Rows != rows) {
+ wp->w_lines_valid = 0;
+ xfree(wp->w_lines);
+ wp->w_lines = xcalloc(rows+1, sizeof(wline_T));
+ }
+
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);
- win_free_lsize(wp);
- win_alloc_lines(wp);
+ grid_alloc(grid, rows, cols, true);
} else {
// Single grid mode, all rendering will be redirected to default_grid.
// 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;
}
@@ -6050,28 +6043,16 @@ retry:
// If anything fails, make grid arrays NULL, so we don't do anything!
// Continuing with the old arrays may result in a crash, because the
// size is wrong.
- FOR_ALL_TAB_WINDOWS(tp, wp) {
- win_free_lsize(wp);
- }
- if (aucmd_win != NULL)
- win_free_lsize(aucmd_win);
grid_alloc(&default_grid, Rows, Columns, !doclear);
StlClickDefinition *new_tab_page_click_defs = xcalloc(
(size_t)Columns, sizeof(*new_tab_page_click_defs));
- FOR_ALL_TAB_WINDOWS(tp, wp) {
- win_alloc_lines(wp);
- }
- if (aucmd_win != NULL && aucmd_win->w_lines == NULL) {
- win_alloc_lines(aucmd_win);
- }
-
clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size);
xfree(tab_page_click_defs);
tab_page_click_defs = new_tab_page_click_defs;
- tab_page_click_defs_size = default_grid.Columns;
+ tab_page_click_defs_size = Columns;
default_grid.row_offset = 0;
default_grid.col_offset = 0;
@@ -6269,7 +6250,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);
}
@@ -6477,7 +6458,7 @@ int showmode(void)
/* if the cmdline is more than one line high, erase top lines */
need_clear = clear_cmdline;
- if (clear_cmdline && cmdline_row < default_grid.Rows - 1) {
+ if (clear_cmdline && cmdline_row < Rows - 1) {
msg_clr_cmdline(); // will reset clear_cmdline
}
@@ -6497,7 +6478,7 @@ int showmode(void)
if (edit_submode != NULL && !shortmess(SHM_COMPLETIONMENU)) {
/* These messages can get long, avoid a wrap in a narrow
* window. Prefer showing edit_submode_extra. */
- length = (default_grid.Rows - msg_row) * default_grid.Columns - 3;
+ length = (Rows - msg_row) * Columns - 3;
if (edit_submode_extra != NULL) {
length -= vim_strsize(edit_submode_extra);
}
@@ -6621,7 +6602,7 @@ int showmode(void)
static void msg_pos_mode(void)
{
msg_col = 0;
- msg_row = default_grid.Rows - 1;
+ msg_row = Rows - 1;
}
/// Delete mode message. Used when ESC is typed which is expected to end
@@ -6695,7 +6676,7 @@ static void draw_tabline(void)
// Init TabPageIdxs[] to zero: Clicking outside of tabs has no effect.
- assert(default_grid.Columns == tab_page_click_defs_size);
+ assert(Columns == tab_page_click_defs_size);
clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size);
/* Use the 'tabline' option if it's set. */
@@ -6717,7 +6698,7 @@ static void draw_tabline(void)
}
if (tabcount > 0) {
- tabwidth = (default_grid.Columns - 1 + tabcount / 2) / tabcount;
+ tabwidth = (Columns - 1 + tabcount / 2) / tabcount;
}
if (tabwidth < 6) {
@@ -6728,7 +6709,7 @@ static void draw_tabline(void)
tabcount = 0;
FOR_ALL_TABS(tp) {
- if (col >= default_grid.Columns - 4) {
+ if (col >= Columns - 4) {
break;
}
@@ -6769,7 +6750,7 @@ static void draw_tabline(void)
if (wincount > 1) {
vim_snprintf((char *)NameBuff, MAXPATHL, "%d", wincount);
len = (int)STRLEN(NameBuff);
- if (col + len >= default_grid.Columns - 3) {
+ if (col + len >= Columns - 3) {
break;
}
grid_puts_len(&default_grid, NameBuff, len, 0, col,
@@ -6798,8 +6779,8 @@ static void draw_tabline(void)
p += len - room;
len = room;
}
- if (len > default_grid.Columns - col - 1) {
- len = default_grid.Columns - col - 1;
+ if (len > Columns - col - 1) {
+ len = Columns - col - 1;
}
grid_puts_len(&default_grid, p, (int)STRLEN(p), 0, col, attr);
@@ -6823,14 +6804,14 @@ static void draw_tabline(void)
c = '_';
else
c = ' ';
- grid_fill(&default_grid, 0, 1, col, (int)default_grid.Columns, c, c,
+ grid_fill(&default_grid, 0, 1, col, (int)Columns, c, c,
attr_fill);
/* Put an "X" for closing the current tab if there are several. */
if (first_tabpage->tp_next != NULL) {
- grid_putchar(&default_grid, 'X', 0, (int)default_grid.Columns - 1,
+ grid_putchar(&default_grid, 'X', 0, (int)Columns - 1,
attr_nosel);
- tab_page_click_defs[default_grid.Columns - 1] = (StlClickDefinition) {
+ tab_page_click_defs[Columns - 1] = (StlClickDefinition) {
.type = kStlClickTabClose,
.tabnr = 999,
.func = NULL,
@@ -7026,10 +7007,10 @@ static void win_redr_ruler(win_T *wp, int always)
off = wp->w_wincol;
width = wp->w_width;
} else {
- row = default_grid.Rows - 1;
+ row = Rows - 1;
fillchar = ' ';
attr = 0;
- width = default_grid.Columns;
+ width = Columns;
off = 0;
}
@@ -7067,7 +7048,7 @@ static void win_redr_ruler(win_T *wp, int always)
if (wp->w_status_height == 0) { // can't use last char of screen
o++;
}
- int this_ru_col = ru_col - (default_grid.Columns - width);
+ int this_ru_col = ru_col - (Columns - width);
if (this_ru_col < 0) {
this_ru_col = 0;
}
@@ -7122,7 +7103,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 eae0f7ca13..6516f46b2f 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -334,41 +334,32 @@ void terminal_close(Terminal *term, char *msg)
}
}
-void terminal_resize(Terminal *term, uint16_t width, uint16_t height)
+void terminal_check_size(Terminal *term)
{
if (term->closed) {
- // If two windows display the same terminal and one is closed by keypress.
return;
}
- bool force = width == UINT16_MAX || height == UINT16_MAX;
+
int curwidth, curheight;
vterm_get_size(term->vt, &curheight, &curwidth);
+ uint16_t width = 0, height = 0;
- if (force || !width) {
- width = (uint16_t)curwidth;
- }
-
- if (force || !height) {
- height = (uint16_t)curheight;
- }
-
- if (!force && curheight == height && curwidth == width) {
- return;
- }
-
- if (height == 0 || width == 0) {
- return;
- }
FOR_ALL_TAB_WINDOWS(tp, wp) {
if (wp->w_buffer && wp->w_buffer->terminal == term) {
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);
}
}
+ // if no window displays the terminal, or such all windows are zero-height,
+ // don't resize the terminal.
+ if ((curheight == height && curwidth == width) || height == 0 || width == 0) {
+ return;
+ }
+
vterm_set_size(term->vt, height, width);
vterm_screen_flush_damage(term->vts);
term->pending_resize = true;
@@ -383,8 +374,10 @@ void terminal_enter(void)
memset(s, 0, sizeof(TerminalState));
s->term = buf->terminal;
- // Ensure the terminal is properly sized.
- terminal_resize(s->term, 0, 0);
+ // Ensure the terminal is properly sized. Ideally window size management
+ // code should always have resized the terminal already, but check here to
+ // be sure.
+ terminal_check_size(s->term);
int save_state = State;
s->save_rd = RedrawingDisabled;
diff --git a/src/nvim/testdir/test_menu.vim b/src/nvim/testdir/test_menu.vim
index af18760065..055d944b15 100644
--- a/src/nvim/testdir/test_menu.vim
+++ b/src/nvim/testdir/test_menu.vim
@@ -1,9 +1,32 @@
" Test that the system menu can be loaded.
+if !has('menu')
+ finish
+endif
+
func Test_load_menu()
try
source $VIMRUNTIME/menu.vim
catch
call assert_report('error while loading menus: ' . v:exception)
endtry
+ call assert_match('browse confirm w', execute(':menu File.Save'))
+ source $VIMRUNTIME/delmenu.vim
+endfunc
+
+func Test_translate_menu()
+ if !has('multi_lang')
+ return
+ endif
+ if !filereadable($VIMRUNTIME . '/lang/menu_de_de.latin1.vim')
+ throw 'Skipped: translated menu not found'
+ endif
+
+ " First delete any English menus.
+ source $VIMRUNTIME/delmenu.vim
+ set langmenu=de_de
+ source $VIMRUNTIME/menu.vim
+ call assert_match('browse confirm w', execute(':menu Datei.Speichern'))
+
+ source $VIMRUNTIME/delmenu.vim
endfunc
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index 73d45d8192..b65f3be746 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 a2e3825274..91a983e4c7 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;
}
@@ -3889,7 +3891,6 @@ static win_T *win_alloc(win_T *after, int hidden)
// allocate window structure and linesizes arrays
win_T *new_wp = xcalloc(1, sizeof(win_T));
- win_alloc_lines(new_wp);
new_wp->handle = ++last_win_id;
handle_register_window(new_wp);
@@ -3970,7 +3971,7 @@ win_free (
}
}
- win_free_lsize(wp);
+ xfree(wp->w_lines);
for (i = 0; i < wp->w_tagstacklen; ++i)
xfree(wp->w_tagstack[i].tagname);
@@ -4118,28 +4119,6 @@ static void frame_remove(frame_T *frp)
/*
- * Allocate w_lines[] for window "wp".
- */
-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));
-}
-
-/*
- * free lsize arrays for a window
- */
-void win_free_lsize(win_T *wp)
-{
- // TODO: why would wp be NULL here?
- if (wp != NULL) {
- xfree(wp->w_lines);
- wp->w_lines = NULL;
- }
-}
-
-/*
* Called from win_new_shellsize() after Rows changed.
* This only does the current tab page, others must be done when made active.
*/
@@ -4876,9 +4855,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 +4868,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 +4909,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 +4922,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,21 +4982,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_resize(wp->w_buffer->terminal, 0, wp->w_height);
- 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);
}
}
@@ -5046,24 +5041,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_resize.
- 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_resize(wp->w_buffer->terminal,
- (uint16_t)(MAX(0, wp->w_width - win_col_off(wp))),
- 0);
- }
- }
wp->w_pos_changed = true;
}