diff --git a/Neon Vision Editor.xcodeproj/project.pbxproj b/Neon Vision Editor.xcodeproj/project.pbxproj index 6e9b422..668914e 100644 --- a/Neon Vision Editor.xcodeproj/project.pbxproj +++ b/Neon Vision Editor.xcodeproj/project.pbxproj @@ -361,7 +361,7 @@ CODE_SIGNING_ALLOWED = YES; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 400; + CURRENT_PROJECT_VERSION = 401; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = CS727NF72U; ENABLE_APP_SANDBOX = YES; @@ -444,7 +444,7 @@ CODE_SIGNING_ALLOWED = YES; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 400; + CURRENT_PROJECT_VERSION = 401; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = CS727NF72U; ENABLE_APP_SANDBOX = YES; diff --git a/Neon Vision Editor/Data/EditorViewModel.swift b/Neon Vision Editor/Data/EditorViewModel.swift index 83efbca..80d0c61 100644 --- a/Neon Vision Editor/Data/EditorViewModel.swift +++ b/Neon Vision Editor/Data/EditorViewModel.swift @@ -82,6 +82,10 @@ private enum EditorLoadHelper { defer { input.close() } var aggregate = Data() + if let expectedSize = try? url.resourceValues(forKeys: [.fileSizeKey]).fileSize, + expectedSize > 0 { + aggregate.reserveCapacity(expectedSize) + } var buffer = [UInt8](repeating: 0, count: streamChunkBytes) while true { @@ -1145,7 +1149,13 @@ class EditorViewModel { let data: Data if isLargeCandidate { - data = try EditorLoadHelper.streamFileData(from: url) + // Prefer memory-mapped IO for very large files to reduce peak memory churn. + // Fall back to streaming if mapping is unavailable for the provider. + if let mapped = try? Data(contentsOf: url, options: [.mappedIfSafe]) { + data = mapped + } else { + data = try EditorLoadHelper.streamFileData(from: url) + } } else { data = try Data(contentsOf: url, options: [.mappedIfSafe]) } diff --git a/Neon Vision Editor/UI/ContentView.swift b/Neon Vision Editor/UI/ContentView.swift index 24ed0d7..0a12e02 100644 --- a/Neon Vision Editor/UI/ContentView.swift +++ b/Neon Vision Editor/UI/ContentView.swift @@ -1441,12 +1441,22 @@ struct ContentView: View { let exceedsLineThreshold: Bool = { if exceedsByteThreshold { return true } var lineBreaks = 0 + var currentLineLength = 0 + let csvLongLineThreshold = 16_000 for codeUnit in text.utf16 { if codeUnit == 10 { // '\n' lineBreaks += 1 + currentLineLength = 0 if lineBreaks >= lineThreshold { return true } + continue + } + if isCSVLike { + currentLineLength += 1 + if currentLineLength >= csvLongLineThreshold { + return true + } } } return false