win_line: update w_last_cursorline always

Vim patch 8.1.0856 (54d9ea6) caused a performance regression in Neovim,
when `set conceallevel=1 nocursorline` was used, since then due to
refactoring in 23c71d5 `w_last_cursorline` would never get updated
anymore.

Adds/uses `redrawdebug+=nodelta` for testing this.

Fixes https://github.com/neovim/neovim/issues/11100.
Closes https://github.com/neovim/neovim/pull/11101.
This commit is contained in:
Daniel Hahler 2019-09-26 09:15:21 +02:00
parent cd73a0342a
commit a341eb6087
5 changed files with 67 additions and 8 deletions

View File

@ -4588,9 +4588,11 @@ A jump table for the options with a short description can be found at |Q_op|.
larger scroll when drawing the message area (with larger scroll when drawing the message area (with
'display' msgsep flag active). 'display' msgsep flag active).
invalid Enable stricter checking (abort) of inconsistencies invalid Enable stricter checking (abort) of inconsistencies
of the internal screen state. This is mosly of the internal screen state. This is mostly
useful when running nvim inside a debugger (and useful when running nvim inside a debugger (and
the test suite). the test suite).
nodelta Send all internally redrawn cells to the UI, even if
they are unchanged from the already displayed state.
*'redrawtime'* *'rdt'* *'redrawtime'* *'rdt'*
'redrawtime' 'rdt' number (default 2000) 'redrawtime' 'rdt' number (default 2000)
@ -6916,7 +6918,6 @@ A jump table for the options with a short description can be found at |Q_op|.
global global
The number of milliseconds to wait for each character sent to the The number of milliseconds to wait for each character sent to the
screen. When positive, characters are sent to the UI one by one. screen. When positive, characters are sent to the UI one by one.
When negative, all redrawn characters cause a delay, even if the See 'redrawdebug' for more options. For debugging purposes.
character already was displayed by the UI. For debugging purposes.
vim:tw=78:ts=8:noet:ft=help:norl: vim:tw=78:ts=8:noet:ft=help:norl:

View File

@ -4306,6 +4306,10 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
if (value < 0) { if (value < 0) {
errmsg = e_positive; errmsg = e_positive;
} }
} else if (pp == &p_wd) {
if (value < 0) {
errmsg = e_positive;
}
} }
// Don't change the value and return early if validation failed. // Don't change the value and return early if validation failed.

View File

@ -518,11 +518,18 @@ EXTERN long p_pyx; // 'pyxversion'
EXTERN char_u *p_rdb; // 'redrawdebug' EXTERN char_u *p_rdb; // 'redrawdebug'
EXTERN unsigned rdb_flags; EXTERN unsigned rdb_flags;
# ifdef IN_OPTION_C # ifdef IN_OPTION_C
static char *(p_rdb_values[]) = { "compositor", "nothrottle", "invalid", NULL }; static char *(p_rdb_values[]) = {
"compositor",
"nothrottle",
"invalid",
"nodelta",
NULL
};
# endif # endif
# define RDB_COMPOSITOR 0x001 # define RDB_COMPOSITOR 0x001
# define RDB_NOTHROTTLE 0x002 # define RDB_NOTHROTTLE 0x002
# define RDB_INVALID 0x004 # define RDB_INVALID 0x004
# define RDB_NODELTA 0x008
EXTERN long p_rdt; // 'redrawtime' EXTERN long p_rdt; // 'redrawtime'
EXTERN int p_remap; // 'remap' EXTERN int p_remap; // 'remap'

View File

@ -577,7 +577,7 @@ void conceal_check_cursor_line(void)
/// Whether cursorline is drawn in a special way /// Whether cursorline is drawn in a special way
/// ///
/// If true, both old and new cursorline will need /// If true, both old and new cursorline will need
/// need to be redrawn when moving cursor within windows. /// to be redrawn when moving cursor within windows.
/// TODO(bfredl): VIsual_active shouldn't be needed, but is used to fix a glitch /// TODO(bfredl): VIsual_active shouldn't be needed, but is used to fix a glitch
/// caused by scrolling. /// caused by scrolling.
bool win_cursorline_standout(const win_T *wp) bool win_cursorline_standout(const win_T *wp)
@ -2406,10 +2406,10 @@ win_line (
filler_todo = filler_lines; filler_todo = filler_lines;
// Cursor line highlighting for 'cursorline' in the current window. // Cursor line highlighting for 'cursorline' in the current window.
if (wp->w_p_cul && lnum == wp->w_cursor.lnum) { if (lnum == wp->w_cursor.lnum) {
// Do not show the cursor line when Visual mode is active, because it's // Do not show the cursor line when Visual mode is active, because it's
// not clear what is selected then. // not clear what is selected then.
if (!(wp == curwin && VIsual_active)) { if (wp->w_p_cul && !(wp == curwin && VIsual_active)) {
int cul_attr = win_hl_attr(wp, HLF_CUL); int cul_attr = win_hl_attr(wp, HLF_CUL);
HlAttrs ae = syn_attr2entry(cul_attr); HlAttrs ae = syn_attr2entry(cul_attr);
@ -4354,7 +4354,7 @@ static int grid_char_needs_redraw(ScreenGrid *grid, int off_from, int 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->chars[off_to + 1]))) grid->chars[off_to + 1])))
|| p_wd < 0)); || rdb_flags & RDB_NODELTA));
} }
/// Move one buffered line to the window grid, but only the characters that /// Move one buffered line to the window grid, but only the characters that

View File

@ -1,6 +1,7 @@
local helpers = require('test.functional.helpers')(after_each) local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen') local Screen = require('test.functional.ui.screen')
local clear, feed, command = helpers.clear, helpers.feed, helpers.command local clear, feed, command = helpers.clear, helpers.feed, helpers.command
local eq = helpers.eq
local insert = helpers.insert local insert = helpers.insert
describe('Screen', function() describe('Screen', function()
@ -870,4 +871,50 @@ describe('Screen', function()
]]} ]]}
end) end)
end) end)
it('redraws not too much with conceallevel=1', function()
command('set conceallevel=1')
command('set redrawdebug+=nodelta')
insert([[
aaa
bbb
ccc
]])
screen:expect{grid=[[
aaa |
bbb |
ccc |
^ |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
|
]]}
-- XXX: hack to get notifications, and check only a single line is
-- updated. Could use next_msg() also.
local orig_handle_grid_line = screen._handle_grid_line
local grid_lines = {}
function screen._handle_grid_line(self, grid, row, col, items)
table.insert(grid_lines, {row, col, items})
orig_handle_grid_line(self, grid, row, col, items)
end
feed('k')
screen:expect{grid=[[
aaa |
bbb |
^ccc |
|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
|
]]}
eq(grid_lines, {{2, 0, {{'c', 0, 3}}}})
end)
end) end)