comparison src/ops.c @ 27183:be5e01f3ee3b v8.2.4120

patch 8.2.4120: block insert goes over the end of the line Commit: https://github.com/vim/vim/commit/9f8c304c8a390ade133bac29963dc8e56ab14cbc Author: Bram Moolenaar <Bram@vim.org> Date: Mon Jan 17 17:30:21 2022 +0000 patch 8.2.4120: block insert goes over the end of the line Problem: Block insert goes over the end of the line. Solution: Handle invalid byte better. Fix inserting the wrong text.
author Bram Moolenaar <Bram@vim.org>
date Mon, 17 Jan 2022 18:45:03 +0100
parents a9eeb18e749c
children 776db9e02b61
comparison
equal deleted inserted replaced
27182:cea72d70e4b8 27183:be5e01f3ee3b
534 534
535 // Avoid starting halfway a multi-byte character. 535 // Avoid starting halfway a multi-byte character.
536 if (b_insert) 536 if (b_insert)
537 { 537 {
538 off = (*mb_head_off)(oldp, oldp + offset + spaces); 538 off = (*mb_head_off)(oldp, oldp + offset + spaces);
539 spaces -= off;
540 count -= off;
539 } 541 }
540 else 542 else
541 { 543 {
542 off = (*mb_off_next)(oldp, oldp + offset); 544 // spaces fill the gap, the character that's at the edge moves
543 offset += off; 545 // right
544 } 546 off = (*mb_head_off)(oldp, oldp + offset);
545 spaces -= off; 547 offset -= off;
546 count -= off; 548 }
547 } 549 }
548 if (spaces < 0) // can happen when the cursor was moved 550 if (spaces < 0) // can happen when the cursor was moved
549 spaces = 0; 551 spaces = 0;
550 552
551 newp = alloc(STRLEN(oldp) + s_len + count + 1); 553 // Make sure the allocated size matches what is actually copied below.
554 newp = alloc(STRLEN(oldp) + spaces + s_len
555 + (spaces > 0 && !bdp->is_short ? ts_val - spaces : 0)
556 + count + 1);
552 if (newp == NULL) 557 if (newp == NULL)
553 continue; 558 continue;
554 559
555 // copy up to shifted part 560 // copy up to shifted part
556 mch_memmove(newp, oldp, (size_t)(offset)); 561 mch_memmove(newp, oldp, (size_t)offset);
557 oldp += offset; 562 oldp += offset;
558 563
559 // insert pre-padding 564 // insert pre-padding
560 vim_memset(newp + offset, ' ', (size_t)spaces); 565 vim_memset(newp + offset, ' ', (size_t)spaces);
561 startcol = offset + spaces; 566 startcol = offset + spaces;
562 567
563 // copy the new text 568 // copy the new text
564 mch_memmove(newp + startcol, s, (size_t)s_len); 569 mch_memmove(newp + startcol, s, (size_t)s_len);
565 offset += s_len; 570 offset += s_len;
566 571
567 if (spaces && !bdp->is_short) 572 if (spaces > 0 && !bdp->is_short)
568 { 573 {
569 // insert post-padding 574 if (*oldp == TAB)
570 vim_memset(newp + offset + spaces, ' ', (size_t)(ts_val - spaces)); 575 {
571 // We're splitting a TAB, don't copy it. 576 // insert post-padding
572 oldp++; 577 vim_memset(newp + offset + spaces, ' ',
573 // We allowed for that TAB, remember this now 578 (size_t)(ts_val - spaces));
574 count++; 579 // we're splitting a TAB, don't copy it
580 oldp++;
581 // We allowed for that TAB, remember this now
582 count++;
583 }
584 else
585 // Not a TAB, no extra spaces
586 count = spaces;
575 } 587 }
576 588
577 if (spaces > 0) 589 if (spaces > 0)
578 offset += count; 590 offset += count;
579 STRMOVE(newp + offset, oldp); 591 STRMOVE(newp + offset, oldp);
1596 oap->start.col = curbuf->b_op_start_orig.col; 1608 oap->start.col = curbuf->b_op_start_orig.col;
1597 pre_textlen -= t - oap->start_vcol; 1609 pre_textlen -= t - oap->start_vcol;
1598 oap->start_vcol = t; 1610 oap->start_vcol = t;
1599 } 1611 }
1600 else if (oap->op_type == OP_APPEND 1612 else if (oap->op_type == OP_APPEND
1601 && oap->end.col + oap->end.coladd 1613 && oap->start.col + oap->start.coladd
1602 >= curbuf->b_op_start_orig.col 1614 >= curbuf->b_op_start_orig.col
1603 + curbuf->b_op_start_orig.coladd) 1615 + curbuf->b_op_start_orig.coladd)
1604 { 1616 {
1605 oap->start.col = curbuf->b_op_start_orig.col; 1617 oap->start.col = curbuf->b_op_start_orig.col;
1606 // reset pre_textlen to the value of OP_INSERT 1618 // reset pre_textlen to the value of OP_INSERT