fix(extmarks): handle inline virt_text with empty chunk (#24005)

This commit is contained in:
zeertzjq 2023-06-13 11:30:19 +08:00 committed by GitHub
parent a7e5d4238a
commit 4c7cec4e29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 13 deletions

View File

@ -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;
}
}

View File

@ -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 })