diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-06-13 11:30:19 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-13 11:30:19 +0800 |
commit | 4c7cec4e293495e69c105f883905f78af4c151c0 (patch) | |
tree | 639a7fdcbe7cea8ac41effd61a587724f86ae166 | |
parent | a7e5d4238a00d5bfa5809b2860047eca2d565e62 (diff) | |
download | rneovim-4c7cec4e293495e69c105f883905f78af4c151c0.tar.gz rneovim-4c7cec4e293495e69c105f883905f78af4c151c0.tar.bz2 rneovim-4c7cec4e293495e69c105f883905f78af4c151c0.zip |
fix(extmarks): handle inline virt_text with empty chunk (#24005)
-rw-r--r-- | src/nvim/drawline.c | 27 | ||||
-rw-r--r-- | test/functional/ui/decorations_spec.lua | 47 |
2 files changed, 61 insertions, 13 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 280c1d6994..eb5de14f32 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -871,9 +871,15 @@ static void apply_cursorline_highlight(win_T *wp, winlinevars_T *wlv) static void handle_inline_virtual_text(win_T *wp, winlinevars_T *wlv, ptrdiff_t v, bool *do_save) { - while (true) { - // we could already be inside an existing inline text with multiple chunks - if (!(wlv->virt_inline_i < kv_size(wlv->virt_inline))) { + if (wlv->n_extra == 0 || !wlv->extra_for_extmark) { + wlv->reset_extra_attr = false; + } + + while (wlv->n_extra == 0) { + if (wlv->virt_inline_i >= kv_size(wlv->virt_inline)) { + // need to find inline virtual text + wlv->virt_inline = VIRTTEXT_EMPTY; + wlv->virt_inline_i = 0; DecorState *state = &decor_state; for (size_t i = 0; i < kv_size(state->active); i++) { DecorRange *item = &kv_A(state->active, i); @@ -884,18 +890,16 @@ static void handle_inline_virtual_text(win_T *wp, winlinevars_T *wlv, ptrdiff_t } if (item->draw_col >= -1 && item->start_col == v) { wlv->virt_inline = item->decor.virt_text; - wlv->virt_inline_i = 0; item->draw_col = INT_MIN; break; } } - } - - if (wlv->n_extra == 0 || !wlv->extra_for_extmark) { - wlv->reset_extra_attr = false; - } - - if (wlv->n_extra <= 0 && wlv->virt_inline_i < kv_size(wlv->virt_inline)) { + if (!kv_size(wlv->virt_inline)) { + // no more inline virtual text here + break; + } + } else { + // already inside existing inline virtual text with multiple chunks VirtTextChunk vtc = kv_A(wlv->virt_inline, wlv->virt_inline_i); wlv->p_extra = vtc.text; wlv->n_extra = (int)strlen(wlv->p_extra); @@ -932,7 +936,6 @@ static void handle_inline_virtual_text(win_T *wp, winlinevars_T *wlv, ptrdiff_t } } } - break; } } diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index cbf0178d28..36c414e58f 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -1618,6 +1618,51 @@ describe('decorations: inline virtual text', function() ]]} end) + it('works with empty chunk', function() + insert(example_text) + feed 'gg' + screen:expect{grid=[[ + ^for _,item in ipairs(items) do | + local text, hl_id_cell, count = unpack(item) | + if hl_id_cell ~= nil then | + hl_id = hl_id_cell | + end | + for _ = 1, (count or 1) do | + local cell = line[colpos] | + cell.text = text | + cell.hl_id = hl_id | + | + ]]} + + meths.buf_set_extmark(0, ns, 1, 14, {virt_text={{''}, {': ', 'Special'}, {'string', 'Type'}}, virt_text_pos='inline'}) + screen:expect{grid=[[ + ^for _,item in ipairs(items) do | + local text{10:: }{3:string}, hl_id_cell, count = unpack| + (item) | + if hl_id_cell ~= nil then | + hl_id = hl_id_cell | + end | + for _ = 1, (count or 1) do | + local cell = line[colpos] | + cell.text = text | + | + ]]} + + feed('jf,') + screen:expect{grid=[[ + for _,item in ipairs(items) do | + local text{10:: }{3:string}^, hl_id_cell, count = unpack| + (item) | + if hl_id_cell ~= nil then | + hl_id = hl_id_cell | + end | + for _ = 1, (count or 1) do | + local cell = line[colpos] | + cell.text = text | + | + ]]} + end) + it('cursor positions are correct with multiple inline virtual text', function() insert('12345678') meths.buf_set_extmark(0, ns, 0, 4, @@ -2013,7 +2058,7 @@ bbbbbbb]]) ]]} end) - it('cursor position is correct when inserting around virtual texts with both left and right gravity ', function() + it('cursor position is correct when inserting around virtual texts with both left and right gravity', function() insert('foo foo foo foo') meths.buf_set_extmark(0, ns, 0, 8, { virt_text = {{ '>>', 'Special' }}, virt_text_pos = 'inline', right_gravity = false }) meths.buf_set_extmark(0, ns, 0, 8, { virt_text = {{ '<<', 'Special' }}, virt_text_pos = 'inline', right_gravity = true }) |