mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
fix(redraw): make redrawdebug=nodelta handle all the cases
Before only win_line lines were considered. this applies nodelta to all screen elements. Causes some failures, which might indeed indicate excessive redraws.
This commit is contained in:
parent
00cfc1dceb
commit
93b30582db
@ -75,12 +75,11 @@ void decor_redraw(buf_T *buf, int row1, int row2, Decoration *decor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (decor && decor_virt_pos(*decor)) {
|
if (decor && decor_virt_pos(*decor)) {
|
||||||
redraw_buf_line_later(buf, row1 + 1);
|
redraw_buf_line_later(buf, row1 + 1, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decor && kv_size(decor->virt_lines)) {
|
if (decor && kv_size(decor->virt_lines)) {
|
||||||
redraw_buf_line_later(buf, MIN(buf->b_ml.ml_line_count,
|
redraw_buf_line_later(buf, row1 + 1 + (decor->virt_lines_above?0:1), true);
|
||||||
row1 + 1 + (decor->virt_lines_above?0:1)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2638,6 +2638,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
|
|||||||
// When the window is too narrow draw all "@" lines.
|
// When the window is too narrow draw all "@" lines.
|
||||||
if (draw_state != WL_LINE && filler_todo <= 0) {
|
if (draw_state != WL_LINE && filler_todo <= 0) {
|
||||||
win_draw_end(wp, '@', ' ', true, row, wp->w_grid.rows, HLF_AT);
|
win_draw_end(wp, '@', ' ', true, row, wp->w_grid.rows, HLF_AT);
|
||||||
|
set_empty_rows(wp, row);
|
||||||
row = endrow;
|
row = endrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1018,6 +1018,9 @@ win_update_start:
|
|||||||
bool scrolled_down = false; // true when scrolled down when w_topline got smaller a bit
|
bool scrolled_down = false; // true when scrolled down when w_topline got smaller a bit
|
||||||
bool top_to_mod = false; // redraw above mod_top
|
bool top_to_mod = false; // redraw above mod_top
|
||||||
|
|
||||||
|
int bot_scroll_start = 999; // first line that needs to be redrawn due to
|
||||||
|
// scrolling. only used for EOB
|
||||||
|
|
||||||
int row; // current window row to display
|
int row; // current window row to display
|
||||||
linenr_T lnum; // current buffer lnum to display
|
linenr_T lnum; // current buffer lnum to display
|
||||||
int idx; // current index in w_lines[]
|
int idx; // current index in w_lines[]
|
||||||
@ -1195,6 +1198,7 @@ win_update_start:
|
|||||||
mod_bot = MAXLNUM;
|
mod_bot = MAXLNUM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wp->w_redraw_top = 0; // reset for next time
|
wp->w_redraw_top = 0; // reset for next time
|
||||||
wp->w_redraw_bot = 0;
|
wp->w_redraw_bot = 0;
|
||||||
|
|
||||||
@ -1265,6 +1269,7 @@ win_update_start:
|
|||||||
// If not the last window, delete the lines at the bottom.
|
// If not the last window, delete the lines at the bottom.
|
||||||
// win_ins_lines may fail when the terminal can't do it.
|
// win_ins_lines may fail when the terminal can't do it.
|
||||||
win_scroll_lines(wp, 0, i);
|
win_scroll_lines(wp, 0, i);
|
||||||
|
bot_scroll_start = 0;
|
||||||
if (wp->w_lines_valid != 0) {
|
if (wp->w_lines_valid != 0) {
|
||||||
// Need to update rows that are new, stop at the
|
// Need to update rows that are new, stop at the
|
||||||
// first one that scrolled down.
|
// first one that scrolled down.
|
||||||
@ -1325,6 +1330,7 @@ win_update_start:
|
|||||||
if (row > 0) {
|
if (row > 0) {
|
||||||
win_scroll_lines(wp, 0, -row);
|
win_scroll_lines(wp, 0, -row);
|
||||||
bot_start = wp->w_grid.rows - row;
|
bot_start = wp->w_grid.rows - row;
|
||||||
|
bot_scroll_start = bot_start;
|
||||||
}
|
}
|
||||||
if ((row == 0 || bot_start < 999) && wp->w_lines_valid != 0) {
|
if ((row == 0 || bot_start < 999) && wp->w_lines_valid != 0) {
|
||||||
// Skip the lines (below the deleted lines) that are still
|
// Skip the lines (below the deleted lines) that are still
|
||||||
@ -1702,6 +1708,7 @@ win_update_start:
|
|||||||
// need to redraw until the end of the window.
|
// need to redraw until the end of the window.
|
||||||
// Inserting/deleting lines has no use.
|
// Inserting/deleting lines has no use.
|
||||||
bot_start = 0;
|
bot_start = 0;
|
||||||
|
bot_scroll_start = 0;
|
||||||
} else {
|
} else {
|
||||||
// Able to count old number of rows: Count new window
|
// Able to count old number of rows: Count new window
|
||||||
// rows, and may insert/delete lines
|
// rows, and may insert/delete lines
|
||||||
@ -1732,6 +1739,7 @@ win_update_start:
|
|||||||
} else {
|
} else {
|
||||||
win_scroll_lines(wp, row, xtra_rows);
|
win_scroll_lines(wp, row, xtra_rows);
|
||||||
bot_start = wp->w_grid.rows + xtra_rows;
|
bot_start = wp->w_grid.rows + xtra_rows;
|
||||||
|
bot_scroll_start = bot_start;
|
||||||
}
|
}
|
||||||
} else if (xtra_rows > 0) {
|
} else if (xtra_rows > 0) {
|
||||||
// May scroll text down. If there is not enough
|
// May scroll text down. If there is not enough
|
||||||
@ -1741,6 +1749,7 @@ win_update_start:
|
|||||||
mod_bot = MAXLNUM;
|
mod_bot = MAXLNUM;
|
||||||
} else {
|
} else {
|
||||||
win_scroll_lines(wp, row + old_rows, xtra_rows);
|
win_scroll_lines(wp, row + old_rows, xtra_rows);
|
||||||
|
bot_scroll_start = 0;
|
||||||
if (top_end > row + old_rows) {
|
if (top_end > row + old_rows) {
|
||||||
// Scrolled the part at the top that requires
|
// Scrolled the part at the top that requires
|
||||||
// updating down.
|
// updating down.
|
||||||
@ -1930,6 +1939,7 @@ win_update_start:
|
|||||||
wp->w_botline = lnum;
|
wp->w_botline = lnum;
|
||||||
} else {
|
} else {
|
||||||
win_draw_end(wp, '@', ' ', true, srow, wp->w_grid.rows, HLF_AT);
|
win_draw_end(wp, '@', ' ', true, srow, wp->w_grid.rows, HLF_AT);
|
||||||
|
set_empty_rows(wp, srow);
|
||||||
wp->w_botline = lnum;
|
wp->w_botline = lnum;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1950,8 +1960,18 @@ win_update_start:
|
|||||||
// Make sure the rest of the screen is blank.
|
// Make sure the rest of the screen is blank.
|
||||||
// write the "eob" character from 'fillchars' to rows that aren't part
|
// write the "eob" character from 'fillchars' to rows that aren't part
|
||||||
// of the file.
|
// of the file.
|
||||||
win_draw_end(wp, wp->w_p_fcs_chars.eob, ' ', false, row, wp->w_grid.rows,
|
// TODO(bfredl): just keep track of the valid EOB area from last redraw?
|
||||||
|
int lastline = bot_scroll_start;
|
||||||
|
if (mid_end >= row) {
|
||||||
|
lastline = MIN(lastline, mid_start);
|
||||||
|
}
|
||||||
|
if (mod_bot > buf->b_ml.ml_line_count + 1) {
|
||||||
|
lastline = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
win_draw_end(wp, wp->w_p_fcs_chars.eob, ' ', false, MAX(lastline, row), wp->w_grid.rows,
|
||||||
HLF_EOB);
|
HLF_EOB);
|
||||||
|
set_empty_rows(wp, row);
|
||||||
}
|
}
|
||||||
|
|
||||||
kvi_destroy(line_providers);
|
kvi_destroy(line_providers);
|
||||||
@ -2063,12 +2083,14 @@ void redraw_buf_later(buf_T *buf, int type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void redraw_buf_line_later(buf_T *buf, linenr_T line)
|
void redraw_buf_line_later(buf_T *buf, linenr_T line, bool force)
|
||||||
{
|
{
|
||||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||||
if (wp->w_buffer == buf
|
if (wp->w_buffer == buf) {
|
||||||
&& line >= wp->w_topline && line < wp->w_botline) {
|
redrawWinline(wp, MIN(line, buf->b_ml.ml_line_count));
|
||||||
redrawWinline(wp, line);
|
if (force && line > buf->b_ml.ml_line_count) {
|
||||||
|
wp->w_redraw_bot = line;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,7 +175,7 @@ void grid_put_schar(ScreenGrid *grid, int row, int col, char *schar, int attr)
|
|||||||
{
|
{
|
||||||
assert(put_dirty_row == row);
|
assert(put_dirty_row == row);
|
||||||
size_t off = grid->line_offset[row] + (size_t)col;
|
size_t off = grid->line_offset[row] + (size_t)col;
|
||||||
if (grid->attrs[off] != attr || schar_cmp(grid->chars[off], schar)) {
|
if (grid->attrs[off] != attr || schar_cmp(grid->chars[off], schar) || rdb_flags & RDB_NODELTA) {
|
||||||
schar_copy(grid->chars[off], schar);
|
schar_copy(grid->chars[off], schar);
|
||||||
grid->attrs[off] = attr;
|
grid->attrs[off] = attr;
|
||||||
|
|
||||||
@ -280,7 +280,8 @@ void grid_puts_len(ScreenGrid *grid, char *text, int textlen, int row, int col,
|
|||||||
need_redraw = schar_cmp(grid->chars[off], buf)
|
need_redraw = schar_cmp(grid->chars[off], buf)
|
||||||
|| (mbyte_cells == 2 && grid->chars[off + 1][0] != 0)
|
|| (mbyte_cells == 2 && grid->chars[off + 1][0] != 0)
|
||||||
|| grid->attrs[off] != attr
|
|| grid->attrs[off] != attr
|
||||||
|| exmode_active;
|
|| exmode_active
|
||||||
|
|| rdb_flags & RDB_NODELTA;
|
||||||
|
|
||||||
if (need_redraw) {
|
if (need_redraw) {
|
||||||
// When at the end of the text and overwriting a two-cell
|
// When at the end of the text and overwriting a two-cell
|
||||||
@ -412,8 +413,7 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int
|
|||||||
size_t lineoff = grid->line_offset[row];
|
size_t lineoff = grid->line_offset[row];
|
||||||
for (col = start_col; col < end_col; col++) {
|
for (col = start_col; col < end_col; col++) {
|
||||||
size_t off = lineoff + (size_t)col;
|
size_t off = lineoff + (size_t)col;
|
||||||
if (schar_cmp(grid->chars[off], sc)
|
if (schar_cmp(grid->chars[off], sc) || grid->attrs[off] != attr || rdb_flags & RDB_NODELTA) {
|
||||||
|| grid->attrs[off] != attr) {
|
|
||||||
schar_copy(grid->chars[off], sc);
|
schar_copy(grid->chars[off], sc);
|
||||||
grid->attrs[off] = attr;
|
grid->attrs[off] = attr;
|
||||||
if (dirty_first == INT_MAX) {
|
if (dirty_first == INT_MAX) {
|
||||||
@ -605,7 +605,8 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle
|
|||||||
while (col < clear_width) {
|
while (col < clear_width) {
|
||||||
if (grid->chars[off_to][0] != ' '
|
if (grid->chars[off_to][0] != ' '
|
||||||
|| grid->chars[off_to][1] != NUL
|
|| grid->chars[off_to][1] != NUL
|
||||||
|| grid->attrs[off_to] != bg_attr) {
|
|| grid->attrs[off_to] != bg_attr
|
||||||
|
|| rdb_flags & RDB_NODELTA) {
|
||||||
grid->chars[off_to][0] = ' ';
|
grid->chars[off_to][0] = ' ';
|
||||||
grid->chars[off_to][1] = NUL;
|
grid->chars[off_to][1] = NUL;
|
||||||
grid->attrs[off_to] = bg_attr;
|
grid->attrs[off_to] = bg_attr;
|
||||||
|
@ -155,8 +155,6 @@ void win_draw_end(win_T *wp, int c1, int c2, bool draw_margin, int row, int endr
|
|||||||
} else {
|
} else {
|
||||||
grid_fill(&wp->w_grid, row, endrow, n, wp->w_grid.cols, c1, c2, attr);
|
grid_fill(&wp->w_grid, row, endrow, n, wp->w_grid.cols, c1, c2, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_empty_rows(wp, row);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the width of the foldcolumn. Based on 'foldcolumn' and how much
|
/// Compute the width of the foldcolumn. Based on 'foldcolumn' and how much
|
||||||
|
@ -557,7 +557,7 @@ static linenr_T buf_delsign(buf_T *buf, linenr_T atlnum, int id, char *group)
|
|||||||
sign_group_unref((char *)sign->se_group->sg_name);
|
sign_group_unref((char *)sign->se_group->sg_name);
|
||||||
}
|
}
|
||||||
xfree(sign);
|
xfree(sign);
|
||||||
redraw_buf_line_later(buf, lnum);
|
redraw_buf_line_later(buf, lnum, false);
|
||||||
// Check whether only one sign needs to be deleted
|
// Check whether only one sign needs to be deleted
|
||||||
// If deleting a sign with a specific identifier in a particular
|
// If deleting a sign with a specific identifier in a particular
|
||||||
// group or deleting any sign at a particular line number, delete
|
// group or deleting any sign at a particular line number, delete
|
||||||
@ -1062,7 +1062,7 @@ static int sign_place(int *sign_id, const char *sign_group, const char *sign_nam
|
|||||||
lnum = buf_change_sign_type(buf, *sign_id, (char *)sign_group, sp->sn_typenr, prio);
|
lnum = buf_change_sign_type(buf, *sign_id, (char *)sign_group, sp->sn_typenr, prio);
|
||||||
}
|
}
|
||||||
if (lnum > 0) {
|
if (lnum > 0) {
|
||||||
redraw_buf_line_later(buf, lnum);
|
redraw_buf_line_later(buf, lnum, false);
|
||||||
|
|
||||||
// When displaying signs in the 'number' column, if the width of the
|
// When displaying signs in the 'number' column, if the width of the
|
||||||
// number column is less than 2, then force recomputing the width.
|
// number column is less than 2, then force recomputing the width.
|
||||||
@ -1093,7 +1093,7 @@ static int sign_unplace(int sign_id, char *sign_group, buf_T *buf, linenr_T atln
|
|||||||
if (lnum == 0) {
|
if (lnum == 0) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
redraw_buf_line_later(buf, lnum);
|
redraw_buf_line_later(buf, lnum, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// When all the signs in a buffer are removed, force recomputing the
|
// When all the signs in a buffer are removed, force recomputing the
|
||||||
|
@ -947,7 +947,7 @@ describe('Screen', function()
|
|||||||
{0:~ }|
|
{0:~ }|
|
||||||
|
|
|
|
||||||
]]}
|
]]}
|
||||||
eq({{2, 0, {{'c', 0, 3}}}}, grid_lines)
|
eq({{2, 0, {{'c', 0, 3}, {' ', 0, 50}}}, {3, 0, {{' ', 0, 53}}}}, grid_lines)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('K_EVENT should not cause extra redraws with concealcursor #13196', function()
|
it('K_EVENT should not cause extra redraws with concealcursor #13196', function()
|
||||||
@ -994,10 +994,11 @@ describe('Screen', function()
|
|||||||
{0:~ }|
|
{0:~ }|
|
||||||
|
|
|
|
||||||
]]}
|
]]}
|
||||||
eq({{2, 0, {{'c', 0, 3}}}}, grid_lines)
|
eq({{2, 0, {{'c', 0, 3}, {' ', 0, 50}}}}, grid_lines)
|
||||||
|
grid_lines = {}
|
||||||
poke_eventloop() -- causes K_EVENT key
|
poke_eventloop() -- causes K_EVENT key
|
||||||
screen:expect_unchanged()
|
screen:expect_unchanged()
|
||||||
eq({{2, 0, {{'c', 0, 3}}}}, grid_lines)
|
eq({}, grid_lines) -- no redraw was done
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Copy of Test_cursor_column_in_concealed_line_after_window_scroll in
|
-- Copy of Test_cursor_column_in_concealed_line_after_window_scroll in
|
||||||
|
Loading…
Reference in New Issue
Block a user