aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/decoration.c32
-rw-r--r--src/nvim/drawscreen.c8
-rw-r--r--test/functional/ui/decorations_spec.lua15
-rw-r--r--test/functional/ui/sign_spec.lua7
4 files changed, 42 insertions, 20 deletions
diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c
index 20311d80e5..62cbd33186 100644
--- a/src/nvim/decoration.c
+++ b/src/nvim/decoration.c
@@ -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);
diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c
index a436dd2766..314764d117 100644
--- a/src/nvim/drawscreen.c
+++ b/src/nvim/drawscreen.c
@@ -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);
}
diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua
index a60562380a..925243054c 100644
--- a/test/functional/ui/decorations_spec.lua
+++ b/test/functional/ui/decorations_spec.lua
@@ -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()
diff --git a/test/functional/ui/sign_spec.lua b/test/functional/ui/sign_spec.lua
index b12e79bd42..1c0a6f663b 100644
--- a/test/functional/ui/sign_spec.lua
+++ b/test/functional/ui/sign_spec.lua
@@ -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:~ }|