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