vim-patch:9.0.0178: cursor position wrong with virtual text before Tab

Problem:    Cursor position wrong with virtual text before Tab.
Solution:   Use the byte length, not the cell with, to compare the column.
            Correct tab size after text prop. (closes vim/vim#10866)

e428fa04a7

Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
Ibby
2023-03-26 16:09:09 +11:00
committed by bfredl
parent 43c2eaada2
commit dee3af2122
3 changed files with 116 additions and 4 deletions

View File

@@ -1084,10 +1084,6 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en
} }
if (cursor != NULL) { if (cursor != NULL) {
if ((State & MODE_INSERT) == 0 && !on_NUL) {
// cursor is after inserted text, unless on the NUL
vcol += cts.cts_cur_text_width;
}
if ((*ptr == TAB) if ((*ptr == TAB)
&& (State & MODE_NORMAL) && (State & MODE_NORMAL)
&& !wp->w_p_list && !wp->w_p_list
@@ -1096,6 +1092,10 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en
// cursor at end // cursor at end
*cursor = vcol + incr - 1; *cursor = vcol + incr - 1;
} else { } else {
if ((State & MODE_INSERT) == 0 && !on_NUL) {
// cursor is after inserted text, unless on the NUL
vcol += cts.cts_cur_text_width;
}
// cursor at start // cursor at start
*cursor = vcol + head; *cursor = vcol + head;
} }

View File

@@ -411,6 +411,7 @@ int win_lbr_chartabsize(chartabsize_T *cts, int *headp)
// First get normal size, without 'linebreak' or virtual text // First get normal size, without 'linebreak' or virtual text
int size = win_chartabsize(wp, s, vcol); int size = win_chartabsize(wp, s, vcol);
if (cts->cts_has_virt_text) { if (cts->cts_has_virt_text) {
int tab_size = size;
int charlen = *s == NUL ? 1 : utf_ptr2len(s); int charlen = *s == NUL ? 1 : utf_ptr2len(s);
int col = (int)(s - line); int col = (int)(s - line);
while (true) { while (true) {
@@ -425,6 +426,12 @@ int win_lbr_chartabsize(chartabsize_T *cts, int *headp)
if (decor.virt_text_pos == kVTInline) { if (decor.virt_text_pos == kVTInline) {
cts->cts_cur_text_width += decor.virt_text_width; cts->cts_cur_text_width += decor.virt_text_width;
size += decor.virt_text_width; size += decor.virt_text_width;
if (*s == TAB) {
// tab size changes because of the inserted text
size -= tab_size;
tab_size = win_chartabsize(wp, s, vcol + size);
size += tab_size;
}
} }
} }
} }

View File

@@ -1476,6 +1476,111 @@ bbbbbbb]])
| |
]]} ]]}
end) end)
it('cursor position is correct with virtual text attatched to hard tabs', function()
command('set noexpandtab')
feed('i')
feed('<TAB>')
feed('<TAB>')
feed('test')
feed('<ESC>')
meths.buf_set_extmark(0, ns, 0, 1,
{ virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' })
feed('0')
screen:expect { grid = [[
^ {28:virtual text} test |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
|
]]}
feed('l')
screen:expect { grid = [[
{28:virtual text} ^ test |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
|
]]}
feed('l')
screen:expect { grid = [[
{28:virtual text} ^test |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
|
]]}
feed('l')
screen:expect { grid = [[
{28:virtual text} t^est |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
|
]]}
feed('l')
screen:expect { grid = [[
{28:virtual text} te^st |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
|
]]}
end)
end) end)
describe('decorations: virtual lines', function() describe('decorations: virtual lines', function()