fix(ui): fix tabs not being spaced properly after virtual text with no wrap

also fixes incorrect skipping of multibyte characters
This commit is contained in:
Ibby 2023-04-12 18:21:46 +10:00 committed by bfredl
parent 7423d3479d
commit 5d7afb2e9f
3 changed files with 63 additions and 6 deletions

View File

@ -969,8 +969,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
int n_skip = 0; // nr of chars to skip for 'nowrap' or
// concealing
int skip_cells = 0; // nr of cells to skip for virtual text
// after the line, when w_skipcol is
// larger than the text length
int skipped_cells = 0; // nr of skipped virtual text cells
int fromcol_prev = -2; // start of inverting after cursor
bool noinvcur = false; // don't invert the cursor
@ -1786,14 +1785,22 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
// If the text didn't reach until the first window
// column we need to skip cells.
if (skip_cells > 0) {
if (wlv.n_extra > skip_cells) {
wlv.n_extra -= skip_cells;
wlv.p_extra += skip_cells;
int virt_text_len = n_attr;
if (virt_text_len > skip_cells) {
int len = mb_charlen2bytelen(wlv.p_extra, skip_cells);
wlv.n_extra -= len;
wlv.p_extra += len;
n_attr -= skip_cells;
// Skipped cells needed to be accounted for in vcol.
skipped_cells += skip_cells;
skip_cells = 0;
} else {
// the whole text is left of the window, drop
// it and advance to the next one
skip_cells -= wlv.n_extra;
skip_cells -= virt_text_len;
// Skipped cells needed to be accounted for in vcol.
skipped_cells += virt_text_len;
n_attr = 0;
wlv.n_extra = 0;
}
}
@ -2969,6 +2976,13 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
n_skip--;
}
// The skipped cells need to be accounted for in vcol.
if (wlv.draw_state > WL_STC
&& skipped_cells > 0) {
wlv.vcol += skipped_cells;
skipped_cells = 0;
}
// Only advance the "wlv.vcol" when after the 'number' or
// 'relativenumber' column.
if (wlv.draw_state > WL_STC

View File

@ -2024,6 +2024,24 @@ 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)
{

View File

@ -1793,6 +1793,31 @@ bbbbbbb]])
|
]]}
end)
it('tabs are the correct length with no wrap following virtual text', function()
command('set nowrap')
feed('itest<TAB>a<ESC>')
meths.buf_set_extmark(0, ns, 0, 0,
{ virt_text = { { string.rep('a', 55), 'Special' } }, virt_text_pos = 'inline' })
feed('gg$')
screen:expect { grid = [[
{28:aaaaaaaaaaaaaaaaaaaaaaaaa}test ^a |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
|
]]}
end)
end)
describe('decorations: virtual lines', function()