blob: b1db4645ee9938ca411959fe9d516043c475240c (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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
}
|