multigrid: rename grid->ScreenLines and other grid arrays

This commit is contained in:
Björn Linse
2018-12-31 13:29:58 +01:00
parent c778c2e107
commit c72d9ce0a6
9 changed files with 170 additions and 181 deletions

View File

@@ -1924,9 +1924,9 @@ Array nvim__inspect_cell(Integer row, Integer col, Error *err)
|| col < 0 || col >= default_grid.Columns) { || col < 0 || col >= default_grid.Columns) {
return ret; return ret;
} }
size_t off = default_grid.LineOffset[(size_t)row] + (size_t)col; size_t off = default_grid.line_offset[(size_t)row] + (size_t)col;
ADD(ret, STRING_OBJ(cstr_to_string((char *)default_grid.ScreenLines[off]))); ADD(ret, STRING_OBJ(cstr_to_string((char *)default_grid.chars[off])));
int attr = default_grid.ScreenAttrs[off]; int attr = default_grid.attrs[off];
ADD(ret, DICTIONARY_OBJ(hl_get_attr_by_id(attr, true, err))); ADD(ret, DICTIONARY_OBJ(hl_get_attr_by_id(attr, true, err)));
// will not work first time // will not work first time
if (!highlight_use_hlstate()) { if (!highlight_use_hlstate()) {

View File

@@ -1494,7 +1494,7 @@ void edit_putchar(int c, int highlight)
{ {
int attr; int attr;
if (curwin->w_grid.ScreenLines != NULL || default_grid.ScreenLines != NULL) { if (curwin->w_grid.chars != NULL || default_grid.chars != NULL) {
update_topline(); // just in case w_topline isn't valid update_topline(); // just in case w_topline isn't valid
validate_cursor(); validate_cursor();
if (highlight) { if (highlight) {

View File

@@ -14027,7 +14027,7 @@ static void f_screenattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|| col < 0 || col >= default_grid.Columns) { || col < 0 || col >= default_grid.Columns) {
c = -1; c = -1;
} else { } else {
c = default_grid.ScreenAttrs[default_grid.LineOffset[row] + col]; c = default_grid.attrs[default_grid.line_offset[row] + col];
} }
rettv->vval.v_number = c; rettv->vval.v_number = c;
} }
@@ -14046,8 +14046,8 @@ static void f_screenchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|| col < 0 || col >= default_grid.Columns) { || col < 0 || col >= default_grid.Columns) {
c = -1; c = -1;
} else { } else {
off = default_grid.LineOffset[row] + col; off = default_grid.line_offset[row] + col;
c = utf_ptr2char(default_grid.ScreenLines[off]); c = utf_ptr2char(default_grid.chars[off]);
} }
rettv->vval.v_number = c; rettv->vval.v_number = c;
} }

View File

