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

Commit fe1472f

Browse files
author
Nathan Sobo
committed
Return oldRange and newRange in coalesced changes instead of extents
The start, oldExtent, and newExtent field continue to exist, but are non-enumerable to discourage their use. Eventually we can deprecate them.
1 parent 7ec7375 commit fe1472f

File tree

3 files changed

+109
-66
lines changed

3 files changed

+109
-66
lines changed

spec/text-buffer-spec.coffee

Lines changed: 66 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -648,10 +648,20 @@ describe "TextBuffer", ->
648648
buffer.setTextInRange([[1, 0], [1, 2]], 'yz')
649649

650650
expect(buffer.getText()).toBe 'abc\nyzf\nghi\njkl\nmno\npqr\nstu\nvwx\n'
651-
expect(buffer.getChangesSinceCheckpoint(checkpoint)).toEqual [
652-
{start: [1, 0], oldExtent: [0, 2], newExtent: [0, 2], oldText: 'de', newText: 'yz'},
653-
{start: [5, 0], oldExtent: [0, 0], newExtent: [3, 0], oldText: '', newText: 'pqr\nstu\nvwx\n'}
654-
]
651+
assertChangesEqual(buffer.getChangesSinceCheckpoint(checkpoint), [
652+
{
653+
oldRange: [[1, 0], [1, 2]],
654+
newRange: [[1, 0], [1, 2]],
655+
oldText: "de",
656+
newText: "yz",
657+
},
658+
{
659+
oldRange: [[5, 0], [5, 0]],
660+
newRange: [[5, 0], [8, 0]],
661+
oldText: "",
662+
newText: "pqr\nstu\nvwx\n",
663+
}
664+
])
655665

656666
it "returns an empty list of changes when no change has been made since the checkpoint", ->
657667
checkpoint = buffer.createCheckpoint()
@@ -2618,18 +2628,16 @@ describe "TextBuffer", ->
26182628

