patch 9.2.0289: 'linebreak' may lead to wrong Visual block highlighting

Problem:  'linebreak' may lead to wrong Visual block highlighting when
          end char occupies multiple cells (after 7.4.467).
Solution: Exclude 'linebreak' from the ending column instead of setting
          'virtualedit' temporarily (zeertzjq).

fixes:  #19898
closes: #19900

Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
zeertzjq
2026-04-03 09:48:49 +00:00
committed by Christian Brabandt
parent af58a9f5e9
commit 23be1889d1
30 changed files with 227 additions and 108 deletions
+1 -1
View File
@@ -1263,7 +1263,7 @@ ins_char_bytes(char_u *buf, int charlen)
// characters (zero if it's a TAB). Count the number of bytes to
// be deleted to make room for the new character, counting screen
// cells. May result in adding spaces to fill a gap.
getvcol(curwin, &curwin->w_cursor, NULL, &vcol, NULL);
getvcol(curwin, &curwin->w_cursor, NULL, &vcol, NULL, 0);
new_vcol = vcol + chartabsize(buf, vcol);
while (oldp[col + oldlen] != NUL && vcol < new_vcol)
{
+40 -19
View File
@@ -905,7 +905,7 @@ win_linetabsize_cts(chartabsize_T *cts, colnr_T len)
for ( ; *cts->cts_ptr != NUL && (len == MAXCOL || cts->cts_ptr < cts->cts_line + len);
MB_PTR_ADV(cts->cts_ptr))
{
vcol += win_lbr_chartabsize(cts, NULL);
vcol += win_lbr_chartabsize(cts, NULL, NULL);
if (vcol > MAXCOL)
{
cts->cts_vcol = MAXCOL;
@@ -919,7 +919,7 @@ win_linetabsize_cts(chartabsize_T *cts, colnr_T len)
if (len == MAXCOL && cts->cts_has_prop_with_text && *cts->cts_ptr == NUL)
{
int head = 0;
(void)win_lbr_chartabsize(cts, &head);
(void)win_lbr_chartabsize(cts, &head, NULL);
vcol += cts->cts_cur_text_width + head;
// when properties are above or below the empty line must also be
// counted
@@ -1186,7 +1186,7 @@ lbr_chartabsize(chartabsize_T *cts)
RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, cts->cts_ptr, cts->cts_vcol)
#if defined(FEAT_LINEBREAK) || defined(FEAT_PROP_POPUP)
}
return win_lbr_chartabsize(cts, NULL);
return win_lbr_chartabsize(cts, NULL, NULL);
#endif
}
@@ -1209,19 +1209,24 @@ lbr_chartabsize_adv(chartabsize_T *cts)
* inserts text.
* This function is used very often, keep it fast!!!!
*
* If "headp" not NULL, set "*headp" to the size of 'showbreak'/'breakindent'
* If "headp" isn't NULL, set "*headp" to the size of 'showbreak'/'breakindent'
* included in the return value.
* When "cts->cts_max_head_vcol" is positive, only count in "*headp" the size
* of 'showbreak'/'breakindent' before "cts->cts_max_head_vcol".
* When "cts->cts_max_head_vcol" is negative, only count in "*headp" the size
* of 'showbreak'/'breakindent' before where cursor should be placed.
*
* Warning: "*headp" may not be set if it's 0, init to 0 before calling.
* If "tailp" isn't NULL, set "*tailp" to the size of 'linebreak' included in
* the return value.
*
* Warning: "*headp" and "*tailp" may not be set if the value is 0, init to 0
* before calling.
*/
int
win_lbr_chartabsize(
chartabsize_T *cts,
int *headp UNUSED)
int *headp UNUSED,
int *tailp UNUSED)
{
win_T *wp = cts->cts_win;
#if defined(FEAT_PROP_POPUP) || defined(FEAT_LINEBREAK)
@@ -1470,6 +1475,7 @@ win_lbr_chartabsize(
if (headp != NULL)
*headp = head;
int size_before_lbr = size;
int need_lbr = FALSE;
/*
* If 'linebreak' set check at a blank before a non-blank if the line
@@ -1522,6 +1528,9 @@ win_lbr_chartabsize(
}
}
if (tailp != NULL)
*tailp = size - size_before_lbr;
# ifdef FEAT_PROP_POPUP
size += cts->cts_first_char;
# endif
@@ -1598,6 +1607,10 @@ in_win_border(win_T *wp, colnr_T vcol)
* cursor: where the cursor is on this character (first char, except for TAB)
* end: on the last position of this character (TAB, ctrl)
*
* When 'linebreak' follows this character, "end" is set to the position before
* 'linebreak' if "flags" contains GETVCOL_END_EXCL_LBR, otherwise it's set to
* the end of 'linebreak'.
*
* This is used very often, keep it fast!
*/
void
@@ -1606,13 +1619,15 @@ getvcol(
pos_T *pos,
colnr_T *start,
colnr_T *cursor,
colnr_T *end)
colnr_T *end,
int flags)
{
colnr_T vcol;
char_u *ptr; // points to current char
char_u *line; // start of the line
int incr;
int head;
int tail;
#ifdef FEAT_VARTABS
int *vts = wp->w_buffer->b_p_vts_array;
#endif
@@ -1693,6 +1708,8 @@ getvcol(
vcol += incr;
ptr = next_ptr;
}
tail = 0;
}
else
{
@@ -1701,7 +1718,8 @@ getvcol(
// A tab gets expanded, depending on the current column.
// Other things also take up space.
head = 0;
incr = win_lbr_chartabsize(&cts, &head);
tail = 0;
incr = win_lbr_chartabsize(&cts, &head, &tail);
// make sure we don't go past the end of the line
if (*cts.cts_ptr == NUL)
{
@@ -1736,7 +1754,7 @@ getvcol(
if (start != NULL)
*start = vcol + head;
if (end != NULL)
*end = vcol + incr - 1;
*end = vcol + incr - (flags & GETVCOL_END_EXCL_LBR ? tail : 0) - 1;
if (cursor != NULL)
{
if (*ptr == TAB
@@ -1746,6 +1764,7 @@ getvcol(
&& !(VIsual_active
&& (*p_sel == 'e' || LTOREQ_POS(*pos, VIsual)))
)
// TODO: subtracting "tail" may lead to better cursor position
*cursor = vcol + incr - 1; // cursor at end
else
{
@@ -1775,9 +1794,9 @@ getvcol_nolist(pos_T *posp)
curwin->w_p_list = FALSE;
if (posp->coladd)
getvvcol(curwin, posp, NULL, &vcol, NULL);
getvvcol(curwin, posp, NULL, &vcol, NULL, 0);
else
getvcol(curwin, posp, NULL, &vcol, NULL);
getvcol(curwin, posp, NULL, &vcol, NULL, 0);
curwin->w_p_list = list_save;
return vcol;
}
@@ -1791,7 +1810,8 @@ getvvcol(
pos_T *pos,
colnr_T *start,
colnr_T *cursor,
colnr_T *end)
colnr_T *end,
int flags)
{
colnr_T col;
colnr_T coladd;
@@ -1801,7 +1821,7 @@ getvvcol(
if (virtual_active())
{
// For virtual mode, only want one value
getvcol(wp, pos, &col, NULL, NULL);
getvcol(wp, pos, &col, NULL, NULL, flags);
coladd = pos->coladd;
endadd = 0;
@@ -1829,7 +1849,7 @@ getvvcol(
*end = col + endadd;
}
else
getvcol(wp, pos, start, cursor, end);
getvcol(wp, pos, start, cursor, end, flags);
}
/*
@@ -1842,19 +1862,20 @@ getvcols(
pos_T *pos1,
pos_T *pos2,
colnr_T *left,
colnr_T *right)
colnr_T *right,
int flags)
{
colnr_T from1, from2, to1, to2;
if (LT_POSP(pos1, pos2))
{
getvvcol(wp, pos1, &from1, NULL, &to1);
getvvcol(wp, pos2, &from2, NULL, &to2);
getvvcol(wp, pos1, &from1, NULL, &to1, flags);
getvvcol(wp, pos2, &from2, NULL, &to2, flags);
}
else
{
getvvcol(wp, pos2, &from1, NULL, &to1);
getvvcol(wp, pos1, &from2, NULL, &to2);
getvvcol(wp, pos2, &from1, NULL, &to1, flags);
getvvcol(wp, pos1, &from2, NULL, &to2, flags);
}
if (from2 < from1)
*left = from2;
+9 -9
View File
@@ -978,7 +978,7 @@ get_indent_nolabel (linenr_T lnum) // XXX
fp.col = (colnr_T)(p - l);
fp.lnum = lnum;
getvcol(curwin, &fp, &col, NULL, NULL);
getvcol(curwin, &fp, &col, NULL, NULL, 0);
return (int)col;
}
@@ -1062,7 +1062,7 @@ cin_first_id_amount(void)
p = skipwhite(p + len);
fp.lnum = curwin->w_cursor.lnum;
fp.col = (colnr_T)(p - line);
getvcol(curwin, &fp, &col, NULL, NULL);
getvcol(curwin, &fp, &col, NULL, NULL, 0);
return (int)col;
}
@@ -1110,7 +1110,7 @@ cin_get_equal_amount(linenr_T lnum)
fp.lnum = lnum;
fp.col = (colnr_T)(s - line);
getvcol(curwin, &fp, &col, NULL, NULL);
getvcol(curwin, &fp, &col, NULL, NULL, 0);
return (int)col;
}
@@ -1705,7 +1705,7 @@ get_baseclass_amount(int col)
else
{
curwin->w_cursor.col = col;
getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL, 0);
amount = (int)vcol;
}
if (amount < curbuf->b_ind_cpp_baseclass)
@@ -2265,7 +2265,7 @@ get_c_indent(void)
if (trypos != NULL)
{
// find how indented the line beginning the comment is
getvcol(curwin, trypos, &col, NULL, NULL);
getvcol(curwin, trypos, &col, NULL, NULL, 0);
amount = col;
goto theend;
}
@@ -2287,7 +2287,7 @@ get_c_indent(void)
int done = FALSE;
// find how indented the line beginning the comment is
getvcol(curwin, comment_pos, &col, NULL, NULL);
getvcol(curwin, comment_pos, &col, NULL, NULL, 0);
amount = col;
*lead_start = NUL;
*lead_middle = NUL;
@@ -2413,7 +2413,7 @@ get_c_indent(void)
if (*look != NUL) // if something after it
comment_pos->col = (colnr_T)(skipwhite(look) - start);
}
getvcol(curwin, comment_pos, &col, NULL, NULL);
getvcol(curwin, comment_pos, &col, NULL, NULL, 0);
amount = col;
if (curbuf->b_ind_in_comment2 || *look == NUL)
amount += curbuf->b_ind_in_comment;
@@ -2615,7 +2615,7 @@ get_c_indent(void)
// if we did the above "if".
if (our_paren_pos.col > 0)
{
getvcol(curwin, &our_paren_pos, &col, NULL, NULL);
getvcol(curwin, &our_paren_pos, &col, NULL, NULL, 0);
if (cur_amount > (int)col)
cur_amount = col;
}
@@ -2704,7 +2704,7 @@ get_c_indent(void)
look = skipwhite(start);
if (*look == '{')
{
getvcol(curwin, trypos, &col, NULL, NULL);
getvcol(curwin, trypos, &col, NULL, NULL, 0);
amount = col;
if (*start == '{')
start_brace = BRACE_IN_COL0;
+11 -9
View File
@@ -1418,7 +1418,8 @@ win_line(
wlv.fromcol = 0;
else
{
getvvcol(wp, top, (colnr_T *)&wlv.fromcol, NULL, NULL);
getvvcol(wp, top, (colnr_T *)&wlv.fromcol,
NULL, NULL, 0);
if (gchar_pos(top) == NUL)
wlv.tocol = wlv.fromcol + 1;
}
@@ -1437,11 +1438,11 @@ win_line(
pos = *bot;
if (*p_sel == 'e')
getvvcol(wp, &pos, (colnr_T *)&wlv.tocol,
NULL, NULL);
NULL, NULL, 0);
else
{
getvvcol(wp, &pos, NULL, NULL,
(colnr_T *)&wlv.tocol);
(colnr_T *)&wlv.tocol, 0);
++wlv.tocol;
}
}
@@ -1480,14 +1481,14 @@ win_line(
{
if (lnum == curwin->w_cursor.lnum)
getvcol(curwin, &(curwin->w_cursor),
(colnr_T *)&wlv.fromcol, NULL, NULL);
(colnr_T *)&wlv.fromcol, NULL, NULL, 0);
else
wlv.fromcol = 0;
if (lnum == curwin->w_cursor.lnum + search_match_lines)
{
pos.lnum = lnum;
pos.col = search_match_endcol;
getvcol(curwin, &pos, (colnr_T *)&wlv.tocol, NULL, NULL);
getvcol(curwin, &pos, (colnr_T *)&wlv.tocol, NULL, NULL, 0);
}
else
wlv.tocol = MAXCOL;
@@ -1761,7 +1762,7 @@ win_line(
{
chartabsize_T cts;
init_chartabsize_arg(&cts, wp, lnum, 0, line, line);
(void)win_lbr_chartabsize(&cts, NULL);
(void)win_lbr_chartabsize(&cts, NULL, NULL);
vcol_first_char = cts.cts_first_char;
clear_chartabsize_arg(&cts);
}
@@ -1785,7 +1786,7 @@ win_line(
while (cts.cts_vcol < v)
{
head = 0;
charsize = win_lbr_chartabsize(&cts, &head);
charsize = win_lbr_chartabsize(&cts, &head, NULL);
cts.cts_vcol += charsize;
prev_ptr = cts.cts_ptr;
if (*prev_ptr == NUL)
@@ -3120,7 +3121,8 @@ win_line(
// do not want virtual text counted here
cts.cts_has_prop_with_text = FALSE;
# endif
wlv.n_extra = win_lbr_chartabsize(&cts, NULL) - 1;
// TODO: consider using "tailp" here
wlv.n_extra = win_lbr_chartabsize(&cts, NULL, NULL) - 1;
clear_chartabsize_arg(&cts);
if (on_last_col && c != TAB)
@@ -3780,7 +3782,7 @@ win_line(
colnr_T tcol;
if (preedit_end_col == MAXCOL)
getvcol(curwin, &(wp->w_cursor), &tcol, NULL, NULL);
getvcol(curwin, &(wp->w_cursor), &tcol, NULL, NULL, 0);
else
tcol = preedit_end_col;
if ((long)preedit_start_col <= wlv.vcol && wlv.vcol < (long)tcol)
+4 -11
View File
@@ -769,7 +769,7 @@ win_redr_ruler(win_T *wp, int always, int ignore_pum)
if (wp->w_p_list && wp->w_lcs_chars.tab1 == NUL)
{
wp->w_p_list = FALSE;
getvvcol(wp, &wp->w_cursor, NULL, &virtcol, NULL);
getvvcol(wp, &wp->w_cursor, NULL, &virtcol, NULL, 0);
wp->w_p_list = TRUE;
}
@@ -2078,17 +2078,10 @@ win_update(win_T *wp)
if (VIsual_mode == Ctrl_V)
{
colnr_T fromc, toc;
#if defined(FEAT_LINEBREAK)
int save_ve_flags = curwin->w_ve_flags;
if (curwin->w_p_lbr)
curwin->w_ve_flags = VE_ALL;
#endif
getvcols(wp, &VIsual, &curwin->w_cursor, &fromc, &toc);
getvcols(wp, &VIsual, &curwin->w_cursor, &fromc, &toc,
GETVCOL_END_EXCL_LBR);
++toc;
#if defined(FEAT_LINEBREAK)
curwin->w_ve_flags = save_ve_flags;
#endif
// Highlight to the end of the line, unless 'virtualedit' has
// "block".
if (curwin->w_curswant == MAXCOL)
@@ -2110,7 +2103,7 @@ win_update(win_T *wp)
colnr_T t;
pos.col = (int)ml_get_buf_len(wp->w_buffer, pos.lnum);
getvvcol(wp, &pos, NULL, NULL, &t);
getvvcol(wp, &pos, NULL, NULL, &t, 0);
if (toc < t)
toc = t;
}
+3 -3
View File
@@ -3354,7 +3354,7 @@ replace_do_bs(int limit_col)
{
// Get the number of screen cells used by the character we are
// going to delete.
getvcol(curwin, &curwin->w_cursor, NULL, &start_vcol, NULL);
getvcol(curwin, &curwin->w_cursor, NULL, &start_vcol, NULL, 0);
orig_vcols = chartabsize(ml_get_cursor(), start_vcol);
}
if (has_mbyte)
@@ -5152,8 +5152,8 @@ ins_tab(void)
}
// compute virtual column numbers of first white and cursor
getvcol(curwin, &fpos, &vcol, NULL, NULL);
getvcol(curwin, cursor, &want_vcol, NULL, NULL);
getvcol(curwin, &fpos, &vcol, NULL, NULL, 0);
getvcol(curwin, cursor, &want_vcol, NULL, NULL, 0);
init_chartabsize_arg(&cts, curwin, 0, vcol, tab, tab);
+3 -3
View File
@@ -6186,8 +6186,8 @@ getregionpos(
int lbr_saved = reset_lbr();
#endif
getvvcol(curwin, p1, &sc1, NULL, &ec1);
getvvcol(curwin, p2, &sc2, NULL, &ec2);
getvvcol(curwin, p1, &sc1, NULL, &ec1, 0);
getvvcol(curwin, p2, &sc2, NULL, &ec2, 0);
#ifdef FEAT_LINEBREAK
restore_lbr(lbr_saved);
@@ -12782,7 +12782,7 @@ f_virtcol(typval_T *argvars, typval_T *rettv)
if (fp->col > len)
fp->col = len;
}
getvvcol(curwin, fp, &vcol_start, NULL, &vcol_end);
getvvcol(curwin, fp, &vcol_start, NULL, &vcol_end, 0);
++vcol_start;
++vcol_end;
}
+4 -2
View File
@@ -4585,11 +4585,13 @@ ex_substitute(exarg_T *eap)
print_line_no_prefix(lnum,
subflags.do_number, subflags.do_list);
getvcol(curwin, &curwin->w_cursor, &sc, NULL, NULL);
getvcol(curwin, &curwin->w_cursor,
&sc, NULL, NULL, 0);
curwin->w_cursor.col = regmatch.endpos[0].col - 1;
if (curwin->w_cursor.col < 0)
curwin->w_cursor.col = 0;
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &ec);
getvcol(curwin, &curwin->w_cursor,
NULL, NULL, &ec, 0);
curwin->w_cursor.col = regmatch.startpos[0].col;
if (subflags.do_number || curwin->w_p_nu)
{
+1 -1
View File
@@ -174,7 +174,7 @@ init_preedit_start_col(void)
if (State & MODE_CMDLINE)
preedit_start_col = cmdline_getvcol_cursor();
else if (curwin != NULL && curwin->w_buffer != NULL)
getvcol(curwin, &curwin->w_cursor, &preedit_start_col, NULL, NULL);
getvcol(curwin, &curwin->w_cursor, &preedit_start_col, NULL, NULL, 0);
// Prevent that preediting marks the buffer as changed.
xim_changed_while_preediting = curbuf->b_changed;
}
+1 -1
View File
@@ -866,7 +866,7 @@ get_number_indent(linenr_T lnum)
if (pos.lnum == 0 || *ml_get_pos(&pos) == NUL)
return -1;
getvcol(curwin, &pos, &col, NULL, NULL);
getvcol(curwin, &pos, &col, NULL, NULL, 0);
return (int)col;
}
+2 -2
View File
@@ -467,7 +467,7 @@ plines_win_col(win_T *wp, linenr_T lnum, long column)
init_chartabsize_arg(&cts, wp, lnum, 0, line, line);
while (*cts.cts_ptr != NUL && --column >= 0)
{
cts.cts_vcol += win_lbr_chartabsize(&cts, NULL);
cts.cts_vcol += win_lbr_chartabsize(&cts, NULL, NULL);
MB_PTR_ADV(cts.cts_ptr);
}
@@ -481,7 +481,7 @@ plines_win_col(win_T *wp, linenr_T lnum, long column)
col = cts.cts_vcol;
if (*cts.cts_ptr == TAB && (State & MODE_NORMAL)
&& (!wp->w_p_list || wp->w_lcs_chars.tab1))
col += win_lbr_chartabsize(&cts, NULL) - 1;
col += win_lbr_chartabsize(&cts, NULL, NULL) - 1;
clear_chartabsize_arg(&cts);
/*
+6 -6
View File
@@ -43,7 +43,7 @@ getviscol(void)
{
colnr_T x;
getvvcol(curwin, &curwin->w_cursor, &x, NULL, NULL);
getvvcol(curwin, &curwin->w_cursor, &x, NULL, NULL, 0);
return (int)x;
}
@@ -77,7 +77,7 @@ getviscol2(colnr_T col, colnr_T coladd)
pos.lnum = curwin->w_cursor.lnum;
pos.col = col;
pos.coladd = coladd;
getvvcol(curwin, &pos, &x, NULL, NULL);
getvvcol(curwin, &pos, &x, NULL, NULL, 0);
return (int)x;
}
@@ -185,7 +185,7 @@ coladvance2(
#endif
// Count a tab for what it's worth (if list mode not on)
#ifdef FEAT_LINEBREAK
csize = win_lbr_chartabsize(&cts, &head);
csize = win_lbr_chartabsize(&cts, &head, NULL);
MB_PTR_ADV(cts.cts_ptr);
#else
csize = lbr_chartabsize_adv(&cts);
@@ -298,7 +298,7 @@ coladvance2(
{
colnr_T scol, ecol;
getvcol(curwin, pos, &scol, NULL, &ecol);
getvcol(curwin, pos, &scol, NULL, &ecol, 0);
pos->coladd = ecol - scol;
}
}
@@ -606,7 +606,7 @@ check_cursor_col_win(win_T *win)
{
int cs, ce;
getvcol(win, &win->w_cursor, &cs, NULL, &ce);
getvcol(win, &win->w_cursor, &cs, NULL, &ce, 0);
if (win->w_cursor.coladd > ce - cs)
win->w_cursor.coladd = ce - cs;
}
@@ -702,7 +702,7 @@ set_leftcol(colnr_T leftcol)
// advance the cursor one more char. If this fails (last char of the
// line) adjust the scrolling.
colnr_T s, e;
getvvcol(curwin, &curwin->w_cursor, &s, NULL, &e);
getvvcol(curwin, &curwin->w_cursor, &s, NULL, &e, 0);
if (e > (colnr_T)lastcol)
{
retval = TRUE;
+5 -4
View File
@@ -663,8 +663,8 @@ do_mouse(
else if (VIsual_mode == Ctrl_V)
{
getvcols(curwin, &curwin->w_cursor, &VIsual,
&leftcol, &rightcol);
getvcol(curwin, &m_pos, NULL, &m_pos.col, NULL);
&leftcol, &rightcol, 0);
getvcol(curwin, &m_pos, NULL, &m_pos.col, NULL, 0);
if (m_pos.col < leftcol || m_pos.col > rightcol)
jump_flags = MOUSE_MAY_STOP_VIS;
}
@@ -831,7 +831,8 @@ do_mouse(
// that is in the quarter that the cursor is in.
if (VIsual_mode == Ctrl_V)
{
getvcols(curwin, &start_visual, &end_visual, &leftcol, &rightcol);
getvcols(curwin, &start_visual, &end_visual,
&leftcol, &rightcol, 0);
if (curwin->w_curswant > (leftcol + rightcol) / 2)
end_visual.col = leftcol;
else
@@ -3250,7 +3251,7 @@ vcol2col(win_T *wp, linenr_T lnum, int vcol, colnr_T *coladdp)
init_chartabsize_arg(&cts, wp, lnum, 0, line, line);
while (cts.cts_vcol < vcol && *cts.cts_ptr != NUL)
{
int size = win_lbr_chartabsize(&cts, NULL);
int size = win_lbr_chartabsize(&cts, NULL, NULL);
if (cts.cts_vcol + size > vcol)
break;
cts.cts_vcol += size;
+4 -4
View File
@@ -361,7 +361,7 @@ update_topline(void)
// Check that the cursor position is visible. Add columns for
// the marker displayed in the top-left if needed.
getvvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
getvvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL, 0);
overlap = sms_marker_overlap(curwin, -1);
if (curwin->w_skipcol + overlap > vcol)
check_topline = TRUE;
@@ -1021,7 +1021,7 @@ validate_virtcol_win(win_T *wp)
#ifdef FEAT_PROP_POPUP
wp->w_virtcol_first_char = 0;
#endif
getvvcol(wp, &wp->w_cursor, NULL, &(wp->w_virtcol), NULL);
getvvcol(wp, &wp->w_cursor, NULL, &(wp->w_virtcol), NULL, 0);
#ifdef FEAT_SYN_HL
redraw_for_cursorcolumn(wp);
#endif
@@ -1183,7 +1183,7 @@ curs_columns(
else
#endif
getvvcol(curwin, &curwin->w_cursor,
&startcol, &(curwin->w_virtcol), &endcol);
&startcol, &(curwin->w_virtcol), &endcol, 0);
// remove '$' from change command when cursor moves onto it
if (startcol > dollar_vcol)
@@ -1491,7 +1491,7 @@ textpos2screenpos(
else
# endif
{
getvcol(wp, pos, &scol, &ccol, &ecol);
getvcol(wp, pos, &scol, &ccol, &ecol, 0);
// similar to what is done in validate_cursor_col()
col = scol;
+8 -7
View File
@@ -1652,7 +1652,8 @@ clear_showcmd(void)
p_sbr = empty_option;
curwin->w_p_sbr = empty_option;
#endif
getvcols(curwin, &curwin->w_cursor, &VIsual, &leftcol, &rightcol);
getvcols(curwin, &curwin->w_cursor, &VIsual,
&leftcol, &rightcol, 0);
#ifdef FEAT_LINEBREAK
p_sbr = saved_sbr;
curwin->w_p_sbr = saved_w_sbr;
@@ -2765,7 +2766,7 @@ nv_zet(cmdarg_T *cap)
col = 0; // like the cursor is in col 0
else
#endif
getvcol(curwin, &curwin->w_cursor, &col, NULL, NULL);
getvcol(curwin, &curwin->w_cursor, &col, NULL, NULL, 0);
if ((long)col > siso)
col -= siso;
else
@@ -2786,7 +2787,7 @@ nv_zet(cmdarg_T *cap)
col = 0; // like the cursor is in col 0
else
#endif
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col);
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col, 0);
n = curwin->w_width - curwin_col_off();
if ((long)col + siso < n)
col = 0;
@@ -4295,7 +4296,7 @@ nv_csearch(cmdarg_T *cap)
{
colnr_T scol, ecol;
getvcol(curwin, &curwin->w_cursor, &scol, NULL, &ecol);
getvcol(curwin, &curwin->w_cursor, &scol, NULL, &ecol, 0);
curwin->w_cursor.coladd = ecol - scol;
}
else
@@ -5000,7 +5001,7 @@ v_swap_corners(int cmdchar)
if (cmdchar == 'O' && VIsual_mode == Ctrl_V)
{
old_cursor = curwin->w_cursor;
getvcols(curwin, &old_cursor, &VIsual, &left, &right);
getvcols(curwin, &old_cursor, &VIsual, &left, &right, 0);
curwin->w_cursor.lnum = VIsual.lnum;
coladvance(left);
VIsual = curwin->w_cursor;
@@ -5927,7 +5928,7 @@ nv_g_dollar_cmd(cmdarg_T *cap)
{
colnr_T vcol;
getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &vcol);
getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &vcol, 0);
if (vcol >= curwin->w_leftcol + curwin->w_width - col_off)
--curwin->w_cursor.col;
}
@@ -6765,7 +6766,7 @@ unadjust_for_sel_inner(pos_T *pp)
mb_adjustpos(curbuf, pp);
if (virtual_active())
{
getvcol(curwin, pp, &cs, NULL, &ce);
getvcol(curwin, pp, &cs, NULL, &ce, 0);
pp->coladd = ce - cs;
}
}
+14 -11
View File
@@ -2064,7 +2064,7 @@ adjust_cursor_eol(void)
colnr_T scol, ecol;
// Coladd is set to the width of the last character.
getvcol(curwin, &curwin->w_cursor, &scol, NULL, &ecol);
getvcol(curwin, &curwin->w_cursor, &scol, NULL, &ecol, 0);
curwin->w_cursor.coladd = ecol - scol + 1;
}
}
@@ -2396,6 +2396,9 @@ theend:
#ifdef FEAT_LINEBREAK
/*
* TODO: consider using "tailp" of win_lbr_chartabsize() instead of temporarily
* resetting 'linebreak'.
*
* Reset 'linebreak' and take care of side effects.
* Returns the previous value, to be passed to restore_lbr().
*/
@@ -2617,7 +2620,7 @@ charwise_block_prep(
startcol = start.col;
if (virtual_op)
{
getvcol(curwin, &start, &cs, NULL, &ce);
getvcol(curwin, &start, &cs, NULL, &ce, false);
if (ce != cs && start.coladd > 0)
{
// Part of a tab selected -- but don't
@@ -2636,7 +2639,7 @@ charwise_block_prep(
endcol = end.col;
if (virtual_op)
{
getvcol(curwin, &end, &cs, NULL, &ce);
getvcol(curwin, &end, &cs, NULL, &ce, false);
if (p[endcol] == NUL || (cs + end.coladd < ce
// Don't add space for double-wide
// char; endcol will be on last byte
@@ -3409,7 +3412,7 @@ cursor_pos_info(dict_T *dict)
oparg.block_mode = TRUE;
oparg.op_type = OP_NOP;
getvcols(curwin, &min_pos, &max_pos,
&oparg.start_vcol, &oparg.end_vcol);
&oparg.start_vcol, &oparg.end_vcol, 0);
#ifdef FEAT_LINEBREAK
p_sbr = saved_sbr;
curwin->w_p_sbr = saved_w_sbr;
@@ -3511,8 +3514,8 @@ cursor_pos_info(dict_T *dict)
{
if (VIsual_mode == Ctrl_V && curwin->w_curswant < MAXCOL)
{
getvcols(curwin, &min_pos, &max_pos, &min_pos.col,
&max_pos.col);
getvcols(curwin, &min_pos, &max_pos,
&min_pos.col, &max_pos.col, 0);
vim_snprintf((char *)buf1, sizeof(buf1), _("%ld Cols; "),
(long)(oparg.end_vcol - oparg.start_vcol + 1));
}
@@ -3798,11 +3801,11 @@ get_op_vcol(
if (has_mbyte)
mb_adjustpos(curwin->w_buffer, &oap->end);
getvvcol(curwin, &(oap->start), &oap->start_vcol, NULL, &oap->end_vcol);
getvvcol(curwin, &(oap->start), &oap->start_vcol, NULL, &oap->end_vcol, 0);
if (!redo_VIsual_busy)
{
getvvcol(curwin, &(oap->end), &start, NULL, &end);
getvvcol(curwin, &(oap->end), &start, NULL, &end, 0);
if (start < oap->start_vcol)
oap->start_vcol = start;
@@ -3825,7 +3828,7 @@ get_op_vcol(
curwin->w_cursor.lnum <= oap->end.lnum;
++curwin->w_cursor.lnum)
{
getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &end);
getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &end, 0);
if (end > oap->end_vcol)
oap->end_vcol = end;
}
@@ -4130,12 +4133,12 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
{
if (VIsual_mode != Ctrl_V)
getvvcol(curwin, &(oap->end),
NULL, NULL, &oap->end_vcol);
NULL, NULL, &oap->end_vcol, 0);
if (VIsual_mode == Ctrl_V || oap->line_count <= 1)
{
if (VIsual_mode != Ctrl_V)
getvvcol(curwin, &(oap->start),
&oap->start_vcol, NULL, NULL);
&oap->start_vcol, NULL, NULL, 0);
resel_VIsual_vcol = oap->end_vcol - oap->start_vcol + 1;
}
else
+2 -2
View File
@@ -212,11 +212,11 @@ set_mousemoved_columns(win_T *wp, int flags)
// convert text column to mouse column
pos.col = col;
pos.coladd = 0;
getvcol(textwp, &pos, &mcol, NULL, NULL);
getvcol(textwp, &pos, &mcol, NULL, NULL, 0);
wp->w_popup_mouse_mincol = mcol;
pos.col = col + (colnr_T)STRLEN(text) - 1;
getvcol(textwp, &pos, NULL, NULL, &mcol);
getvcol(textwp, &pos, NULL, NULL, &mcol, 0);
wp->w_popup_mouse_maxcol = mcol;
vim_free(text);
}
+4 -4
View File
@@ -40,11 +40,11 @@ void init_chartabsize_arg(chartabsize_T *cts, win_T *wp, linenr_T lnum, colnr_T
void clear_chartabsize_arg(chartabsize_T *cts);
int lbr_chartabsize(chartabsize_T *cts);
int lbr_chartabsize_adv(chartabsize_T *cts);
int win_lbr_chartabsize(chartabsize_T *cts, int *headp);
void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end);
int win_lbr_chartabsize(chartabsize_T *cts, int *headp, int *tailp);
void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end, int flags);
colnr_T getvcol_nolist(pos_T *posp);
void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end);
void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, colnr_T *right);
void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end, int flags);
void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, colnr_T *right, int flags);
char_u *skipwhite(char_u *q);
char_u *skipwhite_and_nl(char_u *q);
int getwhitecols_curline(void);
+2 -2
View File
@@ -1464,8 +1464,8 @@ reg_match_visual(void)
}
else if (mode == Ctrl_V)
{
getvvcol(wp, &top, &start, NULL, &end);
getvvcol(wp, &bot, &start2, NULL, &end2);
getvvcol(wp, &top, &start, NULL, &end, 0);
getvvcol(wp, &bot, &start2, NULL, &end2, 0);
if (start2 < start)
start = start2;
if (end2 > end)
+1 -1
View File
@@ -1689,7 +1689,7 @@ regatom(int *flagp)
colnr_T vcol = 0;
getvvcol(curwin, &curwin->w_cursor,
NULL, NULL, &vcol);
NULL, NULL, &vcol, 0);
++vcol;
n = vcol;
}
+1 -1
View File
@@ -1717,7 +1717,7 @@ nfa_regatom(void)
colnr_T vcol = 0;
getvvcol(curwin, &curwin->w_cursor,
NULL, NULL, &vcol);
NULL, NULL, &vcol, 0);
n = ++vcol;
}
// \%{n}v \%{n}<v \%{n}>v
+4 -4
View File
@@ -1855,9 +1855,9 @@ do_put(
if (dir == FORWARD && c != NUL)
{
if (cur_ve_flags == VE_ALL)
getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2);
getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2, 0);
else
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col);
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col, 0);
if (has_mbyte)
// move to start of next multi-byte character
@@ -1868,7 +1868,7 @@ do_put(
++col;
}
else
getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2);
getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2, 0);
col += curwin->w_cursor.coladd;
if (cur_ve_flags == VE_ALL
@@ -2112,7 +2112,7 @@ do_put(
pos.lnum = lnum;
pos.col = col;
pos.coladd = 0;
getvcol(curwin, &pos, NULL, &vcol, NULL);
getvcol(curwin, &pos, NULL, &vcol, NULL, 0);
}
}
+1 -1
View File
@@ -2858,7 +2858,7 @@ showmatch(
return;
if (!curwin->w_p_wrap)
getvcol(curwin, lpos, NULL, &vcol, NULL);
getvcol(curwin, lpos, NULL, &vcol, NULL, 0);
int col_visible = (curwin->w_p_wrap
|| (vcol >= curwin->w_leftcol
@@ -0,0 +1,6 @@
|f+0#0000001#a8a8a8255|o@1| |x+0#0000000#ffffff0@9| @5||+1&&| +0&&@53
|f+0#0000001#a8a8a8255|o@1> +0#0000000#ffffff0@16||+1&&|~+0#4040ff13&| @52
|x+0#0000000&@19||+1&&|~+0#4040ff13&| @52
|~| @18||+1#0000000&|~+0#4040ff13&| @52
|<+3#0000000&|a|m|e|]| |[|+|]| |2|,|4| @3|A|l@1| |[+1&&|N|o| |N|a|m|e|]| @26|0|,|0|-|1| @9|A|l@1
|-+2&&@1| |V|I|S|U|A|L| |B|L|O|C|K| |-@1| +0&&@45|2|x|2|0| @6
@@ -0,0 +1,6 @@
|f+0&#ffffff0|o+0#0000001#a8a8a8255@1| @4|b+0#0000000#ffffff0|a|r| @63
|f|o+0#0000001#a8a8a8255@1|1|2|3|4|5|b+0#0000000#ffffff0|a|r| @63
|f>o|o+0#0000001#a8a8a8255| @4|b+0#0000000#ffffff0|a|r| @63
|~+0#4040ff13&| @73
|~| @73
|-+2#0000000&@1| |V|I|S|U|A|L| |B|L|O|C|K| |-@1| +0&&@28|3|x|7| @6|3|,|2| @10|A|l@1|
@@ -0,0 +1,6 @@
|f+0&#ffffff0|o+0#0000001#a8a8a8255@1|<|f@3|>|b+0#0000000#ffffff0|a|r| @62
|f|o+0#0000001#a8a8a8255@1|1|2|3|4|5|6|b+0#0000000#ffffff0|a|r| @62
|f>o|o+0#0000001#a8a8a8255|<|f@3|>|b+0#0000000#ffffff0|a|r| @62
|~+0#4040ff13&| @73
|~| @73
|-+2#0000000&@1| |V|I|S|U|A|L| |B|L|O|C|K| |-@1| +0&&@28|3|x|8| @6|3|,|2| @10|A|l@1|
@@ -0,0 +1,6 @@
|x+0&#ffffff0@1|x+0#0000001#a8a8a8255@7|x+0#0000000#ffffff0@4| @59
|x@1|x+0#0000001#a8a8a8255@1|f+0#0000000#ffffff0|o@1|:| |x+0#0000001#a8a8a8255|x+0#0000000#ffffff0@4| @59
|x@1|x+0#0000001#a8a8a8255@1|b+0#0000000#ffffff0|a|r|:| >x@5| @59
|~+0#4040ff13&| @73
|~| @73
|-+2#0000000&@1| |V|I|S|U|A|L| |B|L|O|C|K| |-@1| +0&&@28|3|x|8| @6|3|,|5|-|1|0| @7|A|l@1|
+67
View File
@@ -385,4 +385,71 @@ func Test_visual_ends_before_showbreak()
call StopVimInTerminal(buf)
endfunc
func Test_visual_block_hl_with_linebreak()
CheckScreendump
let lines =<< trim END
func Case1()
20vnew
setlocal linebreak
call setline(1, ['foo ' .. repeat('x', 10), 'foo ' .. repeat('x', 20)])
exe "normal! gg0\<C-V>3lj"
endfunc
func Case2()
setlocal nolinebreak
call setline(1, ["foo\tbar", 'foo12345bar', "foo\tbar"])
exe "normal! gg03l\<C-V>2j2h"
endfunc
func Case3()
setlocal nolinebreak
call setline(1, ["foo\uffffbar", 'foo123456bar', "foo\uffffbar"])
exe "normal! gg03l\<C-V>2j2h"
endfunc
func Case4()
setlocal nolinebreak
call setline(1, [repeat('x', 15), repeat('x', 10), repeat('x', 10)])
call prop_type_add('test', {})
call prop_add(2, 5, #{text: "foo: ",type: "test"})
call prop_add(3, 5, #{text: "bar: ",type: "test"})
exe "normal! gg02l\<C-V>2j2l"
endfunc
" FIXME: clipboard=autoselect sometimes changes Visual highlight
set clipboard=
END
call writefile(lines, 'XvisualBlockHlWithLinebreak', 'D')
let buf = RunVimInTerminal('-S XvisualBlockHlWithLinebreak', #{rows: 6})
" 'linebreak' after end char (initially fixed by patch 7.4.467)
call term_sendkeys(buf, ":call Case1()\r")
call VerifyScreenDump(buf, 'Test_visual_block_hl_with_linebreak_1', {})
" TAB as end char: 'linebreak' shouldn't break Visual block hl
call term_sendkeys(buf, "\<Esc>:bwipe! | call Case2()\r")
call VerifyScreenDump(buf, 'Test_visual_block_hl_with_linebreak_2', {})
call term_sendkeys(buf, "\<Esc>:setlocal linebreak\rgv")
call term_wait(buf, 50)
call VerifyScreenDump(buf, 'Test_visual_block_hl_with_linebreak_2', {})
" Unprintable end char: 'linebreak' shouldn't break Visual block hl
call term_sendkeys(buf, "\<Esc>:bwipe! | call Case3()\r")
call VerifyScreenDump(buf, 'Test_visual_block_hl_with_linebreak_3', {})
call term_sendkeys(buf, "\<Esc>:setlocal linebreak\rgv")
call term_wait(buf, 50)
call VerifyScreenDump(buf, 'Test_visual_block_hl_with_linebreak_3', {})
" Virtual text before end char: 'linebreak' shouldn't break Visual block hl
call term_sendkeys(buf, "\<Esc>:bwipe! | call Case4()\r")
call VerifyScreenDump(buf, 'Test_visual_block_hl_with_linebreak_4', {})
call term_sendkeys(buf, "\<Esc>:setlocal linebreak\rgv")
call term_wait(buf, 50)
call VerifyScreenDump(buf, 'Test_visual_block_hl_with_linebreak_4', {})
call term_sendkeys(buf, "\<Esc>")
call StopVimInTerminal(buf)
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+2
View File
@@ -734,6 +734,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
289,
/**/
288,
/**/
+3
View File
@@ -3093,4 +3093,7 @@ long elapsed(DWORD start_tick);
#define CF_INTERFACE 2 // inside an interface
#define CF_ABSTRACT_METHOD 4 // inside an abstract class
// Flags used by getvcol()
#define GETVCOL_END_EXCL_LBR 1
#endif // VIM__H