fix(diffs): Correct line count when edits split or form a CR/LF#956
Open
necolas wants to merge 1 commit into
Open
fix(diffs): Correct line count when edits split or form a CR/LF#956necolas wants to merge 1 commit into
necolas wants to merge 1 commit into
Conversation
Reproduce:
1. Open a document whose content is "a\r\nb" (two lines).
2. Insert "X" between the \r and the \n (offset 2) to make
"a\rX\nb".
3. Ask the document for its line count.
It reports 2 lines instead of 3. In that state positionAt(2)
returns {line:0,character:2} instead of {line:1,character:0},
getLineText(2) throws "Line index out of range", and a search
for "X" returns the wrong range. The mirror case is also wrong:
inserting a "\r" just before an existing "\n" reports an extra
line instead of merging the two into one \r\n break.
Each piece derived its line-break count from the shared buffer's
offsets, which record a \r\n as one break after the \n. An edit
that split a \r\n across a piece boundary, or formed one across
two pieces, was then miscounted, corrupting the line count and
every position, line-text, and search result that relies on it.
The add buffer had the same flaw: appending text that begins
with "\n" after a buffer ending in "\r" recorded two breaks for
the resulting \r\n.
Count each piece's breaks as if its text stood alone, then
reconcile boundary pairs in the tree by folding a \r ending one
piece with a \n starting the next into a single break. Drop the
stale lone-\r offset in the add buffer when an append merges it
into a \r\n. Trim the trailing line break in getTextSlice once
at the slice end instead of per piece, so an interior \r split
across pieces is preserved.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Collaborator
|
how can i insert "X" between the \r and the \n (offset 2) to make "a\rX\nb" in the edit file? the fix is great! but seems introduce some extra complex, as we do not expose the piecetable class as API. |
fat
approved these changes
Jul 10, 2026
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.
Reproduce:
It reports 2 lines instead of 3. In that state positionAt(2) returns {line:0,character:2} instead of {line:1,character:0}, getLineText(2) throws "Line index out of range", and a search for "X" returns the wrong range. The mirror case is also wrong: inserting a "\r" just before an existing "\n" reports an extra line instead of merging the two into one \r\n break.
Each piece derived its line-break count from the shared buffer's offsets, which record a \r\n as one break after the \n. An edit that split a \r\n across a piece boundary, or formed one across two pieces, was then miscounted, corrupting the line count and every position, line-text, and search result that relies on it. The add buffer had the same flaw: appending text that begins with "\n" after a buffer ending in "\r" recorded two breaks for the resulting \r\n.
Count each piece's breaks as if its text stood alone, then reconcile boundary pairs in the tree by folding a \r ending one piece with a \n starting the next into a single break. Drop the stale lone-\r offset in the add buffer when an append merges it into a \r\n. Trim the trailing line break in getTextSlice once at the slice end instead of per piece, so an interior \r split across pieces is preserved.