Skip to content

Commit

Permalink
RangeMutation adjustments needed for #44
Browse files Browse the repository at this point in the history
  • Loading branch information
mattmassicotte committed May 10, 2024
1 parent e2c6700 commit 26f53e5
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/ChimeHQ/SwiftTreeSitter",
"state" : {
"revision" : "7ccb58219c3e928bf1938dd43d33fd349dc71808"
"revision" : "b01904a3737649c1d8520106bbb285724fe5b0bb"
}
}
],
Expand Down
33 changes: 27 additions & 6 deletions Sources/RangeState/RangeProcessor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -184,19 +184,40 @@ extension RangeProcessor {
}

public func didChangeContent(_ mutation: RangeMutation) {
guard processed(mutation.range) else { return }

processMutation(mutation)
didChangeContent(in: mutation.range, delta: mutation.delta)
}

public func didChangeContent(in range: NSRange, delta: Int) {
let limit = maximumProcessedLocation ?? 0
if processed(range.location) == false {
return
}

guard let limit = maximumProcessedLocation else {
return
}

precondition(limit >= 0)

let mutation = RangeMutation(range: range, delta: delta, limit: limit)
let visibleRange = range.clamped(to: limit)
let effectiveLimit = limit
let clampLength = range.upperBound - visibleRange.upperBound

didChangeContent(mutation)
precondition(clampLength >= 0)

// The logic to adjust the delta is pretty tricky.
let visibleDelta: Int

if clampLength == 0 {
visibleDelta = delta
} else if delta < 0 {
visibleDelta = max(delta + clampLength, 0)
} else {
visibleDelta = 0
}

let mutation = RangeMutation(range: visibleRange, delta: visibleDelta, limit: effectiveLimit)

processMutation(mutation)
}

private func processMutation(_ mutation: RangeMutation) {
Expand Down
49 changes: 49 additions & 0 deletions Tests/RangeStateTests/RangeProcessorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,53 @@ final class RangeProcessorTests: XCTestCase {

XCTAssertEqual(handler.mutations, expected)
}

@MainActor
func testInsertWithNothingProcessed() {
let processor = RangeProcessor(
configuration: .init(
lengthProvider: { 10 },
changeHandler: { _, _ in fatalError() }
)
)

processor.didChangeContent(in: NSRange(0..<10), delta: 10)
}

@MainActor
func testChangeThatOverlapsUnprocessedRegion() {
let exp = expectation(description: "mutation")
exp.expectedFulfillmentCount = 2

let handler = MockChangeHandler()

handler.changeCompleted = {
exp.fulfill()
}

let content = StringContent(string: "abcdefghij")

let processor = RangeProcessor(
configuration: .init(
lengthProvider: { content.currentLength },
changeHandler: handler.handleChange
)
)

// process half
XCTAssertTrue(processor.processLocation(5, mode: .required))
XCTAssertTrue(processor.processed(5))

// change everything
processor.didChangeContent(in: NSRange(0..<10), delta: 0)

wait(for: [exp], enforceOrder: true)

let expected = [
RangeMutation(range: NSRange(0..<0), delta: 5, limit: nil),
RangeMutation(range: NSRange(0..<5), delta: 0, limit: 5),
]

XCTAssertEqual(handler.mutations, expected)
}
}

0 comments on commit 26f53e5

Please sign in to comment.