perf(column): avoid counting when max signs are removed from a range

This commit is contained in:
Luuk van Baal 2023-12-08 05:58:29 +01:00 committed by Lewis Russell
parent 808fbe67a8
commit 2289ca273c
4 changed files with 42 additions and 20 deletions

View File

@ -792,17 +792,16 @@ DecorSignHighlight *decor_find_sign(DecorInline decor)
}
}
/// If "count" is greater than current max, set it and reset "max_count".
static void buf_signcols_validate_row(buf_T *buf, int count, int add)
{
int del = add < 0 ? -add : 0;
// If "count" is greater than current max, set it and reset "max_count".
if (count > buf->b_signcols.max) {
buf->b_signcols.max = count;
buf->b_signcols.max_count = 0;
buf->b_signcols.resized = true;
}
/// Add sign of "add" to "max_count"
if (count == buf->b_signcols.max - del) {
// If row has or had "max" signs, adjust "max_count" with sign of "add".
if (count == buf->b_signcols.max - (add < 0 ? -add : 0)) {
buf->b_signcols.max_count += (add > 0) - (add < 0);
}
}
@ -811,7 +810,12 @@ static void buf_signcols_validate_row(buf_T *buf, int count, int add)
/// "b_signcols" accordingly.
static void buf_signcols_validate_range(buf_T *buf, int row1, int row2, int add)
{
int count = 0; // Number of signs on the current line
if (-add == buf->b_signcols.max) {
buf->b_signcols.max_count -= (row2 + 1 - row1);
return; // max signs were removed from the range, no need to count.
}
int count = 0; // Number of signs on the current row
int currow = row1;
MTPair pair = { 0 };
MarkTreeIter itr[1];
@ -847,8 +851,8 @@ static void buf_signcols_validate_range(buf_T *buf, int row1, int row2, int add)
count++;
if (mt_paired(mark)) {
MTPos end = marktree_get_altpos(buf->b_marktree, mark, NULL);
for (int i = mark.pos.row; i < MIN(row2, end.row); i++) {
overlap[row2 - i]++;
for (int i = mark.pos.row + 1; i <= MIN(row2, end.row); i++) {
overlap[i - row1]++;
}
}
}
@ -861,13 +865,17 @@ static void buf_signcols_validate_range(buf_T *buf, int row1, int row2, int add)
int buf_signcols_validate(win_T *wp, buf_T *buf, bool stc_check)
{
if (!map_size(buf->b_signcols.invalid)) {
return buf->b_signcols.max;
}
int start;
SignRange range;
map_foreach(buf->b_signcols.invalid, start, range, {
// Leave rest of the ranges invalid if max is already greater than
// configured maximum or resize is detected for 'statuscolumn' rebuild.
if ((!stc_check || buf->b_signcols.resized)
&& (range.add > 0 && buf->b_signcols.max >= wp->w_maxscwidth)) {
// Leave rest of the ranges invalid if max is already at configured
// maximum or resize is detected for a 'statuscolumn' rebuild.
if ((stc_check && buf->b_signcols.resized)
|| (!stc_check && range.add > 0 && buf->b_signcols.max >= wp->w_maxscwidth)) {
return wp->w_maxscwidth;
}
buf_signcols_validate_range(buf, start, range.end, range.add);
@ -877,7 +885,7 @@ int buf_signcols_validate(win_T *wp, buf_T *buf, bool stc_check)
if (buf->b_signcols.max_count == 0) {
buf->b_signcols.max = 0;
buf->b_signcols.resized = true;
buf_signcols_validate_range(buf, 0, buf->b_ml.ml_line_count, 0);
buf_signcols_validate_range(buf, 0, buf->b_ml.ml_line_count, 1);
}
map_clear(int, buf->b_signcols.invalid);

View File

@ -1195,15 +1195,13 @@ void comp_col(void)
/// Redraw entire window "wp" if configured 'signcolumn' width changes.
static bool win_redraw_signcols(win_T *wp)
{
int width;
bool rebuild_stc = false;
buf_T *buf = wp->w_buffer;
int width = buf->b_signcols.max;
if (wp->w_minscwidth <= SCL_NO) {
if (*wp->w_p_stc) {
if (map_size(buf->b_signcols.invalid)) {
buf_signcols_validate(wp, buf, true);
}
buf_signcols_validate(wp, buf, true);
if (buf->b_signcols.resized) {
rebuild_stc = true;
wp->w_nrwidth_line_count = 0;
@ -1212,7 +1210,7 @@ static bool win_redraw_signcols(win_T *wp)
width = 0;
} else if (wp->w_maxscwidth <= 1 && buf->b_signs_with_text >= (size_t)wp->w_maxscwidth) {
width = wp->w_maxscwidth;
} else if (map_size(buf->b_signcols.invalid)) {
} else {
width = buf_signcols_validate(wp, buf, false);
}

View File

@ -4989,6 +4989,21 @@ l5
|
]]}
end)
it('correct width with multiple overlapping signs', function()
screen:try_resize(20, 4)
insert(example_test3)
meths.buf_set_extmark(0, ns, 0, -1, {sign_text='S1', end_row=2})
meths.buf_set_extmark(0, ns, 1, -1, {sign_text='S2', end_row=2})
feed('gg')
screen:expect{grid=[[
S1{1: }^l1 |
S1S2l2 |
S1S2l3 |
|
]]}
end)
end)
describe('decorations: virt_text', function()

View File

@ -367,11 +367,12 @@ describe('Signs', function()
|
]]}
-- line deletion deletes signs.
command('3move1')
command('2d')
screen:expect([[
{1:>>}{8:XX}{2: }{6: 1 }a |
{8:XX}{1:>>}WW{6: 2 }^c |
{2: }{6: 3 } |
{1:>>}{8:XX}{6: 1 }a |
{8:XX}{1:>>}{6: 2 }^b |
{2: }{6: 3 } |
{0:~ }|
{0:~ }|
{0:~ }|