Mercurial > vim
comparison src/ops.c @ 26313:74e706afae3f v8.2.3687
patch 8.2.3687: blockwise insert does not handle autoindent properly
Commit: https://github.com/vim/vim/commit/59f4f9505ae7ca2499904b94100db103e5ada5a6
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Nov 27 22:47:43 2021 +0000
patch 8.2.3687: blockwise insert does not handle autoindent properly
Problem: Blockwise insert does not handle autoindent properly when tab is
inserted.
Solution: Adjust text column for indent before computing column.
(closes #9229)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 28 Nov 2021 00:00:04 +0100 |
parents | 294736db2561 |
children | 13ba00ef7687 |
comparison
equal
deleted
inserted
replaced
26312:97c299ecd366 | 26313:74e706afae3f |
---|---|
1454 void | 1454 void |
1455 op_insert(oparg_T *oap, long count1) | 1455 op_insert(oparg_T *oap, long count1) |
1456 { | 1456 { |
1457 long ins_len, pre_textlen = 0; | 1457 long ins_len, pre_textlen = 0; |
1458 char_u *firstline, *ins_text; | 1458 char_u *firstline, *ins_text; |
1459 colnr_T ind_pre = 0, ind_post; | 1459 colnr_T ind_pre_col = 0, ind_post_col; |
1460 int ind_pre_vcol = 0, ind_post_vcol = 0; | |
1460 struct block_def bd; | 1461 struct block_def bd; |
1461 int i; | 1462 int i; |
1462 pos_T t1; | 1463 pos_T t1; |
1463 pos_T start_insert; | 1464 pos_T start_insert; |
1464 // offset when cursor was moved in insert mode | 1465 // offset when cursor was moved in insert mode |
1495 curwin->w_ve_flags = old_ve_flags; | 1496 curwin->w_ve_flags = old_ve_flags; |
1496 } | 1497 } |
1497 // Get the info about the block before entering the text | 1498 // Get the info about the block before entering the text |
1498 block_prep(oap, &bd, oap->start.lnum, TRUE); | 1499 block_prep(oap, &bd, oap->start.lnum, TRUE); |
1499 // Get indent information | 1500 // Get indent information |
1500 ind_pre = (colnr_T)getwhitecols_curline(); | 1501 ind_pre_col = (colnr_T)getwhitecols_curline(); |
1502 ind_pre_vcol = get_indent(); | |
1501 firstline = ml_get(oap->start.lnum) + bd.textcol; | 1503 firstline = ml_get(oap->start.lnum) + bd.textcol; |
1502 | 1504 |
1503 if (oap->op_type == OP_APPEND) | 1505 if (oap->op_type == OP_APPEND) |
1504 firstline += bd.textlen; | 1506 firstline += bd.textlen; |
1505 pre_textlen = (long)STRLEN(firstline); | 1507 pre_textlen = (long)STRLEN(firstline); |
1561 size_t len; | 1563 size_t len; |
1562 int add; | 1564 int add; |
1563 | 1565 |
1564 // If indent kicked in, the firstline might have changed | 1566 // If indent kicked in, the firstline might have changed |
1565 // but only do that, if the indent actually increased. | 1567 // but only do that, if the indent actually increased. |
1566 ind_post = (colnr_T)getwhitecols_curline(); | 1568 ind_post_col = (colnr_T)getwhitecols_curline(); |
1567 if (curbuf->b_op_start.col > ind_pre && ind_post > ind_pre) | 1569 if (curbuf->b_op_start.col > ind_pre_col && ind_post_col > ind_pre_col) |
1568 { | 1570 { |
1569 bd.textcol += ind_post - ind_pre; | 1571 bd.textcol += ind_post_col - ind_pre_col; |
1570 bd.start_vcol += ind_post - ind_pre; | 1572 ind_post_vcol = get_indent(); |
1573 bd.start_vcol += ind_post_vcol - ind_pre_vcol; | |
1571 did_indent = TRUE; | 1574 did_indent = TRUE; |
1572 } | 1575 } |
1573 | 1576 |
1574 // The user may have moved the cursor before inserting something, try | 1577 // The user may have moved the cursor before inserting something, try |
1575 // to adjust the block for that. But only do it, if the difference | 1578 // to adjust the block for that. But only do it, if the difference |
1610 pre_textlen += bd.textlen; | 1613 pre_textlen += bd.textlen; |
1611 pre_textlen -= t - oap->start_vcol; | 1614 pre_textlen -= t - oap->start_vcol; |
1612 } | 1615 } |
1613 } | 1616 } |
1614 | 1617 |
1615 /* | 1618 // Spaces and tabs in the indent may have changed to other spaces and |
1616 * Spaces and tabs in the indent may have changed to other spaces and | 1619 // tabs. Get the starting column again and correct the length. |
1617 * tabs. Get the starting column again and correct the length. | 1620 // Don't do this when "$" used, end-of-line will have changed. |
1618 * Don't do this when "$" used, end-of-line will have changed. | 1621 // |
1619 */ | 1622 // if indent was added and the inserted text was after the indent, |
1623 // correct the selection for the new indent. | |
1624 if (did_indent && bd.textcol - ind_post_col > 0) | |
1625 { | |
1626 oap->start.col += ind_post_col - ind_pre_col; | |
1627 oap->start_vcol += ind_post_vcol - ind_pre_vcol; | |
1628 oap->end.col += ind_post_col - ind_pre_col; | |
1629 oap->end_vcol += ind_post_vcol - ind_pre_vcol; | |
1630 } | |
1620 block_prep(oap, &bd2, oap->start.lnum, TRUE); | 1631 block_prep(oap, &bd2, oap->start.lnum, TRUE); |
1632 if (did_indent && bd.textcol - ind_post_col > 0) | |
1633 { | |
1634 // undo for where "oap" is used below | |
1635 oap->start.col -= ind_post_col - ind_pre_col; | |
1636 oap->start_vcol -= ind_post_vcol - ind_pre_vcol; | |
1637 oap->end.col -= ind_post_col - ind_pre_col; | |
1638 oap->end_vcol -= ind_post_vcol - ind_pre_vcol; | |
1639 } | |
1621 if (!bd.is_MAX || bd2.textlen < bd.textlen) | 1640 if (!bd.is_MAX || bd2.textlen < bd.textlen) |
1622 { | 1641 { |
1623 if (oap->op_type == OP_APPEND) | 1642 if (oap->op_type == OP_APPEND) |
1624 { | 1643 { |
1625 pre_textlen += bd2.textlen - bd.textlen; | 1644 pre_textlen += bd2.textlen - bd.textlen; |
1626 if (bd2.endspaces) | 1645 if (bd2.endspaces) |
1627 --bd2.textlen; | 1646 --bd2.textlen; |
1628 } | 1647 } |
1629 bd.textcol = bd2.textcol; | 1648 bd.textcol = bd2.textcol; |
1630 if (did_indent && bd.textcol > ind_pre) | |
1631 // If the insert was in the indent then include the indent | |
1632 // change in the new text, otherwise don't. | |
1633 bd.textcol += ind_post - ind_pre; | |
1634 bd.textlen = bd2.textlen; | 1649 bd.textlen = bd2.textlen; |
1635 } | 1650 } |
1636 | 1651 |
1637 /* | 1652 /* |
1638 * Subsequent calls to ml_get() flush the firstline data - take a | 1653 * Subsequent calls to ml_get() flush the firstline data - take a |