@@ -92,7 +92,7 @@ EXTERN struct nvim_stats_s {
* Number of Rows and Columns in the screen. * Number of Rows and Columns in the screen.
* Must be long to be able to use them as options in option.c. * Must be long to be able to use them as options in option.c.
* Note: Use default_grid.Rows and default_grid.Columns to access items in * Note: Use default_grid.Rows and default_grid.Columns to access items in
* default_grid.ScreenLines[]. They may have different values when the screen * default_grid.chars[]. They may have different values when the screen
* wasn't (re)allocated yet after setting Rows or Columns (e.g., when starting * wasn't (re)allocated yet after setting Rows or Columns (e.g., when starting
* up). * up).
*/ */
@@ -190,11 +190,8 @@ EXTERN int compl_cont_status INIT(= 0);
# define CONT_LOCAL 32 /* for ctrl_x_mode 0, ^X^P/^X^N do a local # define CONT_LOCAL 32 /* for ctrl_x_mode 0, ^X^P/^X^N do a local
* expansion, (eg use complete=.) */ * expansion, (eg use complete=.) */
/* // state for putting characters in the message area
* Functions for putting characters in the command line, EXTERN int cmdmsg_rl INIT(= false); // cmdline is drawn right to left
* while keeping ScreenLines[] updated.
*/
EXTERN int cmdmsg_rl INIT(= FALSE); /* cmdline is drawn right to left */
EXTERN int msg_col; EXTERN int msg_col;
EXTERN int msg_row; EXTERN int msg_row;
EXTERN int msg_scrolled; /* Number of screen lines that windows have EXTERN int msg_scrolled; /* Number of screen lines that windows have

View File

@@ -13,7 +13,7 @@ typedef int16_t sattr_T;
/// ScreenGrid represents a resizable rectuangular grid displayed by UI clients. /// ScreenGrid represents a resizable rectuangular grid displayed by UI clients.
/// ///
/// ScreenLines contains the UTF-8 text that is currently displayed on the grid. /// chars[] contains the UTF-8 text that is currently displayed on the grid.
/// It is stored as a single block of cells. When redrawing a part of the grid, /// It is stored as a single block of cells. When redrawing a part of the grid,
/// the new state can be compared with the existing state of the grid. This way /// the new state can be compared with the existing state of the grid. This way
/// we can avoid sending bigger updates than neccessary to the Ul layer. /// we can avoid sending bigger updates than neccessary to the Ul layer.
@@ -26,20 +26,20 @@ typedef int16_t sattr_T;
/// and the right cell should only contain the empty string. When a part of the /// and the right cell should only contain the empty string. When a part of the
/// screen is cleared, the cells should be filled with a single whitespace char. /// screen is cleared, the cells should be filled with a single whitespace char.
/// ///
/// ScreenAttrs[] contains the highlighting attribute for each cell. /// attrs[] contains the highlighting attribute for each cell.
/// LineOffset[n] is the offset from ScreenLines[] and ScreenAttrs[] for the /// line_offset[n] is the offset from chars[] and attrs[] for the
/// start of line 'n'. These offsets are in general not linear, as full screen /// start of line 'n'. These offsets are in general not linear, as full screen
/// scrolling is implemented by rotating the offsets in the LineOffset array. /// scrolling is implemented by rotating the offsets in the line_offset array.
/// LineWraps[] is an array of boolean flags indicating if the screen line wraps /// line_wraps[] is an array of boolean flags indicating if the screen line
/// to the next line. It can only be true if a window occupies the entire screen /// wraps to the next line. It can only be true if a window occupies the entire
/// width. /// screen width.
typedef struct { typedef struct {
handle_T handle; handle_T handle;
schar_T *ScreenLines; schar_T *chars;
sattr_T *ScreenAttrs; sattr_T *attrs;
unsigned *LineOffset; unsigned *line_offset;
char_u *LineWraps; char_u *line_wraps;
// the size of the allocated grid. // the size of the allocated grid.
int Rows; int Rows;

View File

@@ -110,8 +110,8 @@ retnomove:
// Remember the character under the mouse, it might be a '-' or '+' in the // Remember the character under the mouse, it might be a '-' or '+' in the
// fold column. NB: only works for ASCII chars! // fold column. NB: only works for ASCII chars!
if (row >= 0 && row < Rows && col >= 0 && col <= Columns if (row >= 0 && row < Rows && col >= 0 && col <= Columns
&& default_grid.ScreenLines != NULL) { && default_grid.chars != NULL) {
mouse_char = default_grid.ScreenLines[default_grid.LineOffset[row] mouse_char = default_grid.chars[default_grid.line_offset[row]
+ (unsigned)col][0]; + (unsigned)col][0];
} else { } else {
mouse_char = ' '; mouse_char = ' ';

View File

@@ -7,8 +7,7 @@
// by remembering what is already on the screen, and only updating the parts // by remembering what is already on the screen, and only updating the parts
// that changed. // that changed.
// //
// The screen_*() functions write to the screen and handle updating // The grid_*() functions write to the screen and handle updating grid->lines[].
// ScreenLines[].
// //
// update_screen() is the function that updates all windows and status lines. // update_screen() is the function that updates all windows and status lines.
// It is called from the main loop when must_redraw is non-zero. It may be // It is called from the main loop when must_redraw is non-zero. It may be
@@ -253,12 +252,12 @@ void update_curbuf(int type)
update_screen(type); update_screen(type);
} }
/* /// Redraw the parts of the screen that is marked for redraw.
* update_screen() ///
* /// Most code shouldn't call this directly, rather use redraw_later() and
* Based on the current value of curwin->w_topline, transfer a screenfull /// and redraw_all_later() to mark parts of the screen as needing a redraw.
* of stuff from Filemem to ScreenLines[], and update curwin->w_botline. ///
*/ /// @param type set to a NOT_VALID to force redraw of entire screen
void update_screen(int type) void update_screen(int type)
{ {
static int did_intro = FALSE; static int did_intro = FALSE;
@@ -2046,7 +2045,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
} }
/// Copy "buf[len]" to ScreenLines["off"] and set attributes to "attr". /// Copy "buf[len]" to linebuf_char["off"] and set attributes to "attr".
/// ///
/// Only works for ASCII text! /// Only works for ASCII text!
static void copy_text_attr(int off, char_u *buf, int len, int attr) static void copy_text_attr(int off, char_u *buf, int len, int attr)
@@ -3529,8 +3528,7 @@ win_line (
*/ */
if (!vim_isprintc(c)) { if (!vim_isprintc(c)) {
// when getting a character from the file, we may have to // when getting a character from the file, we may have to
// turn it into something else on the way to putting it // turn it into something else on the way to putting it on the screen.
// into "ScreenLines".
if (c == TAB && (!wp->w_p_list || lcs_tab1)) { if (c == TAB && (!wp->w_p_list || lcs_tab1)) {
int tab_len = 0; int tab_len = 0;
long vcol_adjusted = vcol; // removed showbreak length long vcol_adjusted = vcol; // removed showbreak length
@@ -4274,10 +4272,10 @@ win_line (
} }
// Force a redraw of the first column of the next line. // Force a redraw of the first column of the next line.
current_grid->ScreenAttrs[current_grid->LineOffset[current_row+1]] = -1; current_grid->attrs[current_grid->line_offset[current_row+1]] = -1;
// Remember that the line wraps, used for modeless copy. // Remember that the line wraps, used for modeless copy.
current_grid->LineWraps[current_row] = true; current_grid->line_wraps[current_row] = true;
} }
boguscols = 0; boguscols = 0;
@@ -4352,11 +4350,11 @@ static int grid_char_needs_redraw(ScreenGrid *grid, int off_from, int off_to,
int cols) int cols)
{ {
return (cols > 0 return (cols > 0
&& ((schar_cmp(linebuf_char[off_from], grid->ScreenLines[off_to]) && ((schar_cmp(linebuf_char[off_from], grid->chars[off_to])
|| linebuf_attr[off_from] != grid->ScreenAttrs[off_to] || linebuf_attr[off_from] != grid->attrs[off_to]
|| (line_off2cells(linebuf_char, off_from, off_from + cols) > 1 || (line_off2cells(linebuf_char, off_from, off_from + cols) > 1
&& schar_cmp(linebuf_char[off_from + 1], && schar_cmp(linebuf_char[off_from + 1],
grid->ScreenLines[off_to + 1]))) grid->chars[off_to + 1])))
|| p_wd < 0)); || p_wd < 0));
} }
@@ -4403,16 +4401,16 @@ static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol,
} }
off_from = 0; off_from = 0;
off_to = grid->LineOffset[row] + coloff; off_to = grid->line_offset[row] + coloff;
max_off_from = linebuf_size; max_off_from = linebuf_size;
max_off_to = grid->LineOffset[row] + grid->Columns; max_off_to = grid->line_offset[row] + grid->Columns;
if (rlflag) { if (rlflag) {
/* Clear rest first, because it's left of the text. */ /* Clear rest first, because it's left of the text. */
if (clear_width > 0) { if (clear_width > 0) {
while (col <= endcol && grid->ScreenLines[off_to][0] == ' ' while (col <= endcol && grid->chars[off_to][0] == ' '
&& grid->ScreenLines[off_to][1] == NUL && grid->chars[off_to][1] == NUL
&& grid->ScreenAttrs[off_to] == bg_attr && grid->attrs[off_to] == bg_attr
) { ) {
++off_to; ++off_to;
++col; ++col;
@@ -4423,7 +4421,7 @@ static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol,
} }
} }
col = endcol + 1; col = endcol + 1;
off_to = grid->LineOffset[row] + col + coloff; off_to = grid->line_offset[row] + col + coloff;
off_from += col; off_from += col;
endcol = (clear_width > 0 ? clear_width : -clear_width); endcol = (clear_width > 0 ? clear_width : -clear_width);
} }
@@ -4466,16 +4464,16 @@ static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol,
clear_next = true; clear_next = true;
} }
schar_copy(grid->ScreenLines[off_to], linebuf_char[off_from]); schar_copy(grid->chars[off_to], linebuf_char[off_from]);
if (char_cells == 2) { if (char_cells == 2) {
schar_copy(grid->ScreenLines[off_to+1], linebuf_char[off_from+1]); schar_copy(grid->chars[off_to+1], linebuf_char[off_from+1]);
} }
grid->ScreenAttrs[off_to] = linebuf_attr[off_from]; grid->attrs[off_to] = linebuf_attr[off_from];
// For simplicity set the attributes of second half of a // For simplicity set the attributes of second half of a
// double-wide character equal to the first half. // double-wide character equal to the first half.
if (char_cells == 2) { if (char_cells == 2) {
grid->ScreenAttrs[off_to + 1] = linebuf_attr[off_from]; grid->attrs[off_to + 1] = linebuf_attr[off_from];
} }
} }
@@ -4487,7 +4485,7 @@ static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol,
if (clear_next) { if (clear_next) {
/* Clear the second half of a double-wide character of which the left /* Clear the second half of a double-wide character of which the left
* half was overwritten with a single-wide character. */ * half was overwritten with a single-wide character. */
schar_from_ascii(grid->ScreenLines[off_to], ' '); schar_from_ascii(grid->chars[off_to], ' ');
end_dirty++; end_dirty++;
} }
@@ -4496,12 +4494,12 @@ static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol,
// blank out the rest of the line // blank out the rest of the line
// TODO(bfredl): we could cache winline widths // TODO(bfredl): we could cache winline widths
while (col < clear_width) { while (col < clear_width) {
if (grid->ScreenLines[off_to][0] != ' ' if (grid->chars[off_to][0] != ' '
|| grid->ScreenLines[off_to][1] != NUL || grid->chars[off_to][1] != NUL
|| grid->ScreenAttrs[off_to] != bg_attr) { || grid->attrs[off_to] != bg_attr) {
grid->ScreenLines[off_to][0] = ' '; grid->chars[off_to][0] = ' ';
grid->ScreenLines[off_to][1] = NUL; grid->chars[off_to][1] = NUL;
grid->ScreenAttrs[off_to] = bg_attr; grid->attrs[off_to] = bg_attr;
if (start_dirty == -1) { if (start_dirty == -1) {
start_dirty = col; start_dirty = col;
end_dirty = col; end_dirty = col;
@@ -4518,7 +4516,7 @@ static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol,
if (clear_width > 0 || wp->w_width != grid->Columns) { if (clear_width > 0 || wp->w_width != grid->Columns) {
// If we cleared after the end of the line, it did not wrap. // If we cleared after the end of the line, it did not wrap.
// For vsplit, line wrapping is not possible. // For vsplit, line wrapping is not possible.
grid->LineWraps[row] = false; grid->line_wraps[row] = false;
} }
if (clear_end < end_dirty) { if (clear_end < end_dirty) {
@@ -5289,11 +5287,11 @@ static int line_off2cells(schar_T *line, size_t off, size_t max_off)
return (off + 1 < max_off && line[off + 1][0] == 0) ? 2 : 1; return (off + 1 < max_off && line[off + 1][0] == 0) ? 2 : 1;
} }
/// Return number of display cells for char at ScreenLines[off]. /// Return number of display cells for char at grid->chars[off].
/// We make sure that the offset used is less than "max_off". /// We make sure that the offset used is less than "max_off".
static int grid_off2cells(ScreenGrid *grid, size_t off, size_t max_off) static int grid_off2cells(ScreenGrid *grid, size_t off, size_t max_off)
{ {
return line_off2cells(grid->ScreenLines, off, max_off); return line_off2cells(grid->chars, off, max_off);
} }
/// Return true if the character at "row"/"col" on the screen is the left side /// Return true if the character at "row"/"col" on the screen is the left side
@@ -5308,8 +5306,8 @@ bool grid_lefthalve(ScreenGrid *grid, int row, int col)
grid = &default_grid; grid = &default_grid;
} }
return grid_off2cells(grid, grid->LineOffset[row] + col, return grid_off2cells(grid, grid->line_offset[row] + col,
grid->LineOffset[row] + grid->Columns) > 1; grid->line_offset[row] + grid->Columns) > 1;
} }
/// Correct a position on the screen, if it's the right half of a double-wide /// Correct a position on the screen, if it's the right half of a double-wide
@@ -5324,14 +5322,14 @@ int grid_fix_col(ScreenGrid *grid, int col, int row)
} }
col += coloff; col += coloff;
if (grid->ScreenLines != NULL && col > 0 if (grid->chars != NULL && col > 0
&& grid->ScreenLines[grid->LineOffset[row] + col][0] == 0) { && grid->chars[grid->line_offset[row] + col][0] == 0) {
return col - 1 - coloff; return col - 1 - coloff;
} }
return col - coloff; return col - coloff;
} }
/// output a single character directly to the grid and update ScreenLines. /// output a single character directly to the grid
void grid_putchar(ScreenGrid *grid, int c, int row, int col, int attr) void grid_putchar(ScreenGrid *grid, int c, int row, int col, int attr)
{ {
char_u buf[MB_MAXBYTES + 1]; char_u buf[MB_MAXBYTES + 1];
@@ -5340,7 +5338,7 @@ void grid_putchar(ScreenGrid *grid, int c, int row, int col, int attr)
grid_puts(grid, buf, row, col, attr); grid_puts(grid, buf, row, col, attr);
} }
/// get a single character directly from grid.ScreenLines into "bytes[]". /// get a single character directly from grid.chars into "bytes[]".
/// Also return its attribute in *attrp; /// Also return its attribute in *attrp;
void grid_getbytes(ScreenGrid *grid, int row, int col, char_u *bytes, void grid_getbytes(ScreenGrid *grid, int row, int col, char_u *bytes,
int *attrp) int *attrp)
@@ -5354,18 +5352,18 @@ void grid_getbytes(ScreenGrid *grid, int row, int col, char_u *bytes,
} }
// safety check // safety check
if (grid->ScreenLines != NULL && row < grid->Rows && col < grid->Columns) { if (grid->chars != NULL && row < grid->Rows && col < grid->Columns) {
off = grid->LineOffset[row] + col; off = grid->line_offset[row] + col;
*attrp = grid->ScreenAttrs[off]; *attrp = grid->attrs[off];
schar_copy(bytes, grid->ScreenLines[off]); schar_copy(bytes, grid->chars[off]);
} }
} }
/// put string '*text' on the window grid at position 'row' and 'col', with /// put string '*text' on the window grid at position 'row' and 'col', with
/// attributes 'attr', and update ScreenLines[] and ScreenAttrs[]. /// attributes 'attr', and update chars[] and attrs[].
/// Note: only outputs within one row, message is truncated at grid boundary! /// Note: only outputs within one row, message is truncated at grid boundary!
/// Note: if ScreenLines[], row and/or col is invalid, nothing is done. /// Note: if grid, row and/or col is invalid, nothing is done.
void grid_puts(ScreenGrid *grid, char_u *text, int row, int col, int attr) void grid_puts(ScreenGrid *grid, char_u *text, int row, int col, int attr)
{ {
grid_puts_len(grid, text, -1, row, col, attr); grid_puts_len(grid, text, -1, row, col, attr);
@@ -5416,7 +5414,7 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row,
} }
// safety check // safety check
if (grid->ScreenLines == NULL || row >= grid->Rows || col >= grid->Columns) { if (grid->chars == NULL || row >= grid->Rows || col >= grid->Columns) {
return; return;
} }
@@ -5428,13 +5426,13 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row,
abort(); abort();
} }
} }
off = grid->LineOffset[row] + col; off = grid->line_offset[row] + col;
/* When drawing over the right halve of a double-wide char clear out the /* When drawing over the right halve of a double-wide char clear out the
* left halve. Only needed in a terminal. */ * left halve. Only needed in a terminal. */
if (col > 0 && col < grid->Columns && grid_fix_col(grid, col, row) != col) { if (col > 0 && col < grid->Columns && grid_fix_col(grid, col, row) != col) {
schar_from_ascii(grid->ScreenLines[off - 1], ' '); schar_from_ascii(grid->chars[off - 1], ' ');
grid->ScreenAttrs[off - 1] = 0; grid->attrs[off - 1] = 0;
// redraw the previous cell, make it empty // redraw the previous cell, make it empty
if (put_dirty_first == -1) { if (put_dirty_first == -1) {
put_dirty_first = col-1; put_dirty_first = col-1;
@@ -5444,7 +5442,7 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row,
force_redraw_next = true; force_redraw_next = true;
} }
max_off = grid->LineOffset[row] + grid->Columns; max_off = grid->line_offset[row] + grid->Columns;
while (col < grid->Columns while (col < grid->Columns
&& (len < 0 || (int)(ptr - text) < len) && (len < 0 || (int)(ptr - text) < len)
&& *ptr != NUL) { && *ptr != NUL) {
@@ -5492,9 +5490,9 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row,
force_redraw_this = force_redraw_next; force_redraw_this = force_redraw_next;
force_redraw_next = FALSE; force_redraw_next = FALSE;
need_redraw = schar_cmp(grid->ScreenLines[off], buf) need_redraw = schar_cmp(grid->chars[off], buf)
|| (mbyte_cells == 2 && grid->ScreenLines[off + 1][0] != 0) || (mbyte_cells == 2 && grid->chars[off + 1][0] != 0)
|| grid->ScreenAttrs[off] != attr || grid->attrs[off] != attr
|| exmode_active; || exmode_active;
if (need_redraw || force_redraw_this) { if (need_redraw || force_redraw_this) {
@@ -5515,11 +5513,11 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row,
clear_next_cell = true; clear_next_cell = true;
} }
schar_copy(grid->ScreenLines[off], buf); schar_copy(grid->chars[off], buf);
grid->ScreenAttrs[off] = attr; grid->attrs[off] = attr;
if (mbyte_cells == 2) { if (mbyte_cells == 2) {
grid->ScreenLines[off + 1][0] = 0; grid->chars[off + 1][0] = 0;
grid->ScreenAttrs[off + 1] = attr; grid->attrs[off + 1] = attr;
} }
if (put_dirty_first == -1) { if (put_dirty_first == -1) {
put_dirty_first = col; put_dirty_first = col;
@@ -5886,9 +5884,7 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col,
} }
// nothing to do // nothing to do
if (grid->ScreenLines == NULL if (grid->chars == NULL || start_row >= end_row || start_col >= end_col) {
|| start_row >= end_row
|| start_col >= end_col) {
return; return;
} }
@@ -5915,13 +5911,13 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col,
int col = start_col; int col = start_col;
schar_from_char(sc, c1); schar_from_char(sc, c1);
int lineoff = grid->LineOffset[row]; int lineoff = grid->line_offset[row];
for (col = start_col; col < end_col; col++) { for (col = start_col; col < end_col; col++) {
int off = lineoff + col; int off = lineoff + col;
if (schar_cmp(grid->ScreenLines[off], sc) if (schar_cmp(grid->chars[off], sc)
|| grid->ScreenAttrs[off] != attr) { || grid->attrs[off] != attr) {
schar_copy(grid->ScreenLines[off], sc); schar_copy(grid->chars[off], sc);
grid->ScreenAttrs[off] = attr; grid->attrs[off] = attr;
if (dirty_first == INT_MAX) { if (dirty_first == INT_MAX) {
dirty_first = col; dirty_first = col;
} }
@@ -5945,7 +5941,7 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col,
} }
if (end_col == grid->Columns) { if (end_col == grid->Columns) {
grid->LineWraps[row] = false; grid->line_wraps[row] = false;
} }
// TODO(bfredl): The relevant caller should do this // TODO(bfredl): The relevant caller should do this
@@ -5988,7 +5984,7 @@ void check_for_delay(int check_msg_scroll)
int screen_valid(int doclear) int screen_valid(int doclear)
{ {
screenalloc(doclear); // allocate screen buffers if size changed screenalloc(doclear); // allocate screen buffers if size changed
return default_grid.ScreenLines != NULL; return default_grid.chars != NULL;
} }
/// (Re)allocates a window grid if size changed while in ext_multigrid mode. /// (Re)allocates a window grid if size changed while in ext_multigrid mode.
@@ -6012,7 +6008,7 @@ void win_grid_alloc(win_T *wp)
// TODO(bfredl): floating windows should force this to true // TODO(bfredl): floating windows should force this to true
bool want_allocation = ui_is_external(kUIMultigrid); bool want_allocation = ui_is_external(kUIMultigrid);
bool has_allocation = (grid->ScreenLines != NULL); bool has_allocation = (grid->chars != NULL);
if (want_allocation && has_allocation && highlights_invalid) { if (want_allocation && has_allocation && highlights_invalid) {
grid_invalidate(grid); grid_invalidate(grid);
@@ -6059,17 +6055,16 @@ void grid_assign_handle(ScreenGrid *grid)
} }
} }
/* /// Resize the screen to Rows and Columns.
* Resize the shell to Rows and Columns. ///
* Allocate default_grid.ScreenLines[] and associated items. /// Allocate default_grid.chars[] and other grid arrays.
* ///
* There may be some time between setting Rows and Columns and (re)allocating /// There may be some time between setting Rows and Columns and (re)allocating
* default_grid.ScreenLines[]. This happens when starting up and when /// default_grid arrays. This happens when starting up and when
* (manually) changing the shell size. Always use default_grid.Rows and /// (manually) changing the shell size. Always use default_grid.Rows and
* default_grid.Columns to access items in default_grid.ScreenLines[]. Use Rows /// default_grid.Columns to access items in default_grid.chars[]. Use Rows
* and Columns for positioning text etc. where the final size of the shell is /// and Columns for positioning text etc. where the final size of the shell is
* needed. /// needed.
*/
void screenalloc(bool doclear) void screenalloc(bool doclear)
{ {
static bool entered = false; // avoid recursiveness static bool entered = false; // avoid recursiveness
@@ -6079,13 +6074,13 @@ retry:
// Allocation of the screen buffers is done only when the size changes and // Allocation of the screen buffers is done only when the size changes and
// when Rows and Columns have been set and we have started doing full // when Rows and Columns have been set and we have started doing full
// screen stuff. // screen stuff.
if ((default_grid.ScreenLines != NULL if ((default_grid.chars != NULL
&& Rows == default_grid.Rows && Rows == default_grid.Rows
&& Columns == default_grid.Columns && Columns == default_grid.Columns
) )
|| Rows == 0 || Rows == 0
|| Columns == 0 || Columns == 0
|| (!full_screen && default_grid.ScreenLines == NULL)) { || (!full_screen && default_grid.chars == NULL)) {
return; return;
} }
@@ -6108,17 +6103,15 @@ retry:
comp_col(); /* recompute columns for shown command and ruler */ comp_col(); /* recompute columns for shown command and ruler */
/* // We're changing the size of the screen.
* We're changing the size of the screen. // - Allocate new arrays for default_grid
* - Allocate new arrays for ScreenLines and ScreenAttrs. // - Move lines from the old arrays into the new arrays, clear extra
* - Move lines from the old arrays into the new arrays, clear extra // lines (unless the screen is going to be cleared).
* lines (unless the screen is going to be cleared). // - Free the old arrays.
* - Free the old arrays. //
* // If anything fails, make grid arrays NULL, so we don't do anything!
* If anything fails, make ScreenLines NULL, so we don't do anything! // Continuing with the old arrays may result in a crash, because the
* Continuing with the old ScreenLines may result in a crash, because the // size is wrong.
* size is wrong.
*/
FOR_ALL_TAB_WINDOWS(tp, wp) { FOR_ALL_TAB_WINDOWS(tp, wp) {
win_free_lsize(wp); win_free_lsize(wp);
} }
@@ -6172,32 +6165,32 @@ void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy)
ScreenGrid new = *grid; ScreenGrid new = *grid;
size_t ncells = (size_t)((rows+1) * columns); size_t ncells = (size_t)((rows+1) * columns);
new.ScreenLines = xmalloc(ncells * sizeof(schar_T)); new.chars = xmalloc(ncells * sizeof(schar_T));
new.ScreenAttrs = xmalloc(ncells * sizeof(sattr_T)); new.attrs = xmalloc(ncells * sizeof(sattr_T));
new.LineOffset = xmalloc((size_t)(rows * sizeof(unsigned))); new.line_offset = xmalloc((size_t)(rows * sizeof(unsigned)));
new.LineWraps = xmalloc((size_t)(rows * sizeof(char_u))); new.line_wraps = xmalloc((size_t)(rows * sizeof(char_u)));
new.Rows = rows; new.Rows = rows;
new.Columns = columns; new.Columns = columns;
for (new_row = 0; new_row < new.Rows; new_row++) { for (new_row = 0; new_row < new.Rows; new_row++) {
new.LineOffset[new_row] = new_row * new.Columns; new.line_offset[new_row] = new_row * new.Columns;
new.LineWraps[new_row] = false; new.line_wraps[new_row] = false;
grid_clear_line(&new, new.LineOffset[new_row], columns, true); grid_clear_line(&new, new.line_offset[new_row], columns, true);
if (copy) { if (copy) {
// If the screen is not going to be cleared, copy as much as // If the screen is not going to be cleared, copy as much as
// possible from the old screen to the new one and clear the rest // possible from the old screen to the new one and clear the rest
// (used when resizing the window at the "--more--" prompt or when // (used when resizing the window at the "--more--" prompt or when
// executing an external command, for the GUI). // executing an external command, for the GUI).
if (new_row < grid->Rows && grid->ScreenLines != NULL) { if (new_row < grid->Rows && grid->chars != NULL) {
int len = MIN(grid->Columns, new.Columns); int len = MIN(grid->Columns, new.Columns);
memmove(new.ScreenLines + new.LineOffset[new_row], memmove(new.chars + new.line_offset[new_row],
grid->ScreenLines + grid->LineOffset[new_row], grid->chars + grid->line_offset[new_row],
(size_t)len * sizeof(schar_T)); (size_t)len * sizeof(schar_T));
memmove(new.ScreenAttrs + new.LineOffset[new_row], memmove(new.attrs + new.line_offset[new_row],
grid->ScreenAttrs + grid->LineOffset[new_row], grid->attrs + grid->line_offset[new_row],
(size_t)len * sizeof(sattr_T)); (size_t)len * sizeof(sattr_T));
} }
} }
@@ -6218,15 +6211,15 @@ void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy)
void grid_free(ScreenGrid *grid) void grid_free(ScreenGrid *grid)
{ {
xfree(grid->ScreenLines); xfree(grid->chars);
xfree(grid->ScreenAttrs); xfree(grid->attrs);
xfree(grid->LineOffset); xfree(grid->line_offset);
xfree(grid->LineWraps); xfree(grid->line_wraps);
grid->ScreenLines = NULL; grid->chars = NULL;
grid->ScreenAttrs = NULL; grid->attrs = NULL;
grid->LineOffset = NULL; grid->line_offset = NULL;
grid->LineWraps = NULL; grid->line_wraps = NULL;
} }
/// Doesn't allow reinit, so must only be called by free_all_mem! /// Doesn't allow reinit, so must only be called by free_all_mem!
@@ -6265,15 +6258,15 @@ static void screenclear2(void)
{ {
int i; int i;
if (starting == NO_SCREEN || default_grid.ScreenLines == NULL) { if (starting == NO_SCREEN || default_grid.chars == NULL) {
return; return;
} }
// blank out ScreenLines // blank out the default grid
for (i = 0; i < default_grid.Rows; i++) { for (i = 0; i < default_grid.Rows; i++) {
grid_clear_line(&default_grid, default_grid.LineOffset[i], grid_clear_line(&default_grid, default_grid.line_offset[i],
(int)default_grid.Columns, true); (int)default_grid.Columns, true);
default_grid.LineWraps[i] = false; default_grid.line_wraps[i] = false;
} }
ui_call_grid_clear(1); // clear the display ui_call_grid_clear(1); // clear the display
@@ -6300,28 +6293,27 @@ static void grid_clear_line(ScreenGrid *grid, unsigned off, int width,
bool valid) bool valid)
{ {
for (int col = 0; col < width; col++) { for (int col = 0; col < width; col++) {
schar_from_ascii(grid->ScreenLines[off + col], ' '); schar_from_ascii(grid->chars[off + col], ' ');
} }
int fill = valid ? 0 : -1; int fill = valid ? 0 : -1;
(void)memset(grid->ScreenAttrs + off, fill, (size_t)width * sizeof(sattr_T)); (void)memset(grid->attrs + off, fill, (size_t)width * sizeof(sattr_T));
} }
static void grid_invalidate(ScreenGrid *grid) static void grid_invalidate(ScreenGrid *grid)
{ {
(void)memset(grid->ScreenAttrs, -1, (void)memset(grid->attrs, -1, grid->Rows * grid->Columns * sizeof(sattr_T));
grid->Rows * grid->Columns * sizeof(sattr_T));
} }
/// Copy part of a Screenline for vertically split window. /// Copy part of a grid line for vertically split window.
static void linecopy(ScreenGrid *grid, int to, int from, int col, int width) static void linecopy(ScreenGrid *grid, int to, int from, int col, int width)
{ {
unsigned off_to = grid->LineOffset[to] + col; unsigned off_to = grid->line_offset[to] + col;
unsigned off_from = grid->LineOffset[from] + col; unsigned off_from = grid->line_offset[from] + col;
memmove(grid->ScreenLines + off_to, grid->ScreenLines + off_from, memmove(grid->chars + off_to, grid->chars + off_from,
width * sizeof(schar_T)); width * sizeof(schar_T));
memmove(grid->ScreenAttrs + off_to, grid->ScreenAttrs + off_from, memmove(grid->attrs + off_to, grid->attrs + off_from,
width * sizeof(sattr_T)); width * sizeof(sattr_T));
} }
@@ -6397,7 +6389,7 @@ static int win_do_lines(win_T *wp, int row, int line_count, int del)
*/ */
/// insert lines on the screen and update ScreenLines[] /// insert lines on the screen and move the existing lines down
/// 'line_count' is the number of lines to be inserted. /// 'line_count' is the number of lines to be inserted.
/// 'end' is the line after the scrolled part. Normally it is Rows. /// 'end' is the line after the scrolled part. Normally it is Rows.
/// 'col' is the column from with we start inserting. /// 'col' is the column from with we start inserting.
@@ -6424,8 +6416,8 @@ int grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
return FAIL; return FAIL;
} }
// Shift LineOffset[] line_count down to reflect the inserted lines. // Shift line_offset[] line_count down to reflect the inserted lines.
// Clear the inserted lines in ScreenLines[]. // Clear the inserted lines.
for (i = 0; i < line_count; i++) { for (i = 0; i < line_count; i++) {
if (width != grid->Columns) { if (width != grid->Columns) {
// need to copy part of a line // need to copy part of a line
@@ -6434,17 +6426,17 @@ int grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
linecopy(grid, j + line_count, j, col, width); linecopy(grid, j + line_count, j, col, width);
} }
j += line_count; j += line_count;
grid_clear_line(grid, grid->LineOffset[j] + col, width, false); grid_clear_line(grid, grid->line_offset[j] + col, width, false);
grid->LineWraps[j] = false; grid->line_wraps[j] = false;
} else { } else {
j = end - 1 - i; j = end - 1 - i;
temp = grid->LineOffset[j]; temp = grid->line_offset[j];
while ((j -= line_count) >= row) { while ((j -= line_count) >= row) {
grid->LineOffset[j + line_count] = grid->LineOffset[j]; grid->line_offset[j + line_count] = grid->line_offset[j];
grid->LineWraps[j + line_count] = grid->LineWraps[j]; grid->line_wraps[j + line_count] = grid->line_wraps[j];
} }
grid->LineOffset[j + line_count] = temp; grid->line_offset[j + line_count] = temp;
grid->LineWraps[j + line_count] = false; grid->line_wraps[j + line_count] = false;
grid_clear_line(grid, temp, (int)grid->Columns, false); grid_clear_line(grid, temp, (int)grid->Columns, false);
} }
} }
@@ -6454,7 +6446,7 @@ int grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
return OK; return OK;
} }
/// delete lines on the screen and update ScreenLines[] /// delete lines on the screen and move lines up.
/// 'end' is the line after the scrolled part. Normally it is Rows. /// 'end' is the line after the scrolled part. Normally it is Rows.
/// When scrolling region used 'off' is the offset from the top for the region. /// When scrolling region used 'off' is the offset from the top for the region.
/// 'row' and 'end' are relative to the start of the region. /// 'row' and 'end' are relative to the start of the region.
@@ -6479,8 +6471,8 @@ int grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
return FAIL; return FAIL;
} }
// Now shift LineOffset[] line_count up to reflect the deleted lines. // Now shift line_offset[] line_count up to reflect the deleted lines.
// Clear the inserted lines in ScreenLines[]. // Clear the inserted lines.
for (i = 0; i < line_count; i++) { for (i = 0; i < line_count; i++) {
if (width != grid->Columns) { if (width != grid->Columns) {
// need to copy part of a line // need to copy part of a line
@@ -6489,18 +6481,18 @@ int grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
linecopy(grid, j - line_count, j, col, width); linecopy(grid, j - line_count, j, col, width);
} }
j -= line_count; j -= line_count;
grid_clear_line(grid, grid->LineOffset[j] + col, width, false); grid_clear_line(grid, grid->line_offset[j] + col, width, false);
grid->LineWraps[j] = false; grid->line_wraps[j] = false;
} else { } else {
// whole width, moving the line pointers is faster // whole width, moving the line pointers is faster
j = row + i; j = row + i;
temp = grid->LineOffset[j]; temp = grid->line_offset[j];
while ((j += line_count) <= end - 1) { while ((j += line_count) <= end - 1) {
grid->LineOffset[j - line_count] = grid->LineOffset[j]; grid->line_offset[j - line_count] = grid->line_offset[j];
grid->LineWraps[j - line_count] = grid->LineWraps[j]; grid->line_wraps[j - line_count] = grid->line_wraps[j];
} }
grid->LineOffset[j - line_count] = temp; grid->line_offset[j - line_count] = temp;
grid->LineWraps[j - line_count] = false; grid->line_wraps[j - line_count] = false;
grid_clear_line(grid, temp, (int)grid->Columns, false); grid_clear_line(grid, temp, (int)grid->Columns, false);
} }
} }
@@ -6755,7 +6747,7 @@ static void draw_tabline(void)
int use_sep_chars = (t_colors < 8 int use_sep_chars = (t_colors < 8
); );
if (default_grid.ScreenLines == NULL) { if (default_grid.chars == NULL) {
return; return;
} }
redraw_tabline = false; redraw_tabline = false;
@@ -7280,7 +7272,7 @@ void screen_resize(int width, int height)
* - in Ex mode, don't redraw anything. * - in Ex mode, don't redraw anything.
* - Otherwise, redraw right now, and position the cursor. * - Otherwise, redraw right now, and position the cursor.
* Always need to call update_screen() or screenalloc(), to make * Always need to call update_screen() or screenalloc(), to make
* sure Rows/Columns and the size of ScreenLines[] is correct! * sure Rows/Columns and the size of the screen is correct!
*/ */
if (State == ASKMORE || State == EXTERNCMD || State == CONFIRM if (State == ASKMORE || State == EXTERNCMD || State == CONFIRM
|| exmode_active) { || exmode_active) {

View File

@@ -320,14 +320,14 @@ void ui_set_ext_option(UI *ui, UIExtension ext, bool active)
void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol, void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol,
int clearattr, bool wrap) int clearattr, bool wrap)
{ {
size_t off = grid->LineOffset[row] + (size_t)startcol; size_t off = grid->line_offset[row] + (size_t)startcol;
int row_off = ui_is_external(kUIMultigrid) ? 0 : grid->row_offset; int row_off = ui_is_external(kUIMultigrid) ? 0 : grid->row_offset;
int col_off = ui_is_external(kUIMultigrid) ? 0 : grid->col_offset; int col_off = ui_is_external(kUIMultigrid) ? 0 : grid->col_offset;
UI_CALL(raw_line, grid->handle, row_off + row, col_off + startcol, UI_CALL(raw_line, grid->handle, row_off + row, col_off + startcol,
col_off + endcol, col_off + clearcol, clearattr, wrap, col_off + endcol, col_off + clearcol, clearattr, wrap,
(const schar_T *)grid->ScreenLines + off, (const schar_T *)grid->chars + off,
(const sattr_T *)grid->ScreenAttrs + off); (const sattr_T *)grid->attrs + off);
if (p_wd) { // 'writedelay': flush & delay each time. if (p_wd) { // 'writedelay': flush & delay each time.
int old_row = row, old_col = col; int old_row = row, old_col = col;

View File

@@ -6096,7 +6096,7 @@ void win_ui_flush(void)
} }
FOR_ALL_TAB_WINDOWS(tp, wp) { FOR_ALL_TAB_WINDOWS(tp, wp) {
if (wp->w_pos_changed && wp->w_grid.ScreenLines != NULL) { if (wp->w_pos_changed && wp->w_grid.chars != NULL) {
if (tp == curtab) { if (tp == curtab) {
ui_call_win_pos(wp->w_grid.handle, wp->handle, wp->w_winrow, ui_call_win_pos(wp->w_grid.handle, wp->handle, wp->w_winrow,
wp->w_wincol, wp->w_width, wp->w_height); wp->w_wincol, wp->w_width, wp->w_height);