77
88import SwiftUI
99
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
1220
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
1429 public var insertionPoint : NSColor
15- public var invisibles : NSColor
30+ public var invisibles : Attribute
1631 public var background : NSColor
1732 public var lineHighlight : NSColor
1833 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
2944
3045 public init (
31- text: NSColor ,
46+ text: Attribute ,
3247 insertionPoint: NSColor ,
33- invisibles: NSColor ,
48+ invisibles: Attribute ,
3449 background: NSColor ,
3550 lineHighlight: NSColor ,
3651 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
4762 ) {
4863 self . text = text
4964 self . insertionPoint = insertionPoint
@@ -63,10 +78,10 @@ public struct EditorTheme {
6378 self . comments = comments
6479 }
6580
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 {
7085 switch capture {
7186 case . include, . constructor, . keyword, . boolean, . variableBuiltin,
7287 . keywordReturn, . keywordFunction, . repeat , . conditional, . tag:
@@ -82,25 +97,35 @@ public struct EditorTheme {
8297 default : return text
8398 }
8499 }
85- }
86100
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
105130 }
106131}
0 commit comments