refactor(signs): more efficient signcol calc

When iterating signs to calculate the sign column, stop iterating when
we reach the maximum configured from 'signcolumn'.
This commit is contained in:
Lewis Russell 2022-02-12 17:12:09 +00:00
parent 7db0aa027c
commit 50250542c3
3 changed files with 40 additions and 26 deletions

View File

@ -5455,30 +5455,43 @@ bool find_win_for_buf(buf_T *buf, win_T **wp, tabpage_T **tp)
return false;
}
int buf_signcols(buf_T *buf)
static int buf_signcols_inner(buf_T *buf, int maximum)
{
sign_entry_T *sign; // a sign in the sign list
int signcols = 0;
int linesum = 0;
linenr_T curline = 0;
FOR_ALL_SIGNS_IN_BUF(buf, sign) {
if (sign->se_lnum > curline) {
if (linesum > signcols) {
signcols = linesum;
if (signcols >= maximum) {
return maximum;
}
}
curline = sign->se_lnum;
linesum = 0;
}
if (sign->se_has_text_or_icon) {
linesum++;
}
}
if (linesum > signcols) {
signcols = linesum;
if (signcols >= maximum) {
return maximum;
}
}
return signcols;
}
int buf_signcols(buf_T *buf, int maximum)
{
if (!buf->b_signcols_valid) {
sign_entry_T *sign; // a sign in the sign list
int signcols = 0;
int linesum = 0;
linenr_T curline = 0;
FOR_ALL_SIGNS_IN_BUF(buf, sign) {
if (sign->se_lnum > curline) {
if (linesum > signcols) {
signcols = linesum;
}
curline = sign->se_lnum;
linesum = 0;
}
if (sign->se_has_text_or_icon) {
linesum++;
}
}
if (linesum > signcols) {
signcols = linesum;
}
int signcols = buf_signcols_inner(buf, maximum);
// Check if we need to redraw
if (signcols != buf->b_signcols) {
buf->b_signcols = signcols;

View File

@ -8046,7 +8046,6 @@ int win_signcol_count(win_T *wp)
/// Return the number of requested sign columns, based on user / configuration.
int win_signcol_configured(win_T *wp, int *is_fixed)
{
int minimum = 0, maximum = 1, needed_signcols;
const char *scl = (const char *)wp->w_p_scl;
if (is_fixed) {
@ -8059,7 +8058,6 @@ int win_signcol_configured(win_T *wp, int *is_fixed)
&& (wp->w_p_nu || wp->w_p_rnu)))) {
return 0;
}
needed_signcols = buf_signcols(wp->w_buffer);
// yes or yes
if (!strncmp(scl, "yes:", 4)) {
@ -8075,6 +8073,8 @@ int win_signcol_configured(win_T *wp, int *is_fixed)
*is_fixed = 0;
}
int minimum = 0, maximum = 1;
if (!strncmp(scl, "auto:", 5)) {
// Variable depending on a configuration
maximum = scl[5] - '0';
@ -8085,7 +8085,8 @@ int win_signcol_configured(win_T *wp, int *is_fixed)
}
}
int ret = MAX(minimum, MIN(maximum, needed_signcols));
int needed_signcols = buf_signcols(wp->w_buffer, maximum);
int ret = MAX(minimum, needed_signcols);
assert(ret <= SIGN_SHOW_MAX);
return ret;
}

View File

@ -794,7 +794,7 @@ static void win_update(win_T *wp, Providers *providers)
// If we can compute a change in the automatic sizing of the sign column
// under 'signcolumn=auto:X' and signs currently placed in the buffer, better
// figuring it out here so we can redraw the entire screen for it.
buf_signcols(buf);
win_signcol_count(wp);
type = wp->w_redr_type;