mirror of
https://github.com/neovim/neovim.git
synced 2025-09-29 06:28:35 +00:00
perf(column): only invalidate lines affected by added sign
This commit is contained in:

committed by
Lewis Russell

parent
584c6c25cc
commit
f4001d27ef
@@ -1844,7 +1844,7 @@ buf_T *buflist_new(char *ffname_arg, char *sfname_arg, linenr_T lnum, int flags)
|
||||
buf = xcalloc(1, sizeof(buf_T));
|
||||
// init b: variables
|
||||
buf->b_vars = tv_dict_alloc();
|
||||
buf->b_signcols.valid = false;
|
||||
buf->b_signcols.sentinel = 0;
|
||||
init_var_dict(buf->b_vars, &buf->b_bufvar, VAR_SCOPE);
|
||||
buf_init_changedtick(buf);
|
||||
}
|
||||
@@ -4026,88 +4026,64 @@ char *buf_spname(buf_T *buf)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// Invalidate the signcolumn if needed after deleting
|
||||
/// signs between line1 and line2 (inclusive).
|
||||
///
|
||||
/// @param buf buffer to check
|
||||
/// @param line1 start of region being deleted
|
||||
/// @param line2 end of region being deleted
|
||||
/// Invalidate the signcolumn if needed after deleting a sign ranging from line1 to line2.
|
||||
void buf_signcols_del_check(buf_T *buf, linenr_T line1, linenr_T line2)
|
||||
{
|
||||
if (!buf->b_signcols.valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!buf->b_signcols.sentinel) {
|
||||
buf->b_signcols.valid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
linenr_T sent = buf->b_signcols.sentinel;
|
||||
|
||||
if (sent >= line1 && sent <= line2) {
|
||||
// Only invalidate when removing signs at the sentinel line.
|
||||
buf->b_signcols.valid = false;
|
||||
// When removed sign overlaps the sentinel line, entire buffer needs to be checked.
|
||||
buf->b_signcols.sentinel = buf->b_signcols.size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Re-calculate the signcolumn after adding a sign.
|
||||
///
|
||||
/// @param buf buffer to check
|
||||
/// @param added sign being added
|
||||
/// Invalidate the signcolumn if needed after adding a sign ranging from line1 to line2.
|
||||
void buf_signcols_add_check(buf_T *buf, linenr_T line1, linenr_T line2)
|
||||
{
|
||||
if (!buf->b_signcols.valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!buf->b_signcols.sentinel) {
|
||||
buf->b_signcols.valid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
linenr_T sent = buf->b_signcols.sentinel;
|
||||
|
||||
if (sent >= line1 && sent <= line2) {
|
||||
// If added sign overlaps sentinel line, increment without invalidating.
|
||||
if (buf->b_signcols.size == buf->b_signcols.max) {
|
||||
buf->b_signcols.max++;
|
||||
}
|
||||
buf->b_signcols.size++;
|
||||
redraw_buf_later(buf, UPD_NOT_VALID);
|
||||
return;
|
||||
}
|
||||
|
||||
int signcols = decor_signcols(buf, line1 - 1, line2 - 1, SIGN_SHOW_MAX);
|
||||
|
||||
if (signcols > buf->b_signcols.size) {
|
||||
buf->b_signcols.size = signcols;
|
||||
buf->b_signcols.max = signcols;
|
||||
redraw_buf_later(buf, UPD_NOT_VALID);
|
||||
if (line1 < buf->b_signcols.invalid_top) {
|
||||
buf->b_signcols.invalid_top = line1;
|
||||
}
|
||||
if (line2 > buf->b_signcols.invalid_bot) {
|
||||
buf->b_signcols.invalid_bot = line2;
|
||||
}
|
||||
}
|
||||
|
||||
int buf_signcols(buf_T *buf, int max)
|
||||
{
|
||||
// The maximum can be determined from 'signcolumn' which is window scoped so
|
||||
// need to invalidate signcols if the maximum is greater than the previous
|
||||
// (valid) maximum.
|
||||
if (buf->b_signcols.max && max > buf->b_signcols.max) {
|
||||
buf->b_signcols.valid = false;
|
||||
}
|
||||
|
||||
if (!buf->b_signcols.valid) {
|
||||
buf->b_signcols.sentinel = 0;
|
||||
int signcols = decor_signcols(buf, 0, (int)buf->b_ml.ml_line_count - 1, max);
|
||||
// Check if we need to redraw
|
||||
if (signcols != buf->b_signcols.size) {
|
||||
buf->b_signcols.size = signcols;
|
||||
redraw_buf_later(buf, UPD_NOT_VALID);
|
||||
if (!buf->b_signs_with_text) {
|
||||
buf->b_signcols.size = 0;
|
||||
} else if (max <= 1 && buf->b_signs_with_text >= (size_t)max) {
|
||||
buf->b_signcols.size = max;
|
||||
} else {
|
||||
linenr_T sent = buf->b_signcols.sentinel;
|
||||
if (!sent || max > buf->b_signcols.max) {
|
||||
// Recheck if the window scoped maximum 'signcolumn' is greater than the
|
||||
// previous maximum or if there is no sentinel line yet.
|
||||
buf->b_signcols.invalid_top = sent ? sent : 1;
|
||||
buf->b_signcols.invalid_bot = sent ? sent : buf->b_ml.ml_line_count;
|
||||
}
|
||||
|
||||
buf->b_signcols.max = max;
|
||||
buf->b_signcols.valid = true;
|
||||
if (buf->b_signcols.invalid_bot) {
|
||||
decor_validate_signcols(buf, max);
|
||||
}
|
||||
}
|
||||
|
||||
buf->b_signcols.max = max;
|
||||
buf->b_signcols.invalid_top = MAXLNUM;
|
||||
buf->b_signcols.invalid_bot = 0;
|
||||
return buf->b_signcols.size;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user