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

1 view
Skip to first unread message

Christian Brabandt

unread,
10:47 AM (11 hours ago) 10:47 AM
to vim...@googlegroups.com
patch 9.2.0289: 'linebreak' may lead to wrong Visual block highlighting

Commit: https://github.com/vim/vim/commit/23be1889d1a1212445ca8bb9cd378484d3755f79
Author: zeertzjq <zeer...@outlook.com>
Date: Fri Apr 3 09:48:49 2026 +0000

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 <zeer...@outlook.com>
Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/change.c b/src/change.c
index 3a4fefb2b..8dd7e9d9b 100644
--- a/src/change.c
+++ b/src/change.c
@@ -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)
{
diff --git a/src/charset.c b/src/charset.c
index 49320fcb6..1fbbf98f7 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -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;
diff --git a/src/cindent.c b/src/cindent.c
index 1b4ad0fa4..ddd268176 100644
--- a/src/cindent.c
+++ b/src/cindent.c
@@ -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;
diff --git a/src/drawline.c b/src/drawline.c
index b7910832b..b9b92a1e9 100644
--- a/src/drawline.c
+++ b/src/drawline.c
@@ -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)
diff --git a/src/drawscreen.c b/src/drawscreen.c
index 68ba60572..d619859bd 100644
--- a/src/drawscreen.c
+++ b/src/drawscreen.c
@@ -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;
}
diff --git a/src/edit.c b/src/edit.c
index 2392361fb..79a4177bf 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -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);

diff --git a/src/evalfunc.c b/src/evalfunc.c
index de6975a0d..f026b384e 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -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;
}
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index d4d57d0a7..4382ea5b7 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -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)
{
diff --git a/src/gui_xim.c b/src/gui_xim.c
index 8e9b750a4..26b125d91 100644
--- a/src/gui_xim.c
+++ b/src/gui_xim.c
@@ -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;
}
diff --git a/src/indent.c b/src/indent.c
index 26f60701c..8fe4177c3 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -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;
}

diff --git a/src/misc1.c b/src/misc1.c
index 8a951298b..3fa34c35e 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -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);

/*
diff --git a/src/misc2.c b/src/misc2.c
index a7f52e55e..1d3a35b06 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -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;
diff --git a/src/mouse.c b/src/mouse.c
index e043e1b4f..3f2f86dc8 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -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;
diff --git a/src/move.c b/src/move.c
index ebc885361..ee9a8eb5a 100644
--- a/src/move.c
+++ b/src/move.c
@@ -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;
diff --git a/src/normal.c b/src/normal.c
index 01ea4c091..e7be75757 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -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;
}
}
diff --git a/src/ops.c b/src/ops.c
index 3fad2b44f..140cdc8c5 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -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
diff --git a/src/popupwin.c b/src/popupwin.c
index d54751600..cbbb7c6e5 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -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);
}
diff --git a/src/proto/charset.pro b/src/proto/charset.pro
index c9af1b0d6..bc09b01b8 100644
--- a/src/proto/charset.pro
+++ b/src/proto/charset.pro
@@ -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);
diff --git a/src/regexp.c b/src/regexp.c
index 34325e61d..6ac74467f 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -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)
diff --git a/src/regexp_bt.c b/src/regexp_bt.c
index 37fba5e6f..063510c64 100644
--- a/src/regexp_bt.c
+++ b/src/regexp_bt.c
@@ -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;
}
diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c
index 807bc203c..b17d4d349 100644
--- a/src/regexp_nfa.c
+++ b/src/regexp_nfa.c
@@ -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
diff --git a/src/register.c b/src/register.c
index de89b1864..a20e5c1d0 100644
--- a/src/register.c
+++ b/src/register.c
@@ -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);
}
}

diff --git a/src/search.c b/src/search.c
index 5d50b1fc5..9b51ef94a 100644
--- a/src/search.c
+++ b/src/search.c
@@ -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
diff --git a/src/testdir/dumps/Test_visual_block_hl_with_linebreak_1.dump b/src/testdir/dumps/Test_visual_block_hl_with_linebreak_1.dump
new file mode 100644
index 000000000..a1825a9ee
--- /dev/null
+++ b/src/testdir/dumps/Test_visual_block_hl_with_linebreak_1.dump
@@ -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
diff --git a/src/testdir/dumps/Test_visual_block_hl_with_linebreak_2.dump b/src/testdir/dumps/Test_visual_block_hl_with_linebreak_2.dump
new file mode 100644
index 000000000..d3dae6661
--- /dev/null
+++ b/src/testdir/dumps/Test_visual_block_hl_with_linebreak_2.dump
@@ -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|
diff --git a/src/testdir/dumps/Test_visual_block_hl_with_linebreak_3.dump b/src/testdir/dumps/Test_visual_block_hl_with_linebreak_3.dump
new file mode 100644
index 000000000..fe26ea2b1
--- /dev/null
+++ b/src/testdir/dumps/Test_visual_block_hl_with_linebreak_3.dump
@@ -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|
diff --git a/src/testdir/dumps/Test_visual_block_hl_with_linebreak_4.dump b/src/testdir/dumps/Test_visual_block_hl_with_linebreak_4.dump
new file mode 100644
index 000000000..cc4c19dfe
--- /dev/null
+++ b/src/testdir/dumps/Test_visual_block_hl_with_linebreak_4.dump
@@ -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|
diff --git a/src/testdir/test_listlbr_utf8.vim b/src/testdir/test_listlbr_utf8.vim
index be77566a7..bde1a4958 100644
--- a/src/testdir/test_listlbr_utf8.vim
+++ b/src/testdir/test_listlbr_utf8.vim
@@ -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 bar", 'foo12345bar', "foo bar"])
+ 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()
")
+ 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()
")
+ call VerifyScreenDump(buf, 'Test_visual_block_hl_with_linebreak_2', {})
+ call term_sendkeys(buf, "\<Esc>:setlocal linebreak
gv")
+ 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()
")
+ call VerifyScreenDump(buf, 'Test_visual_block_hl_with_linebreak_3', {})
+ call term_sendkeys(buf, "\<Esc>:setlocal linebreak
gv")
+ 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()
")
+ call VerifyScreenDump(buf, 'Test_visual_block_hl_with_linebreak_4', {})
+ call term_sendkeys(buf, "\<Esc>:setlocal linebreak
gv")
+ 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
diff --git a/src/version.c b/src/version.c
index e81115c31..64db5b884 100644
--- a/src/version.c
+++ b/src/version.c
@@ -734,6 +734,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 289,
/**/
288,
/**/
diff --git a/src/vim.h b/src/vim.h
index f2e3a1610..51d0cc1f3 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -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
Reply all
Reply to author
Forward
0 new messages