7
7
8
8
import SwiftUI
9
9
10
- /// A collection of `NSColor` used for syntax higlighting
11
- public struct EditorTheme {
10
+ /// A collection of attributes used for syntax highlighting and other colors for the editor.
11
+ ///
12
+ /// Attributes of a theme that do not apply to text (background, line highlight) are a single `NSColor` for simplicity.
13
+ /// All other attributes use the ``EditorTheme/Attribute`` type to store
14
+ public struct EditorTheme : Equatable {
15
+ /// Represents attributes that can be applied to style text.
16
+ public struct Attribute : Equatable , Hashable , Sendable {
17
+ public let color : NSColor
18
+ public let bold : Bool
19
+ public let italic : Bool
12
20
13
- public var text : NSColor
21
+ public init ( color: NSColor , bold: Bool = false , italic: Bool = false ) {
22
+ self . color = color
23
+ self . bold = bold
24
+ self . italic = italic
25
+ }
26
+ }
27
+
28
+ public var text : Attribute
14
29
public var insertionPoint : NSColor
15
- public var invisibles : NSColor
30
+ public var invisibles : Attribute
16
31
public var background : NSColor
17
32
public var lineHighlight : NSColor
18
33
public var selection : NSColor
19
- public var keywords : NSColor
20
- public var commands : NSColor
21
- public var types : NSColor
22
- public var attributes : NSColor
23
- public var variables : NSColor
24
- public var values : NSColor
25
- public var numbers : NSColor
26
- public var strings : NSColor
27
- public var characters : NSColor
28
- public var comments : NSColor
34
+ public var keywords : Attribute
35
+ public var commands : Attribute
36
+ public var types : Attribute
37
+ public var attributes : Attribute
38
+ public var variables : Attribute
39
+ public var values : Attribute
40
+ public var numbers : Attribute
41
+ public var strings : Attribute
42
+ public var characters : Attribute
43
+ public var comments : Attribute
29
44
30
45
public init (
31
- text: NSColor ,
46
+ text: Attribute ,
32
47
insertionPoint: NSColor ,
33
- invisibles: NSColor ,
48
+ invisibles: Attribute ,
34
49
background: NSColor ,
35
50
lineHighlight: NSColor ,
36
51
selection: NSColor ,
37
- keywords: NSColor ,
38
- commands: NSColor ,
39
- types: NSColor ,
40
- attributes: NSColor ,
41
- variables: NSColor ,
42
- values: NSColor ,
43
- numbers: NSColor ,
44
- strings: NSColor ,
45
- characters: NSColor ,
46
- comments: NSColor
52
+ keywords: Attribute ,
53
+ commands: Attribute ,
54
+ types: Attribute ,
55
+ attributes: Attribute ,
56
+ variables: Attribute ,
57
+ values: Attribute ,
58
+ numbers: Attribute ,
59
+ strings: Attribute ,
60
+ characters: Attribute ,
61
+ comments: Attribute
47
62
) {
48
63
self . text = text
49
64
self . insertionPoint = insertionPoint
@@ -63,10 +78,10 @@ public struct EditorTheme {
63
78
self . comments = comments
64
79
}
65
80
66
- /// Get the color from ``theme`` for the specified capture name .
67
- /// - Parameter capture: The capture name
68
- /// - Returns: A `NSColor`
69
- func colorFor ( _ capture: CaptureName ? ) -> NSColor {
81
+ /// Maps a capture type to the attributes for that capture determined by the theme .
82
+ /// - Parameter capture: The capture to map to.
83
+ /// - Returns: Theme attributes for the capture.
84
+ private func mapCapture ( _ capture: CaptureName ? ) -> Attribute {
70
85
switch capture {
71
86
case . include, . constructor, . keyword, . boolean, . variableBuiltin,
72
87
. keywordReturn, . keywordFunction, . repeat , . conditional, . tag:
@@ -82,25 +97,35 @@ public struct EditorTheme {
82
97
default : return text
83
98
}
84
99
}
85
- }
86
100
87
- extension EditorTheme : Equatable {
88
- public static func == ( lhs: EditorTheme , rhs: EditorTheme ) -> Bool {
89
- return lhs. text == rhs. text &&
90
- lhs. insertionPoint == rhs. insertionPoint &&
91
- lhs. invisibles == rhs. invisibles &&
92
- lhs. background == rhs. background &&
93
- lhs. lineHighlight == rhs. lineHighlight &&
94
- lhs. selection == rhs. selection &&
95
- lhs. keywords == rhs. keywords &&
96
- lhs. commands == rhs. commands &&
97
- lhs. types == rhs. types &&
98
- lhs. attributes == rhs. attributes &&
99
- lhs. variables == rhs. variables &&
100
- lhs. values == rhs. values &&
101
- lhs. numbers == rhs. numbers &&
102
- lhs. strings == rhs. strings &&
103
- lhs. characters == rhs. characters &&
104
- lhs. comments == rhs. comments
101
+ /// Get the color from ``theme`` for the specified capture name.
102
+ /// - Parameter capture: The capture name
103
+ /// - Returns: A `NSColor`
104
+ func colorFor( _ capture: CaptureName ? ) -> NSColor {
105
+ return mapCapture ( capture) . color
106
+ }
107
+
108
+ /// Returns the correct font with attributes (bold and italics) for a given capture name.
109
+ /// - Parameters:
110
+ /// - capture: The capture name.
111
+ /// - font: The font to add attributes to.
112
+ /// - Returns: A new font that has the correct attributes for the capture.
113
+ func fontFor( for capture: CaptureName ? , from font: NSFont ) -> NSFont {
114
+ let attributes = mapCapture ( capture)
115
+ guard attributes. bold || attributes. italic else {
116
+ return font
117
+ }
118
+
119
+ var font = font
120
+
121
+ if attributes. bold {
122
+ font = NSFontManager . shared. convert ( font, toHaveTrait: . boldFontMask)
123
+ }
124
+
125
+ if attributes. italic {
126
+ font = NSFontManager . shared. convert ( font, toHaveTrait: . italicFontMask)
127
+ }
128
+
129
+ return font
105
130
}
106
131
}
0 commit comments