54 lines
1.9 KiB
Swift
54 lines
1.9 KiB
Swift
import Foundation
|
|
|
|
/// A file's line-ending style. The editor always keeps its buffer in LF
|
|
/// internally (so `BlockParser`'s `\n` split is clean and no stray `\r`
|
|
/// characters leak into block content); the original style is remembered so
|
|
/// it can be written back on save without silently changing the user's file.
|
|
public enum LineEnding: String, Sendable {
|
|
case lf // "\n"
|
|
case crlf // "\r\n"
|
|
case cr // "\r"
|
|
|
|
/// The literal character sequence for this line ending.
|
|
public var string: String {
|
|
switch self {
|
|
case .lf: return "\n"
|
|
case .crlf: return "\r\n"
|
|
case .cr: return "\r"
|
|
}
|
|
}
|
|
|
|
/// Short label for display in the status bar.
|
|
public var displayName: String {
|
|
switch self {
|
|
case .lf: return "LF"
|
|
case .crlf: return "CRLF"
|
|
case .cr: return "CR"
|
|
}
|
|
}
|
|
|
|
/// Detects the line ending used in `text`. CRLF is checked before CR/LF
|
|
/// because it contains both. Defaults to `.lf` when there are no breaks.
|
|
public static func detect(in text: String) -> LineEnding {
|
|
if text.contains("\r\n") { return .crlf }
|
|
if text.contains("\r") { return .cr }
|
|
return .lf
|
|
}
|
|
|
|
/// Whether `text` mixes more than one line-ending style (e.g. some CRLF and
|
|
/// some LF) — the case the "inconsistent line endings" warning flags.
|
|
public static func isInconsistent(in text: String) -> Bool {
|
|
let hasCRLF = text.contains("\r\n")
|
|
let withoutCRLF = text.replacingOccurrences(of: "\r\n", with: "")
|
|
let hasCR = withoutCRLF.contains("\r")
|
|
let hasLF = withoutCRLF.contains("\n")
|
|
return [hasCRLF, hasCR, hasLF].filter { $0 }.count > 1
|
|
}
|
|
|
|
/// Converts every line ending in `text` to LF (`\n`).
|
|
public static func normalize(_ text: String) -> String {
|
|
text.replacingOccurrences(of: "\r\n", with: "\n")
|
|
.replacingOccurrences(of: "\r", with: "\n")
|
|
}
|
|
}
|