From 35cec0de4acd351119230330f54b0a45f9823695 Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Mon, 27 Nov 2023 16:22:19 +0100 Subject: [PATCH] fix(column): redraw and update signcols for paired extmark Problem: Signcolumn width does not increase when ranged sign does not start at sentinel line. Solution: Handle paired range of added sign when checking signcols. --- src/nvim/buffer.c | 9 ++++---- src/nvim/decoration.c | 10 ++++----- src/nvim/extmark.c | 5 +++-- test/functional/ui/decorations_spec.lua | 29 +++++-------------------- 4 files changed, 18 insertions(+), 35 deletions(-) diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 86cf805345..2a3cebc0ae 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -4055,7 +4055,7 @@ void buf_signcols_del_check(buf_T *buf, linenr_T line1, linenr_T line2) /// /// @param buf buffer to check /// @param added sign being added -void buf_signcols_add_check(buf_T *buf, linenr_T lnum) +void buf_signcols_add_check(buf_T *buf, linenr_T line1, linenr_T line2) { if (!buf->b_signcols.valid) { return; @@ -4066,7 +4066,9 @@ void buf_signcols_add_check(buf_T *buf, linenr_T lnum) return; } - if (lnum == buf->b_signcols.sentinel) { + linenr_T sent = buf->b_signcols.sentinel; + + if (sent >= line1 && sent <= line2) { if (buf->b_signcols.size == buf->b_signcols.max) { buf->b_signcols.max++; } @@ -4075,12 +4077,11 @@ void buf_signcols_add_check(buf_T *buf, linenr_T lnum) return; } - int signcols = decor_signcols(buf, lnum - 1, lnum - 1, SIGN_SHOW_MAX); + 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; - buf->b_signcols.sentinel = lnum; redraw_buf_later(buf, UPD_NOT_VALID); } } diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index 29993bffa5..c2bef5920c 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -169,7 +169,7 @@ DecorSignHighlight decor_sh_from_inline(DecorHighlightInline item) return conv; } -void buf_put_decor(buf_T *buf, DecorInline decor, int row) +void buf_put_decor(buf_T *buf, DecorInline decor, int row, int row2) { if (decor.ext) { DecorVirtText *vt = decor.data.ext.vt; @@ -181,7 +181,7 @@ void buf_put_decor(buf_T *buf, DecorInline decor, int row) uint32_t idx = decor.data.ext.sh_idx; while (idx != DECOR_ID_INVALID) { DecorSignHighlight *sh = &kv_A(decor_items, idx); - buf_put_decor_sh(buf, sh, row); + buf_put_decor_sh(buf, sh, row, row2); idx = sh->next; } } @@ -202,14 +202,14 @@ void buf_put_decor_virt(buf_T *buf, DecorVirtText *vt) } static int sign_add_id = 0; -void buf_put_decor_sh(buf_T *buf, DecorSignHighlight *sh, int row) +void buf_put_decor_sh(buf_T *buf, DecorSignHighlight *sh, int row, int row2) { if (sh->flags & kSHIsSign) { sh->sign_add_id = sign_add_id++; buf->b_signs++; if (sh->text.ptr) { buf->b_signs_with_text++; - buf_signcols_add_check(buf, row + 1); + buf_signcols_add_check(buf, row + 1, row2 + 1); } } } @@ -835,7 +835,7 @@ int decor_signcols(buf_T *buf, int row, int end_row, int max) } if (count > signcols) { - if (row != end_row) { + if (count > buf->b_signcols.size) { buf->b_signcols.sentinel = currow + 1; } if (count >= max) { diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index f50c271990..0bacb2cd4c 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -90,7 +90,7 @@ void extmark_set(buf_T *buf, uint32_t ns_id, uint32_t *idp, int row, colnr_T col revised: if (decor_flags || decor.ext) { - buf_put_decor(buf, decor, row); + buf_put_decor(buf, decor, row, end_row > -1 ? end_row : row); decor_redraw(buf, row, end_row > -1 ? end_row : row, decor); } @@ -393,7 +393,8 @@ void extmark_apply_undo(ExtmarkUndoObject undo_info, bool undo) MarkTreeIter itr[1] = { 0 }; MTKey mark = marktree_lookup(curbuf->b_marktree, pos.mark, itr); mt_itr_rawkey(itr).flags &= (uint16_t) ~MT_FLAG_INVALID; - buf_put_decor(curbuf, mt_decor(mark), mark.pos.row); + MTPos end = marktree_get_altpos(curbuf->b_marktree, mark, itr); + buf_put_decor(curbuf, mt_decor(mark), mark.pos.row, end.row < 0 ? mark.pos.row : end.row); } if (pos.old_row >= 0) { extmark_setraw(curbuf, pos.mark, pos.old_row, pos.old_col); diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index ef02f73960..6d4937b0c0 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -4718,21 +4718,19 @@ l5 {2:~ }| | ]]} - end) it('can add multiple signs (multiple extmarks) 2', function() insert(example_test3) feed 'gg' - meths.buf_set_extmark(0, ns, 1, -1, {sign_text='S1'}) - meths.buf_set_extmark(0, ns, 1, -1, {sign_text='S2'}) - + meths.buf_set_extmark(0, ns, 3, -1, {sign_text='S1'}) + meths.buf_set_extmark(0, ns, 1, -1, {sign_text='S2', end_row = 3}) screen:expect{grid=[[ {1: }^l1 | - S1S2l2 | - {1: }l3 | - {1: }l4 | + S2{1: }l2 | + S2{1: }l3 | + S1S2l4 | {1: }l5 | {1: } | {2:~ }| @@ -4740,23 +4738,6 @@ l5 {2:~ }| | ]]} - - -- TODO(lewis6991): Support ranged signs - -- meths.buf_set_extmark(1, ns, 1, -1, {sign_text='S3', end_row = 2}) - - -- screen:expect{grid=[[ - -- {1: }^l1 | - -- S3S2S1l2 | - -- S3{1: }l3 | - -- {1: }l4 | - -- {1: }l5 | - -- {1: } | - -- {2:~ }| - -- {2:~ }| - -- {2:~ }| - -- | - -- ]]} - end) it('can add multiple signs (multiple extmarks) 3', function()