import Foundation public enum EditorActiveLineTracker { public static func lines(from source: String, activeLineIndex: Int) -> [EditorLine] { var lines: [EditorLine] = [] var lineStart = source.startIndex var utf16Location = 0 var index = 0 while lineStart < source.endIndex { let lineEnd = source[lineStart...].firstIndex(of: "\n") ?? source.endIndex let line = String(source[lineStart.. Int { let clampedLocation = max(0, min(location, source.utf16.count)) var currentLocation = 0 for (index, line) in source.split(separator: "\n", omittingEmptySubsequences: false).enumerated() { let length = line.utf16.count if clampedLocation <= currentLocation + length { return index } currentLocation += length + 1 } return 0 } public static func clampedSelection(_ selection: EditorSelection, in source: String) -> EditorSelection { let sourceLength = source.utf16.count let location = max(0, min(selection.location, sourceLength)) let length = max(0, min(selection.length, sourceLength - location)) return EditorSelection(location: location, length: length) } }