comparison src/ops.c @ 25072:bd46322bea66 v8.2.3073

patch 8.2.3073: when cursor is move for block append wrong text is inserted Commit: https://github.com/vim/vim/commit/4067bd3604215b48e4b4201e28f9e401b08418e4 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Jun 29 18:54:35 2021 +0200 patch 8.2.3073: when cursor is move for block append wrong text is inserted Problem: When cursor is move for block append wrong text is inserted. Solution: Calculate an offset. (Christian Brabandt, closes https://github.com/vim/vim/issues/8433, closes #8288)
author Bram Moolenaar <Bram@vim.org>
date Tue, 29 Jun 2021 19:00:05 +0200
parents 8f2262c72178
children ac88cd21ae88
comparison
equal deleted inserted replaced
25071:1b6cde423089 25072:bd46322bea66
543 offset += off; 543 offset += off;
544 } 544 }
545 spaces -= off; 545 spaces -= off;
546 count -= off; 546 count -= off;
547 } 547 }
548 if (spaces < 0) // can happen when the cursor was moved
549 spaces = 0;
548 550
549 newp = alloc(STRLEN(oldp) + s_len + count + 1); 551 newp = alloc(STRLEN(oldp) + s_len + count + 1);
550 if (newp == NULL) 552 if (newp == NULL)
551 continue; 553 continue;
552 554
1453 char_u *firstline, *ins_text; 1455 char_u *firstline, *ins_text;
1454 colnr_T ind_pre = 0, ind_post; 1456 colnr_T ind_pre = 0, ind_post;
1455 struct block_def bd; 1457 struct block_def bd;
1456 int i; 1458 int i;
1457 pos_T t1; 1459 pos_T t1;
1460 pos_T start_insert;
1461 // offset when cursor was moved in insert mode
1462 int offset = 0;
1458 1463
1459 // edit() changes this - record it for OP_APPEND 1464 // edit() changes this - record it for OP_APPEND
1460 bd.is_MAX = (curwin->w_curswant == MAXCOL); 1465 bd.is_MAX = (curwin->w_curswant == MAXCOL);
1461 1466
1462 // vis block is still marked. Get rid of it now. 1467 // vis block is still marked. Get rid of it now.
1524 inc_cursor(); 1529 inc_cursor();
1525 } 1530 }
1526 } 1531 }
1527 1532
1528 t1 = oap->start; 1533 t1 = oap->start;
1534 start_insert = curwin->w_cursor;
1529 (void)edit(NUL, FALSE, (linenr_T)count1); 1535 (void)edit(NUL, FALSE, (linenr_T)count1);
1530 1536
1531 // When a tab was inserted, and the characters in front of the tab 1537 // When a tab was inserted, and the characters in front of the tab
1532 // have been converted to a tab as well, the column of the cursor 1538 // have been converted to a tab as well, the column of the cursor
1533 // might have actually been reduced, so need to adjust here. 1539 // might have actually been reduced, so need to adjust here.
1562 // to adjust the block for that. But only do it, if the difference 1568 // to adjust the block for that. But only do it, if the difference
1563 // does not come from indent kicking in. 1569 // does not come from indent kicking in.
1564 if (oap->start.lnum == curbuf->b_op_start_orig.lnum 1570 if (oap->start.lnum == curbuf->b_op_start_orig.lnum
1565 && !bd.is_MAX && !did_indent) 1571 && !bd.is_MAX && !did_indent)
1566 { 1572 {
1567 if (oap->op_type == OP_INSERT 1573 int t = getviscol2(curbuf->b_op_start_orig.col,
1568 && oap->start.col + oap->start.coladd 1574 curbuf->b_op_start_orig.coladd);
1569 != curbuf->b_op_start_orig.col 1575
1576 if (!bd.is_MAX)
1577 {
1578 if (oap->op_type == OP_INSERT
1579 && oap->start.col + oap->start.coladd
1580 != curbuf->b_op_start_orig.col
1570 + curbuf->b_op_start_orig.coladd) 1581 + curbuf->b_op_start_orig.coladd)
1571 { 1582 {
1572 int t = getviscol2(curbuf->b_op_start_orig.col, 1583 oap->start.col = curbuf->b_op_start_orig.col;
1573 curbuf->b_op_start_orig.coladd); 1584 pre_textlen -= t - oap->start_vcol;
1574 oap->start.col = curbuf->b_op_start_orig.col; 1585 oap->start_vcol = t;
1575 pre_textlen -= t - oap->start_vcol; 1586 }
1576 oap->start_vcol = t; 1587 else if (oap->op_type == OP_APPEND
1577 } 1588 && oap->end.col + oap->end.coladd
1578 else if (oap->op_type == OP_APPEND 1589 >= curbuf->b_op_start_orig.col
1579 && oap->end.col + oap->end.coladd
1580 >= curbuf->b_op_start_orig.col
1581 + curbuf->b_op_start_orig.coladd) 1590 + curbuf->b_op_start_orig.coladd)
1582 { 1591 {
1583 int t = getviscol2(curbuf->b_op_start_orig.col, 1592 oap->start.col = curbuf->b_op_start_orig.col;
1584 curbuf->b_op_start_orig.coladd); 1593 // reset pre_textlen to the value of OP_INSERT
1585 oap->start.col = curbuf->b_op_start_orig.col; 1594 pre_textlen += bd.textlen;
1595 pre_textlen -= t - oap->start_vcol;
1596 oap->start_vcol = t;
1597 oap->op_type = OP_INSERT;
1598 }
1599 }
1600 else if (bd.is_MAX && oap->op_type == OP_APPEND)
1601 {
1586 // reset pre_textlen to the value of OP_INSERT 1602 // reset pre_textlen to the value of OP_INSERT
1587 pre_textlen += bd.textlen; 1603 pre_textlen += bd.textlen;
1588 pre_textlen -= t - oap->start_vcol; 1604 pre_textlen -= t - oap->start_vcol;
1589 oap->start_vcol = t;
1590 oap->op_type = OP_INSERT;
1591 } 1605 }
1592 } 1606 }
1593 1607
1594 /* 1608 /*
1595 * Spaces and tabs in the indent may have changed to other spaces and 1609 * Spaces and tabs in the indent may have changed to other spaces and
1615 */ 1629 */
1616 firstline = ml_get(oap->start.lnum); 1630 firstline = ml_get(oap->start.lnum);
1617 len = STRLEN(firstline); 1631 len = STRLEN(firstline);
1618 add = bd.textcol; 1632 add = bd.textcol;
1619 if (oap->op_type == OP_APPEND) 1633 if (oap->op_type == OP_APPEND)
1634 {
1620 add += bd.textlen; 1635 add += bd.textlen;
1636 // account for pressing cursor in insert mode when '$' was used
1637 if (bd.is_MAX
1638 && (start_insert.lnum == Insstart.lnum
1639 && start_insert.col > Insstart.col))
1640 {
1641 offset = (start_insert.col - Insstart.col);
1642 add -= offset;
1643 if (oap->end_vcol > offset)
1644 oap->end_vcol -= (offset + 1);
1645 else
1646 // moved outside of the visual block, what to do?
1647 return;
1648 }
1649 }
1621 if ((size_t)add > len) 1650 if ((size_t)add > len)
1622 firstline += len; // short line, point to the NUL 1651 firstline += len; // short line, point to the NUL
1623 else 1652 else
1624 firstline += add; 1653 firstline += add;
1625 if (pre_textlen >= 0 1654 if (pre_textlen >= 0 && (ins_len =
1626 && (ins_len = (long)STRLEN(firstline) - pre_textlen) > 0) 1655 (long)STRLEN(firstline) - pre_textlen - offset) > 0)
1627 { 1656 {
1628 ins_text = vim_strnsave(firstline, ins_len); 1657 ins_text = vim_strnsave(firstline, ins_len);
1629 if (ins_text != NULL) 1658 if (ins_text != NULL)
1630 { 1659 {
1631 // block handled here 1660 // block handled here