Files
wehub-resource-sync 5b99bf6bca
CI / test (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:34:54 +08:00

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")
}
}