patch 9.0.0179: cursor pos wrong with wrapping virtual text in empty line
Problem: Cursor position wrong with wrapping virtual text in empty line. Solution: Adjust handling of an empty line. (closes #10875)
This commit is contained in:
@ -759,6 +759,14 @@ linetabsize_col(int startcol, char_u *s)
|
|||||||
init_chartabsize_arg(&cts, curwin, 0, startcol, s, s);
|
init_chartabsize_arg(&cts, curwin, 0, startcol, s, s);
|
||||||
while (*cts.cts_ptr != NUL)
|
while (*cts.cts_ptr != NUL)
|
||||||
cts.cts_vcol += lbr_chartabsize_adv(&cts);
|
cts.cts_vcol += lbr_chartabsize_adv(&cts);
|
||||||
|
#ifdef FEAT_PROP_POPUP
|
||||||
|
if (cts.cts_has_prop_with_text && cts.cts_ptr == cts.cts_line)
|
||||||
|
{
|
||||||
|
// check for virtual text in an empty line
|
||||||
|
(void)lbr_chartabsize_adv(&cts);
|
||||||
|
cts.cts_vcol += cts.cts_cur_text_width;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
clear_chartabsize_arg(&cts);
|
clear_chartabsize_arg(&cts);
|
||||||
return (int)cts.cts_vcol;
|
return (int)cts.cts_vcol;
|
||||||
}
|
}
|
||||||
@ -772,16 +780,31 @@ win_linetabsize(win_T *wp, linenr_T lnum, char_u *line, colnr_T len)
|
|||||||
chartabsize_T cts;
|
chartabsize_T cts;
|
||||||
|
|
||||||
init_chartabsize_arg(&cts, wp, lnum, 0, line, line);
|
init_chartabsize_arg(&cts, wp, lnum, 0, line, line);
|
||||||
#ifdef FEAT_PROP_POPUP
|
win_linetabsize_cts(&cts, len);
|
||||||
cts.cts_with_trailing = len == MAXCOL;
|
|
||||||
#endif
|
|
||||||
for ( ; *cts.cts_ptr != NUL && (len == MAXCOL || cts.cts_ptr < line + len);
|
|
||||||
MB_PTR_ADV(cts.cts_ptr))
|
|
||||||
cts.cts_vcol += win_lbr_chartabsize(&cts, NULL);
|
|
||||||
clear_chartabsize_arg(&cts);
|
clear_chartabsize_arg(&cts);
|
||||||
return (int)cts.cts_vcol;
|
return (int)cts.cts_vcol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
win_linetabsize_cts(chartabsize_T *cts, colnr_T len)
|
||||||
|
{
|
||||||
|
#ifdef FEAT_PROP_POPUP
|
||||||
|
cts->cts_with_trailing = len == MAXCOL;
|
||||||
|
#endif
|
||||||
|
for ( ; *cts->cts_ptr != NUL && (len == MAXCOL || cts->cts_ptr < cts->cts_line + len);
|
||||||
|
MB_PTR_ADV(cts->cts_ptr))
|
||||||
|
cts->cts_vcol += win_lbr_chartabsize(cts, NULL);
|
||||||
|
#ifdef FEAT_PROP_POPUP
|
||||||
|
// check for a virtual text on an empty line
|
||||||
|
if (cts->cts_has_prop_with_text && *cts->cts_ptr == NUL
|
||||||
|
&& cts->cts_ptr == cts->cts_line)
|
||||||
|
{
|
||||||
|
(void)win_lbr_chartabsize(cts, NULL);
|
||||||
|
cts->cts_vcol += cts->cts_cur_text_width;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return TRUE if 'c' is a normal identifier character:
|
* Return TRUE if 'c' is a normal identifier character:
|
||||||
* Letters and characters from the 'isident' option.
|
* Letters and characters from the 'isident' option.
|
||||||
@ -1128,10 +1151,10 @@ win_lbr_chartabsize(
|
|||||||
size = win_chartabsize(wp, s, vcol);
|
size = win_chartabsize(wp, s, vcol);
|
||||||
|
|
||||||
# ifdef FEAT_PROP_POPUP
|
# ifdef FEAT_PROP_POPUP
|
||||||
if (cts->cts_has_prop_with_text && *line != NUL)
|
if (cts->cts_has_prop_with_text)
|
||||||
{
|
{
|
||||||
int tab_size = size;
|
int tab_size = size;
|
||||||
int charlen = mb_ptr2len(s);
|
int charlen = *s == NUL ? 1 : mb_ptr2len(s);
|
||||||
int i;
|
int i;
|
||||||
int col = (int)(s - line);
|
int col = (int)(s - line);
|
||||||
garray_T *gap = &wp->w_buffer->b_textprop_text;
|
garray_T *gap = &wp->w_buffer->b_textprop_text;
|
||||||
@ -1412,6 +1435,9 @@ getvcol(
|
|||||||
int ts = wp->w_buffer->b_p_ts;
|
int ts = wp->w_buffer->b_p_ts;
|
||||||
int c;
|
int c;
|
||||||
chartabsize_T cts;
|
chartabsize_T cts;
|
||||||
|
#ifdef FEAT_PROP_POPUP
|
||||||
|
int on_NUL = FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
vcol = 0;
|
vcol = 0;
|
||||||
line = ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
|
line = ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
|
||||||
@ -1512,6 +1538,11 @@ getvcol(
|
|||||||
if (*cts.cts_ptr == NUL)
|
if (*cts.cts_ptr == NUL)
|
||||||
{
|
{
|
||||||
incr = 1; // NUL at end of line only takes one column
|
incr = 1; // NUL at end of line only takes one column
|
||||||
|
#ifdef FEAT_PROP_POPUP
|
||||||
|
if (cts.cts_cur_text_width > 0)
|
||||||
|
incr = cts.cts_cur_text_width;
|
||||||
|
on_NUL = TRUE;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1544,8 +1575,8 @@ getvcol(
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef FEAT_PROP_POPUP
|
#ifdef FEAT_PROP_POPUP
|
||||||
if ((State & MODE_INSERT) == 0)
|
if ((State & MODE_INSERT) == 0 && !on_NUL)
|
||||||
// cursor is after inserted text
|
// cursor is after inserted text, unless on the NUL
|
||||||
vcol += cts.cts_cur_text_width;
|
vcol += cts.cts_cur_text_width;
|
||||||
#endif
|
#endif
|
||||||
*cursor = vcol + head; // cursor at start
|
*cursor = vcol + head; // cursor at start
|
||||||
|
|||||||
14
src/misc1.c
14
src/misc1.c
@ -399,11 +399,19 @@ plines_win_nofold(win_T *wp, linenr_T lnum)
|
|||||||
char_u *s;
|
char_u *s;
|
||||||
long col;
|
long col;
|
||||||
int width;
|
int width;
|
||||||
|
chartabsize_T cts;
|
||||||
|
|
||||||
s = ml_get_buf(wp->w_buffer, lnum, FALSE);
|
s = ml_get_buf(wp->w_buffer, lnum, FALSE);
|
||||||
if (*s == NUL) // empty line
|
init_chartabsize_arg(&cts, wp, lnum, 0, s, s);
|
||||||
return 1;
|
if (*s == NUL
|
||||||
col = win_linetabsize(wp, lnum, s, (colnr_T)MAXCOL);
|
#ifdef FEAT_PROP_POPUP
|
||||||
|
&& !cts.cts_has_prop_with_text
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
return 1; // be quick for an empty line
|
||||||
|
win_linetabsize_cts(&cts, (colnr_T)MAXCOL);
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
|
col = (int)cts.cts_vcol;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If list mode is on, then the '$' at the end of the line may take up one
|
* If list mode is on, then the '$' at the end of the line may take up one
|
||||||
|
|||||||
@ -18,6 +18,7 @@ int chartabsize(char_u *p, colnr_T col);
|
|||||||
int linetabsize(char_u *s);
|
int linetabsize(char_u *s);
|
||||||
int linetabsize_col(int startcol, char_u *s);
|
int linetabsize_col(int startcol, char_u *s);
|
||||||
int win_linetabsize(win_T *wp, linenr_T lnum, char_u *line, colnr_T len);
|
int win_linetabsize(win_T *wp, linenr_T lnum, char_u *line, colnr_T len);
|
||||||
|
void win_linetabsize_cts(chartabsize_T *cts, colnr_T len);
|
||||||
int vim_isIDc(int c);
|
int vim_isIDc(int c);
|
||||||
int vim_isNormalIDc(int c);
|
int vim_isNormalIDc(int c);
|
||||||
int vim_iswordc(int c);
|
int vim_iswordc(int c);
|
||||||
|
|||||||
8
src/testdir/dumps/Test_prop_with_text_empty_line_1.dump
Normal file
8
src/testdir/dumps/Test_prop_with_text_empty_line_1.dump
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
>X+0&#ffff4012@59
|
||||||
|
|a+0&#ffffff0@2| @56
|
||||||
|
|X+0&#ffff4012@59
|
||||||
|
@1| +0&#ffffff0@58
|
||||||
|
|b@5| @53
|
||||||
|
|~+0#4040ff13&| @58
|
||||||
|
|~| @58
|
||||||
|
| +0#0000000&@41|1|,|0|-|1| @8|A|l@1|
|
||||||
8
src/testdir/dumps/Test_prop_with_text_empty_line_2.dump
Normal file
8
src/testdir/dumps/Test_prop_with_text_empty_line_2.dump
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
>X+0&#ffff4012@59
|
||||||
|
|a+0&#ffffff0@2| @56
|
||||||
|
|X+0&#ffff4012@59
|
||||||
|
@1| +0&#ffffff0@58
|
||||||
|
|b@5| @53
|
||||||
|
|~+0#4040ff13&| @58
|
||||||
|
|~| @58
|
||||||
|
| +0#0000000&@41|1|,|0|-|1| @8|A|l@1|
|
||||||
8
src/testdir/dumps/Test_prop_with_text_empty_line_3.dump
Normal file
8
src/testdir/dumps/Test_prop_with_text_empty_line_3.dump
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
|X+0&#ffff4012@59
|
||||||
|
|a+0&#ffffff0@1>a| @56
|
||||||
|
|X+0&#ffff4012@59
|
||||||
|
@1| +0&#ffffff0@58
|
||||||
|
|b@5| @53
|
||||||
|
|~+0#4040ff13&| @58
|
||||||
|
|~| @58
|
||||||
|
| +0#0000000&@41|2|,|3| @10|A|l@1|
|
||||||
8
src/testdir/dumps/Test_prop_with_text_empty_line_4.dump
Normal file
8
src/testdir/dumps/Test_prop_with_text_empty_line_4.dump
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
|X+0&#ffff4012@59
|
||||||
|
|a+0&#ffffff0@2| @56
|
||||||
|
>X+0&#ffff4012@59
|
||||||
|
@1| +0&#ffffff0@58
|
||||||
|
|b@5| @53
|
||||||
|
|~+0#4040ff13&| @58
|
||||||
|
|~| @58
|
||||||
|
| +0#0000000&@41|3|,|0|-|1| @8|A|l@1|
|
||||||
8
src/testdir/dumps/Test_prop_with_text_empty_line_5.dump
Normal file
8
src/testdir/dumps/Test_prop_with_text_empty_line_5.dump
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
|X+0&#ffff4012@59
|
||||||
|
|a+0&#ffffff0@2| @56
|
||||||
|
|X+0&#ffff4012@59
|
||||||
|
@1| +0&#ffffff0@58
|
||||||
|
|b@4>b| @53
|
||||||
|
|~+0#4040ff13&| @58
|
||||||
|
|~| @58
|
||||||
|
| +0#0000000&@41|4|,|6| @10|A|l@1|
|
||||||
@ -2557,6 +2557,32 @@ func Test_props_with_text_after_truncated()
|
|||||||
call delete('XscriptPropsWithTextAfterTrunc')
|
call delete('XscriptPropsWithTextAfterTrunc')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_props_with_text_empty_line()
|
||||||
|
CheckRunVimInTerminal
|
||||||
|
|
||||||
|
let lines =<< trim END
|
||||||
|
call setline(1, ['', 'aaa', '', 'bbbbbb'])
|
||||||
|
call prop_type_add('prop1', #{highlight: 'Search'})
|
||||||
|
call prop_add(1, 1, #{type: 'prop1', text_wrap: 'wrap', text: repeat('X', &columns)})
|
||||||
|
call prop_add(3, 1, #{type: 'prop1', text_wrap: 'wrap', text: repeat('X', &columns + 1)})
|
||||||
|
normal gg0
|
||||||
|
END
|
||||||
|
call writefile(lines, 'XscriptPropsWithTextEmptyLine')
|
||||||
|
let buf = RunVimInTerminal('-S XscriptPropsWithTextEmptyLine', #{rows: 8, cols: 60})
|
||||||
|
call VerifyScreenDump(buf, 'Test_prop_with_text_empty_line_1', {})
|
||||||
|
call term_sendkeys(buf, "$")
|
||||||
|
call VerifyScreenDump(buf, 'Test_prop_with_text_empty_line_2', {})
|
||||||
|
call term_sendkeys(buf, "j")
|
||||||
|
call VerifyScreenDump(buf, 'Test_prop_with_text_empty_line_3', {})
|
||||||
|
call term_sendkeys(buf, "j")
|
||||||
|
call VerifyScreenDump(buf, 'Test_prop_with_text_empty_line_4', {})
|
||||||
|
call term_sendkeys(buf, "j")
|
||||||
|
call VerifyScreenDump(buf, 'Test_prop_with_text_empty_line_5', {})
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
call delete('XscriptPropsWithTextEmptyLine')
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_props_with_text_after_wraps()
|
func Test_props_with_text_after_wraps()
|
||||||
CheckRunVimInTerminal
|
CheckRunVimInTerminal
|
||||||
|
|
||||||
|
|||||||
@ -735,6 +735,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
179,
|
||||||
/**/
|
/**/
|
||||||
178,
|
178,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user