patch 8.0.1041: bogus characters when indenting during visual-block append
Problem: Bogus characters appear when indenting kicks in while doing a
visual-block append.
Solution: Recompute when indenting is done. (Christian Brabandt)
This commit is contained in:
@ -314,8 +314,8 @@ Visual-block Insert *v_b_I*
|
|||||||
With a blockwise selection, I{string}<ESC> will insert {string} at the start
|
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
|
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
|
block. Thus lines that are short will remain unmodified. TABs are split to
|
||||||
retain visual columns.
|
retain visual columns. Works only for adding text to a line, not for
|
||||||
See |v_b_I_example|.
|
deletions. See |v_b_I_example|.
|
||||||
|
|
||||||
Visual-block Append *v_b_A*
|
Visual-block Append *v_b_A*
|
||||||
With a blockwise selection, A{string}<ESC> will append {string} to the end of
|
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
|
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
|
selected block. This was done intentionally, so that you can do it the way
|
||||||
you want.
|
you want.
|
||||||
|
Works only for adding text to a line, not for deletions.
|
||||||
|
|
||||||
Visual-block change *v_b_c*
|
Visual-block change *v_b_c*
|
||||||
All selected text in the block will be replaced by the same text string. When
|
All selected text in the block will be replaced by the same text string. When
|
||||||
|
|||||||
@ -1535,6 +1535,22 @@ skipwhite(char_u *q)
|
|||||||
return p;
|
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
|
* skip over digits
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -5182,7 +5182,7 @@ ins_complete(int c, int enable_pum)
|
|||||||
* first non_blank in the line, if it is not a wordchar
|
* first non_blank in the line, if it is not a wordchar
|
||||||
* include it to get a better pattern, but then we don't
|
* include it to get a better pattern, but then we don't
|
||||||
* want the "\\<" prefix, check it bellow */
|
* 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.col = compl_col;
|
||||||
compl_startpos.lnum = curwin->w_cursor.lnum;
|
compl_startpos.lnum = curwin->w_cursor.lnum;
|
||||||
compl_cont_status &= ~CONT_SOL; /* clear SOL if present */
|
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))
|
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;
|
compl_length = (int)curs_col - (int)compl_col;
|
||||||
if (compl_length < 0) /* cursor in indent: empty pattern */
|
if (compl_length < 0) /* cursor in indent: empty pattern */
|
||||||
compl_length = 0;
|
compl_length = 0;
|
||||||
@ -8208,8 +8208,7 @@ in_cinkeys(
|
|||||||
{
|
{
|
||||||
/* "0=word": Check if there are only blanks before the
|
/* "0=word": Check if there are only blanks before the
|
||||||
* word. */
|
* word. */
|
||||||
line = ml_get_curline();
|
if (getwhitecols(line) !=
|
||||||
if ((int)(skipwhite(line) - line) !=
|
|
||||||
(int)(curwin->w_cursor.col - (p - look)))
|
(int)(curwin->w_cursor.col - (p - look)))
|
||||||
match = FALSE;
|
match = FALSE;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1589,8 +1589,7 @@ open_line(
|
|||||||
&& curbuf->b_p_ai)
|
&& curbuf->b_p_ai)
|
||||||
{
|
{
|
||||||
fixthisline(get_lisp_indent);
|
fixthisline(get_lisp_indent);
|
||||||
p = ml_get_curline();
|
ai_col = (colnr_T)getwhitecols_curline();
|
||||||
ai_col = (colnr_T)(skipwhite(p) - p);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef FEAT_CINDENT
|
#ifdef FEAT_CINDENT
|
||||||
@ -1608,8 +1607,7 @@ open_line(
|
|||||||
: KEY_OPEN_BACK, ' ', linewhite(curwin->w_cursor.lnum)))
|
: KEY_OPEN_BACK, ' ', linewhite(curwin->w_cursor.lnum)))
|
||||||
{
|
{
|
||||||
do_c_expr_indent();
|
do_c_expr_indent();
|
||||||
p = ml_get_curline();
|
ai_col = (colnr_T)getwhitecols_curline();
|
||||||
ai_col = (colnr_T)(skipwhite(p) - p);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(FEAT_VREPLACE) && (defined(FEAT_LISP) || defined(FEAT_CINDENT))
|
#if defined(FEAT_VREPLACE) && (defined(FEAT_LISP) || defined(FEAT_CINDENT))
|
||||||
|
|||||||
19
src/ops.c
19
src/ops.c
@ -2507,6 +2507,7 @@ op_insert(oparg_T *oap, long count1)
|
|||||||
{
|
{
|
||||||
long ins_len, pre_textlen = 0;
|
long ins_len, pre_textlen = 0;
|
||||||
char_u *firstline, *ins_text;
|
char_u *firstline, *ins_text;
|
||||||
|
colnr_T ind_pre, ind_post;
|
||||||
struct block_def bd;
|
struct block_def bd;
|
||||||
int i;
|
int i;
|
||||||
pos_T t1;
|
pos_T t1;
|
||||||
@ -2541,7 +2542,10 @@ op_insert(oparg_T *oap, long count1)
|
|||||||
#endif
|
#endif
|
||||||
/* Get the info about the block before entering the text */
|
/* Get the info about the block before entering the text */
|
||||||
block_prep(oap, &bd, oap->start.lnum, TRUE);
|
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;
|
firstline = ml_get(oap->start.lnum) + bd.textcol;
|
||||||
|
|
||||||
if (oap->op_type == OP_APPEND)
|
if (oap->op_type == OP_APPEND)
|
||||||
firstline += bd.textlen;
|
firstline += bd.textlen;
|
||||||
pre_textlen = (long)STRLEN(firstline);
|
pre_textlen = (long)STRLEN(firstline);
|
||||||
@ -2593,6 +2597,14 @@ op_insert(oparg_T *oap, long count1)
|
|||||||
&& LT_POS(curbuf->b_op_start_orig, t1))
|
&& LT_POS(curbuf->b_op_start_orig, t1))
|
||||||
oap->start = curbuf->b_op_start_orig;
|
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
|
/* If user has moved off this line, we don't know what to do, so do
|
||||||
* nothing.
|
* nothing.
|
||||||
* Also don't repeat the insert when Insert mode ended with CTRL-C. */
|
* Also don't repeat the insert when Insert mode ended with CTRL-C. */
|
||||||
@ -2754,7 +2766,7 @@ op_change(oparg_T *oap)
|
|||||||
# endif
|
# endif
|
||||||
firstline = ml_get(oap->start.lnum);
|
firstline = ml_get(oap->start.lnum);
|
||||||
pre_textlen = (long)STRLEN(firstline);
|
pre_textlen = (long)STRLEN(firstline);
|
||||||
pre_indent = (long)(skipwhite(firstline) - firstline);
|
pre_indent = (long)getwhitecols(firstline);
|
||||||
bd.textcol = curwin->w_cursor.col;
|
bd.textcol = curwin->w_cursor.col;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -2779,7 +2791,7 @@ op_change(oparg_T *oap)
|
|||||||
firstline = ml_get(oap->start.lnum);
|
firstline = ml_get(oap->start.lnum);
|
||||||
if (bd.textcol > (colnr_T)pre_indent)
|
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;
|
pre_textlen += new_indent - pre_indent;
|
||||||
bd.textcol += new_indent - pre_indent;
|
bd.textcol += new_indent - pre_indent;
|
||||||
@ -5065,8 +5077,7 @@ format_lines(
|
|||||||
#endif
|
#endif
|
||||||
if (second_indent > 0) /* the "leader" for FO_Q_SECOND */
|
if (second_indent > 0) /* the "leader" for FO_Q_SECOND */
|
||||||
{
|
{
|
||||||
char_u *p = ml_get_curline();
|
int indent = getwhitecols_curline();
|
||||||
int indent = (int)(skipwhite(p) - p);
|
|
||||||
|
|
||||||
if (indent > 0)
|
if (indent > 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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 getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end);
|
||||||
void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, colnr_T *right);
|
void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, colnr_T *right);
|
||||||
char_u *skipwhite(char_u *q);
|
char_u *skipwhite(char_u *q);
|
||||||
|
int getwhitecols_curline(void);
|
||||||
|
int getwhitecols(char_u *p);
|
||||||
char_u *skipdigits(char_u *q);
|
char_u *skipdigits(char_u *q);
|
||||||
char_u *skipbin(char_u *q);
|
char_u *skipbin(char_u *q);
|
||||||
char_u *skiphex(char_u *q);
|
char_u *skiphex(char_u *q);
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
/* misc1.c */
|
/* misc1.c */
|
||||||
|
int get_whitespace_line_start(linenr_T lnum);
|
||||||
int get_indent(void);
|
int get_indent(void);
|
||||||
int get_indent_lnum(linenr_T lnum);
|
int get_indent_lnum(linenr_T lnum);
|
||||||
int get_indent_buf(buf_T *buf, linenr_T lnum);
|
int get_indent_buf(buf_T *buf, linenr_T lnum);
|
||||||
|
|||||||
@ -3463,7 +3463,7 @@ win_line(
|
|||||||
{
|
{
|
||||||
/* For checking first word with a capital skip white space. */
|
/* For checking first word with a capital skip white space. */
|
||||||
if (cap_col == 0)
|
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
|
/* 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
|
* current line into nextline[]. Above the start of the next line was
|
||||||
|
|||||||
@ -1625,11 +1625,11 @@ spell_move_to(
|
|||||||
|
|
||||||
/* For checking first word with a capital skip white space. */
|
/* For checking first word with a capital skip white space. */
|
||||||
if (capcol == 0)
|
if (capcol == 0)
|
||||||
capcol = (int)(skipwhite(line) - line);
|
capcol = getwhitecols(line);
|
||||||
else if (curline && wp == curwin)
|
else if (curline && wp == curwin)
|
||||||
{
|
{
|
||||||
/* For spellbadword(): check if first word needs a capital. */
|
/* For spellbadword(): check if first word needs a capital. */
|
||||||
col = (int)(skipwhite(line) - line);
|
col = getwhitecols(line);
|
||||||
if (check_need_cap(lnum, col))
|
if (check_need_cap(lnum, col))
|
||||||
capcol = col;
|
capcol = col;
|
||||||
|
|
||||||
@ -3593,7 +3593,7 @@ check_need_cap(linenr_T lnum, colnr_T col)
|
|||||||
|
|
||||||
line = ml_get_curline();
|
line = ml_get_curline();
|
||||||
endcol = 0;
|
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
|
/* At start of line, check if previous line is empty or sentence
|
||||||
* ends there. */
|
* ends there. */
|
||||||
|
|||||||
@ -71,7 +71,7 @@ func Test_cino_extern_c()
|
|||||||
bwipe!
|
bwipe!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func! Test_cindent_rawstring()
|
func Test_cindent_rawstring()
|
||||||
new
|
new
|
||||||
setl cindent
|
setl cindent
|
||||||
call feedkeys("i" .
|
call feedkeys("i" .
|
||||||
@ -81,5 +81,25 @@ func! Test_cindent_rawstring()
|
|||||||
\ "statement;\<Esc>", "x")
|
\ "statement;\<Esc>", "x")
|
||||||
call assert_equal("\tstatement;", getline(line('.')))
|
call assert_equal("\tstatement;", getline(line('.')))
|
||||||
bw!
|
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
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
|||||||
@ -769,6 +769,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1041,
|
||||||
/**/
|
/**/
|
||||||
1040,
|
1040,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user