diff options
| author | Christian Cleberg <[email protected]> | 2026-03-17 23:19:43 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-03-17 23:19:43 -0500 |
| commit | 32ad6cab8d58d99ebd8a28e8fa6e6f4e587cb1e5 (patch) | |
| tree | ee36d421d704e508d5617d803b4c8cbdb4804fe1 /Hutch/Views/Repositories/DiffView.swift | |
| parent | 8f2057c53e9009c2529c9c4849c914666c0e4b40 (diff) | |
| download | hutch-32ad6cab8d58d99ebd8a28e8fa6e6f4e587cb1e5.tar.gz hutch-32ad6cab8d58d99ebd8a28e8fa6e6f4e587cb1e5.tar.bz2 hutch-32ad6cab8d58d99ebd8a28e8fa6e6f4e587cb1e5.zip | |
v1.0
Diffstat (limited to 'Hutch/Views/Repositories/DiffView.swift')
| -rw-r--r-- | Hutch/Views/Repositories/DiffView.swift | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/Hutch/Views/Repositories/DiffView.swift b/Hutch/Views/Repositories/DiffView.swift new file mode 100644 index 0000000..b1db464 --- /dev/null +++ b/Hutch/Views/Repositories/DiffView.swift @@ -0,0 +1,79 @@ +import SwiftUI + +/// Renders a unified diff string with syntax highlighting: +/// - Green background for added lines (+) +/// - Red background for removed lines (-) +/// - Gray for hunk headers (@@) +/// - File headers (--- / +++ / diff) in bold +struct DiffView: View { + let diff: String + + var body: some View { + let lines = diff.components(separatedBy: "\n") + + LazyVStack(alignment: .leading, spacing: 0) { + ForEach(Array(lines.enumerated()), id: \.offset) { _, line in + DiffLineView(line: line) + } + } + .font(.caption.monospaced()) + } +} + +private struct DiffLineView: View { + let line: String + + var body: some View { + Text(line.isEmpty ? " " : line) + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.horizontal, 8) + .padding(.vertical, 1) + .background(backgroundColor) + .foregroundStyle(foregroundColor) + .fontWeight(isHeader ? .semibold : .regular) + } + + private var kind: DiffLineKind { + if line.hasPrefix("@@") { return .hunk } + if line.hasPrefix("+++") || line.hasPrefix("---") { return .fileHeader } + if line.hasPrefix("diff ") { return .fileHeader } + if line.hasPrefix("index ") { return .meta } + if line.hasPrefix("+") { return .added } + if line.hasPrefix("-") { return .removed } + return .context + } + + private var backgroundColor: Color { + switch kind { + case .added: .green.opacity(0.15) + case .removed: .red.opacity(0.15) + case .hunk: .gray.opacity(0.12) + case .fileHeader: .gray.opacity(0.08) + case .meta: .gray.opacity(0.05) + case .context: .clear + } + } + + private var foregroundColor: Color { + switch kind { + case .added: .green + case .removed: .red + case .hunk: .secondary + case .meta: .secondary + default: .primary + } + } + + private var isHeader: Bool { + kind == .fileHeader + } +} + +private enum DiffLineKind { + case added + case removed + case hunk + case fileHeader + case meta + case context +} |
