-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathDiffEnvironment.swift
More file actions
138 lines (122 loc) · 5.2 KB
/
DiffEnvironment.swift
File metadata and controls
138 lines (122 loc) · 5.2 KB
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import SwiftUI
/// Environment key for diff configuration
struct DiffConfigurationKey: EnvironmentKey {
static let defaultValue = DiffConfiguration.default
}
/// Environment key for the active diff parser. Defaults to
/// ``UnifiedDiffParser`` so existing callers see no change.
struct DiffParserKey: EnvironmentKey {
static let defaultValue: any DiffParsing = UnifiedDiffParser()
}
/// Environment extensions for diff configuration
extension EnvironmentValues {
public var diffConfiguration: DiffConfiguration {
get { self[DiffConfigurationKey.self] }
set { self[DiffConfigurationKey.self] = newValue }
}
public var diffParser: any DiffParsing {
get { self[DiffParserKey.self] }
set { self[DiffParserKey.self] = newValue }
}
}
// MARK: - View Modifiers
/// View modifiers for configuring diff rendering
public extension View {
/// Applies a complete diff configuration.
/// - Parameter configuration: The configuration to apply
func diffConfiguration(_ configuration: DiffConfiguration) -> some View {
environment(\.diffConfiguration, configuration)
}
/// Sets the color theme.
/// - Parameter theme: The theme to apply
func diffTheme(_ theme: DiffTheme) -> some View {
transformEnvironment(\.diffConfiguration) { config in
config = config.with(theme: theme)
}
}
/// Shows or hides line numbers (legacy API — for finer control prefer
/// ``diffLineNumberStyle(_:)``). Maps `true` → ``DiffConfiguration/LineNumberStyle/dual``,
/// `false` → ``DiffConfiguration/LineNumberStyle/hidden``.
func diffLineNumbers(_ show: Bool) -> some View {
transformEnvironment(\.diffConfiguration) { config in
config = config.withLineNumbers(show)
}
}
/// Selects how the line-number gutter is rendered:
/// `.hidden` (no gutter), `.single` (compact single column — ideal for
/// mobile / narrow viewports), or `.dual` (side-by-side old/new
/// columns — the desktop default).
func diffLineNumberStyle(_ style: DiffConfiguration.LineNumberStyle) -> some View {
transformEnvironment(\.diffConfiguration) { config in
config = config.withLineNumberStyle(style)
}
}
/// Shows or hides file headers (the `diff --git` / `---` / `+++` header
/// block at the top of each file).
func diffFileHeaders(_ show: Bool) -> some View {
transformEnvironment(\.diffConfiguration) { config in
config = config.withFileHeaders(show)
}
}
/// Shows or hides per-hunk `@@ -a,b +c,d @@` separator lines. Hide
/// these in minimal renderers where hunk boundaries are already
/// implied by line backgrounds — the prose around the diff (a chip
/// showing filename + stats, a sheet title, etc.) carries the location.
func diffHunkHeaders(_ show: Bool) -> some View {
transformEnvironment(\.diffConfiguration) { config in
config = config.withHunkHeaders(show)
}
}
/// Configures font properties.
/// - Parameters:
/// - size: Font size
/// - weight: Font weight
/// - design: Font design (e.g., monospaced)
func diffFont(size: CGFloat? = nil, weight: Font.Weight? = nil, design: Font.Design? = nil) -> some View {
transformEnvironment(\.diffConfiguration) { config in
config = config.withFont(size: size, weight: weight, design: design)
}
}
/// Sets line spacing.
/// - Parameter spacing: The spacing mode
func diffLineSpacing(_ spacing: DiffConfiguration.LineSpacing) -> some View {
transformEnvironment(\.diffConfiguration) { config in
config = config.withLineSpacing(spacing)
}
}
/// Enables or disables word wrapping.
/// - Parameter wrap: Whether to wrap long lines
func diffWordWrap(_ wrap: Bool) -> some View {
transformEnvironment(\.diffConfiguration) { config in
config = config.withWordWrap(wrap)
}
}
/// Injects a custom ``DiffParsing`` implementation so the renderer can
/// consume formats other than standard unified diff (annotated diffs,
/// server-side payloads, JSON patches, …). The default parser is
/// ``UnifiedDiffParser``.
///
/// - Parameter parser: Any value conforming to ``DiffParsing``.
func diffParser(_ parser: any DiffParsing) -> some View {
environment(\.diffParser, parser)
}
/// Sets content padding
func diffPadding(_ padding: EdgeInsets) -> some View {
transformEnvironment(\.diffConfiguration) { config in
config = DiffConfiguration(
theme: config.theme,
showLineNumbers: config.showLineNumbers,
lineNumberStyle: config.lineNumberStyle,
showFileHeaders: config.showFileHeaders,
showHunkHeaders: config.showHunkHeaders,
fontFamily: config.fontFamily,
fontSize: config.fontSize,
fontWeight: config.fontWeight,
lineHeight: config.lineHeight,
lineSpacing: config.lineSpacing,
wordWrap: config.wordWrap,
contentPadding: padding
)
}
}
}