Skip to content

Commit 4a32acd

Browse files
committed
Fix Iterator Edge Case
1 parent 2603ff1 commit 4a32acd

File tree

1 file changed

+19
-6
lines changed

1 file changed

+19
-6
lines changed

Sources/CodeEditTextView/TextLineStorage/TextLineStorage+Iterator.swift

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,24 @@
77

88
import Foundation
99

10+
/// # Dev Note
11+
///
12+
/// For these iterators, prefer `.getLine(atIndex: )` for finding the next item in the iteration.
13+
/// Using plain indexes instead of y positions or ranges has led to far fewer edge cases.
1014
public extension TextLineStorage {
15+
/// Iterate over all lines overlapping a range of `y` positions. Positions in the middle of line contents will
16+
/// return that line.
17+
/// - Parameters:
18+
/// - minY: The minimum y position to start at.
19+
/// - maxY: The maximum y position to stop at.
20+
/// - Returns: A lazy iterator for retrieving lines.
1121
func linesStartingAt(_ minY: CGFloat, until maxY: CGFloat) -> TextLineStorageYIterator {
1222
TextLineStorageYIterator(storage: self, minY: minY, maxY: maxY)
1323
}
14-
24+
25+
/// Iterate over all lines overlapping a range in the document.
26+
/// - Parameter range: The range to query.
27+
/// - Returns: A lazy iterator for retrieving lines.
1528
func linesInRange(_ range: NSRange) -> TextLineStorageRangeIterator {
1629
TextLineStorageRangeIterator(storage: self, range: range)
1730
}
@@ -36,7 +49,7 @@ public extension TextLineStorage {
3649
return nil
3750
}
3851
self.currentPosition = nextPosition
39-
return self.currentPosition!
52+
return nextPosition
4053
} else if let nextPosition = storage.getLine(atPosition: minY) {
4154
self.currentPosition = nextPosition
4255
return nextPosition
@@ -60,11 +73,11 @@ public extension TextLineStorage {
6073
public mutating func next() -> TextLinePosition? {
6174
if let currentPosition {
6275
guard currentPosition.range.max < range.max,
63-
let nextPosition = storage.getLine(atOffset: currentPosition.range.max) else {
76+
let nextPosition = storage.getLine(atIndex: currentPosition.index + 1) else {
6477
return nil
6578
}
6679
self.currentPosition = nextPosition
67-
return self.currentPosition!
80+
return nextPosition
6881
} else if let nextPosition = storage.getLine(atOffset: range.location) {
6982
self.currentPosition = nextPosition
7083
return nextPosition
@@ -92,11 +105,11 @@ extension TextLineStorage: LazySequenceProtocol {
92105
public mutating func next() -> TextLinePosition? {
93106
if let currentPosition {
94107
guard currentPosition.range.max < storage.length,
95-
let nextPosition = storage.getLine(atOffset: currentPosition.range.max) else {
108+
let nextPosition = storage.getLine(atIndex: currentPosition.index + 1) else {
96109
return nil
97110
}
98111
self.currentPosition = nextPosition
99-
return self.currentPosition!
112+
return nextPosition
100113
} else if let nextPosition = storage.getLine(atOffset: 0) {
101114
self.currentPosition = nextPosition
102115
return nextPosition

0 commit comments

Comments
 (0)