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) 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) { if (count > buf->b_signcols.max) {
buf->b_signcols.max = count; buf->b_signcols.max = count;
buf->b_signcols.max_count = 0; buf->b_signcols.max_count = 0;
buf->b_signcols.resized = true; buf->b_signcols.resized = true;
} }
/// Add sign of "add" to "max_count" // If row has or had "max" signs, adjust "max_count" with sign of "add".
if (count == buf->b_signcols.max - del) { if (count == buf->b_signcols.max - (add < 0 ? -add : 0)) {
buf->b_signcols.max_count += (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. /// "b_signcols" accordingly.
static void buf_signcols_validate_range(buf_T *buf, int row1, int row2, int add) 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; int currow = row1;
MTPair pair = { 0 }; MTPair pair = { 0 };
MarkTreeIter itr[1]; MarkTreeIter itr[1];
@ -847,8 +851,8 @@ static void buf_signcols_validate_range(buf_T *buf, int row1, int row2, int add)
count++; count++;
if (mt_paired(mark)) { if (mt_paired(mark)) {
MTPos end = marktree_get_altpos(buf->b_marktree, mark, NULL); MTPos end = marktree_get_altpos(buf->b_marktree, mark, NULL);
for (int i = mark.pos.row; i < MIN(row2, end.row); i++) { for (int i = mark.pos.row + 1; i <= MIN(row2, end.row); i++) {
overlap[row2 - 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) 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; int start;
SignRange range; SignRange range;
map_foreach(buf->b_signcols.invalid, start, range, { map_foreach(buf->b_signcols.invalid, start, range, {
// Leave rest of the ranges invalid if max is already greater than // Leave rest of the ranges invalid if max is already at configured
// configured maximum or resize is detected for 'statuscolumn' rebuild. // maximum or resize is detected for a 'statuscolumn' rebuild.
if ((!stc_check || buf->b_signcols.resized) if ((stc_check && buf->b_signcols.resized)
&& (range.add > 0 && buf->b_signcols.max >= wp->w_maxscwidth)) { || (!stc_check && range.add > 0 && buf->b_signcols.max >= wp->w_maxscwidth)) {
return wp->w_maxscwidth; return wp->w_maxscwidth;
} }
buf_signcols_validate_range(buf, start, range.end, range.add); 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) { if (buf->b_signcols.max_count == 0) {
buf->b_signcols.max = 0; buf->b_signcols.max = 0;
buf->b_signcols.resized = true; 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); 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. /// Redraw entire window "wp" if configured 'signcolumn' width changes.
static bool win_redraw_signcols(win_T *wp) static bool win_redraw_signcols(win_T *wp)
{ {
int width;
bool rebuild_stc = false; bool rebuild_stc = false;
buf_T *buf = wp->w_buffer; buf_T *buf = wp->w_buffer;
int width = buf->b_signcols.max;
if (wp->w_minscwidth <= SCL_NO) { if (wp->w_minscwidth <= SCL_NO) {
if (*wp->w_p_stc) { 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) { if (buf->b_signcols.resized) {
rebuild_stc = true; rebuild_stc = true;
wp->w_nrwidth_line_count = 0; wp->w_nrwidth_line_count = 0;
@ -1212,7 +1210,7 @@ static bool win_redraw_signcols(win_T *wp)
width = 0; width = 0;
} else if (wp->w_maxscwidth <= 1 && buf->b_signs_with_text >= (size_t)wp->w_maxscwidth) { } else if (wp->w_maxscwidth <= 1 && buf->b_signs_with_text >= (size_t)wp->w_maxscwidth) {
width = wp->w_maxscwidth; width = wp->w_maxscwidth;
} else if (map_size(buf->b_signcols.invalid)) { } else {
width = buf_signcols_validate(wp, buf, false); width = buf_signcols_validate(wp, buf, false);
} }

View File

@ -4989,6 +4989,21 @@ l5
| |
]]} ]]}
end) 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) end)
describe('decorations: virt_text', function() describe('decorations: virt_text', function()

View File

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