Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.

Commit 03f1e6e

Browse files
author
Antonio Scandurra
committed
Calculate newEnd correctly when line ending normalization takes place
As part of #255, we changed the way the `onDidChangeText` and `onDidStopChanging` collected changes so that they could avoid relying on the history (see 8a4a4d8 for more background). Later, in ce1964f, we improved the performance of combining the accumulated changes by also storing the change's `newEnd`. This was, however, slightly incorrect, as we calculated such coordinate before normalizing line endings, thus causing the various text change events to report inaccurate information. With this commit we are fixing that oversight (adding also test coverage to ensure we don't regress in the future), as well as streamlining `applyChange`. In particular, we will now take care of normalizing lines in `setTextInRange` instead of `applyChange`, as that's the only call site in which normalization needs to take place.
1 parent 2b2dffe commit 03f1e6e

File tree

2 files changed

+39
-21
lines changed

2 files changed

+39
-21
lines changed

spec/text-buffer-spec.coffee

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,30 @@ describe "TextBuffer", ->
213213
expect(buffer.lineEndingForRow(6)).toBe ''
214214
expect(changeEvents[1].newText).toBe "ms\r\ndo you\r\nlike\r\ndirt"
215215

216+
buffer.setTextInRange([[5, 1], [5, 3]], '\r')
217+
expect(changeEvents[2]).toEqual({
218+
oldRange: [[5, 1], [5, 3]],
219+
newRange: [[5, 1], [6, 0]],
220+
oldText: 'ik',
221+
newText: '\r\n'
222+
})
223+
224+
buffer.undo()
225+
expect(changeEvents[3]).toEqual({
226+
oldRange: [[5, 1], [6, 0]],
227+
newRange: [[5, 1], [5, 3]],
228+
oldText: '\r\n',
229+
newText: 'ik'
230+
})
231+
232+
buffer.redo()
233+
expect(changeEvents[4]).toEqual({
234+
oldRange: [[5, 1], [5, 3]],
235+
newRange: [[5, 1], [6, 0]],
236+
oldText: 'ik',
237+
newText: '\r\n'
238+
})
239+
216240
describe "when the range's start row has no line ending (because it's the last line of the buffer)", ->
217241
describe "when the buffer contains no newlines", ->
218242
it "honors the newlines in the inserted text", ->

src/text-buffer.coffee

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -824,14 +824,18 @@ class TextBuffer
824824

825825
oldRange = @clipRange(range)
826826
oldText = @getTextInRange(oldRange)
827+
828+
if normalizeLineEndings
829+
normalizedEnding = @preferredLineEnding or
830+
@lineEndingForRow(oldRange.start.row) or
831+
@lineEndingForRow(oldRange.start.row - 1)
832+
if normalizedEnding
833+
newText = newText.replace(newlineRegex, normalizedEnding)
834+
827835
change = {
828-
oldStart: oldRange.start,
829-
newStart: oldRange.start,
830-
oldEnd: oldRange.end,
831-
newEnd: traverse(oldRange.start, extentForText(newText)),
832-
oldText,
833-
newText,
834-
normalizeLineEndings
836+
oldStart: oldRange.start, oldEnd: oldRange.end,
837+
newStart: oldRange.start, newEnd: traverse(oldRange.start, extentForText(newText))
838+
oldText, newText
835839
}
836840
@applyChange(change, undo isnt 'skip')
837841

@@ -861,25 +865,15 @@ class TextBuffer
861865

862866
# Applies a change to the buffer based on its old range and new text.
863867
applyChange: (change, pushToHistory = false) ->
864-
{newStart, newEnd, oldStart, oldEnd, oldText, newText, normalizeLineEndings} = change
868+
{newStart, newEnd, oldStart, oldEnd, oldText, newText} = change
865869

866870
oldExtent = traversal(oldEnd, oldStart)
867-
newStart = Point.fromObject(newStart)
868-
oldRange = Range(newStart, newStart.traverse(oldExtent))
871+
oldRange = Range(newStart, traverse(newStart, oldExtent))
869872
oldRange.freeze()
870873

871-
# Determine how to normalize the line endings of inserted text if enabled
872-
if normalizeLineEndings
873-
startRow = oldRange.start.row
874-
normalizedEnding = @preferredLineEnding or
875-
@lineEndingForRow(startRow) or
876-
@lineEndingForRow(startRow - 1)
877-
if normalizedEnding
878-
newText = newText.replace(newlineRegex, normalizedEnding)
879-
880-
newRange = Range(newStart, newEnd)
874+
newExtent = traversal(newEnd, newStart)
875+
newRange = Range(newStart, traverse(newStart, newExtent))
881876
newRange.freeze()
882-
newExtent = newRange.getExtent()
883877

884878
if pushToHistory
885879
change.oldExtent ?= oldExtent

0 commit comments

Comments
 (0)