Skip to content

Commit fb42f6f

Browse files
committed
Smarter Highlight Provider Defaults Management
1 parent 15798b8 commit fb42f6f

File tree

2 files changed

+35
-21
lines changed

2 files changed

+35
-21
lines changed

Sources/CodeEditSourceEditor/CodeEditSourceEditor/CodeEditSourceEditor+Coordinator.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@ extension CodeEditSourceEditor {
1818
var text: TextAPI
1919
@Binding var cursorPositions: [CursorPosition]
2020

21-
init(text: TextAPI, cursorPositions: Binding<[CursorPosition]>) {
21+
private(set) var highlightProviders: [any HighlightProviding]
22+
23+
init(text: TextAPI, cursorPositions: Binding<[CursorPosition]>, highlightProviders: [any HighlightProviding]?) {
2224
self.text = text
2325
self._cursorPositions = cursorPositions
26+
self.highlightProviders = highlightProviders ?? [TreeSitterClient()]
2427
super.init()
2528

2629
NotificationCenter.default.addObserver(
@@ -38,6 +41,14 @@ extension CodeEditSourceEditor {
3841
)
3942
}
4043

44+
func updateHighlightProviders(_ highlightProviders: [any HighlightProviding]?) {
45+
guard let highlightProviders else {
46+
return // Keep our default `TreeSitterClient` if they're `nil`
47+
}
48+
// Otherwise, we can replace the stored providers.
49+
self.highlightProviders = highlightProviders
50+
}
51+
4152
@objc func textViewDidChangeText(_ notification: Notification) {
4253
guard let textView = notification.object as? TextView,
4354
let controller,

Sources/CodeEditSourceEditor/CodeEditSourceEditor/CodeEditSourceEditor.swift

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
3535
/// - cursorPositions: The cursor's position in the editor, measured in `(lineNum, columnNum)`
3636
/// - useThemeBackground: Determines whether the editor uses the theme's background color, or a transparent
3737
/// background color
38-
/// - highlightProvider: A class you provide to perform syntax highlighting. Leave this as `nil` to use the
39-
/// built-in `TreeSitterClient` highlighter.
38+
/// - highlightProviders: A set of classes you provide to perform syntax highlighting. Leave this as `nil` to use
39+
/// the default `TreeSitterClient` highlighter.
4040
/// - contentInsets: Insets to use to offset the content in the enclosing scroll view. Leave as `nil` to let the
4141
/// scroll view automatically adjust content insets.
4242
/// - additionalTextInsets: An additional amount to inset the text of the editor by.
@@ -62,7 +62,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
6262
editorOverscroll: CGFloat = 0,
6363
cursorPositions: Binding<[CursorPosition]>,
6464
useThemeBackground: Bool = true,
65-
highlightProviders: [any HighlightProviding] = [TreeSitterClient()],
65+
highlightProviders: [any HighlightProviding]? = nil,
6666
contentInsets: NSEdgeInsets? = nil,
6767
additionalTextInsets: NSEdgeInsets? = nil,
6868
isEditable: Bool = true,
@@ -114,8 +114,8 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
114114
/// - cursorPositions: The cursor's position in the editor, measured in `(lineNum, columnNum)`
115115
/// - useThemeBackground: Determines whether the editor uses the theme's background color, or a transparent
116116
/// background color
117-
/// - highlightProvider: A class you provide to perform syntax highlighting. Leave this as `nil` to use the
118-
/// built-in `TreeSitterClient` highlighter.
117+
/// - highlightProviders: A set of classes you provide to perform syntax highlighting. Leave this as `nil` to use
118+
/// the default `TreeSitterClient` highlighter.
119119
/// - contentInsets: Insets to use to offset the content in the enclosing scroll view. Leave as `nil` to let the
120120
/// scroll view automatically adjust content insets.
121121
/// - isEditable: A Boolean value that controls whether the text view allows the user to edit text.
@@ -139,7 +139,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
139139
editorOverscroll: CGFloat = 0,
140140
cursorPositions: Binding<[CursorPosition]>,
141141
useThemeBackground: Bool = true,
142-
highlightProviders: [any HighlightProviding] = [TreeSitterClient()],
142+
highlightProviders: [any HighlightProviding]? = nil,
143143
contentInsets: NSEdgeInsets? = nil,
144144
additionalTextInsets: NSEdgeInsets? = nil,
145145
isEditable: Bool = true,
@@ -188,7 +188,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
188188
private var editorOverscroll: CGFloat
189189
package var cursorPositions: Binding<[CursorPosition]>
190190
private var useThemeBackground: Bool
191-
private var highlightProviders: [any HighlightProviding]
191+
private var highlightProviders: [any HighlightProviding]?
192192
private var contentInsets: NSEdgeInsets?
193193
private var additionalTextInsets: NSEdgeInsets?
194194
private var isEditable: Bool
@@ -214,7 +214,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
214214
cursorPositions: cursorPositions.wrappedValue,
215215
editorOverscroll: editorOverscroll,
216216
useThemeBackground: useThemeBackground,
217-
highlightProviders: highlightProviders,
217+
highlightProviders: context.coordinator.highlightProviders,
218218
contentInsets: contentInsets,
219219
additionalTextInsets: additionalTextInsets,
220220
isEditable: isEditable,
@@ -243,10 +243,12 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
243243
}
244244

245245
public func makeCoordinator() -> Coordinator {
246-
Coordinator(text: text, cursorPositions: cursorPositions)
246+
Coordinator(text: text, cursorPositions: cursorPositions, highlightProviders: highlightProviders)
247247
}
248248

249249
public func updateNSViewController(_ controller: TextViewController, context: Context) {
250+
context.coordinator.updateHighlightProviders(highlightProviders)
251+
250252
if !context.coordinator.isUpdateFromTextView {
251253
// Prevent infinite loop of update notifications
252254
context.coordinator.isUpdatingFromRepresentable = true
@@ -261,23 +263,23 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
261263

262264
// Do manual diffing to reduce the amount of reloads.
263265
// This helps a lot in view performance, as it otherwise gets triggered on each environment change.
264-
guard !paramsAreEqual(controller: controller) else {
266+
guard !paramsAreEqual(controller: controller, coordinator: context.coordinator) else {
265267
return
266268
}
267269

268-
updateControllerParams(controller: controller)
270+
updateControllerParams(controller: controller, coordinator: context.coordinator)
269271

270272
controller.reloadUI()
271273
return
272274
}
273275

274276
/// Update the parameters of the controller.
275277
/// - Parameter controller: The controller to update.
276-
func updateControllerParams(controller: TextViewController) {
278+
func updateControllerParams(controller: TextViewController, coordinator: Coordinator) {
277279
updateTextProperties(controller)
278280
updateEditorProperties(controller)
279281
updateThemeAndLanguage(controller)
280-
updateHighlighting(controller)
282+
updateHighlighting(controller, coordinator: coordinator)
281283
}
282284

283285
private func updateTextProperties(_ controller: TextViewController) {
@@ -329,9 +331,9 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
329331
}
330332
}
331333

332-
private func updateHighlighting(_ controller: TextViewController) {
333-
if !areHighlightProvidersEqual(controller: controller) {
334-
controller.setHighlightProviders(highlightProviders)
334+
private func updateHighlighting(_ controller: TextViewController, coordinator: Coordinator) {
335+
if !areHighlightProvidersEqual(controller: controller, coordinator: coordinator) {
336+
controller.setHighlightProviders(coordinator.highlightProviders)
335337
}
336338

337339
if controller.bracketPairEmphasis != bracketPairEmphasis {
@@ -342,7 +344,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
342344
/// Checks if the controller needs updating.
343345
/// - Parameter controller: The controller to check.
344346
/// - Returns: True, if the controller's parameters should be updated.
345-
func paramsAreEqual(controller: NSViewControllerType) -> Bool {
347+
func paramsAreEqual(controller: NSViewControllerType, coordinator: Coordinator) -> Bool {
346348
controller.font == font &&
347349
controller.isEditable == isEditable &&
348350
controller.isSelectable == isSelectable &&
@@ -359,11 +361,12 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
359361
controller.letterSpacing == letterSpacing &&
360362
controller.bracketPairEmphasis == bracketPairEmphasis &&
361363
controller.useSystemCursor == useSystemCursor &&
362-
areHighlightProvidersEqual(controller: controller)
364+
areHighlightProvidersEqual(controller: controller, coordinator: coordinator)
363365
}
364366

365-
private func areHighlightProvidersEqual(controller: TextViewController) -> Bool {
366-
controller.highlightProviders.map { ObjectIdentifier($0) } == highlightProviders.map { ObjectIdentifier($0) }
367+
private func areHighlightProvidersEqual(controller: TextViewController, coordinator: Coordinator) -> Bool {
368+
controller.highlightProviders.map { ObjectIdentifier($0) }
369+
== coordinator.highlightProviders.map { ObjectIdentifier($0) }
367370
}
368371
}
369372

0 commit comments

Comments
 (0)