On Wednesday, November 14, 2018 at 10:23:52 PM UTC+1, Tom M wrote: > > Hi, > > I propose the following patch (please see the attachment) to fix issues of > John and Tony. It ads handling of 'showbreak' and 'linebreak' in visual block > operations. > > Tom
Oooops, wrong attachment. Please see the correct one. Sorry for the noise. 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 vim_dev+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
>From ca2062628e4ff4fe8c6a51812fb8b7c054a87b3a Mon Sep 17 00:00:00 2001 From: tom <tom@debian9> Date: Wed, 14 Nov 2018 22:54:06 +0100 Subject: [PATCH] support showbreak and linebreak in visual block operations --- src/buffer.c | 2 +- src/charset.c | 78 +++++++++++++++++++++++++++++++++++++++------ src/edit.c | 14 ++++----- src/evalfunc.c | 2 +- src/ex_cmds.c | 4 +-- src/mbyte.c | 2 +- src/misc1.c | 22 ++++++------- src/misc2.c | 10 +++--- src/move.c | 4 +-- src/normal.c | 87 +++++++++++++++++++++++++++++++++++++-------------- src/ops.c | 45 +++++++++++++++++++++----- src/proto/charset.pro | 6 ++-- src/regexp.c | 4 +-- src/screen.c | 14 ++++----- src/search.c | 2 +- src/vim.h | 2 +- 16 files changed, 214 insertions(+), 84 deletions(-) diff --git a/src/buffer.c b/src/buffer.c index 8e892dadf..574fc5efe 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, &virtcol, NULL, NULL); wp->w_p_list = TRUE; } ++virtcol; diff --git a/src/charset.c b/src/charset.c index 028095453..be1861c17 100644 --- a/src/charset.c +++ b/src/charset.c @@ -1276,6 +1276,9 @@ in_win_border(win_T *wp, colnr_T vcol) * 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) + * If "headp" not NULL, set *headp to the size of what we add for 'showbreak' + * string at start of line. Warning: *headp is only set if it's a non-zero + * value, init to 0 before calling. * * This is used very often, keep it fast! */ @@ -1285,7 +1288,8 @@ getvcol( pos_T *pos, colnr_T *start, colnr_T *cursor, - colnr_T *end) + colnr_T *end, + int *headp UNUSED) { colnr_T vcol; char_u *ptr; /* points to current char */ @@ -1423,6 +1427,8 @@ getvcol( else *cursor = vcol + head; /* cursor at start */ } + if (headp != NULL) + *headp = head; } /* @@ -1437,10 +1443,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, &vcol, NULL, NULL); else #endif - getvcol(curwin, posp, NULL, &vcol, NULL); + getvcol(curwin, posp, NULL, &vcol, NULL, NULL); curwin->w_p_list = list_save; return vcol; } @@ -1455,7 +1461,8 @@ getvvcol( pos_T *pos, colnr_T *start, colnr_T *cursor, - colnr_T *end) + colnr_T *end, + int *headp) { colnr_T col; colnr_T coladd; @@ -1467,7 +1474,7 @@ getvvcol( if (virtual_active()) { /* For virtual mode, only want one value */ - getvcol(wp, pos, &col, NULL, NULL); + getvcol(wp, pos, &col, NULL, NULL, headp); coladd = pos->coladd; endadd = 0; @@ -1497,11 +1504,62 @@ getvvcol( *end = col + endadd; } else - getvcol(wp, pos, start, cursor, end); + getvcol(wp, pos, start, cursor, end, headp); } #endif /* + * Like getvvcol() without head, but don't count the "phantom" whitespace added + * by 'lbr' to the size of the char. + */ + void +getvvcol_chop_lbr( + pos_T *pos, + colnr_T *start, + colnr_T *cursor, + colnr_T *end) +{ + colnr_T start_vcol, cursor_vcol, end_vcol; + char_u *char_ptr, *line; + int csize; + int head = 0; + + getvvcol(curwin, pos, &start_vcol, &cursor_vcol, &end_vcol, &head); + +#ifdef FEAT_LINEBREAK + if (curwin->w_p_wrap && curwin->w_p_lbr && pos->col != MAXCOL +# ifdef FEAT_VIRTUALEDIT + && !virtual_active() +# endif + ) + { + line = 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) + pos->col = 0; + char_ptr = line + pos->col; + if (*char_ptr != NUL) + { + curwin->w_p_lbr = FALSE; + // Count end vcol again. Ignore lbr. But do consider sbr/bri. + csize = win_lbr_chartabsize(curwin, line, char_ptr, + start_vcol - head, NULL); + curwin->w_p_lbr = TRUE; + end_vcol = start_vcol - head + csize - 1; + } + } +#endif + + if (start != NULL) + *start = start_vcol; + if (cursor != NULL) + *cursor = cursor_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 +1575,13 @@ getvcols( if (LT_POSP(pos1, pos2)) { - getvvcol(wp, pos1, &from1, NULL, &to1); - getvvcol(wp, pos2, &from2, NULL, &to2); + getvvcol(wp, pos1, &from1, NULL, &to1, NULL); + getvvcol(wp, pos2, &from2, NULL, &to2, NULL); } else { - getvvcol(wp, pos2, &from1, NULL, &to1); - getvvcol(wp, pos1, &from2, NULL, &to2); + getvvcol(wp, pos2, &from1, NULL, &to1, NULL); + getvvcol(wp, pos1, &from2, NULL, &to2, NULL); } if (from2 < from1) *left = from2; diff --git a/src/edit.c b/src/edit.c index 239881ee5..89ee044df 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, &start_vcol, NULL, 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, vcolp, NULL, 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, &vcol, NULL, NULL, NULL); start_vcol = vcol; dec_cursor(); - getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol); + getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol, NULL); 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, &vcol, NULL, 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, &vcol, NULL, NULL, NULL); + getvcol(curwin, cursor, &want_vcol, NULL, 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..edc5dbb7a 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, &vcol, NULL); ++vcol; } diff --git a/src/ex_cmds.c b/src/ex_cmds.c index cb728d405..0e5aabfa9 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -5403,11 +5403,11 @@ 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, &sc, NULL, 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, &ec, NULL); 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..2f2dc93e6 100644 --- a/src/mbyte.c +++ b/src/mbyte.c @@ -4852,7 +4852,7 @@ 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, &preedit_start_col, NULL, 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..8bce02818 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, &col, NULL, 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, &vcol, NULL, 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, &col, NULL, 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, &col, NULL, 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, &col, NULL, 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, &vcol, NULL, 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, &col, NULL, 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, &col, NULL, 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, &col, NULL, 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, &col, NULL, 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, &col, NULL, NULL, NULL); amount = col; if (*start == '{') start_brace = BRACE_IN_COL0; diff --git a/src/misc2.c b/src/misc2.c index ce695979d..53b11a9c4 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, 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, &x, NULL, NULL, NULL); return (int)x; } @@ -301,7 +301,7 @@ coladvance2( { colnr_T scol, ecol; - getvcol(curwin, pos, &scol, NULL, &ecol); + getvcol(curwin, pos, &scol, NULL, &ecol, NULL); 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, &cs, NULL, &ce, NULL); 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, &s, NULL, &e, NULL); if (e > (colnr_T)lastcol) { retval = TRUE; diff --git a/src/move.c b/src/move.c index 214c362f4..e841f650c 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, &(wp->w_virtcol), NULL, 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); + &startcol, &(curwin->w_virtcol), &endcol, NULL); /* remove '$' from change command when cursor moves onto it */ if (startcol > dollar_vcol) diff --git a/src/normal.c b/src/normal.c index a0683b207..d3134b90a 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, &oap->end_vcol, NULL); 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, 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,16 @@ 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. + if (curwin->w_p_lbr != lbr_saved) + 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 +1875,16 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank) } else { +#ifdef FEAT_LINEBREAK + // Temporarily restore linebreak, vcols are calculated with it. + if (curwin->w_p_lbr != lbr_saved) + 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 +1903,15 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank) else { #ifdef FEAT_LINEBREAK - curwin->w_p_lbr = lbr_saved; + // Temporarily restore linebreak, vcols are calculated with it. + if (curwin->w_p_lbr != lbr_saved) + 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; @@ -1897,10 +1938,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank) /* 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); - } #endif /* Reset finish_op now, don't want it set inside edit(). */ finish_op = FALSE; @@ -1958,7 +1996,18 @@ 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. + if (curwin->w_p_lbr != lbr_saved) + 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 +2053,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. */ + // Temporarily restore linebreak, vcols are calculated with it. if (curwin->w_p_lbr != lbr_saved) - { curwin->w_p_lbr = lbr_saved; - get_op_vcol(oap, redo_VIsual_mode, FALSE); - } #endif op_insert(oap, cap->count1); #ifdef FEAT_LINEBREAK @@ -2045,13 +2090,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. */ + // Temporarily restore linebreak, vcols are calculated with it. if (curwin->w_p_lbr != lbr_saved) - { curwin->w_p_lbr = lbr_saved; - get_op_vcol(oap, redo_VIsual_mode, FALSE); - } # endif op_replace(oap, cap->nchar); } @@ -2702,7 +2743,7 @@ do_mouse( { getvcols(curwin, &curwin->w_cursor, &VIsual, &leftcol, &rightcol); - getvcol(curwin, &m_pos, NULL, &m_pos.col, NULL); + getvcol(curwin, &m_pos, NULL, &m_pos.col, NULL, NULL); if (m_pos.col < leftcol || m_pos.col > rightcol) jump_flags = MOUSE_MAY_STOP_VIS; } @@ -4936,7 +4977,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, &col, NULL, NULL, NULL); if ((long)col > p_siso) col -= p_siso; else @@ -4957,7 +4998,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, &col, NULL); n = curwin->w_width - curwin_col_off(); if ((long)col + p_siso < n) col = 0; @@ -6433,7 +6474,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, NULL); curwin->w_cursor.coladd = ecol - scol; } else @@ -9650,11 +9691,11 @@ get_op_vcol( mb_adjustpos(curwin->w_buffer, &oap->end); #endif - getvvcol(curwin, &(oap->start), &oap->start_vcol, NULL, &oap->end_vcol); + getvvcol_chop_lbr(&(oap->start), &oap->start_vcol, NULL, &oap->end_vcol); if (!redo_VIsual_busy) { - getvvcol(curwin, &(oap->end), &start, NULL, &end); + getvvcol_chop_lbr(&(oap->end), &start, NULL, &end); if (start < oap->start_vcol) oap->start_vcol = start; @@ -9677,7 +9718,7 @@ get_op_vcol( curwin->w_cursor.lnum <= oap->end.lnum; ++curwin->w_cursor.lnum) { - getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &end); + getvvcol_chop_lbr(&curwin->w_cursor, NULL, NULL, &end); if (end > oap->end_vcol) oap->end_vcol = end; } diff --git a/src/ops.c b/src/ops.c index d6559a2b1..069c128a3 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, &cs, NULL, &ce, NULL); 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, &cs, NULL, &ce, NULL); 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, &col, NULL, &endcol2, NULL); else #endif - getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col); + getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col, NULL); #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, &col, NULL, &endcol2, NULL); #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, &scol, NULL, &ecol, NULL); curwin->w_cursor.coladd = ecol - scol + 1; } #endif @@ -5396,6 +5396,7 @@ block_prep( linenr_T lnum, int is_del) { + int head = 0; int incr = 0; char_u *pend; char_u *pstart; @@ -5422,8 +5423,18 @@ block_prep( prev_pstart = line; while (bdp->start_vcol < oap->start_vcol && *pstart) { - /* Count a tab for what it's worth (if list mode not on) */ - incr = lbr_chartabsize(line, pstart, (colnr_T)bdp->start_vcol); + head = 0; + // Count a tab for what it's worth. + incr = win_lbr_chartabsize(curwin, line, pstart, + (colnr_T)bdp->start_vcol, &head); + if (bdp->start_vcol + head >= oap->start_vcol) + { + bdp->start_vcol += head; + // 'showbreak' is in effect, nr of chars's vcols is actually + // smaller. + incr = incr - head; + break; + } bdp->start_vcol += incr; #ifdef FEAT_VISUALEXTRA if (VIM_ISWHITE(*pstart)) @@ -5487,6 +5498,7 @@ block_prep( } else { + bdp->end_vcol = bdp->start_vcol - head; prev_pend = pend; while (bdp->end_vcol <= oap->end_vcol && *pend != NUL) { @@ -5495,6 +5507,23 @@ block_prep( incr = lbr_chartabsize_adv(line, &pend, (colnr_T)bdp->end_vcol); bdp->end_vcol += incr; } +#ifdef FEAT_LINEBREAK + if (curwin->w_p_wrap && curwin->w_p_lbr && *prev_pend != NUL + && is_del) + { + bdp->end_vcol -= incr; + curwin->w_p_lbr = FALSE; + // Don't count the "phantom" whitespace added by lbr to the + // right side of the last character. But do consider sbr/bri. + incr = win_lbr_chartabsize(curwin, line, prev_pend, + bdp->end_vcol, &head); + curwin->w_p_lbr = TRUE; + bdp->end_vcol += incr; + // If 'showbreak' is in effect, nr of chars's vcols is actually + // smaller. + incr -= head; + } +#endif if (bdp->end_vcol <= oap->end_vcol && (!is_del || oap->op_type == OP_APPEND diff --git a/src/proto/charset.pro b/src/proto/charset.pro index bb4132fe7..5bea9bee0 100644 --- a/src/proto/charset.pro +++ b/src/proto/charset.pro @@ -29,10 +29,12 @@ int vim_isprintc_strict(int c); 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 win_nolbr_chartabsize(win_T *wp, 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 *start, colnr_T *cursor, colnr_T *end, int *headp); 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 getvvcol_chop_lbr(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); char_u *skipwhite(char_u *q); int getwhitecols_curline(void); diff --git a/src/regexp.c b/src/regexp.c index 04116675f..6e31f03df 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, &start, NULL, &end, NULL); + getvvcol(wp, &bot, &start2, NULL, &end2, NULL); if (start2 < start) start = start2; if (end2 > end) diff --git a/src/screen.c b/src/screen.c index 69f755844..d4e2a9a3b 100644 --- a/src/screen.c +++ b/src/screen.c @@ -3385,7 +3385,7 @@ win_line( fromcol = 0; else { - getvvcol(wp, top, (colnr_T *)&fromcol, NULL, NULL); + getvvcol(wp, top, (colnr_T *)&fromcol, NULL, NULL, NULL); if (gchar_pos(top) == NUL) tocol = fromcol + 1; } @@ -3407,10 +3407,10 @@ win_line( { pos = *bot; if (*p_sel == 'e') - getvvcol(wp, &pos, (colnr_T *)&tocol, NULL, NULL); + getvvcol(wp, &pos, (colnr_T *)&tocol, NULL, NULL, NULL); else { - getvvcol(wp, &pos, NULL, NULL, (colnr_T *)&tocol); + getvvcol(wp, &pos, NULL, NULL, (colnr_T *)&tocol, NULL); ++tocol; } } @@ -3450,14 +3450,14 @@ win_line( { if (lnum == curwin->w_cursor.lnum) getvcol(curwin, &(curwin->w_cursor), - (colnr_T *)&fromcol, NULL, NULL); + (colnr_T *)&fromcol, NULL, 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, (colnr_T *)&tocol, NULL, NULL, NULL); } else tocol = MAXCOL; @@ -5295,7 +5295,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, NULL); else tcol = preedit_end_col; if ((long)preedit_start_col <= vcol && vcol < (long)tcol) @@ -11056,7 +11056,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, &virtcol, NULL, NULL); wp->w_p_list = TRUE; } diff --git a/src/search.c b/src/search.c index dff532d8f..a6fe1c050 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, &vcol, NULL, NULL); if (curwin->w_p_wrap || (vcol >= curwin->w_leftcol && vcol < curwin->w_leftcol + curwin->w_width)) { diff --git a/src/vim.h b/src/vim.h index 7a66ab0e2..a02be5df2 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, s, c, e, h) getvcol((w), (p), (s), (c), (e), (h)) # define virtual_active() FALSE # define virtual_op FALSE #endif -- 2.11.0