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