On Mon, Dec 24, 2018 at 9:36 AM Christian Brabandt <[email protected]> wrote:
> I'll have a look.
>
> Tom, can you provide a simple test case?
It's about the issue reported by John Little and Tony Mechelynck on
Wed, Oct 24, 2018: "linebreak, showbreak, and visual block yank
problem". See: https://groups.google.com/forum/#!topic/vim_dev/xy7eYYZXe_w
.
This example yanks "56\nEF" when it should yank "78\nGH":
setl lbr
call setline(1, repeat('a', winwidth(0)-2) . '.123456789')
call setline(2, repeat('a', winwidth(0)-4) . '.ABCDEFGHI')
exe "norm gg0f7\<c-v>jly"
The point is, that 'linebreak' is not fully supported by
do_pending_operator(), lbr is temporarily reset while executing
operations. So the start/end vcols are calculated incorrectly. I
managed to correct it (via fixing get_op_vcol()), but that's just the
easy part. It seems that startspaces/endspaces computation in
block_prep() needs amending too. And with that all functions that call
block_prep() - functioons implementing block yank, delete, change,
append (this is where I am beeing at the moment), insert, tilde, ... I
am completely new to most of the code, so the progress is slow.
Anyway, comments are welcome.
I am attaching a patch file - my current state of my changes. Main
changes are in normal.c, charset.c and ops.c. Other than that it's all
just consequences of altering getvcol() prototype.
Mery Christmas!
Tom
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/charset.c b/src/charset.c
index 028095453..92ed0e6eb 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -1273,9 +1273,11 @@ in_win_border(win_T *wp, colnr_T vcol)
/*
* Get virtual column number of pos.
- * start: on the first position of this character (TAB, ctrl)
- * cursor: where the cursor is on this character (first char, except for TAB)
- * end: on the last position of this character (TAB, ctrl)
+ * start: on the first position of this character (TAB, ctrl)
+ * cursor: where the cursor is on this character (first char, except for TAB)
+ * end: on the last position of this character (TAB, ctrl)
+ * virtcol: the real first virtual column, either equal to 'start' or even
+ * less if 'sbr' or 'bri' comes into play
*
* This is used very often, keep it fast!
*/
@@ -1283,6 +1285,7 @@ in_win_border(win_T *wp, colnr_T vcol)
getvcol(
win_T *wp,
pos_T *pos,
+ colnr_T *virtcol,
colnr_T *start,
colnr_T *cursor,
colnr_T *end)
@@ -1406,6 +1409,8 @@ getvcol(
MB_PTR_ADV(ptr);
}
}
+ if (virtcol != NULL)
+ *virtcol = vcol;
if (start != NULL)
*start = vcol + head;
if (end != NULL)
@@ -1437,10 +1442,10 @@ getvcol_nolist(pos_T *posp)
curwin->w_p_list = FALSE;
#ifdef FEAT_VIRTUALEDIT
if (posp->coladd)
- getvvcol(curwin, posp, NULL, &vcol, NULL);
+ getvvcol(curwin, posp, NULL, NULL, &vcol, NULL);
else
#endif
- getvcol(curwin, posp, NULL, &vcol, NULL);
+ getvcol(curwin, posp, NULL, NULL, &vcol, NULL);
curwin->w_p_list = list_save;
return vcol;
}
@@ -1453,6 +1458,7 @@ getvcol_nolist(pos_T *posp)
getvvcol(
win_T *wp,
pos_T *pos,
+ colnr_T *virtcol,
colnr_T *start,
colnr_T *cursor,
colnr_T *end)
@@ -1467,7 +1473,7 @@ getvvcol(
if (virtual_active())
{
/* For virtual mode, only want one value */
- getvcol(wp, pos, &col, NULL, NULL);
+ getvcol(wp, pos, NULL, &col, NULL, NULL);
coladd = pos->coladd;
endadd = 0;
@@ -1497,11 +1503,57 @@ getvvcol(
*end = col + endadd;
}
else
- getvcol(wp, pos, start, cursor, end);
+ getvcol(wp, pos, NULL, start, cursor, end);
}
#endif
/*
+ * Like getvvcol() but don't count the extension of the character size applied
+ * by 'lbr'
+ */
+ void
+chop_lbr_getvvcol(
+ win_T *wp,
+ pos_T *pos,
+ colnr_T *start,
+ colnr_T *end)
+{
+ colnr_T init_vcol, start_vcol, end_vcol;
+ char_u *char_ptr, *line;
+ int char_size;
+
+ getvvcol(wp, pos, &init_vcol, &start_vcol, NULL, &end_vcol);
+
+#ifdef FEAT_LINEBREAK
+ if (wp->w_p_wrap && wp->w_p_lbr && pos->col != MAXCOL
+# ifdef FEAT_VIRTUALEDIT
+ && !virtual_active()
+# endif
+ )
+ {
+ line = char_ptr = ml_get(pos->lnum);
+ // Special check for an empty line, which can happen on exit, when
+ // ml_get_buf() always returns an empty string.
+ if (*line != NUL)
+ char_ptr = line + pos->col;
+ if (*char_ptr != NUL)
+ {
+ wp->w_p_lbr = FALSE;
+ // Recount end vcol. This time ignore lbr, but do consider sbr/bri.
+ char_size = win_lbr_chartabsize(wp, line, char_ptr, init_vcol,
+ NULL);
+ wp->w_p_lbr = TRUE;
+ end_vcol = start_vcol + char_size - 1;
+ }
+ }
+#endif
+ if (start != NULL)
+ *start = start_vcol;
+ if (end != NULL)
+ *end = end_vcol;
+}
+
+/*
* Get the leftmost and rightmost virtual column of pos1 and pos2.
* Used for Visual block mode.
*/
@@ -1517,13 +1569,13 @@ getvcols(
if (LT_POSP(pos1, pos2))
{
- getvvcol(wp, pos1, &from1, NULL, &to1);
- getvvcol(wp, pos2, &from2, NULL, &to2);
+ getvvcol(wp, pos1, NULL, &from1, NULL, &to1);
+ getvvcol(wp, pos2, NULL, &from2, NULL, &to2);
}
else
{
- getvvcol(wp, pos2, &from1, NULL, &to1);
- getvvcol(wp, pos1, &from2, NULL, &to2);
+ getvvcol(wp, pos2, NULL, &from1, NULL, &to1);
+ getvvcol(wp, pos1, NULL, &from2, NULL, &to2);
}
if (from2 < from1)
*left = from2;
diff --git a/src/normal.c b/src/normal.c
index a0683b207..f626e7af9 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -1595,8 +1595,19 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
if (VIsual_active || redo_VIsual_busy)
{
+#ifdef FEAT_LINEBREAK
+ // Temporarily restore linebreak, so that vcols reflect it.
+ if (curwin->w_p_lbr != lbr_saved)
+ curwin->w_p_lbr = lbr_saved;
+#endif
+
get_op_vcol(oap, redo_VIsual_vcol, TRUE);
+#ifdef FEAT_LINEBREAK
+ // Revert the temporary restore of linebreak.
+ curwin->w_p_lbr = FALSE;
+#endif
+
if (!redo_VIsual_busy && !gui_yank)
{
/*
@@ -1610,12 +1621,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, NULL, &oap->end_vcol);
if (VIsual_mode == Ctrl_V || oap->line_count <= 1)
{
if (VIsual_mode != Ctrl_V)
getvvcol(curwin, &(oap->start),
- &oap->start_vcol, NULL, NULL);
+ NULL, &oap->start_vcol, NULL, NULL);
resel_VIsual_vcol = oap->end_vcol - oap->start_vcol + 1;
}
else
@@ -1733,6 +1744,9 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
curwin->w_p_lbr = lbr_saved;
#endif
redraw_curbuf_later(INVERTED);
+#ifdef FEAT_LINEBREAK
+ curwin->w_p_lbr = FALSE;
+#endif
}
}
}
@@ -1782,6 +1796,9 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
curwin->w_p_lbr = lbr_saved;
#endif
redraw_curbuf_later(INVERTED);
+#ifdef FEAT_LINEBREAK
+ curwin->w_p_lbr = FALSE;
+#endif
}
/*
@@ -1821,7 +1838,15 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
{
case OP_LSHIFT:
case OP_RSHIFT:
+#ifdef FEAT_LINEBREAK
+ // Temporarily restore linebreak, vcols are calculated with it.
+ curwin->w_p_lbr = lbr_saved;
+#endif
op_shift(oap, TRUE, oap->is_VIsual ? (int)cap->count1 : 1);
+#ifdef FEAT_LINEBREAK
+ // Reset linebreak, so that formatting works correctly.
+ curwin->w_p_lbr = FALSE;
+#endif
auto_format(FALSE, TRUE);
break;
@@ -1849,7 +1874,15 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
}
else
{
+#ifdef FEAT_LINEBREAK
+ // Temporarily restore linebreak, vcols are calculated with it.
+ curwin->w_p_lbr = lbr_saved;
+#endif
(void)op_delete(oap);
+#ifdef FEAT_LINEBREAK
+ // Reset linebreak, so that formatting works correctly.
+ curwin->w_p_lbr = FALSE;
+#endif
if (oap->motion_type == MLINE && has_format_option(FO_AUTO))
u_save_cursor(); /* cursor line wasn't saved yet */
auto_format(FALSE, TRUE);
@@ -1868,9 +1901,14 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
else
{
#ifdef FEAT_LINEBREAK
+ // Temporarily restore linebreak, vcols are calculated with it.
curwin->w_p_lbr = lbr_saved;
#endif
(void)op_yank(oap, FALSE, !gui_yank);
+#ifdef FEAT_LINEBREAK
+ // Reset linebreak, so that formatting works correctly.
+ curwin->w_p_lbr = FALSE;
+#endif
}
check_cursor_col();
break;
@@ -1894,13 +1932,9 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
restart_edit_save = 0;
restart_edit = 0;
#ifdef FEAT_LINEBREAK
- /* Restore linebreak, so that when the user edits it looks as
- * before. */
- if (curwin->w_p_lbr != lbr_saved)
- {
- curwin->w_p_lbr = lbr_saved;
- get_op_vcol(oap, redo_VIsual_mode, FALSE);
- }
+ // Temporarily restore linebreak, vcols are calculated with it.
+ // Also restore it, so that when the user edits it looks as before.
+ curwin->w_p_lbr = lbr_saved;
#endif
/* Reset finish_op now, don't want it set inside edit(). */
finish_op = FALSE;
@@ -1958,7 +1992,17 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
CancelRedo();
}
else
+ {
+#ifdef FEAT_LINEBREAK
+ // Temporarily restore linebreak, vcols are calculated with it.
+ curwin->w_p_lbr = lbr_saved;
+#endif
op_tilde(oap);
+#ifdef FEAT_LINEBREAK
+ // Reset linebreak, so that formatting works correctly.
+ curwin->w_p_lbr = FALSE;
+#endif
+ }
check_cursor_col();
break;
@@ -2004,13 +2048,9 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
restart_edit_save = restart_edit;
restart_edit = 0;
#ifdef FEAT_LINEBREAK
- /* Restore linebreak, so that when the user edits it looks as
- * before. */
- if (curwin->w_p_lbr != lbr_saved)
- {
- curwin->w_p_lbr = lbr_saved;
- get_op_vcol(oap, redo_VIsual_mode, FALSE);
- }
+ // Temporarily restore linebreak, vcols are calculated with it.
+ // Also restore it, so that when the user edits it looks as before.
+ curwin->w_p_lbr = lbr_saved;
#endif
op_insert(oap, cap->count1);
#ifdef FEAT_LINEBREAK
@@ -2045,13 +2085,9 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
else
{
# ifdef FEAT_LINEBREAK
- /* Restore linebreak, so that when the user edits it looks as
- * before. */
- if (curwin->w_p_lbr != lbr_saved)
- {
- curwin->w_p_lbr = lbr_saved;
- get_op_vcol(oap, redo_VIsual_mode, FALSE);
- }
+ // Temporarily restore linebreak, vcols are calculated with it.
+ // Also restore it, so that when the user edits it looks as before.
+ curwin->w_p_lbr = lbr_saved;
# endif
op_replace(oap, cap->nchar);
}
@@ -2702,7 +2738,8 @@ do_mouse(
{
getvcols(curwin, &curwin->w_cursor, &VIsual,
&leftcol, &rightcol);
- getvcol(curwin, &m_pos, NULL, &m_pos.col, NULL);
+ getvcol(curwin, &m_pos,
+ NULL, NULL, &m_pos.col, NULL);
if (m_pos.col < leftcol || m_pos.col > rightcol)
jump_flags = MOUSE_MAY_STOP_VIS;
}
@@ -4936,7 +4973,7 @@ dozet:
col = 0; /* like the cursor is in col 0 */
else
#endif
- getvcol(curwin, &curwin->w_cursor, &col, NULL, NULL);
+ getvcol(curwin, &curwin->w_cursor, NULL, &col, NULL, NULL);
if ((long)col > p_siso)
col -= p_siso;
else
@@ -4957,7 +4994,7 @@ dozet:
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, NULL, &col);
n = curwin->w_width - curwin_col_off();
if ((long)col + p_siso < n)
col = 0;
@@ -6433,7 +6470,7 @@ nv_csearch(cmdarg_T *cap)
{
colnr_T scol, ecol;
- getvcol(curwin, &curwin->w_cursor, &scol, NULL, &ecol);
+ getvcol(curwin, &curwin->w_cursor, NULL, &scol, NULL, &ecol);
curwin->w_cursor.coladd = ecol - scol;
}
else
@@ -9650,11 +9687,11 @@ get_op_vcol(
mb_adjustpos(curwin->w_buffer, &oap->end);
#endif
- getvvcol(curwin, &(oap->start), &oap->start_vcol, NULL, &oap->end_vcol);
+ chop_lbr_getvvcol(curwin, &(oap->start), &oap->start_vcol, &oap->end_vcol);
if (!redo_VIsual_busy)
{
- getvvcol(curwin, &(oap->end), &start, NULL, &end);
+ chop_lbr_getvvcol(curwin, &(oap->end), &start, &end);
if (start < oap->start_vcol)
oap->start_vcol = start;
@@ -9677,7 +9714,7 @@ get_op_vcol(
curwin->w_cursor.lnum <= oap->end.lnum;
++curwin->w_cursor.lnum)
{
- getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &end);
+ chop_lbr_getvvcol(curwin, &curwin->w_cursor, NULL, &end);
if (end > oap->end_vcol)
oap->end_vcol = end;
}
diff --git a/src/ops.c b/src/ops.c
index d6559a2b1..95f6e4d4e 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -3200,7 +3200,7 @@ op_yank(oparg_T *oap, int deleting, int mess)
#ifdef FEAT_VIRTUALEDIT
if (virtual_op)
{
- getvcol(curwin, &oap->start, &cs, NULL, &ce);
+ getvcol(curwin, &oap->start, NULL, &cs, NULL, &ce);
if (ce != cs && oap->start.coladd > 0)
{
/* Part of a tab selected -- but don't
@@ -3219,7 +3219,7 @@ op_yank(oparg_T *oap, int deleting, int mess)
#ifdef FEAT_VIRTUALEDIT
if (virtual_op)
{
- getvcol(curwin, &oap->end, &cs, NULL, &ce);
+ getvcol(curwin, &oap->end, NULL, &cs, NULL, &ce);
if (p[endcol] == NUL || (cs + oap->end.coladd < ce
# ifdef FEAT_MBYTE
/* Don't add space for double-wide
@@ -3745,10 +3745,10 @@ do_put(
{
#ifdef FEAT_VIRTUALEDIT
if (ve_flags == VE_ALL)
- getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2);
+ getvcol(curwin, &curwin->w_cursor, NULL, &col, NULL, &endcol2);
else
#endif
- getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col);
+ getvcol(curwin, &curwin->w_cursor, NULL, NULL, NULL, &col);
#ifdef FEAT_MBYTE
if (has_mbyte)
@@ -3763,7 +3763,7 @@ do_put(
++col;
}
else
- getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2);
+ getvcol(curwin, &curwin->w_cursor, NULL, &col, NULL, &endcol2);
#ifdef FEAT_VIRTUALEDIT
col += curwin->w_cursor.coladd;
@@ -4205,7 +4205,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, NULL, &scol, NULL, &ecol);
curwin->w_cursor.coladd = ecol - scol + 1;
}
#endif
@@ -5396,6 +5396,8 @@ block_prep(
linenr_T lnum,
int is_del)
{
+ colnr_T start_vcol_nolbr;
+ colnr_T start_char_vcols_lbr;
int incr = 0;
char_u *pend;
char_u *pstart;
@@ -5441,6 +5443,23 @@ block_prep(
MB_PTR_ADV(pstart);
}
bdp->start_char_vcols = incr;
+ start_char_vcols_lbr = bdp->start_char_vcols;
+#ifdef FEAT_LINEBREAK
+ if (curwin->w_p_wrap && curwin->w_p_lbr && prev_pstart != line)
+ {
+ // Recount start char vcols. Ignore lbr, but do consider sbr/bri.
+ curwin->w_p_lbr = FALSE;
+ start_vcol_nolbr = bdp->start_vcol - bdp->start_char_vcols;
+ incr = win_lbr_chartabsize(curwin, line,
+ prev_pstart, start_vcol_nolbr, NULL);
+ bdp->start_char_vcols = incr;
+ start_vcol_nolbr += incr;
+ curwin->w_p_lbr = TRUE;
+ }
+ else
+#endif
+ start_vcol_nolbr = bdp->start_vcol;
+
if (bdp->start_vcol < oap->start_vcol) /* line too short */
{
bdp->end_vcol = bdp->start_vcol;
@@ -5454,9 +5473,17 @@ block_prep(
{
/* notice: this converts partly selected Multibyte characters to
* spaces, too. */
- bdp->startspaces = bdp->start_vcol - oap->start_vcol;
- if (is_del && bdp->startspaces)
- bdp->startspaces = bdp->start_char_vcols - bdp->startspaces;
+ if (oap->start_vcol < start_vcol_nolbr
+ || start_vcol_nolbr == bdp->start_vcol)
+ {
+ bdp->startspaces = start_vcol_nolbr - oap->start_vcol;
+ if (is_del && bdp->startspaces)
+ bdp->startspaces = bdp->start_char_vcols - bdp->startspaces;
+ }
+ // TODO: remove the following old code backup
+ // bdp->startspaces = bdp->start_vcol - oap->start_vcol;
+ // if (is_del && bdp->startspaces)
+ // bdp->startspaces = bdp->start_char_vcols - bdp->startspaces;
pend = pstart;
bdp->end_vcol = bdp->start_vcol;
if (bdp->end_vcol > oap->end_vcol) /* it's all in one character */
@@ -5479,14 +5506,21 @@ block_prep(
/* just putting the sum of those two into
* bdp->startspaces doesn't work for Visual replace,
* so we have to split the tab in two */
- bdp->startspaces = bdp->start_char_vcols
+ bdp->startspaces = start_char_vcols_lbr
- (bdp->start_vcol - oap->start_vcol);
- bdp->endspaces = bdp->end_vcol - oap->end_vcol - 1;
+ if (bdp->startspaces > bdp->start_char_vcols)
+ bdp->startspaces = bdp->start_char_vcols;
+ // if lbr not in effect: start_vcol_nolbr == bdp->end_vcol
+ bdp->endspaces = start_vcol_nolbr - oap->end_vcol - 1;
+ if (bdp->endspaces < 0)
+ bdp->endspaces = 0;
}
}
}
else
{
+ colnr_T end_vcol_lbr;
+
prev_pend = pend;
while (bdp->end_vcol <= oap->end_vcol && *pend != NUL)
{
@@ -5495,13 +5529,29 @@ block_prep(
incr = lbr_chartabsize_adv(line, &pend, (colnr_T)bdp->end_vcol);
bdp->end_vcol += incr;
}
+ end_vcol_lbr = bdp->end_vcol;
+#ifdef FEAT_LINEBREAK
+ if (curwin->w_p_wrap && curwin->w_p_lbr && *prev_pend != NUL)
+ {
+ // Recount end vcol. This time ignore lbr, but do consider
+ // sbr/bri.
+ curwin->w_p_lbr = FALSE;
+ bdp->end_vcol -= incr;
+ incr = win_lbr_chartabsize(curwin, line,
+ prev_pend, bdp->end_vcol, NULL);
+ bdp->end_vcol += incr;
+ curwin->w_p_lbr = TRUE;
+ }
+#endif
if (bdp->end_vcol <= oap->end_vcol
&& (!is_del
|| oap->op_type == OP_APPEND
|| oap->op_type == OP_REPLACE)) /* line too short */
{
#ifdef FEAT_VISUALEXTRA
- bdp->is_short = TRUE;
+ // bdp->is_short = TRUE;
+ // TODO: set to TRUE as before ???
+ bdp->is_short = end_vcol_lbr <= oap->end_vcol;
#endif
/* Alternative: include spaces to fill up the block.
* Disadvantage: can lead to trailing spaces when the line is
@@ -5523,6 +5573,7 @@ block_prep(
pend = prev_pend;
}
}
+ bdp->end_vcol = end_vcol_lbr;
}
#ifdef FEAT_VISUALEXTRA
bdp->end_char_vcols = incr;
diff --git a/src/proto/charset.pro b/src/proto/charset.pro
index bb4132fe7..0c12de4e6 100644
--- a/src/proto/charset.pro
+++ b/src/proto/charset.pro
@@ -30,9 +30,10 @@ int lbr_chartabsize(char_u *line, unsigned char *s, colnr_T col);
int lbr_chartabsize_adv(char_u *line, char_u **s, colnr_T col);
int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *headp);
int in_win_border(win_T *wp, colnr_T vcol);
-void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end);
+void getvcol(win_T *wp, pos_T *pos, colnr_T *init, colnr_T *start, colnr_T *cursor, colnr_T *end);
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 getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end, int *headp);
+void chop_lbr_getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *end);
void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, colnr_T *right);
char_u *skipwhite(char_u *q);
int getwhitecols_curline(void);
diff --git a/src/regexp.c b/src/regexp.c
index 04116675f..03a100509 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -4207,8 +4207,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, NULL, &start, NULL, &end);
+ getvvcol(wp, &bot, NULL, &start2, NULL, &end2);
if (start2 < start)
start = start2;
if (end2 > end)
diff --git a/src/screen.c b/src/screen.c
index 69f755844..9eeda54e6 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -3385,7 +3385,8 @@ win_line(
fromcol = 0;
else
{
- getvvcol(wp, top, (colnr_T *)&fromcol, NULL, NULL);
+ getvvcol(wp, top,
+ NULL, (colnr_T *)&fromcol, NULL, NULL);
if (gchar_pos(top) == NUL)
tocol = fromcol + 1;
}
@@ -3407,10 +3408,12 @@ win_line(
{
pos = *bot;
if (*p_sel == 'e')
- getvvcol(wp, &pos, (colnr_T *)&tocol, NULL, NULL);
+ getvvcol(wp, &pos, NULL,
+ (colnr_T *)&tocol, NULL, NULL);
else
{
- getvvcol(wp, &pos, NULL, NULL, (colnr_T *)&tocol);
+ getvvcol(wp, &pos,
+ NULL, NULL, NULL, (colnr_T *)&tocol);
++tocol;
}
}
@@ -3450,14 +3453,14 @@ win_line(
{
if (lnum == curwin->w_cursor.lnum)
getvcol(curwin, &(curwin->w_cursor),
- (colnr_T *)&fromcol, NULL, NULL);
+ NULL, (colnr_T *)&fromcol, NULL, NULL);
else
fromcol = 0;
if (lnum == curwin->w_cursor.lnum + search_match_lines)
{
pos.lnum = lnum;
pos.col = search_match_endcol;
- getvcol(curwin, &pos, (colnr_T *)&tocol, NULL, NULL);
+ getvcol(curwin, &pos, NULL, (colnr_T *)&tocol, NULL, NULL);
}
else
tocol = MAXCOL;
@@ -5295,7 +5298,7 @@ win_line(
colnr_T tcol;
if (preedit_end_col == MAXCOL)
- getvcol(curwin, &(wp->w_cursor), &tcol, NULL, NULL);
+ getvcol(curwin, &(wp->w_cursor), NULL, &tcol, NULL, NULL);
else
tcol = preedit_end_col;
if ((long)preedit_start_col <= vcol && vcol < (long)tcol)
@@ -11056,7 +11059,7 @@ win_redr_ruler(win_T *wp, int always, int ignore_pum)
if (wp->w_p_list && lcs_tab1 == NUL)
{
wp->w_p_list = FALSE;
- getvvcol(wp, &wp->w_cursor, NULL, &virtcol, NULL);
+ getvvcol(wp, &wp->w_cursor, NULL, NULL, &virtcol, NULL);
wp->w_p_list = TRUE;
}
diff --git a/src/search.c b/src/search.c
index dff532d8f..b5a699fbe 100644
--- a/src/search.c
+++ b/src/search.c
@@ -2644,7 +2644,7 @@ showmatch(
else if (lpos->lnum >= curwin->w_topline && lpos->lnum < curwin->w_botline)
{
if (!curwin->w_p_wrap)
- getvcol(curwin, lpos, NULL, &vcol, NULL);
+ getvcol(curwin, lpos, NULL, NULL, &vcol, NULL);
if (curwin->w_p_wrap || (vcol >= curwin->w_leftcol
&& vcol < curwin->w_leftcol + curwin->w_width))
{
diff --git a/src/testdir/Makefile b/src/testdir/Makefile
index e9e0f4b32..c6567feef 100644
--- a/src/testdir/Makefile
+++ b/src/testdir/Makefile
@@ -38,6 +38,14 @@ SCRIPTS_BENCH = bench_re_freeze.out
nongui: nolog $(SCRIPTS_FIRST) $(SCRIPTS) newtests report
+tom39a: nolog $(SCRIPTS_FIRST) tom39a.res report
+
+tom: nolog $(SCRIPTS_FIRST) test_lbr_visual_block_yank_delete.res report
+
+tom2: nolog $(SCRIPTS_FIRST) tom2.res report
+
+tom3: nolog $(SCRIPTS_FIRST) tom3.res report
+
gui: nolog $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_GUI) newtests report
benchmark: $(SCRIPTS_BENCH)
diff --git a/src/vim.h b/src/vim.h
index 7a66ab0e2..679f1197a 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -2173,7 +2173,7 @@ typedef enum {
#include "globals.h" /* global variables and messages */
#ifndef FEAT_VIRTUALEDIT
-# define getvvcol(w, p, s, c, e) getvcol((w), (p), (s), (c), (e))
+# define getvvcol(w, p, i, s, c, e) getvcol((w), (p), (i), (s), (c), (e))
# define virtual_active() FALSE
# define virtual_op FALSE
#endif
diff --git a/src/buffer.c b/src/buffer.c
index 8e892dadf..df2996f24 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -4289,7 +4289,7 @@ build_stl_str_hl(
if (wp->w_p_list && lcs_tab1 == NUL)
{
wp->w_p_list = FALSE;
- getvcol(wp, &wp->w_cursor, NULL, &virtcol, NULL);
+ getvcol(wp, &wp->w_cursor, NULL, NULL, &virtcol, NULL);
wp->w_p_list = TRUE;
}
++virtcol;
diff --git a/src/edit.c b/src/edit.c
index 239881ee5..bb1d32697 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -7968,7 +7968,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, NULL, &start_vcol, NULL);
orig_vcols = chartabsize(ml_get_cursor(), start_vcol);
}
#ifdef FEAT_MBYTE
@@ -9049,7 +9049,7 @@ ins_del(void)
ins_bs_one(colnr_T *vcolp)
{
dec_cursor();
- getvcol(curwin, &curwin->w_cursor, vcolp, NULL, NULL);
+ getvcol(curwin, &curwin->w_cursor, NULL, vcolp, NULL, NULL);
if (State & REPLACE_FLAG)
{
/* Don't delete characters before the insert point when in
@@ -9299,10 +9299,10 @@ ins_bs(
/* Compute the virtual column where we want to be. Since
* 'showbreak' may get in the way, need to get the last column of
* the previous character. */
- getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
+ getvcol(curwin, &curwin->w_cursor, NULL, &vcol, NULL, NULL);
start_vcol = vcol;
dec_cursor();
- getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol);
+ getvcol(curwin, &curwin->w_cursor, NULL, NULL, NULL, &want_vcol);
inc_cursor();
#ifdef FEAT_VARTABS
if (p_sta && in_indent)
@@ -9342,7 +9342,7 @@ ins_bs(
if ((State & REPLACE_FLAG))
replace_push(NUL);
}
- getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
+ getvcol(curwin, &curwin->w_cursor, NULL, &vcol, NULL, NULL);
}
/* If we are now back where we started delete one character. Can
@@ -10248,8 +10248,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, NULL, &vcol, NULL, NULL);
+ getvcol(curwin, cursor, NULL, &want_vcol, NULL, NULL);
/* Use as many TABs as possible. Beware of 'breakindent', 'showbreak'
* and 'linebreak' adding extra virtual columns. */
diff --git a/src/evalfunc.c b/src/evalfunc.c
index f55739ed5..47402b9bb 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -13877,7 +13877,7 @@ f_virtcol(typval_T *argvars, typval_T *rettv)
if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count
&& fnum == curbuf->b_fnum)
{
- getvvcol(curwin, fp, NULL, NULL, &vcol);
+ getvvcol(curwin, fp, NULL, NULL, NULL, &vcol);
++vcol;
}
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index cb728d405..fd84cb5f0 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -5403,11 +5403,13 @@ do_sub(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,
+ NULL, &sc, NULL, NULL);
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, NULL, &ec);
if (subflags.do_number || curwin->w_p_nu)
{
int numw = number_width(curwin) + 1;
diff --git a/src/mbyte.c b/src/mbyte.c
index 26233e423..1500ad1df 100644
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -4852,7 +4852,8 @@ init_preedit_start_col(void)
if (State & 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,
+ NULL, &preedit_start_col, NULL, NULL);
/* Prevent that preediting marks the buffer as changed. */
xim_changed_while_preediting = curbuf->b_changed;
}
diff --git a/src/misc1.c b/src/misc1.c
index 820f8f994..3c1be0d40 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -626,7 +626,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, NULL, &col, NULL, NULL);
return (int)col;
}
@@ -2404,7 +2404,7 @@ ins_char_bytes(char_u *buf, int charlen)
* 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, NULL, &vcol, NULL);
#ifndef FEAT_MBYTE
buf[0] = c;
buf[1] = NUL;
@@ -6134,7 +6134,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, NULL, &col, NULL, NULL);
return (int)col;
}
@@ -6218,7 +6218,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, NULL, &col, NULL, NULL);
return (int)col;
}
@@ -6266,7 +6266,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, NULL, &col, NULL, NULL);
return (int)col;
}
@@ -6872,7 +6872,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, NULL, &vcol, NULL, NULL);
amount = (int)vcol;
}
if (amount < curbuf->b_ind_cpp_baseclass)
@@ -7483,7 +7483,7 @@ get_c_indent(void)
&& (trypos = find_line_comment()) != NULL) /* XXX */
{
/* find how indented the line beginning the comment is */
- getvcol(curwin, trypos, &col, NULL, NULL);
+ getvcol(curwin, trypos, NULL, &col, NULL, NULL);
amount = col;
goto theend;
}
@@ -7505,7 +7505,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, NULL, &col, NULL, NULL);
amount = col;
*lead_start = NUL;
*lead_middle = NUL;
@@ -7633,7 +7633,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, NULL, &col, NULL, NULL);
amount = col;
if (curbuf->b_ind_in_comment2 || *look == NUL)
amount += curbuf->b_ind_in_comment;
@@ -7846,7 +7846,7 @@ get_c_indent(void)
*/
if (our_paren_pos.col > 0)
{
- getvcol(curwin, &our_paren_pos, &col, NULL, NULL);
+ getvcol(curwin, &our_paren_pos, NULL, &col, NULL, NULL);
if (cur_amount > (int)col)
cur_amount = col;
}
@@ -7941,7 +7941,7 @@ get_c_indent(void)
look = skipwhite(start);
if (*look == '{')
{
- getvcol(curwin, trypos, &col, NULL, NULL);
+ getvcol(curwin, trypos, NULL, &col, NULL, NULL);
amount = col;
if (*start == '{')
start_brace = BRACE_IN_COL0;
diff --git a/src/misc2.c b/src/misc2.c
index ce695979d..b8130af49 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, NULL, &x, NULL, NULL);
return (int)x;
}
@@ -59,7 +59,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, NULL, &x, NULL, NULL);
return (int)x;
}
@@ -301,7 +301,7 @@ coladvance2(
{
colnr_T scol, ecol;
- getvcol(curwin, pos, &scol, NULL, &ecol);
+ getvcol(curwin, pos, NULL, &scol, NULL, &ecol);
pos->coladd = ecol - scol;
}
}
@@ -635,7 +635,7 @@ check_cursor_col_win(win_T *win)
{
int cs, ce;
- getvcol(win, &win->w_cursor, &cs, NULL, &ce);
+ getvcol(win, &win->w_cursor, NULL, &cs, NULL, &ce);
if (win->w_cursor.coladd > ce - cs)
win->w_cursor.coladd = ce - cs;
}
@@ -707,7 +707,7 @@ leftcol_changed(void)
* advance the cursor one more char. If this fails (last char of the
* line) adjust the scrolling.
*/
- getvvcol(curwin, &curwin->w_cursor, &s, NULL, &e);
+ getvvcol(curwin, &curwin->w_cursor, NULL, &s, NULL, &e);
if (e > (colnr_T)lastcol)
{
retval = TRUE;
diff --git a/src/move.c b/src/move.c
index 214c362f4..820bb8254 100644
--- a/src/move.c
+++ b/src/move.c
@@ -819,7 +819,7 @@ validate_virtcol_win(win_T *wp)
check_cursor_moved(wp);
if (!(wp->w_valid & VALID_VIRTCOL))
{
- getvvcol(wp, &wp->w_cursor, NULL, &(wp->w_virtcol), NULL);
+ getvvcol(wp, &wp->w_cursor, NULL, NULL, &(wp->w_virtcol), NULL);
wp->w_valid |= VALID_VIRTCOL;
#ifdef FEAT_SYN_HL
if (wp->w_p_cuc
@@ -976,7 +976,7 @@ curs_columns(
else
#endif
getvvcol(curwin, &curwin->w_cursor,
- &startcol, &(curwin->w_virtcol), &endcol);
+ NULL, &startcol, &(curwin->w_virtcol), &endcol);
/* remove '$' from change command when cursor moves onto it */
if (startcol > dollar_vcol)