To: vim_dev@googlegroups.com Subject: Patch 8.0.1041 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.1041 Problem: Bogus characters appear when indenting kicks in while doing a visual-block append. Solution: Recompute when indenting is done. (Christian Brabandt) Files: runtime/doc/visual.txt, src/charset.c, src/edit.c, src/misc1.c, src/ops.c, src/proto/charset.pro, src/proto/misc1.pro, src/screen.c, src/spell.c, src/testdir/test_cindent.vim *** ../vim-8.0.1040/runtime/doc/visual.txt 2016-09-12 12:45:54.000000000 +0200 --- runtime/doc/visual.txt 2017-09-02 20:13:27.986108245 +0200 *************** *** 314,321 **** With a blockwise selection, I{string} 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|. Visual-block Append *v_b_A* With a blockwise selection, A{string} will append {string} to the end of --- 314,321 ---- With a blockwise selection, I{string} 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. 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} will append {string} to the end of *************** *** 331,336 **** --- 331,337 ---- 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 *** ../vim-8.0.1040/src/charset.c 2017-04-09 13:41:54.785598748 +0200 --- src/charset.c 2017-09-02 20:14:40.901624183 +0200 *************** *** 1536,1541 **** --- 1536,1557 ---- } /* + * 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 */ char_u * *** ../vim-8.0.1040/src/edit.c 2017-08-30 22:00:16.370112624 +0200 --- src/edit.c 2017-09-02 20:10:38.115236130 +0200 *************** *** 5182,5188 **** * 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_startpos.col = compl_col; compl_startpos.lnum = curwin->w_cursor.lnum; compl_cont_status &= ~CONT_SOL; /* clear SOL if present */ --- 5182,5188 ---- * 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)getwhitecols(line); compl_startpos.col = compl_col; compl_startpos.lnum = curwin->w_cursor.lnum; compl_cont_status &= ~CONT_SOL; /* clear SOL if present */ *************** *** 5348,5354 **** } else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) { ! compl_col = (colnr_T)(skipwhite(line) - line); compl_length = (int)curs_col - (int)compl_col; if (compl_length < 0) /* cursor in indent: empty pattern */ compl_length = 0; --- 5348,5354 ---- } else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) { ! 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,8215 **** { /* "0=word": Check if there are only blanks before the * word. */ ! line = ml_get_curline(); ! if ((int)(skipwhite(line) - line) != (int)(curwin->w_cursor.col - (p - look))) match = FALSE; } --- 8208,8214 ---- { /* "0=word": Check if there are only blanks before the * word. */ ! if (getwhitecols(line) != (int)(curwin->w_cursor.col - (p - look))) match = FALSE; } *** ../vim-8.0.1040/src/misc1.c 2017-08-30 22:00:16.374112596 +0200 --- src/misc1.c 2017-09-02 20:10:38.119236103 +0200 *************** *** 1589,1596 **** && curbuf->b_p_ai) { fixthisline(get_lisp_indent); ! p = ml_get_curline(); ! ai_col = (colnr_T)(skipwhite(p) - p); } #endif #ifdef FEAT_CINDENT --- 1589,1595 ---- && curbuf->b_p_ai) { fixthisline(get_lisp_indent); ! ai_col = (colnr_T)getwhitecols_curline(); } #endif #ifdef FEAT_CINDENT *************** *** 1608,1615 **** : KEY_OPEN_BACK, ' ', linewhite(curwin->w_cursor.lnum))) { do_c_expr_indent(); ! p = ml_get_curline(); ! ai_col = (colnr_T)(skipwhite(p) - p); } #endif #if defined(FEAT_VREPLACE) && (defined(FEAT_LISP) || defined(FEAT_CINDENT)) --- 1607,1613 ---- : KEY_OPEN_BACK, ' ', linewhite(curwin->w_cursor.lnum))) { do_c_expr_indent(); ! ai_col = (colnr_T)getwhitecols_curline(); } #endif #if defined(FEAT_VREPLACE) && (defined(FEAT_LISP) || defined(FEAT_CINDENT)) *** ../vim-8.0.1040/src/ops.c 2017-08-06 15:42:01.640570872 +0200 --- src/ops.c 2017-09-02 20:10:38.119236103 +0200 *************** *** 2507,2512 **** --- 2507,2513 ---- { 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,2547 **** --- 2542,2551 ---- #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,2598 **** --- 2597,2610 ---- && 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,2760 **** # endif firstline = ml_get(oap->start.lnum); pre_textlen = (long)STRLEN(firstline); ! pre_indent = (long)(skipwhite(firstline) - firstline); bd.textcol = curwin->w_cursor.col; } #endif --- 2766,2772 ---- # endif firstline = ml_get(oap->start.lnum); pre_textlen = (long)STRLEN(firstline); ! pre_indent = (long)getwhitecols(firstline); bd.textcol = curwin->w_cursor.col; } #endif *************** *** 2779,2785 **** firstline = ml_get(oap->start.lnum); if (bd.textcol > (colnr_T)pre_indent) { ! long new_indent = (long)(skipwhite(firstline) - firstline); pre_textlen += new_indent - pre_indent; bd.textcol += new_indent - pre_indent; --- 2791,2797 ---- firstline = ml_get(oap->start.lnum); if (bd.textcol > (colnr_T)pre_indent) { ! long new_indent = (long)getwhitecols(firstline); pre_textlen += new_indent - pre_indent; bd.textcol += new_indent - pre_indent; *************** *** 5065,5072 **** #endif if (second_indent > 0) /* the "leader" for FO_Q_SECOND */ { ! char_u *p = ml_get_curline(); ! int indent = (int)(skipwhite(p) - p); if (indent > 0) { --- 5077,5083 ---- #endif if (second_indent > 0) /* the "leader" for FO_Q_SECOND */ { ! int indent = getwhitecols_curline(); if (indent > 0) { *** ../vim-8.0.1040/src/proto/charset.pro 2016-09-12 13:03:57.000000000 +0200 --- src/proto/charset.pro 2017-09-02 20:14:47.389581118 +0200 *************** *** 35,40 **** --- 35,42 ---- 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); *** ../vim-8.0.1040/src/proto/misc1.pro 2016-09-12 13:04:13.000000000 +0200 --- src/proto/misc1.pro 2017-09-02 20:10:38.119236103 +0200 *************** *** 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); *** ../vim-8.0.1040/src/screen.c 2017-09-02 18:33:52.453554469 +0200 --- src/screen.c 2017-09-02 20:10:38.123236077 +0200 *************** *** 3463,3469 **** { /* For checking first word with a capital skip white space. */ if (cap_col == 0) ! cap_col = (int)(skipwhite(line) - 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 --- 3463,3469 ---- { /* For checking first word with a capital skip white space. */ if (cap_col == 0) ! 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 *** ../vim-8.0.1040/src/spell.c 2017-06-17 18:44:17.002000920 +0200 --- src/spell.c 2017-09-02 20:10:38.123236077 +0200 *************** *** 1625,1635 **** /* For checking first word with a capital skip white space. */ if (capcol == 0) ! capcol = (int)(skipwhite(line) - line); else if (curline && wp == curwin) { /* For spellbadword(): check if first word needs a capital. */ ! col = (int)(skipwhite(line) - line); if (check_need_cap(lnum, col)) capcol = col; --- 1625,1635 ---- /* For checking first word with a capital skip white space. */ if (capcol == 0) ! capcol = getwhitecols(line); else if (curline && wp == curwin) { /* For spellbadword(): check if first word needs a capital. */ ! col = getwhitecols(line); if (check_need_cap(lnum, col)) capcol = col; *************** *** 3593,3599 **** line = ml_get_curline(); endcol = 0; ! if ((int)(skipwhite(line) - line) >= (int)col) { /* At start of line, check if previous line is empty or sentence * ends there. */ --- 3593,3599 ---- line = ml_get_curline(); endcol = 0; ! if (getwhitecols(line) >= (int)col) { /* At start of line, check if previous line is empty or sentence * ends there. */ *** ../vim-8.0.1040/src/testdir/test_cindent.vim 2017-08-26 17:48:57.578995190 +0200 --- src/testdir/test_cindent.vim 2017-09-02 20:09:52.135541464 +0200 *************** *** 71,77 **** bwipe! endfunc ! func! Test_cindent_rawstring() new setl cindent call feedkeys("i" . --- 71,77 ---- bwipe! endfunc ! func Test_cindent_rawstring() new setl cindent call feedkeys("i" . *************** *** 81,85 **** \ "statement;\", "x") call assert_equal("\tstatement;", getline(line('.'))) bw! ! endfunction " vim: shiftwidth=2 sts=2 expandtab --- 81,105 ---- \ "statement;\", "x") call assert_equal("\tstatement;", getline(line('.'))) bw! ! 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("^\j$A;\", '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("^\j$A;\", 'tnix') ! call assert_equal([' var_a = something();', ' b = something()'], getline(1, '$')) ! bw! ! endfunc ! " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.0.1040/src/version.c 2017-09-02 19:51:40.734765887 +0200 --- src/version.c 2017-09-02 20:16:13.965006434 +0200 *************** *** 771,772 **** --- 771,774 ---- { /* Add new patch number below this line */ + /**/ + 1041, /**/ -- "I can't complain, but sometimes I still do." (Joe Walsh) /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///