fix: return the caret to the edit projection-local undo and redo reverse - #412
Merged
Conversation
The local stacks held whole source strings, so every step set the caret to the end of the projected range whatever it restored, and an edit away from the end lost the author's place. Each entry now carries the selection the document held while it held that source, which mirrors prosemirror-history: a change records the selection in effect before it, and a step pushes the current selection onto the opposite stack. Local history is what the author reaches before the native history it hands off to, so the two agree on where a reversed edit leaves the caret. Deriving the caret by diffing the restored source against the current one was rejected. It cannot see an edit an adapter remapped out of a delimiter, and it resolves to the wrong end of a run of repeated characters, where the common prefix and suffix leave the position ambiguous.
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.
Summary
Projection-local
UndoandRedorestored the source correctly but set the caret to the end of the projected range whatever they restored, so every step lost the author's place, and the further the edit sat from the end of the source the further the caret jumped.The stacks held whole source strings, which cannot recover a caret on their own: the same source can be reached from different positions. Each entry now carries the selection the document held while it held that source, as offsets into it, so an entry survives the range moving under it. A change records the selection in effect before it, and a step pushes the current selection onto the opposite stack, so
Undoreturns to where the author was standing andRedoto where the edit left them. Recording the whole selection rather than a caret follows from the same model: an edit that replaced a selection is undone back onto that selection.That model is
prosemirror-history's own, which is what decides the question #411 leaves open. Local history is what the author reaches before the native history a session hands off to once its own history runs out, and the two now agree on where a reversed edit leaves the caret rather than differing across a seam the author cannot see.Deriving the caret by diffing the restored source against the current one was the alternative. Reading only the two sources, it cannot see an edit an adapter remapped out of a delimiter, and it resolves to the wrong end of a run of repeated characters, where a common prefix and suffix leave the position genuinely ambiguous.
Related Issue
Closes #411
Verification
pnpm check:frontendpasses on the complete change.Focused tests in
sourceProjectionIntegration.test.tsprove that an edit away from the end of the source returns the caret to that edit in both directions, over a marked fragment and over a link, while the text each step restores is unchanged. Both fail against the plugin as it stands before this change, landing at the end of the projected range on the positions #411 reports. The existing tests for a session exhausting its local history and for stepping over a composed, unauthored write are untouched and still pass.Not verified in this session: a pass in the running application. The change is caret placement, which the editor mount the plugin tests drive measures directly.