mirror of
https://github.com/vim/vim.git
synced 2025-09-27 04:14:06 -04:00
patch 9.0.1825: wrong cursor position with virt text and 'linebreak'
Problem: Wrong cursor position with virtual text before a whitespace character and 'linebreak'. Solution: Always set "col_adj" to "size - 1" and apply 'linebreak' after adding the size of 'breakindent' and 'showbreak'. closes: #12956 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: zeertzjq <zeertzjq@outlook.com>
This commit is contained in:
committed by
Christian Brabandt
parent
5bbcfbc4a2
commit
6e55e85f92
115
src/charset.c
115
src/charset.c
@@ -1118,14 +1118,8 @@ win_lbr_chartabsize(
|
|||||||
char_u *s = cts->cts_ptr;
|
char_u *s = cts->cts_ptr;
|
||||||
colnr_T vcol = cts->cts_vcol;
|
colnr_T vcol = cts->cts_vcol;
|
||||||
#ifdef FEAT_LINEBREAK
|
#ifdef FEAT_LINEBREAK
|
||||||
int c;
|
|
||||||
int size;
|
int size;
|
||||||
colnr_T col2;
|
|
||||||
colnr_T col_adj = 0; // vcol + screen size of tab
|
|
||||||
colnr_T colmax;
|
|
||||||
int mb_added = 0;
|
int mb_added = 0;
|
||||||
char_u *ps;
|
|
||||||
int tab_corr = (*s == TAB);
|
|
||||||
int n;
|
int n;
|
||||||
char_u *sbr;
|
char_u *sbr;
|
||||||
int no_sbr = FALSE;
|
int no_sbr = FALSE;
|
||||||
@@ -1248,55 +1242,7 @@ win_lbr_chartabsize(
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef FEAT_LINEBREAK
|
# ifdef FEAT_LINEBREAK
|
||||||
c = *s;
|
if (has_mbyte && size == 2 && MB_BYTE2LEN(*s) > 1
|
||||||
if (tab_corr)
|
|
||||||
col_adj = size - 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If 'linebreak' set check at a blank before a non-blank if the line
|
|
||||||
* needs a break here
|
|
||||||
*/
|
|
||||||
if (wp->w_p_lbr
|
|
||||||
&& VIM_ISBREAK(c)
|
|
||||||
&& !VIM_ISBREAK((int)s[1])
|
|
||||||
&& wp->w_p_wrap
|
|
||||||
&& wp->w_width != 0)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Count all characters from first non-blank after a blank up to next
|
|
||||||
* non-blank after a blank.
|
|
||||||
*/
|
|
||||||
int numberextra = win_col_off(wp);
|
|
||||||
col2 = vcol;
|
|
||||||
colmax = (colnr_T)(wp->w_width - numberextra - col_adj);
|
|
||||||
if (vcol >= colmax)
|
|
||||||
{
|
|
||||||
colmax += col_adj;
|
|
||||||
n = colmax + win_col_off2(wp);
|
|
||||||
if (n > 0)
|
|
||||||
colmax += (((vcol - colmax) / n) + 1) * n - col_adj;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
ps = s;
|
|
||||||
MB_PTR_ADV(s);
|
|
||||||
c = *s;
|
|
||||||
if (!(c != NUL
|
|
||||||
&& (VIM_ISBREAK(c)
|
|
||||||
|| (!VIM_ISBREAK(c)
|
|
||||||
&& (col2 == vcol || !VIM_ISBREAK((int)*ps))))))
|
|
||||||
break;
|
|
||||||
|
|
||||||
col2 += win_chartabsize(wp, s, col2);
|
|
||||||
if (col2 >= colmax) // doesn't fit
|
|
||||||
{
|
|
||||||
size = colmax - vcol + col_adj;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (has_mbyte && size == 2 && MB_BYTE2LEN(*s) > 1
|
|
||||||
&& wp->w_p_wrap && in_win_border(wp, vcol))
|
&& wp->w_p_wrap && in_win_border(wp, vcol))
|
||||||
{
|
{
|
||||||
++size; // Count the ">" in the last column.
|
++size; // Count the ">" in the last column.
|
||||||
@@ -1314,11 +1260,10 @@ win_lbr_chartabsize(
|
|||||||
{
|
{
|
||||||
int col_off_prev = win_col_off(wp);
|
int col_off_prev = win_col_off(wp);
|
||||||
int width2 = wp->w_width - col_off_prev + win_col_off2(wp);
|
int width2 = wp->w_width - col_off_prev + win_col_off2(wp);
|
||||||
vcol += mb_added;
|
|
||||||
#ifdef FEAT_PROP_POPUP
|
|
||||||
vcol -= wp->w_virtcol_first_char;
|
|
||||||
#endif
|
|
||||||
colnr_T wcol = vcol + col_off_prev;
|
colnr_T wcol = vcol + col_off_prev;
|
||||||
|
#ifdef FEAT_PROP_POPUP
|
||||||
|
wcol -= wp->w_virtcol_first_char;
|
||||||
|
#endif
|
||||||
colnr_T max_head_vcol = cts->cts_max_head_vcol;
|
colnr_T max_head_vcol = cts->cts_max_head_vcol;
|
||||||
int added = 0;
|
int added = 0;
|
||||||
|
|
||||||
@@ -1342,6 +1287,8 @@ win_lbr_chartabsize(
|
|||||||
if (max_head_vcol <= 0 || vcol < max_head_vcol)
|
if (max_head_vcol <= 0 || vcol < max_head_vcol)
|
||||||
head += head_prev;
|
head += head_prev;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
head_prev = 0;
|
||||||
wcol += col_off_prev;
|
wcol += col_off_prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1374,7 +1321,7 @@ win_lbr_chartabsize(
|
|||||||
else if (max_head_vcol < 0)
|
else if (max_head_vcol < 0)
|
||||||
{
|
{
|
||||||
int off = 0;
|
int off = 0;
|
||||||
if (c != NUL
|
if (*s != NUL
|
||||||
&& ((State & MODE_NORMAL) || cts->cts_start_incl))
|
&& ((State & MODE_NORMAL) || cts->cts_start_incl))
|
||||||
off += cts->cts_cur_text_width;
|
off += cts->cts_cur_text_width;
|
||||||
if (off >= prev_rem)
|
if (off >= prev_rem)
|
||||||
@@ -1386,8 +1333,56 @@ win_lbr_chartabsize(
|
|||||||
|
|
||||||
size += added;
|
size += added;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (headp != NULL)
|
if (headp != NULL)
|
||||||
*headp = head;
|
*headp = head;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If 'linebreak' set check at a blank before a non-blank if the line
|
||||||
|
* needs a break here
|
||||||
|
*/
|
||||||
|
if (wp->w_p_lbr
|
||||||
|
&& VIM_ISBREAK((int)s[0])
|
||||||
|
&& !VIM_ISBREAK((int)s[1])
|
||||||
|
&& wp->w_p_wrap
|
||||||
|
&& wp->w_width != 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Count all characters from first non-blank after a blank up to next
|
||||||
|
* non-blank after a blank.
|
||||||
|
*/
|
||||||
|
int numberextra = win_col_off(wp);
|
||||||
|
colnr_T col_adj = size - 1;
|
||||||
|
colnr_T colmax = (colnr_T)(wp->w_width - numberextra - col_adj);
|
||||||
|
if (vcol >= colmax)
|
||||||
|
{
|
||||||
|
colmax += col_adj;
|
||||||
|
n = colmax + win_col_off2(wp);
|
||||||
|
if (n > 0)
|
||||||
|
colmax += (((vcol - colmax) / n) + 1) * n - col_adj;
|
||||||
|
}
|
||||||
|
|
||||||
|
colnr_T vcol2 = vcol;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
char_u *ps = s;
|
||||||
|
MB_PTR_ADV(s);
|
||||||
|
int c = *s;
|
||||||
|
if (!(c != NUL
|
||||||
|
&& (VIM_ISBREAK(c)
|
||||||
|
|| (!VIM_ISBREAK(c)
|
||||||
|
&& (vcol2 == vcol || !VIM_ISBREAK((int)*ps))))))
|
||||||
|
break;
|
||||||
|
|
||||||
|
vcol2 += win_chartabsize(wp, s, vcol2);
|
||||||
|
if (vcol2 >= colmax) // doesn't fit
|
||||||
|
{
|
||||||
|
size = colmax - vcol + col_adj;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
@@ -0,0 +1,6 @@
|
|||||||
|
|a+0&#ffffff0@49
|
||||||
|
| @1|++0#4040ff13&|b+0#e000e06&@9| +0#0000000&@36
|
||||||
|
@2|++0#4040ff13&|c+0#0000000&@43>c| @1
|
||||||
|
|~+0#4040ff13&| @48
|
||||||
|
|~| @48
|
||||||
|
| +0#0000000&@31|1|,|9|6|-|1|4|8| @5|A|l@1|
|
@@ -0,0 +1,6 @@
|
|||||||
|
|a+0&#ffffff0@44|b+0#e000e06&@4
|
||||||
|
| +0#0000000&@1|++0#4040ff13&|b+0#e000e06&@4| +0#0000000&@41
|
||||||
|
@2|++0#4040ff13&|c+0#0000000&@43>c| @1
|
||||||
|
|~+0#4040ff13&| @48
|
||||||
|
|~| @48
|
||||||
|
| +0#0000000&@31|1|,|9|1|-|1|4|8| @5|A|l@1|
|
@@ -2791,6 +2791,25 @@ func Test_prop_before_tab_skipcol()
|
|||||||
call StopVimInTerminal(buf)
|
call StopVimInTerminal(buf)
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_prop_inserts_text_before_linebreak()
|
||||||
|
CheckRunVimInTerminal
|
||||||
|
|
||||||
|
let lines =<< trim END
|
||||||
|
setlocal linebreak showbreak=+ breakindent breakindentopt=shift:2
|
||||||
|
call setline(1, repeat('a', 50) .. ' ' .. repeat('c', 45))
|
||||||
|
call prop_type_add('theprop', #{highlight: 'Special'})
|
||||||
|
call prop_add(1, 51, #{type: 'theprop', text: repeat('b', 10), text_wrap: 'wrap'})
|
||||||
|
normal! $
|
||||||
|
END
|
||||||
|
call writefile(lines, 'XscriptPropsBeforeLinebreak', 'D')
|
||||||
|
let buf = RunVimInTerminal('-S XscriptPropsBeforeLinebreak', #{rows: 6, cols: 50})
|
||||||
|
call VerifyScreenDump(buf, 'Test_prop_inserts_text_before_linebreak_1', {})
|
||||||
|
call term_sendkeys(buf, '05x$')
|
||||||
|
call VerifyScreenDump(buf, 'Test_prop_inserts_text_before_linebreak_2', {})
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_prop_inserts_text_lcs_extends()
|
func Test_prop_inserts_text_lcs_extends()
|
||||||
CheckRunVimInTerminal
|
CheckRunVimInTerminal
|
||||||
|
|
||||||
|
@@ -699,6 +699,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 */
|
||||||
|
/**/
|
||||||
|
1825,
|
||||||
/**/
|
/**/
|
||||||
1824,
|
1824,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user