Permalink
Browse files

patch 8.0.1041: bogus characters when indenting during visual-block a…

…ppend

Problem:    Bogus characters appear when indenting kicks in while doing a
            visual-block append.
Solution:   Recompute when indenting is done. (Christian Brabandt)
  • Loading branch information...
brammool committed Sep 2, 2017
1 parent 3653822 commit e2e69e48134cbfdedea7802810932f8592705024
Showing with 70 additions and 20 deletions.
  1. +3 −2 runtime/doc/visual.txt
  2. +16 −0 src/charset.c
  3. +3 −4 src/edit.c
  4. +2 −4 src/misc1.c
  5. +15 −4 src/ops.c
  6. +2 −0 src/proto/charset.pro
  7. +1 −0 src/proto/misc1.pro
  8. +1 −1 src/screen.c
  9. +3 −3 src/spell.c
  10. +22 −2 src/testdir/test_cindent.vim
  11. +2 −0 src/version.c
View
@@ -314,8 +314,8 @@ Visual-block Insert *v_b_I*
With a blockwise selection, I{string}<ESC> will insert {string} at the start
of block on every line of the block, provided that the line extends into the
block. Thus lines that are short will remain unmodified. TABs are split to
retain visual columns.
See |v_b_I_example|.
retain visual columns. Works only for adding text to a line, not for
deletions. See |v_b_I_example|.
Visual-block Append *v_b_A*
With a blockwise selection, A{string}<ESC> will append {string} to the end of
@@ -331,6 +331,7 @@ See |v_b_A_example|.
Note: "I" and "A" behave differently for lines that don't extend into the
selected block. This was done intentionally, so that you can do it the way
you want.
Works only for adding text to a line, not for deletions.
Visual-block change *v_b_c*
All selected text in the block will be replaced by the same text string. When
View
@@ -1535,6 +1535,22 @@ skipwhite(char_u *q)
return p;
}
/*
* getwhitecols: return the number of whitespace
* columns (bytes) at the start of a given line
*/
int
getwhitecols_curline()
{
return getwhitecols(ml_get_curline());
}
int
getwhitecols(char_u *p)
{
return skipwhite(p) - p;
}
/*
* skip over digits
*/
View
@@ -5182,7 +5182,7 @@ ins_complete(int c, int enable_pum)
* first non_blank in the line, if it is not a wordchar
* include it to get a better pattern, but then we don't
* want the "\\<" prefix, check it bellow */
compl_col = (colnr_T)(skipwhite(line) - line);
compl_col = (colnr_T)getwhitecols(line);
compl_startpos.col = compl_col;
compl_startpos.lnum = curwin->w_cursor.lnum;
compl_cont_status &= ~CONT_SOL; /* clear SOL if present */
@@ -5348,7 +5348,7 @@ ins_complete(int c, int enable_pum)
}
else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
{
compl_col = (colnr_T)(skipwhite(line) - line);
compl_col = (colnr_T)getwhitecols(line);
compl_length = (int)curs_col - (int)compl_col;
if (compl_length < 0) /* cursor in indent: empty pattern */
compl_length = 0;
@@ -8208,8 +8208,7 @@ in_cinkeys(
{
/* "0=word": Check if there are only blanks before the
* word. */
line = ml_get_curline();
if ((int)(skipwhite(line) - line) !=
if (getwhitecols(line) !=
(int)(curwin->w_cursor.col - (p - look)))
match = FALSE;
}
View
@@ -1589,8 +1589,7 @@ open_line(
&& curbuf->b_p_ai)
{
fixthisline(get_lisp_indent);
p = ml_get_curline();
ai_col = (colnr_T)(skipwhite(p) - p);
ai_col = (colnr_T)getwhitecols_curline();
}
#endif
#ifdef FEAT_CINDENT
@@ -1608,8 +1607,7 @@ open_line(
: KEY_OPEN_BACK, ' ', linewhite(curwin->w_cursor.lnum)))
{
do_c_expr_indent();
p = ml_get_curline();
ai_col = (colnr_T)(skipwhite(p) - p);
ai_col = (colnr_T)getwhitecols_curline();
}
#endif
#if defined(FEAT_VREPLACE) && (defined(FEAT_LISP) || defined(FEAT_CINDENT))
View
@@ -2507,6 +2507,7 @@ op_insert(oparg_T *oap, long count1)
{
long ins_len, pre_textlen = 0;
char_u *firstline, *ins_text;
colnr_T ind_pre, ind_post;
struct block_def bd;
int i;
pos_T t1;
@@ -2541,7 +2542,10 @@ op_insert(oparg_T *oap, long count1)
#endif
/* Get the info about the block before entering the text */
block_prep(oap, &bd, oap->start.lnum, TRUE);
/* Get indent information */
ind_pre = (colnr_T)getwhitecols_curline();
firstline = ml_get(oap->start.lnum) + bd.textcol;
if (oap->op_type == OP_APPEND)
firstline += bd.textlen;
pre_textlen = (long)STRLEN(firstline);
@@ -2593,6 +2597,14 @@ op_insert(oparg_T *oap, long count1)
&& LT_POS(curbuf->b_op_start_orig, t1))
oap->start = curbuf->b_op_start_orig;
/* if indent kicked in, the firstline might have changed
* but only do that, if the indent actually increased */
ind_post = (colnr_T)getwhitecols_curline();
if (curbuf->b_op_start.col > ind_pre && ind_post > ind_pre)
{
bd.textcol += ind_post - ind_pre;
bd.start_vcol += ind_post - ind_pre;
}
/* If user has moved off this line, we don't know what to do, so do
* nothing.
* Also don't repeat the insert when Insert mode ended with CTRL-C. */
@@ -2754,7 +2766,7 @@ op_change(oparg_T *oap)
# endif
firstline = ml_get(oap->start.lnum);
pre_textlen = (long)STRLEN(firstline);
pre_indent = (long)(skipwhite(firstline) - firstline);
pre_indent = (long)getwhitecols(firstline);
bd.textcol = curwin->w_cursor.col;
}
#endif
@@ -2779,7 +2791,7 @@ op_change(oparg_T *oap)
firstline = ml_get(oap->start.lnum);
if (bd.textcol > (colnr_T)pre_indent)
{
long new_indent = (long)(skipwhite(firstline) - firstline);
long new_indent = (long)getwhitecols(firstline);
pre_textlen += new_indent - pre_indent;
bd.textcol += new_indent - pre_indent;
@@ -5065,8 +5077,7 @@ format_lines(
#endif
if (second_indent > 0) /* the "leader" for FO_Q_SECOND */
{
char_u *p = ml_get_curline();
int indent = (int)(skipwhite(p) - p);
int indent = getwhitecols_curline();
if (indent > 0)
{
View
@@ -35,6 +35,8 @@ colnr_T getvcol_nolist(pos_T *posp);
void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end);
void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, colnr_T *right);
char_u *skipwhite(char_u *q);
int getwhitecols_curline(void);
int getwhitecols(char_u *p);
char_u *skipdigits(char_u *q);
char_u *skipbin(char_u *q);
char_u *skiphex(char_u *q);
View
@@ -1,4 +1,5 @@
/* misc1.c */
int get_whitespace_line_start(linenr_T lnum);
int get_indent(void);
int get_indent_lnum(linenr_T lnum);
int get_indent_buf(buf_T *buf, linenr_T lnum);
View
@@ -3463,7 +3463,7 @@ win_line(
{
/* For checking first word with a capital skip white space. */
if (cap_col == 0)
cap_col = (int)(skipwhite(line) - line);
cap_col = getwhitecols(line);
/* To be able to spell-check over line boundaries copy the end of the
* current line into nextline[]. Above the start of the next line was
View
@@ -1625,11 +1625,11 @@ spell_move_to(
/* For checking first word with a capital skip white space. */
if (capcol == 0)
capcol = (int)(skipwhite(line) - line);
capcol = getwhitecols(line);
else if (curline && wp == curwin)
{
/* For spellbadword(): check if first word needs a capital. */
col = (int)(skipwhite(line) - line);
col = getwhitecols(line);
if (check_need_cap(lnum, col))
capcol = col;
@@ -3593,7 +3593,7 @@ check_need_cap(linenr_T lnum, colnr_T col)
line = ml_get_curline();
endcol = 0;
if ((int)(skipwhite(line) - line) >= (int)col)
if (getwhitecols(line) >= (int)col)
{
/* At start of line, check if previous line is empty or sentence
* ends there. */
@@ -71,7 +71,7 @@ func Test_cino_extern_c()
bwipe!
endfunc
func! Test_cindent_rawstring()
func Test_cindent_rawstring()
new
setl cindent
call feedkeys("i" .
@@ -81,5 +81,25 @@ func! Test_cindent_rawstring()
\ "statement;\<Esc>", "x")
call assert_equal("\tstatement;", getline(line('.')))
bw!
endfunction
endfunc
func Test_cindent_expr()
new
func! MyIndentFunction()
return v:lnum == 1 ? shiftwidth() : 0
endfunc
setl expandtab sw=8 indentkeys+=; indentexpr=MyIndentFunction()
call setline(1, ['var_a = something()', 'b = something()'])
call cursor(1, 1)
call feedkeys("^\<c-v>j$A;\<esc>", 'tnix')
call assert_equal([' var_a = something();', 'b = something();'], getline(1, '$'))
%d
call setline(1, [' var_a = something()', ' b = something()'])
call cursor(1, 1)
call feedkeys("^\<c-v>j$A;\<esc>", 'tnix')
call assert_equal([' var_a = something();', ' b = something()'], getline(1, '$'))
bw!
endfunc
" vim: shiftwidth=2 sts=2 expandtab
View
@@ -769,6 +769,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1041,
/**/
1040,
/**/

0 comments on commit e2e69e4

Please sign in to comment.