26192629
buffer.insert([0, 0], "abc")
26202630
buffer.delete([[0, 0], [0, 1]])
2621-
expect(textChanges).toEqual([
2631+
assertChangesEqual(textChanges, [
26222632
{
2623-
start: {row: 0, column: 0},
2624-
oldExtent: {row: 0, column: 0},
2625-
newExtent: {row: 0, column: 3},
2633+
oldRange: [[0, 0], [0, 0]],
2634+
newRange: [[0, 0], [0, 3]]
26262635
oldText: "",
26272636
newText: "abc"
26282637
},
26292638
{
2630-
start: {row: 0, column: 0},
2631-
oldExtent: {row: 0, column: 1},
2632-
newExtent: {row: 0, column: 0},
2639+
oldRange: [[0, 0], [0, 1]],
2640+
newRange: [[0, 0], [0, 0]],
26332641
oldText: "a",
26342642
newText: ""
26352643
}
@@ -2642,58 +2650,53 @@ describe "TextBuffer", ->
26422650
buffer.insert([2, 3], "zw")
26432651
buffer.delete([[2, 3], [2, 4]])
26442652

2645-
expect(textChanges).toEqual([
2653+
2654+
assertChangesEqual(textChanges, [
26462655
{
2647-
start: {row: 1, column: 0},
2648-
oldExtent: {row: 0, column: 0},
2649-
newExtent: {row: 0, column: 2},
2656+
oldRange: [[1, 0], [1, 0]],
2657+
newRange: [[1, 0], [1, 2]],
26502658
oldText: "",
2651-
newText: "xy"
2659+
newText: "xy",
26522660
},
26532661
{
2654-
start: {row: 2, column: 3},
2655-
oldExtent: {row: 0, column: 0},
2656-
newExtent: {row: 0, column: 1},
2662+
oldRange: [[2, 3], [2, 3]],
2663+
newRange: [[2, 3], [2, 4]],
26572664
oldText: "",
2658-
newText: "w"
2665+
newText: "w",
26592666
}
26602667
])
26612668

26622669
textChanges = []
26632670
buffer.undo()
2664-
expect(textChanges).toEqual([
2671+
assertChangesEqual(textChanges, [
26652672
{
2666-
start: {row: 1, column: 0},
2667-
oldExtent: {row: 0, column: 2},
2668-
newExtent: {row: 0, column: 0},
2673+
oldRange: [[1, 0], [1, 2]],
2674+
newRange: [[1, 0], [1, 0]],
26692675
oldText: "xy",
2670-
newText: ""
2676+
newText: "",
26712677
},
26722678
{
2673-
start: {row: 2, column: 3},
2674-
oldExtent: {row: 0, column: 1},
2675-
newExtent: {row: 0, column: 0},
2679+
oldRange: [[2, 3], [2, 4]],
2680+
newRange: [[2, 3], [2, 3]],
26762681
oldText: "w",
2677-
newText: ""
2682+
newText: "",
26782683
}
26792684
])
26802685

26812686
textChanges = []
26822687
buffer.redo()
2683-
expect(textChanges).toEqual([
2688+
assertChangesEqual(textChanges, [
26842689
{
2685-
start: {row: 1, column: 0},
2686-
oldExtent: {row: 0, column: 0},
2687-
newExtent: {row: 0, column: 2},
2690+
oldRange: [[1, 0], [1, 0]],
2691+
newRange: [[1, 0], [1, 2]],
26882692
oldText: "",
2689-
newText: "xy"
2693+
newText: "xy",
26902694
},
26912695
{
2692-
start: {row: 2, column: 3},
2693-
oldExtent: {row: 0, column: 0},
2694-
newExtent: {row: 0, column: 1},
2696+
oldRange: [[2, 3], [2, 3]],
2697+
newRange: [[2, 3], [2, 4]],
26952698
oldText: "",
2696-
newText: "w"
2699+
newText: "w",
26972700
}
26982701
])
26992702

@@ -2703,13 +2706,12 @@ describe "TextBuffer", ->
27032706
buffer.insert([0, 0], "j")
27042707

27052708
# we emit only one event for nested transactions
2706-
expect(textChanges).toEqual([
2709+
assertChangesEqual(textChanges, [
27072710
{
2708-
start: {row: 0, column: 0},
2709-
oldExtent: {row: 0, column: 0},
2710-
newExtent: {row: 0, column: 1},
2711+
oldRange: [[0, 0], [0, 0]],
2712+
newRange: [[0, 0], [0, 1]],
27112713
oldText: "",
2712-
newText: "j"
2714+
newText: "j",
27132715
}
27142716
])
27152717

@@ -2760,22 +2762,21 @@ describe "TextBuffer", ->
27602762

27612763
beforeEach (done) ->
27622764
expect(didStopChangingCallback).toHaveBeenCalled()
2763-
expect(didStopChangingCallback.calls.mostRecent().args[0].changes).toEqual [
2765+
2766+
assertChangesEqual(didStopChangingCallback.calls.mostRecent().args[0].changes, [
27642767
{
2765-
start: {row: 0, column: 0},
2766-
oldExtent: {row: 0, column: 0},
2767-
newExtent: {row: 0, column: 2},
2768-
oldText: '',
2769-
newText: 'ba'
2768+
oldRange: [[0, 0], [0, 0]],
2769+
newRange: [[0, 0], [0, 2]],
2770+
oldText: "",
2771+
newText: "ba",
27702772
},
27712773
{
2772-
start: {row: 1, column: 0},
2773-
oldExtent: {row: 0, column: 0},
2774-
newExtent: {row: 0, column: 1},
2775-
oldText: '',
2776-
newText: 'c'
2777-
}
2778-
]
2774+
oldRange: [[1, 0], [1, 0]],
2775+
newRange: [[1, 0], [1, 1]],
2776+
oldText: "",
2777+
newText: "c",
2778+
},
2779+
])
27792780

27802781
didStopChangingCallback.calls.reset()
27812782
buffer.undo()
@@ -2955,3 +2956,12 @@ describe "TextBuffer", ->
29552956
it "does not push the encoding change onto the undo stack", ->
29562957
buffer.undo()
29572958
expect(buffer.getText()).toBe 'тест 1234 абвгдеёжз'
2959+
2960+
assertChangesEqual = (actualChanges, expectedChanges) ->
2961+
expect(actualChanges.length).toBe(expectedChanges.length)
2962+
for actualChange, i in actualChanges
2963+
expectedChange = expectedChanges[i]
2964+
expect(actualChange.oldRange).toEqual(expectedChange.oldRange)
2965+
expect(actualChange.newRange).toEqual(expectedChange.newRange)
2966+
expect(actualChange.oldText).toEqual(expectedChange.oldText)
2967+
expect(actualChange.newText).toEqual(expectedChange.newText)

src/helpers.js

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
const Point = require('./point')
2+
const Range = require('./range')
23
const {traversal} = require('./point-helpers')
34

45
const MULTI_LINE_REGEX_REGEX = /\\s|\\r|\\n|\r|\n|^\[\^|[^\\]\[\^/
56

67
exports.newlineRegex = /\r\n|\n|\r/g
78

9+
exports.regexIsSingleLine = function (regex) {
10+
return !MULTI_LINE_REGEX_REGEX.test(regex.source)
11+
}
12+
813
exports.spliceArray = function (array, start, removedCount, insertedItems = []) {
914
const oldLength = array.length
1015
const insertedCount = insertedItems.length
@@ -30,15 +35,41 @@ exports.spliceArray = function (array, start, removedCount, insertedItems = [])
3035
}
3136

3237
exports.normalizePatchChanges = function (changes) {
33-
return changes.map((change) => ({
34-
start: Point.fromObject(change.newStart),
35-
oldExtent: traversal(change.oldEnd, change.oldStart),
36-
newExtent: traversal(change.newEnd, change.newStart),
37-
oldText: change.oldText,
38-
newText: change.newText
39-
}))
38+
return changes.map((change) =>
39+
new TextChange(
40+
Range(change.oldStart, change.oldEnd),
41+
Range(change.newStart, change.newEnd),
42+
change.oldText, change.newText
43+
)
44+
)
4045
}
4146

42-
exports.regexIsSingleLine = function (regex) {
43-
return !MULTI_LINE_REGEX_REGEX.test(regex.source)
47+
class TextChange {
48+
constructor (oldRange, newRange, oldText, newText) {
49+
this.oldRange = oldRange
50+
this.newRange = newRange
51+
this.oldText = oldText
52+
this.newText = newText
53+
}
4454
}
55+
56+
Object.defineProperty(TextChange.prototype, 'start', {
57+
get: function () {
58+
return this.newRange.start
59+
},
60+
enumerable: false
61+
})
62+
63+
Object.defineProperty(TextChange.prototype, 'oldExtent', {
64+
get: function () {
65+
return this.oldRange.getExtent()
66+
},
67+
enumerable: false
68+
})
69+
70+
Object.defineProperty(TextChange.prototype, 'newExtent', {
71+
get: function () {
72+
return this.newRange.getExtent()
73+
},
74+
enumerable: false
75+
})

src/range.coffee

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Point = require './point'
2-
{newlineRegex} = require './helpers'
2+
newlineRegex = null
33

44
# Public: Represents a region in a buffer in row/column coordinates.
55
#
@@ -57,6 +57,8 @@ class Range
5757
#
5858
# Returns: A {Range}
5959
@fromText: (args...) ->
60+
newlineRegex ?= require('./helpers').newlineRegex
61+
6062
if args.length > 1
6163
startPoint = Point.fromObject(args.shift())
6264
else

0 commit comments

Comments
 (0)