Commit cfa40b7
Stop apply_diff() from creating non-monotonic changes
Commit ba41928 (Remove spurious newline when | replaces at buffer end,
2024-11-28) also tried to fix a "DiffOp::Add" code path. Unless I'm
misremembering, I had run into a crash and extracted this unit test.
When apply_diff() decides to erase the last line, and then insert something
at the end, buffer changes might look like:
{.type=Erase, .begin={2, 0}, .end={3, 0}}
{.type=Insert, .begin={1, 5}, .end={5, 0}}
The "{1, 5}" is caused by "pos = buffer.prev(pos);" added by the
aforementioned commit. It's problematic because it breaks the caller's
"ForwardChangesTracker" invariant: the previous Erase leaves the cursor at
{2, 0}, so the insert cannot start before that.
Additionally, the inserted range returned by apply_diff() would be
"{ {2, 0}, {4, 0} }" whose end position is weirdly different from the Insert's
end position. It questionable that we are passing on this weird state.
The "pos = buffer.prev(pos);" statement was added so we actually delete the
current final newline. We still leave "tried_to_erase_final_newline" set,
meaning we'll also delete the the final newline after we're done.
But deleting the "current final newline" the way we do it is confusing,
because we do it at every step DiffOp::Add step. This would blow up if
there are multiple successive contiguous DiffOp::Add events. I doubt this
ever happens but it's still confusing.
Remove this logic, and restore historical behavior in case we append at the
buffer end. This does not break the system test added by ba41928 because
in that case, we
1. first delete the entire buffer, setting pos={0, 0}, but also restoring
the EOL invariant, so the end position would be {0, 1}.
2. then we insert at pos={0, 0}, and since "buffer.is_end(pos)" is false we
don't run into this bad code path.
While at it add an assertion to clarify that we already assume that the
diff algorithm never gives us empty DiffOp::Keep, and always monotonically
increasing positions, except for the very special case where we deleted
until buffer end, which should already be handled.
The unit test is not perfect because it depends on the current behavior of
the diff algorithm.1 parent 7919240 commit cfa40b7
2 files changed
+75
-2
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
224 | 224 | | |
225 | 225 | | |
226 | 226 | | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
227 | 231 | | |
228 | 232 | | |
229 | 233 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
| 4 | + | |
3 | 5 | | |
4 | 6 | | |
5 | 7 | | |
| |||
20 | 22 | | |
21 | 23 | | |
22 | 24 | | |
| 25 | + | |
23 | 26 | | |
24 | 27 | | |
25 | 28 | | |
| |||
555 | 558 | | |
556 | 559 | | |
557 | 560 | | |
| 561 | + | |
558 | 562 | | |
559 | 563 | | |
560 | 564 | | |
561 | 565 | | |
562 | 566 | | |
563 | | - | |
564 | | - | |
| 567 | + | |
| 568 | + | |
565 | 569 | | |
566 | 570 | | |
567 | 571 | | |
568 | 572 | | |
569 | 573 | | |
570 | 574 | | |
| 575 | + | |
571 | 576 | | |
572 | 577 | | |
573 | 578 | | |
| |||
584 | 589 | | |
585 | 590 | | |
586 | 591 | | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
587 | 656 | | |
588 | 657 | | |
589 | 658 | | |
| |||
0 commit comments