mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
fix(marks): handle double-with inline virt_text with 'nowrap' (#32476)
This commit is contained in:
parent
efe92f9dff
commit
8452032554
@ -909,25 +909,39 @@ static void handle_inline_virtual_text(win_T *wp, winlinevars_T *wlv, ptrdiff_t
|
||||
// If the text didn't reach until the first window
|
||||
// column we need to skip cells.
|
||||
if (wlv->skip_cells > 0) {
|
||||
// FIXME: this should use virt_text_width instead
|
||||
int virt_text_len = wlv->n_attr;
|
||||
if (virt_text_len > wlv->skip_cells) {
|
||||
int len = mb_charlen2bytelen(wlv->p_extra, wlv->skip_cells);
|
||||
wlv->n_extra -= len;
|
||||
wlv->p_extra += len;
|
||||
wlv->n_attr -= wlv->skip_cells;
|
||||
int virt_text_width = (int)mb_string2cells(wlv->p_extra);
|
||||
if (virt_text_width > wlv->skip_cells) {
|
||||
int cells_to_skip = wlv->skip_cells;
|
||||
// Skip cells in the text.
|
||||
while (cells_to_skip > 0) {
|
||||
int clen = utf_ptr2len(wlv->p_extra);
|
||||
cells_to_skip -= utf_ptr2cells(wlv->p_extra);
|
||||
wlv->p_extra += clen;
|
||||
wlv->n_extra -= clen;
|
||||
wlv->n_attr--;
|
||||
}
|
||||
// If a double-width char doesn't fit, pad with space.
|
||||
if (cells_to_skip < 0) {
|
||||
int pad_len = -cells_to_skip;
|
||||
char *padded = get_extra_buf((size_t)(wlv->n_extra + pad_len) + 1);
|
||||
memset(padded, ' ', (size_t)pad_len);
|
||||
xmemcpyz(padded + pad_len, wlv->p_extra, (size_t)wlv->n_extra);
|
||||
wlv->p_extra = padded;
|
||||
wlv->n_extra += pad_len;
|
||||
wlv->n_attr += pad_len;
|
||||
}
|
||||
// Skipped cells needed to be accounted for in vcol.
|
||||
wlv->skipped_cells += wlv->skip_cells;
|
||||
wlv->skip_cells = 0;
|
||||
} else {
|
||||
// the whole text is left of the window, drop
|
||||
// it and advance to the next one
|
||||
wlv->skip_cells -= virt_text_len;
|
||||
// The whole text is left of the window, drop
|
||||
// it and advance to the next one.
|
||||
wlv->skip_cells -= virt_text_width;
|
||||
// Skipped cells needed to be accounted for in vcol.
|
||||
wlv->skipped_cells += virt_text_len;
|
||||
wlv->skipped_cells += virt_text_width;
|
||||
wlv->n_attr = 0;
|
||||
wlv->n_extra = 0;
|
||||
// go to the start so the next virtual text chunk can be selected.
|
||||
// Go to the start so the next virtual text chunk can be selected.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -2251,24 +2251,6 @@ int mb_charlen(const char *str)
|
||||
return count;
|
||||
}
|
||||
|
||||
int mb_charlen2bytelen(const char *str, int charlen)
|
||||
{
|
||||
const char *p = str;
|
||||
int count = 0;
|
||||
|
||||
if (p == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; *p != NUL && i < charlen; i++) {
|
||||
int b = utfc_ptr2len(p);
|
||||
p += b;
|
||||
count += b;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/// Like mb_charlen() but for a string with specified length.
|
||||
int mb_charlen_len(const char *str, int len)
|
||||
{
|
||||
|
@ -3375,6 +3375,86 @@ describe('decorations: inline virtual text', function()
|
||||
]]}
|
||||
end)
|
||||
|
||||
it('draws correctly with no wrap and multibyte virtual text', function()
|
||||
insert('12345678')
|
||||
command('set nowrap')
|
||||
api.nvim_buf_set_extmark(0, ns, 0, 2, {
|
||||
virt_text = { { 'αβγ口=', 'Special' }, { '口', 'Special' } },
|
||||
virt_text_pos = 'inline',
|
||||
})
|
||||
screen:expect([[
|
||||
12{10:αβγ口=口}34567^8 |
|
||||
{1:~ }|
|
||||
|
|
||||
]])
|
||||
feed('zl')
|
||||
screen:expect([[
|
||||
2{10:αβγ口=口}34567^8 |
|
||||
{1:~ }|
|
||||
|
|
||||
]])
|
||||
feed('zl')
|
||||
screen:expect([[
|
||||
{10:αβγ口=口}34567^8 |
|
||||
{1:~ }|
|
||||
|
|
||||
]])
|
||||
feed('zl')
|
||||
screen:expect([[
|
||||
{10:βγ口=口}34567^8 |
|
||||
{1:~ }|
|
||||
|
|
||||
]])
|
||||
feed('zl')
|
||||
screen:expect([[
|
||||
{10:γ口=口}34567^8 |
|
||||
{1:~ }|
|
||||
|
|
||||
]])
|
||||
feed('zl')
|
||||
screen:expect([[
|
||||
{10:口=口}34567^8 |
|
||||
{1:~ }|
|
||||
|
|
||||
]])
|
||||
feed('zl')
|
||||
screen:expect([[
|
||||
{10: =口}34567^8 |
|
||||
{1:~ }|
|
||||
|
|
||||
]])
|
||||
feed('zl')
|
||||
screen:expect([[
|
||||
{10:=口}34567^8 |
|
||||
{1:~ }|
|
||||
|
|
||||
]])
|
||||
feed('zl')
|
||||
screen:expect([[
|
||||
{10:口}34567^8 |
|
||||
{1:~ }|
|
||||
|
|
||||
]])
|
||||
feed('zl')
|
||||
screen:expect([[
|
||||
{10: }34567^8 |
|
||||
{1:~ }|
|
||||
|
|
||||
]])
|
||||
feed('zl')
|
||||
screen:expect([[
|
||||
34567^8 |
|
||||
{1:~ }|
|
||||
|
|
||||
]])
|
||||
feed('zl')
|
||||
screen:expect([[
|
||||
4567^8 |
|
||||
{1:~ }|
|
||||
|
|
||||
]])
|
||||
end)
|
||||
|
||||
it('tabs are the correct length with no wrap following virtual text', function()
|
||||
command('set nowrap')
|
||||
feed('itest<TAB>a<ESC>')
|
||||
|
Loading…
Reference in New Issue
Block a user