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

Commit

Permalink
Return oldRange and newRange in coalesced changes instead of extents
Browse files Browse the repository at this point in the history
The start, oldExtent, and newExtent field continue to exist, but are
non-enumerable to discourage their use. Eventually we can deprecate
them.
  • Loading branch information
Nathan Sobo committed Mar 15, 2017
1 parent 7ec7375 commit fe1472f
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 66 deletions.
122 changes: 66 additions & 56 deletions spec/text-buffer-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -648,10 +648,20 @@ describe "TextBuffer", ->
buffer.setTextInRange([[1, 0], [1, 2]], 'yz')

expect(buffer.getText()).toBe 'abc\nyzf\nghi\njkl\nmno\npqr\nstu\nvwx\n'
expect(buffer.getChangesSinceCheckpoint(checkpoint)).toEqual [
{start: [1, 0], oldExtent: [0, 2], newExtent: [0, 2], oldText: 'de', newText: 'yz'},
{start: [5, 0], oldExtent: [0, 0], newExtent: [3, 0], oldText: '', newText: 'pqr\nstu\nvwx\n'}
]
assertChangesEqual(buffer.getChangesSinceCheckpoint(checkpoint), [
{
oldRange: [[1, 0], [1, 2]],
newRange: [[1, 0], [1, 2]],
oldText: "de",
newText: "yz",
},
{
oldRange: [[5, 0], [5, 0]],
newRange: [[5, 0], [8, 0]],
oldText: "",
newText: "pqr\nstu\nvwx\n",
}
])

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

