To: vim_dev@googlegroups.com Subject: Patch 8.2.3073 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3073 Problem: When cursor is move for block append wrong text is inserted. Solution: Calculate an offset. (Christian Brabandt, closes #8433, closes #8288) Files: src/ops.c, src/testdir/test_blockedit.vim, src/testdir/test_visual.vim *** ../vim-8.2.3072/src/ops.c 2021-06-27 22:03:28.645707721 +0200 --- src/ops.c 2021-06-29 18:53:40.156780235 +0200 *************** *** 545,550 **** --- 545,552 ---- spaces -= off; count -= off; } + if (spaces < 0) // can happen when the cursor was moved + spaces = 0; newp = alloc(STRLEN(oldp) + s_len + count + 1); if (newp == NULL) *************** *** 1455,1460 **** --- 1457,1465 ---- struct block_def bd; int i; pos_T t1; + pos_T start_insert; + // offset when cursor was moved in insert mode + int offset = 0; // edit() changes this - record it for OP_APPEND bd.is_MAX = (curwin->w_curswant == MAXCOL); *************** *** 1526,1531 **** --- 1531,1537 ---- } t1 = oap->start; + start_insert = curwin->w_cursor; (void)edit(NUL, FALSE, (linenr_T)count1); // When a tab was inserted, and the characters in front of the tab *************** *** 1564,1593 **** if (oap->start.lnum == curbuf->b_op_start_orig.lnum && !bd.is_MAX && !did_indent) { ! if (oap->op_type == OP_INSERT ! && oap->start.col + oap->start.coladd ! != curbuf->b_op_start_orig.col ! + curbuf->b_op_start_orig.coladd) { ! int t = getviscol2(curbuf->b_op_start_orig.col, ! curbuf->b_op_start_orig.coladd); ! oap->start.col = curbuf->b_op_start_orig.col; ! pre_textlen -= t - oap->start_vcol; ! oap->start_vcol = t; ! } ! else if (oap->op_type == OP_APPEND ! && oap->end.col + oap->end.coladd ! >= curbuf->b_op_start_orig.col + curbuf->b_op_start_orig.coladd) { - int t = getviscol2(curbuf->b_op_start_orig.col, - curbuf->b_op_start_orig.coladd); - oap->start.col = curbuf->b_op_start_orig.col; // reset pre_textlen to the value of OP_INSERT pre_textlen += bd.textlen; pre_textlen -= t - oap->start_vcol; - oap->start_vcol = t; - oap->op_type = OP_INSERT; } } --- 1570,1607 ---- if (oap->start.lnum == curbuf->b_op_start_orig.lnum && !bd.is_MAX && !did_indent) { ! int t = getviscol2(curbuf->b_op_start_orig.col, ! curbuf->b_op_start_orig.coladd); ! ! if (!bd.is_MAX) { ! if (oap->op_type == OP_INSERT ! && oap->start.col + oap->start.coladd ! != curbuf->b_op_start_orig.col + curbuf->b_op_start_orig.coladd) + { + oap->start.col = curbuf->b_op_start_orig.col; + pre_textlen -= t - oap->start_vcol; + oap->start_vcol = t; + } + else if (oap->op_type == OP_APPEND + && oap->end.col + oap->end.coladd + >= curbuf->b_op_start_orig.col + + curbuf->b_op_start_orig.coladd) + { + oap->start.col = curbuf->b_op_start_orig.col; + // reset pre_textlen to the value of OP_INSERT + pre_textlen += bd.textlen; + pre_textlen -= t - oap->start_vcol; + oap->start_vcol = t; + oap->op_type = OP_INSERT; + } + } + else if (bd.is_MAX && oap->op_type == OP_APPEND) { // reset pre_textlen to the value of OP_INSERT pre_textlen += bd.textlen; pre_textlen -= t - oap->start_vcol; } } *************** *** 1617,1629 **** len = STRLEN(firstline); add = bd.textcol; if (oap->op_type == OP_APPEND) add += bd.textlen; if ((size_t)add > len) firstline += len; // short line, point to the NUL else firstline += add; ! if (pre_textlen >= 0 ! && (ins_len = (long)STRLEN(firstline) - pre_textlen) > 0) { ins_text = vim_strnsave(firstline, ins_len); if (ins_text != NULL) --- 1631,1658 ---- len = STRLEN(firstline); add = bd.textcol; if (oap->op_type == OP_APPEND) + { add += bd.textlen; + // account for pressing cursor in insert mode when '$' was used + if (bd.is_MAX + && (start_insert.lnum == Insstart.lnum + && start_insert.col > Insstart.col)) + { + offset = (start_insert.col - Insstart.col); + add -= offset; + if (oap->end_vcol > offset) + oap->end_vcol -= (offset + 1); + else + // moved outside of the visual block, what to do? + return; + } + } if ((size_t)add > len) firstline += len; // short line, point to the NUL else firstline += add; ! if (pre_textlen >= 0 && (ins_len = ! (long)STRLEN(firstline) - pre_textlen - offset) > 0) { ins_text = vim_strnsave(firstline, ins_len); if (ins_text != NULL) *** ../vim-8.2.3072/src/testdir/test_blockedit.vim 2020-08-12 18:50:31.871655841 +0200 --- src/testdir/test_blockedit.vim 2021-06-29 18:43:34.678056996 +0200 *************** *** 28,31 **** --- 28,79 ---- bwipe! endfunc + func Test_blockappend_eol_cursor() + new + " Test 1 Move 1 char left + call setline(1, ['aaa', 'bbb', 'ccc']) + exe "norm! gg$\2jA\x\" + call assert_equal(['aaxa', 'bbxb', 'ccxc'], getline(1, '$')) + " Test 2 Move 2 chars left + sil %d + call setline(1, ['aaa', 'bbb', 'ccc']) + exe "norm! gg$\2jA\\x\" + call assert_equal(['axaa', 'bxbb', 'cxcc'], getline(1, '$')) + " Test 3 Move 3 chars left (outside of the visual selection) + sil %d + call setline(1, ['aaa', 'bbb', 'ccc']) + exe "norm! ggl$\2jA\\\x\" + call assert_equal(['xaaa', 'bbb', 'ccc'], getline(1, '$')) + bw! + endfunc + + func Test_blockappend_eol_cursor2() + new + " Test 1 Move 1 char left + call setline(1, ['aaaaa', 'bbb', 'ccccc']) + exe "norm! gg\$2jA\x\" + call assert_equal(['aaaaxa', 'bbbx', 'ccccxc'], getline(1, '$')) + " Test 2 Move 2 chars left + sil %d + call setline(1, ['aaaaa', 'bbb', 'ccccc']) + exe "norm! gg\$2jA\\x\" + call assert_equal(['aaaxaa', 'bbbx', 'cccxcc'], getline(1, '$')) + " Test 3 Move 3 chars left (to the beginning of the visual selection) + sil %d + call setline(1, ['aaaaa', 'bbb', 'ccccc']) + exe "norm! gg\$2jA\\\x\" + call assert_equal(['aaxaaa', 'bbxb', 'ccxccc'], getline(1, '$')) + " Test 4 Move 3 chars left (outside of the visual selection) + sil %d + call setline(1, ['aaaaa', 'bbb', 'ccccc']) + exe "norm! ggl\$2jA\\\x\" + call assert_equal(['aaxaaa', 'bbxb', 'ccxccc'], getline(1, '$')) + " Test 5 Move 4 chars left (outside of the visual selection) + sil %d + call setline(1, ['aaaaa', 'bbb', 'ccccc']) + exe "norm! ggl\$2jA\\\\x\" + call assert_equal(['axaaaa', 'bxbb', 'cxcccc'], getline(1, '$')) + bw! + endfunc + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.3072/src/testdir/test_visual.vim 2021-06-28 21:54:23.381479210 +0200 --- src/testdir/test_visual.vim 2021-06-29 18:54:08.332721933 +0200 *************** *** 807,817 **** %d _ call setline(1, ['aaa', 'bbb', 'ccc']) exe "normal $\2jA\x" ! " BUG: Instead of adding x as the third character in all the three lines, ! " 'a' is added in the second and third lines at the end. This bug is not ! " reproducible if this operation is performed manually. ! "call assert_equal(['aaxa', 'bbxb', 'ccxc'], getline(1, '$')) ! call assert_equal(['aaxa', 'bbba', 'ccca'], getline(1, '$')) " Repeat the previous test but use 'l' to move the cursor instead of '$' call setline(1, ['aaa', 'bbb', 'ccc']) exe "normal! gg2l\2jA\x" --- 807,813 ---- %d _ call setline(1, ['aaa', 'bbb', 'ccc']) exe "normal $\2jA\x" ! call assert_equal(['aaxa', 'bbxb', 'ccxc'], getline(1, '$')) " Repeat the previous test but use 'l' to move the cursor instead of '$' call setline(1, ['aaa', 'bbb', 'ccc']) exe "normal! gg2l\2jA\x" *** ../vim-8.2.3072/src/version.c 2021-06-28 21:54:23.381479210 +0200 --- src/version.c 2021-06-29 18:47:46.289517868 +0200 *************** *** 757,758 **** --- 757,760 ---- { /* Add new patch number below this line */ + /**/ + 3073, /**/ -- hundred-and-one symptoms of being an internet addict: 48. You get a tatoo that says "This body best viewed with Netscape 3.1 or higher." /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///