Fix JSON editor not updating on appearance change on macOS

This commit is contained in:
世界
2026-04-20 05:26:28 +08:00
parent ad7434d676
commit 8c0d910685
+40 -23
View File
@@ -40,31 +40,40 @@ private extension NSColor {
} }
} }
private func makeTheme() -> EditorTheme { private func makeTheme(for colorScheme: ColorScheme) -> EditorTheme {
EditorTheme( var theme: EditorTheme!
text: .init(color: NSColor.labelColor.forEditor), let build = {
insertionPoint: NSColor.labelColor.forEditor, theme = EditorTheme(
invisibles: .init(color: NSColor.tertiaryLabelColor.forEditor), text: .init(color: NSColor.labelColor.forEditor),
background: NSColor.textBackgroundColor.forEditor, insertionPoint: NSColor.labelColor.forEditor,
lineHighlight: NSColor.quaternaryLabelColor.forEditor, invisibles: .init(color: NSColor.tertiaryLabelColor.forEditor),
selection: NSColor.selectedTextBackgroundColor.forEditor, background: NSColor.textBackgroundColor.forEditor,
keywords: .init(color: NSColor.systemPurple.forEditor), lineHighlight: NSColor.quaternaryLabelColor.forEditor,
commands: .init(color: NSColor.systemCyan.forEditor), selection: NSColor.selectedTextBackgroundColor.forEditor,
types: .init(color: NSColor.systemCyan.forEditor), keywords: .init(color: NSColor.systemPurple.forEditor),
attributes: .init(color: NSColor.systemCyan.forEditor), commands: .init(color: NSColor.systemCyan.forEditor),
variables: .init(color: NSColor.labelColor.forEditor), types: .init(color: NSColor.systemCyan.forEditor),
values: .init(color: NSColor.systemOrange.forEditor), attributes: .init(color: NSColor.systemCyan.forEditor),
numbers: .init(color: NSColor.systemOrange.forEditor), variables: .init(color: NSColor.labelColor.forEditor),
strings: .init(color: NSColor.systemGreen.forEditor), values: .init(color: NSColor.systemOrange.forEditor),
characters: .init(color: NSColor.systemGreen.forEditor), numbers: .init(color: NSColor.systemOrange.forEditor),
comments: .init(color: NSColor.secondaryLabelColor.forEditor) strings: .init(color: NSColor.systemGreen.forEditor),
) characters: .init(color: NSColor.systemGreen.forEditor),
comments: .init(color: NSColor.secondaryLabelColor.forEditor)
)
}
if let appearance = NSAppearance(named: colorScheme == .dark ? .darkAqua : .aqua) {
appearance.performAsCurrentDrawingAppearance(build)
} else {
build()
}
return theme
} }
private func makeConfiguration(isEditable: Bool) -> SourceEditorConfiguration { private func makeConfiguration(isEditable: Bool, colorScheme: ColorScheme) -> SourceEditorConfiguration {
SourceEditorConfiguration( SourceEditorConfiguration(
appearance: .init( appearance: .init(
theme: makeTheme(), theme: makeTheme(for: colorScheme),
font: .monospacedSystemFont(ofSize: 14, weight: .regular), font: .monospacedSystemFont(ofSize: 14, weight: .regular),
lineHeightMultiple: 1.3, lineHeightMultiple: 1.3,
wrapLines: false wrapLines: false
@@ -85,6 +94,8 @@ struct CodeEditTextView: NSViewRepresentable {
let isEditable: Bool let isEditable: Bool
let editorController: CodeEditEditorController? let editorController: CodeEditEditorController?
@Environment(\.colorScheme) private var colorScheme
init(text: Binding<String>, isEditable: Bool, editorController: CodeEditEditorController? = nil) { init(text: Binding<String>, isEditable: Bool, editorController: CodeEditEditorController? = nil) {
_text = text _text = text
self.isEditable = isEditable self.isEditable = isEditable
@@ -95,7 +106,7 @@ struct CodeEditTextView: NSViewRepresentable {
let controller = TextViewController( let controller = TextViewController(
string: text, string: text,
language: .json, language: .json,
configuration: makeConfiguration(isEditable: isEditable), configuration: makeConfiguration(isEditable: isEditable, colorScheme: colorScheme),
cursorPositions: [] cursorPositions: []
) )
controller.loadView() controller.loadView()
@@ -115,6 +126,7 @@ struct CodeEditTextView: NSViewRepresentable {
]) ])
context.coordinator.controller = controller context.coordinator.controller = controller
context.coordinator.lastColorScheme = colorScheme
context.coordinator.setupObservation() context.coordinator.setupObservation()
editorController?.controller = controller editorController?.controller = controller
Task { @MainActor in Task { @MainActor in
@@ -133,7 +145,11 @@ struct CodeEditTextView: NSViewRepresentable {
controller.language = .json controller.language = .json
} }
if controller.configuration.behavior.isEditable != isEditable { if controller.configuration.behavior.isEditable != isEditable {
controller.configuration = makeConfiguration(isEditable: isEditable) controller.configuration.behavior.isEditable = isEditable
}
if context.coordinator.lastColorScheme != colorScheme {
context.coordinator.lastColorScheme = colorScheme
controller.configuration.appearance.theme = makeTheme(for: colorScheme)
} }
editorController?.controller = controller editorController?.controller = controller
} }
@@ -144,6 +160,7 @@ struct CodeEditTextView: NSViewRepresentable {
class Coordinator: NSObject { class Coordinator: NSObject {
var controller: TextViewController? var controller: TextViewController?
var lastColorScheme: ColorScheme?
@Binding var text: String @Binding var text: String
private var observation: NSObjectProtocol? private var observation: NSObjectProtocol?
private weak var editorController: CodeEditEditorController? private weak var editorController: CodeEditEditorController?