buffer.insert([0, 0], "abc")
buffer.delete([[0, 0], [0, 1]])
expect(textChanges).toEqual([
assertChangesEqual(textChanges, [
{
start: {row: 0, column: 0},
oldExtent: {row: 0, column: 0},
newExtent: {row: 0, column: 3},
oldRange: [[0, 0], [0, 0]],
newRange: [[0, 0], [0, 3]]
oldText: "",
newText: "abc"
},
{
start: {row: 0, column: 0},
oldExtent: {row: 0, column: 1},
newExtent: {row: 0, column: 0},
oldRange: [[0, 0], [0, 1]],
newRange: [[0, 0], [0, 0]],
oldText: "a",
newText: ""
}
Expand All @@ -2642,58 +2650,53 @@ describe "TextBuffer", ->
buffer.insert([2, 3], "zw")
buffer.delete([[2, 3], [2, 4]])

expect(textChanges).toEqual([

assertChangesEqual(textChanges, [
{
start: {row: 1, column: 0},
oldExtent: {row: 0, column: 0},
newExtent: {row: 0, column: 2},
oldRange: [[1, 0], [1, 0]],
newRange: [[1, 0], [1, 2]],
oldText: "",
newText: "xy"
newText: "xy",
},
{
start: {row: 2, column: 3},
oldExtent: {row: 0, column: 0},
newExtent: {row: 0, column: 1},
oldRange: [[2, 3], [2, 3]],
newRange: [[2, 3], [2, 4]],
oldText: "",
newText: "w"
newText: "w",
}
])

textChanges = []
buffer.undo()
expect(textChanges).toEqual([
assertChangesEqual(textChanges, [
{
start: {row: 1, column: 0},
oldExtent: {row: 0, column: 2},
newExtent: {row: 0, column: 0},
oldRange: [[1, 0], [1, 2]],
newRange: [[1, 0], [1, 0]],
oldText: "xy",
newText: ""
newText: "",
},
{
start: {row: 2, column: 3},
oldExtent: {row: 0, column: 1},
newExtent: {row: 0, column: 0},
oldRange: [[2, 3], [2, 4]],
newRange: [[2, 3], [2, 3]],
oldText: "w",
newText: ""
newText: "",
}
])

textChanges = []
buffer.redo()
expect(textChanges).toEqual([
assertChangesEqual(textChanges, [
{
start: {row: 1, column: 0},
oldExtent: {row: 0, column: 0},
newExtent: {row: 0, column: 2},
oldRange: [[1, 0], [1, 0]],
newRange: [[1, 0], [1, 2]],
oldText: "",
newText: "xy"
newText: "xy",
},
{
start: {row: 2, column: 3},
oldExtent: {row: 0, column: 0},
newExtent: {row: 0, column: 1},
oldRange: [[2, 3], [2, 3]],
newRange: [[2, 3], [2, 4]],
oldText: "",
newText: "w"
newText: "w",
}
])

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

# we emit only one event for nested transactions
expect(textChanges).toEqual([
assertChangesEqual(textChanges, [
{
start: {row: 0, column: 0},
oldExtent: {row: 0, column: 0},
newExtent: {row: 0, column: 1},
oldRange: [[0, 0], [0, 0]],
newRange: [[0, 0], [0, 1]],
oldText: "",
newText: "j"
newText: "j",
}
])

Expand Down Expand Up @@ -2760,22 +2762,21 @@ describe "TextBuffer", ->

beforeEach (done) ->
expect(didStopChangingCallback).toHaveBeenCalled()
expect(didStopChangingCallback.calls.mostRecent().args[0].changes).toEqual [

assertChangesEqual(didStopChangingCallback.calls.mostRecent().args[0].changes, [
{
start: {row: 0, column: 0},
oldExtent: {row: 0, column: 0},
newExtent: {row: 0, column: 2},
oldText: '',
newText: 'ba'
oldRange: [[0, 0], [0, 0]],
newRange: [[0, 0], [0, 2]],
oldText: "",
newText: "ba",
},
{
start: {row: 1, column: 0},
oldExtent: {row: 0, column: 0},
newExtent: {row: 0, column: 1},
oldText: '',
newText: 'c'
}
]
oldRange: [[1, 0], [1, 0]],
newRange: [[1, 0], [1, 1]],
oldText: "",
newText: "c",
},
])

didStopChangingCallback.calls.reset()
buffer.undo()
Expand Down Expand Up @@ -2955,3 +2956,12 @@ describe "TextBuffer", ->
it "does not push the encoding change onto the undo stack", ->
buffer.undo()
expect(buffer.getText()).toBe 'тест 1234 абвгдеёжз'

assertChangesEqual = (actualChanges, expectedChanges) ->
expect(actualChanges.length).toBe(expectedChanges.length)
for actualChange, i in actualChanges
expectedChange = expectedChanges[i]
expect(actualChange.oldRange).toEqual(expectedChange.oldRange)
expect(actualChange.newRange).toEqual(expectedChange.newRange)
expect(actualChange.oldText).toEqual(expectedChange.oldText)
expect(actualChange.newText).toEqual(expectedChange.newText)
49 changes: 40 additions & 9 deletions src/helpers.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
const Point = require('./point')
const Range = require('./range')
const {traversal} = require('./point-helpers')

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

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

exports.regexIsSingleLine = function (regex) {
return !MULTI_LINE_REGEX_REGEX.test(regex.source)
}

exports.spliceArray = function (array, start, removedCount, insertedItems = []) {
const oldLength = array.length
const insertedCount = insertedItems.length
Expand All @@ -30,15 +35,41 @@ exports.spliceArray = function (array, start, removedCount, insertedItems = [])
}

exports.normalizePatchChanges = function (changes) {
return changes.map((change) => ({
start: Point.fromObject(change.newStart),
oldExtent: traversal(change.oldEnd, change.oldStart),
newExtent: traversal(change.newEnd, change.newStart),
oldText: change.oldText,
newText: change.newText
}))
return changes.map((change) =>
new TextChange(
Range(change.oldStart, change.oldEnd),
Range(change.newStart, change.newEnd),
change.oldText, change.newText
)
)
}

exports.regexIsSingleLine = function (regex) {
return !MULTI_LINE_REGEX_REGEX.test(regex.source)
class TextChange {
constructor (oldRange, newRange, oldText, newText) {
this.oldRange = oldRange
this.newRange = newRange
this.oldText = oldText
this.newText = newText
}
}

Object.defineProperty(TextChange.prototype, 'start', {
get: function () {
return this.newRange.start
},
enumerable: false
})

Object.defineProperty(TextChange.prototype, 'oldExtent', {
get: function () {
return this.oldRange.getExtent()
},
enumerable: false
})

Object.defineProperty(TextChange.prototype, 'newExtent', {
get: function () {
return this.newRange.getExtent()
},
enumerable: false
})
4 changes: 3 additions & 1 deletion src/range.coffee
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Point = require './point'
{newlineRegex} = require './helpers'
newlineRegex = null

# Public: Represents a region in a buffer in row/column coordinates.
#
Expand Down Expand Up @@ -57,6 +57,8 @@ class Range
#
# Returns: A {Range}
@fromText: (args...) ->
newlineRegex ?= require('./helpers').newlineRegex

if args.length > 1
startPoint = Point.fromObject(args.shift())
else
Expand Down

0 comments on commit fe1472f

Please sign in to comment.