mirror of
https://github.com/neovim/neovim.git
synced 2026-09-08 23:18:59 +00:00
vim-patch:9.2.0289: 'linebreak' may lead to wrong Visual block highlighting (#38749)
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: vim/vim#19898
closes: vim/vim#19900
23be1889d1
This commit is contained in:
@@ -741,7 +741,7 @@ void ins_char_bytes(char *buf, size_t charlen)
|
||||
// be deleted to make room for the new character, counting screen
|
||||
// cells. May result in adding spaces to fill a gap.
|
||||
colnr_T vcol;
|
||||
getvcol(curwin, &curwin->w_cursor, NULL, &vcol, NULL);
|
||||
getvcol(curwin, &curwin->w_cursor, NULL, &vcol, NULL, 0);
|
||||
colnr_T new_vcol = vcol + win_chartabsize(curwin, buf, vcol);
|
||||
while (oldp[col + oldlen] != NUL && vcol < new_vcol) {
|
||||
vcol += win_chartabsize(curwin, oldp + col + oldlen, vcol);
|
||||
|
||||
@@ -34,7 +34,7 @@ int 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;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ int 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;
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ static int coladvance2(win_T *wp, pos_T *pos, bool addspaces, bool finetune, col
|
||||
if (!one_more) {
|
||||
colnr_T scol, ecol;
|
||||
|
||||
getvcol(wp, pos, &scol, NULL, &ecol);
|
||||
getvcol(wp, pos, &scol, NULL, &ecol, 0);
|
||||
pos->coladd = ecol - scol;
|
||||
}
|
||||
} else {
|
||||
@@ -372,7 +372,7 @@ void check_cursor_col(win_T *win)
|
||||
assert(win->w_cursor.coladd > 0);
|
||||
int cs, ce;
|
||||
|
||||
getvcol(win, &win->w_cursor, &cs, NULL, &ce);
|
||||
getvcol(win, &win->w_cursor, &cs, NULL, &ce, 0);
|
||||
win->w_cursor.coladd = MIN(win->w_cursor.coladd, ce - cs);
|
||||
}
|
||||
} else {
|
||||
@@ -452,7 +452,7 @@ bool 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;
|
||||
coladvance(curwin, s - 1);
|
||||
|
||||
@@ -1217,7 +1217,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
|
||||
if (VIsual_mode == 'V') { // linewise
|
||||
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;
|
||||
}
|
||||
@@ -1233,9 +1233,9 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
|
||||
} else {
|
||||
pos_T pos = *bot;
|
||||
if (*p_sel == 'e') {
|
||||
getvvcol(wp, &pos, (colnr_T *)&wlv.tocol, NULL, NULL);
|
||||
getvvcol(wp, &pos, (colnr_T *)&wlv.tocol, NULL, NULL, 0);
|
||||
} else {
|
||||
getvvcol(wp, &pos, NULL, NULL, (colnr_T *)&wlv.tocol);
|
||||
getvvcol(wp, &pos, NULL, NULL, (colnr_T *)&wlv.tocol, 0);
|
||||
wlv.tocol++;
|
||||
}
|
||||
}
|
||||
@@ -1260,8 +1260,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
|
||||
&& lnum >= curwin->w_cursor.lnum
|
||||
&& lnum <= curwin->w_cursor.lnum + search_match_lines) {
|
||||
if (lnum == curwin->w_cursor.lnum) {
|
||||
getvcol(curwin, &(curwin->w_cursor),
|
||||
(colnr_T *)&wlv.fromcol, NULL, NULL);
|
||||
getvcol(curwin, &(curwin->w_cursor), (colnr_T *)&wlv.fromcol, NULL, NULL, 0);
|
||||
} else {
|
||||
wlv.fromcol = 0;
|
||||
}
|
||||
@@ -1270,7 +1269,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
|
||||
.lnum = lnum,
|
||||
.col = search_match_endcol,
|
||||
};
|
||||
getvcol(curwin, &pos, (colnr_T *)&wlv.tocol, NULL, NULL);
|
||||
getvcol(curwin, &pos, (colnr_T *)&wlv.tocol, NULL, NULL, 0);
|
||||
}
|
||||
// do at least one character; happens when past end of line
|
||||
if (wlv.fromcol == wlv.tocol && search_match_endcol) {
|
||||
@@ -2331,6 +2330,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
|
||||
CharsizeArg csarg;
|
||||
// lnum == 0, do not want virtual text to be counted here
|
||||
CSType cstype = init_charsize_arg(&csarg, wp, 0, line);
|
||||
// TODO(zeertzjq): consider using CharSize.tail here
|
||||
wlv.n_extra = win_charsize(cstype, wlv.vcol, p, utf_ptr2CharInfo(p).value,
|
||||
&csarg).width - 1;
|
||||
|
||||
|
||||
@@ -1850,15 +1850,8 @@ static void win_update(win_T *wp)
|
||||
// First compute the actual start and end column.
|
||||
if (VIsual_mode == Ctrl_V) {
|
||||
colnr_T fromc, toc;
|
||||
unsigned save_ve_flags = curwin->w_ve_flags;
|
||||
|
||||
if (curwin->w_p_lbr) {
|
||||
curwin->w_ve_flags = kOptVeFlagAll;
|
||||
}
|
||||
|
||||
getvcols(wp, &VIsual, &curwin->w_cursor, &fromc, &toc);
|
||||
getvcols(wp, &VIsual, &curwin->w_cursor, &fromc, &toc, GETVCOL_END_EXCL_LBR);
|
||||
toc++;
|
||||
curwin->w_ve_flags = save_ve_flags;
|
||||
// Highlight to the end of the line, unless 'virtualedit' has
|
||||
// "block".
|
||||
if (curwin->w_curswant == MAXCOL) {
|
||||
@@ -1875,7 +1868,7 @@ static void win_update(win_T *wp)
|
||||
colnr_T t;
|
||||
|
||||
pos.col = ml_get_buf_len(wp->w_buffer, pos.lnum);
|
||||
getvvcol(wp, &pos, NULL, NULL, &t);
|
||||
getvvcol(wp, &pos, NULL, NULL, &t, 0);
|
||||
toc = MAX(toc, t);
|
||||
}
|
||||
toc++;
|
||||
|
||||
@@ -2820,7 +2820,7 @@ static void replace_do_bs(int limit_col)
|
||||
if (l_State & VREPLACE_FLAG) {
|
||||
// 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 = win_chartabsize(curwin, get_cursor_pos_ptr(), start_vcol);
|
||||
}
|
||||
del_char_after_col(limit_col);
|
||||
@@ -4009,8 +4009,8 @@ static bool 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);
|
||||
|
||||
char *tab = "\t";
|
||||
int32_t tab_v = (uint8_t)(*tab);
|
||||
|
||||
@@ -2285,8 +2285,8 @@ static int getregionpos(typval_T *argvars, typval_T *rettv, pos_T *p1, pos_T *p2
|
||||
} else if (*region_type == kMTBlockWise) {
|
||||
colnr_T sc1, ec1, sc2, ec2;
|
||||
const bool lbr_saved = reset_lbr();
|
||||
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);
|
||||
restore_lbr(lbr_saved);
|
||||
oap->motion_type = kMTBlockWise;
|
||||
oap->inclusive = true;
|
||||
@@ -7763,7 +7763,7 @@ static void f_virtcol(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
fp->col = len;
|
||||
}
|
||||
}
|
||||
getvvcol(wp, fp, &vcol_start, NULL, &vcol_end);
|
||||
getvvcol(wp, fp, &vcol_start, NULL, &vcol_end, 0);
|
||||
vcol_start++;
|
||||
vcol_end++;
|
||||
}
|
||||
|
||||
@@ -3959,10 +3959,10 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
|
||||
print_line_no_prefix(lnum, subflags.do_number, subflags.do_list);
|
||||
|
||||
colnr_T sc, ec;
|
||||
getvcol(curwin, &curwin->w_cursor, &sc, NULL, NULL);
|
||||
getvcol(curwin, &curwin->w_cursor, &sc, NULL, NULL, 0);
|
||||
curwin->w_cursor.col = MAX(regmatch.endpos[0].col - 1, 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) {
|
||||
int numw = number_width(curwin) + 1;
|
||||
|
||||
@@ -766,7 +766,7 @@ int 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -679,7 +679,7 @@ static int 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;
|
||||
}
|
||||
|
||||
@@ -754,7 +754,7 @@ static int 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;
|
||||
}
|
||||
|
||||
@@ -803,7 +803,7 @@ static int 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;
|
||||
}
|
||||
|
||||
@@ -1367,7 +1367,7 @@ static int 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) {
|
||||
@@ -2044,7 +2044,7 @@ int 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;
|
||||
}
|
||||
@@ -2064,7 +2064,7 @@ int 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;
|
||||
@@ -2177,7 +2177,7 @@ int get_c_indent(void)
|
||||
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;
|
||||
@@ -2364,7 +2364,7 @@ int get_c_indent(void)
|
||||
// Find how indented the paren is, or the character after it
|
||||
// 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;
|
||||
}
|
||||
@@ -2447,7 +2447,7 @@ int get_c_indent(void)
|
||||
// a whole and then add the "imaginary indent" to that.
|
||||
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;
|
||||
|
||||
@@ -305,8 +305,8 @@ static int do_popup(int which_button, int m_pos_flag, pos_T m_pos)
|
||||
jump_flags = MOUSE_MAY_STOP_VIS;
|
||||
} else if (VIsual_mode == Ctrl_V) {
|
||||
colnr_T leftcol, rightcol;
|
||||
getvcols(curwin, &curwin->w_cursor, &VIsual, &leftcol, &rightcol);
|
||||
getvcol(curwin, &m_pos, NULL, &m_pos.col, NULL);
|
||||
getvcols(curwin, &curwin->w_cursor, &VIsual, &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;
|
||||
}
|
||||
@@ -769,7 +769,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, int count, bool fixindent)
|
||||
// that is in the quarter that the cursor is in.
|
||||
if (VIsual_mode == Ctrl_V) {
|
||||
colnr_T leftcol, rightcol;
|
||||
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 {
|
||||
|
||||
@@ -308,7 +308,7 @@ void update_topline(win_T *wp)
|
||||
|
||||
// Check that the cursor position is visible. Add columns for
|
||||
// the marker displayed in the top-left if needed.
|
||||
getvvcol(wp, &wp->w_cursor, &vcol, NULL, NULL);
|
||||
getvvcol(wp, &wp->w_cursor, &vcol, NULL, NULL, 0);
|
||||
int overlap = sms_marker_overlap(wp, -1);
|
||||
if (wp->w_skipcol + overlap > vcol) {
|
||||
check_topline = true;
|
||||
@@ -730,7 +730,7 @@ void validate_virtcol(win_T *wp)
|
||||
return;
|
||||
}
|
||||
|
||||
getvvcol(wp, &wp->w_cursor, NULL, &(wp->w_virtcol), NULL);
|
||||
getvvcol(wp, &wp->w_cursor, NULL, &(wp->w_virtcol), NULL, 0);
|
||||
redraw_for_cursorcolumn(wp);
|
||||
wp->w_valid |= VALID_VIRTCOL;
|
||||
}
|
||||
@@ -823,7 +823,7 @@ void curs_columns(win_T *wp, int may_scroll)
|
||||
// In a folded line the cursor is always in the first column
|
||||
startcol = wp->w_virtcol = endcol = wp->w_leftcol;
|
||||
} else {
|
||||
getvvcol(wp, &wp->w_cursor, &startcol, &(wp->w_virtcol), &endcol);
|
||||
getvvcol(wp, &wp->w_cursor, &startcol, &(wp->w_virtcol), &endcol, 0);
|
||||
}
|
||||
|
||||
// remove '$' from change command when cursor moves onto it
|
||||
@@ -1083,7 +1083,7 @@ void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp, int *ccolp,
|
||||
coloff = (local ? 0 : wp->w_wincol + wp->w_wincol_off) + 1 + off;
|
||||
} else {
|
||||
assert(lnum == pos->lnum);
|
||||
getvcol(wp, pos, &scol, &ccol, &ecol);
|
||||
getvcol(wp, pos, &scol, &ccol, &ecol, 0);
|
||||
|
||||
// similar to what is done in validate_cursor_col()
|
||||
colnr_T col = scol;
|
||||
|
||||
@@ -1910,7 +1910,7 @@ void clear_showcmd(void)
|
||||
// Make 'sbr' empty for a moment to get the correct size.
|
||||
p_sbr = empty_string_option;
|
||||
curwin->w_p_sbr = empty_string_option;
|
||||
getvcols(curwin, &curwin->w_cursor, &VIsual, &leftcol, &rightcol);
|
||||
getvcols(curwin, &curwin->w_cursor, &VIsual, &leftcol, &rightcol, 0);
|
||||
p_sbr = saved_sbr;
|
||||
curwin->w_p_sbr = saved_w_sbr;
|
||||
snprintf(showcmd_buf, SHOWCMD_BUFLEN, "%" PRId64 "x%" PRId64,
|
||||
@@ -2888,7 +2888,7 @@ static void nv_zet(cmdarg_T *cap)
|
||||
if (hasFolding(curwin, curwin->w_cursor.lnum, NULL, NULL)) {
|
||||
col = 0; // like the cursor is in col 0
|
||||
} else {
|
||||
getvcol(curwin, &curwin->w_cursor, &col, NULL, NULL);
|
||||
getvcol(curwin, &curwin->w_cursor, &col, NULL, NULL, 0);
|
||||
}
|
||||
if (col > siso) {
|
||||
col -= siso;
|
||||
@@ -2908,7 +2908,7 @@ static void nv_zet(cmdarg_T *cap)
|
||||
if (hasFolding(curwin, curwin->w_cursor.lnum, NULL, NULL)) {
|
||||
col = 0; // like the cursor is in col 0
|
||||
} else {
|
||||
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col);
|
||||
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col, 0);
|
||||
}
|
||||
int n = curwin->w_view_width - win_col_off(curwin);
|
||||
if (col + siso < n) {
|
||||
@@ -4086,7 +4086,7 @@ static void nv_csearch(cmdarg_T *cap)
|
||||
&& (t_cmd || cap->oap->op_type != OP_NOP)) {
|
||||
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 {
|
||||
curwin->w_cursor.coladd = 0;
|
||||
@@ -4639,7 +4639,7 @@ static void v_swap_corners(int cmdchar)
|
||||
|
||||
if (cmdchar == 'O' && VIsual_mode == Ctrl_V) {
|
||||
pos_T 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(curwin, left);
|
||||
VIsual = curwin->w_cursor;
|
||||
@@ -5356,7 +5356,7 @@ static void nv_g_dollar_cmd(cmdarg_T *cap)
|
||||
if (curwin->w_cursor.col > 0 && utf_ptr2cells(get_cursor_pos_ptr()) > 1) {
|
||||
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_view_width - col_off) {
|
||||
curwin->w_cursor.col--;
|
||||
}
|
||||
@@ -6077,7 +6077,7 @@ bool unadjust_for_sel_inner(pos_T *pp)
|
||||
mark_mb_adjustpos(curbuf, pp);
|
||||
if (virtual_active(curwin)) {
|
||||
colnr_T cs, ce;
|
||||
getvcol(curwin, pp, &cs, NULL, &ce);
|
||||
getvcol(curwin, pp, &cs, NULL, &ce, 0);
|
||||
pp->coladd = ce - cs;
|
||||
}
|
||||
} else if (pp->lnum > 1) {
|
||||
|
||||
@@ -1806,7 +1806,7 @@ void 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;
|
||||
}
|
||||
}
|
||||
@@ -2076,6 +2076,9 @@ theend:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// TODO(zeertzjq): consider using CharSize.tail instead of temporarily
|
||||
/// resetting 'linebreak'.
|
||||
///
|
||||
/// Reset 'linebreak' and take care of side effects.
|
||||
/// @return the previous value, to be passed to restore_lbr().
|
||||
bool reset_lbr(void)
|
||||
@@ -2253,7 +2256,7 @@ void charwise_block_prep(pos_T start, pos_T end, struct block_def *bdp, linenr_T
|
||||
if (lnum == start.lnum) {
|
||||
startcol = start.col;
|
||||
if (virtual_op) {
|
||||
getvcol(curwin, &start, &cs, NULL, &ce);
|
||||
getvcol(curwin, &start, &cs, NULL, &ce, 0);
|
||||
if (ce != cs && start.coladd > 0) {
|
||||
// Part of a tab selected -- but don't double-count it.
|
||||
bdp->start_char_vcols = ce - cs + 1;
|
||||
@@ -2266,7 +2269,7 @@ void charwise_block_prep(pos_T start, pos_T end, struct block_def *bdp, linenr_T
|
||||
if (lnum == end.lnum) {
|
||||
endcol = end.col;
|
||||
if (virtual_op) {
|
||||
getvcol(curwin, &end, &cs, NULL, &ce);
|
||||
getvcol(curwin, &end, &cs, NULL, &ce, 0);
|
||||
if (p[endcol] == NUL || (cs + end.coladd < ce
|
||||
// Don't add space for double-wide
|
||||
// char; endcol will be on last byte
|
||||
@@ -2871,7 +2874,7 @@ void cursor_pos_info(dict_T *dict)
|
||||
oparg.is_VIsual = true;
|
||||
oparg.motion_type = kMTBlockWise;
|
||||
oparg.op_type = OP_NOP;
|
||||
getvcols(curwin, &min_pos, &max_pos, &oparg.start_vcol, &oparg.end_vcol);
|
||||
getvcols(curwin, &min_pos, &max_pos, &oparg.start_vcol, &oparg.end_vcol, 0);
|
||||
p_sbr = saved_sbr;
|
||||
curwin->w_p_sbr = saved_w_sbr;
|
||||
if (curwin->w_curswant == MAXCOL) {
|
||||
@@ -2961,7 +2964,7 @@ void cursor_pos_info(dict_T *dict)
|
||||
if (dict == NULL) {
|
||||
if (l_VIsual_active) {
|
||||
if (l_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);
|
||||
int64_t cols;
|
||||
STRICT_SUB(oparg.end_vcol + 1, oparg.start_vcol, &cols, int64_t);
|
||||
vim_snprintf(buf1, sizeof(buf1), _("%" PRId64 " Cols; "),
|
||||
@@ -3213,9 +3216,9 @@ static void get_op_vcol(oparg_T *oap, colnr_T redo_VIsual_vcol, bool initial)
|
||||
// prevent from moving onto a trail byte
|
||||
mark_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);
|
||||
|
||||
oap->start_vcol = MIN(oap->start_vcol, start);
|
||||
if (end > oap->end_vcol) {
|
||||
@@ -3235,7 +3238,7 @@ static void get_op_vcol(oparg_T *oap, colnr_T redo_VIsual_vcol, bool initial)
|
||||
oap->end_vcol = 0;
|
||||
for (curwin->w_cursor.lnum = oap->start.lnum;
|
||||
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);
|
||||
oap->end_vcol = MAX(oap->end_vcol, end);
|
||||
}
|
||||
} else if (redo_VIsual_busy) {
|
||||
@@ -3480,13 +3483,11 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
|
||||
resel_VIsual_vcol = MAXCOL;
|
||||
} else {
|
||||
if (VIsual_mode != Ctrl_V) {
|
||||
getvvcol(curwin, &(oap->end),
|
||||
NULL, NULL, &oap->end_vcol);
|
||||
getvvcol(curwin, &(oap->end), 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);
|
||||
getvvcol(curwin, &(oap->start), &oap->start_vcol, NULL, NULL, 0);
|
||||
}
|
||||
resel_VIsual_vcol = oap->end_vcol - oap->start_vcol + 1;
|
||||
} else {
|
||||
|
||||
@@ -288,6 +288,7 @@ CharSize charsize_regular(CharsizeArg *csarg, char *const cur, colnr_T const vco
|
||||
size += added;
|
||||
}
|
||||
|
||||
int size_before_lbr = size;
|
||||
bool need_lbr = false;
|
||||
// If 'linebreak' set check at a blank before a non-blank if the line
|
||||
// needs a break here.
|
||||
@@ -333,7 +334,9 @@ CharSize charsize_regular(CharsizeArg *csarg, char *const cur, colnr_T const vco
|
||||
}
|
||||
}
|
||||
|
||||
return (CharSize){ .width = size, .head = head };
|
||||
int tail = size - size_before_lbr;
|
||||
|
||||
return (CharSize){ .width = size, .head = head, .tail = tail };
|
||||
}
|
||||
|
||||
/// Like charsize_regular(), except it doesn't handle inline virtual text,
|
||||
@@ -512,6 +515,10 @@ static int virt_text_cursor_off(const CharsizeArg *csarg, bool on_NUL)
|
||||
/// 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!
|
||||
///
|
||||
/// @param wp
|
||||
@@ -519,7 +526,8 @@ static int virt_text_cursor_off(const CharsizeArg *csarg, bool on_NUL)
|
||||
/// @param start
|
||||
/// @param cursor
|
||||
/// @param end
|
||||
void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end)
|
||||
/// @param flags
|
||||
void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end, int flags)
|
||||
{
|
||||
char *const line = ml_get_buf(wp->w_buffer, pos->lnum); // start of the line
|
||||
colnr_T const end_col = pos->col;
|
||||
@@ -571,29 +579,27 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en
|
||||
pos->col = (colnr_T)(ci.ptr - line);
|
||||
}
|
||||
|
||||
int head = char_size.head;
|
||||
int incr = char_size.width;
|
||||
int head = char_size.head;
|
||||
int tail = char_size.tail;
|
||||
|
||||
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 (ci.chr.value == TAB
|
||||
&& (State & MODE_NORMAL)
|
||||
&& !wp->w_p_list
|
||||
&& !virtual_active(wp)
|
||||
&& !(VIsual_active && ((*p_sel == 'e') || ltoreq(*pos, VIsual)))) {
|
||||
// cursor at end
|
||||
*cursor = vcol + incr - 1;
|
||||
// TODO(zeertzjq): subtracting "tail" may lead to better cursor position
|
||||
*cursor = vcol + incr - 1; // cursor at end
|
||||
} else {
|
||||
vcol += virt_text_cursor_off(&csarg, on_NUL);
|
||||
// cursor at start
|
||||
*cursor = vcol + head;
|
||||
*cursor = vcol + head; // cursor at start
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -610,9 +616,9 @@ colnr_T 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;
|
||||
@@ -625,13 +631,14 @@ colnr_T getvcol_nolist(pos_T *posp)
|
||||
/// @param start
|
||||
/// @param cursor
|
||||
/// @param end
|
||||
void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end)
|
||||
/// @param flags
|
||||
void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end, int flags)
|
||||
{
|
||||
colnr_T col;
|
||||
|
||||
if (virtual_active(wp)) {
|
||||
// For virtual mode, only want one value
|
||||
getvcol(wp, pos, &col, NULL, NULL);
|
||||
getvcol(wp, pos, &col, NULL, NULL, flags);
|
||||
|
||||
colnr_T coladd = pos->coladd;
|
||||
colnr_T endadd = 0;
|
||||
@@ -644,8 +651,7 @@ void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *e
|
||||
if ((c != TAB) && vim_isprintc(c)) {
|
||||
endadd = (colnr_T)(ptr2cells(ptr + pos->col) - 1);
|
||||
if (coladd > endadd) {
|
||||
// past end of line
|
||||
endadd = 0;
|
||||
endadd = 0; // past end of line
|
||||
} else {
|
||||
coladd = 0;
|
||||
}
|
||||
@@ -656,16 +662,14 @@ void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *e
|
||||
if (start != NULL) {
|
||||
*start = col;
|
||||
}
|
||||
|
||||
if (cursor != NULL) {
|
||||
*cursor = col;
|
||||
}
|
||||
|
||||
if (end != NULL) {
|
||||
*end = col + endadd;
|
||||
}
|
||||
} else {
|
||||
getvcol(wp, pos, start, cursor, end);
|
||||
getvcol(wp, pos, start, cursor, end, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -677,7 +681,8 @@ void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *e
|
||||
/// @param pos2
|
||||
/// @param left
|
||||
/// @param right
|
||||
void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, colnr_T *right)
|
||||
/// @param flags
|
||||
void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, colnr_T *right, int flags)
|
||||
{
|
||||
colnr_T from1;
|
||||
colnr_T from2;
|
||||
@@ -685,11 +690,11 @@ void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, colnr_T *right
|
||||
colnr_T to2;
|
||||
|
||||
if (lt(*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) {
|
||||
|
||||
@@ -34,6 +34,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
int width;
|
||||
int head; ///< Size of 'breakindent' etc. before the character (included in width).
|
||||
int tail; ///< Size of 'linebreak' after the character (included in width).
|
||||
} CharSize;
|
||||
|
||||
#include "plines.h.generated.h"
|
||||
@@ -89,3 +90,8 @@ static inline int win_linetabsize(win_T *wp, linenr_T lnum, char *line, colnr_T
|
||||
return linesize_regular(&csarg, 0, len);
|
||||
}
|
||||
}
|
||||
|
||||
/// Flags used by getvcol()
|
||||
enum {
|
||||
GETVCOL_END_EXCL_LBR = 1,
|
||||
};
|
||||
|
||||
@@ -1493,8 +1493,8 @@ static bool reg_match_visual(void)
|
||||
return false;
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
@@ -4681,7 +4681,7 @@ static uint8_t *regatom(int *flagp)
|
||||
} else {
|
||||
if (cur) {
|
||||
colnr_T vcol = 0;
|
||||
getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &vcol);
|
||||
getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &vcol, 0);
|
||||
n = (uint32_t)(++vcol);
|
||||
}
|
||||
ret = regnode(RE_VCOL);
|
||||
@@ -10389,7 +10389,7 @@ static int nfa_regatom(void)
|
||||
} else {
|
||||
if (cur) {
|
||||
colnr_T vcol = 0;
|
||||
getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &vcol);
|
||||
getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &vcol, 0);
|
||||
n = ++vcol;
|
||||
}
|
||||
// \%{n}v \%{n}<v \%{n}>v
|
||||
|
||||
@@ -1585,16 +1585,16 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
|
||||
|
||||
if (dir == FORWARD && c != NUL) {
|
||||
if (cur_ve_flags == kOptVeFlagAll) {
|
||||
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);
|
||||
}
|
||||
|
||||
// move to start of next multi-byte character
|
||||
curwin->w_cursor.col += utfc_ptr2len(get_cursor_pos_ptr());
|
||||
col++;
|
||||
} else {
|
||||
getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2);
|
||||
getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2, 0);
|
||||
}
|
||||
|
||||
col += curwin->w_cursor.coladd;
|
||||
@@ -1802,7 +1802,7 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
|
||||
.col = col,
|
||||
.coladd = 0,
|
||||
};
|
||||
getvcol(curwin, &pos, NULL, &vcol, NULL);
|
||||
getvcol(curwin, &pos, NULL, &vcol, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2352,7 +2352,7 @@ void showmatch(int c)
|
||||
}
|
||||
|
||||
if (!curwin->w_p_wrap) {
|
||||
getvcol(curwin, lpos, NULL, &vcol, NULL);
|
||||
getvcol(curwin, lpos, NULL, &vcol, NULL, 0);
|
||||
}
|
||||
|
||||
bool col_visible = curwin->w_p_wrap
|
||||
|
||||
@@ -485,7 +485,7 @@ void redraw_ruler(void)
|
||||
colnr_T virtcol = wp->w_virtcol;
|
||||
if (wp->w_p_list && wp->w_p_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;
|
||||
}
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ describe('linebreak', function()
|
||||
|
||||
-- oldtest: Test_visual_ends_before_showbreak()
|
||||
it("Visual area is correct when it ends before multibyte 'showbreak'", function()
|
||||
local screen = Screen.new(60, 8)
|
||||
local screen = Screen.new(60, 6)
|
||||
exec([[
|
||||
let &wrap = v:true
|
||||
let &linebreak = v:true
|
||||
@@ -226,8 +226,84 @@ describe('linebreak', function()
|
||||
xxxxx |
|
||||
{1:↪ }{17:yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy}^ {17: }|
|
||||
{1:↪ }zzzz |
|
||||
{1:~ }|*4
|
||||
{1:~ }|*2
|
||||
{5:-- VISUAL --} |
|
||||
]])
|
||||
end)
|
||||
|
||||
it("Visual block highlight is correct with 'linebreak'", function()
|
||||
local screen = Screen.new(60, 6)
|
||||
exec('set laststatus=0 showcmd ruler')
|
||||
|
||||
-- 'linebreak' after end char (initially fixed by patch 7.4.467)
|
||||
exec([[
|
||||
20vnew
|
||||
setlocal linebreak
|
||||
call setline(1, ['foo ' .. repeat('x', 10), 'foo ' .. repeat('x', 20)])
|
||||
exe "normal! gg0\<C-V>3lj"
|
||||
]])
|
||||
screen:expect([[
|
||||
{17:foo }xxxxxxxxxx │ |
|
||||
{17:foo}^ │{1:~ }|
|
||||
xxxxxxxxxxxxxxxxxxxx│{1:~ }|
|
||||
{1:~ }│{1:~ }|*2
|
||||
{5:-- VISUAL BLOCK --} 2x20 2,4 All |
|
||||
]])
|
||||
|
||||
-- TAB as end char: 'linebreak' shouldn't break Visual block hl
|
||||
exec([[
|
||||
bwipe!
|
||||
setlocal nolinebreak
|
||||
call setline(1, ["foo\tbar", 'foo12345bar', "foo\tbar"])
|
||||
exe "normal! gg03l\<C-V>2j2h"
|
||||
]])
|
||||
screen:expect([[
|
||||
f{17:oo }bar |
|
||||
f{17:oo12345}bar |
|
||||
f^o{17:o }bar |
|
||||
{1:~ }|*2
|
||||
{5:-- VISUAL BLOCK --} 3x7 3,2 All |
|
||||
]])
|
||||
feed('<Esc>:setlocal linebreak<CR>gv')
|
||||
screen:expect_unchanged(true)
|
||||
|
||||
-- Unprintable end char: 'linebreak' shouldn't break Visual block hl
|
||||
exec([[
|
||||
bwipe!
|
||||
setlocal nolinebreak
|
||||
call setline(1, ["foo\uffffbar", 'foo123456bar', "foo\uffffbar"])
|
||||
exe "normal! gg03l\<C-V>2j2h"
|
||||
]])
|
||||
screen:expect([[
|
||||
f{17:oo<ffff>}bar |
|
||||
f{17:oo123456}bar |
|
||||
f^o{17:o<ffff>}bar |
|
||||
{1:~ }|*2
|
||||
{5:-- VISUAL BLOCK --} 3x8 3,2 All |
|
||||
]])
|
||||
feed('<Esc>:setlocal linebreak<CR>gv')
|
||||
screen:expect_unchanged(true)
|
||||
|
||||
-- Virtual text before end char: 'linebreak' shouldn't break Visual block hl
|
||||
exec([=[
|
||||
bwipe!
|
||||
setlocal nolinebreak
|
||||
call setline(1, [repeat('x', 15), repeat('x', 10), repeat('x', 10)])
|
||||
let s:ns = nvim_create_namespace('test')
|
||||
call nvim_buf_set_extmark(0, s:ns, 1, 4, #{virt_text: [['foo: ']],
|
||||
\ virt_text_pos: 'inline'})
|
||||
call nvim_buf_set_extmark(0, s:ns, 2, 4, #{virt_text: [['bar: ']],
|
||||
\ virt_text_pos: 'inline'})
|
||||
exe "normal! gg02l\<C-V>2j2l"
|
||||
]=])
|
||||
screen:expect([[
|
||||
xx{17:xxxxxxxx}xxxxx |
|
||||
xx{17:xx}foo: {17:x}xxxxx |
|
||||
xx{17:xx}bar: ^xxxxxx |
|
||||
{1:~ }|*2
|
||||
{5:-- VISUAL BLOCK --} 3x8 3,5-10 All |
|
||||
]])
|
||||
feed('<Esc>:setlocal linebreak<CR>gv')
|
||||
screen:expect_unchanged(true)
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user