diff options
Diffstat (limited to 'src/nvim/buffer.c')
-rw-r--r-- | src/nvim/buffer.c | 80 |
1 files changed, 28 insertions, 52 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 4d553cc91f..e6bedca232 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -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; } |