Mercurial > vim
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 |