Fix undo/redo corruption when typing at the end of a final-newline file - #917
Open
user77 (hexbinoct) wants to merge 1 commit into
Open
Fix undo/redo corruption when typing at the end of a final-newline file#917user77 (hexbinoct) wants to merge 1 commit into
user77 (hexbinoct) wants to merge 1 commit into
Conversation
The automatic final-newline insertion in TextBuffer::write() moves the
cursor back internally, so the next coalesced write lands before that
newline while the undo entry appends its bytes after the newline's.
Redo replays the entry's recorded bytes as one contiguous string,
reproducing them in write order ("a<LF>b") instead of buffer order
("ab<LF>").
Stop coalescing after a final-newline insertion so every undo entry's
recorded bytes stay contiguous in buffer order.
Fixes microsoft#834
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #834
What breaks
Typing at the end of a buffer that has the automatic POSIX final newline enabled (the default for new files on non-Windows, and enabled on any platform when an opened file ends in a newline), then pressing Ctrl+Z and Ctrl+Y, corrupts the text:
abplus trailing newline comes back asa, newline,b. Deterministic repro and full analysis are on the issue.Root cause
The
insert_final_newlinebranch at the end ofTextBuffer::write()records the appended newline in the current undo entry and then moves the cursor back before it by assigningself.cursordirectly. That bypasses the coalescing break inset_cursor(), so the next typed character coalesces into the same undo entry. Its bytes land before the final newline in the buffer while the entry'saddedvector records them after it: bufferab\n, recordeda\nb. Undo deletes by byte count and works; redo replaysaddedas one contiguous string and reproduces write order.Fix
Stop coalescing after a final-newline insertion (
self.last_history_type = HistoryType::Other;in that branch), so every undo entry's recorded bytes stay contiguous in buffer order. The cost is one extra undo step when typing begins at the end of such a file, since the first character and its automatic newline form their own entry.Tests
crates/edit/tests/undo_redo_834.rsadds six round-trip tests: coalesced typing with the final newline (LF and CRLF), a double undo/redo cycle, a single multi-line write (LF and CRLF), and coalesced typing across a newline without the final-newline feature. The three final-newline tests fail on main and pass with this change. The multi-line write tests pass on main as well as here; they are included to pin down that the redo reinsert loop was not the problem (relevant to #852, where I left verification details).Full workspace test suite and clippy pass locally on Windows; the fix itself is one line.