diff --git a/Sources/CodeEditor/UXCodeTextView.swift b/Sources/CodeEditor/UXCodeTextView.swift index 7c680ae..58cb2d2 100644 --- a/Sources/CodeEditor/UXCodeTextView.swift +++ b/Sources/CodeEditor/UXCodeTextView.swift @@ -58,6 +58,7 @@ final class UXCodeTextView: UXTextView { } private(set) var themeName = CodeEditor.ThemeName.default { didSet { + guard themeName != oldValue else { return } highlightr?.setTheme(to: themeName.rawValue) if let font = highlightr?.theme?.codeFont { self.font = font } } @@ -247,6 +248,7 @@ final class UXCodeTextView: UXTextView { guard let highlightr = highlightr, highlightr.setTheme(to: newTheme.rawValue), let theme = highlightr.theme else { return false } + themeName = newTheme self.backgroundColor = customBackgroundColor ?? theme.themeBackgroundColor if let font = theme.codeFont, font !== self.font { self.font = font } return true @@ -256,13 +258,25 @@ final class UXCodeTextView: UXTextView { func applyNewTheme(_ newTheme: CodeEditor.ThemeName? = nil, andFontSize newSize: CGFloat) -> Bool { + let resolvedTheme = newTheme ?? themeName + let themeChanged = resolvedTheme != themeName + + // Skip expensive setTheme reload when neither theme nor font size changed. + if !themeChanged, + let existingFont = highlightr?.theme?.codeFont, + existingFont.pointSize == newSize { + return true + } + // Setting the theme reloads it (i.e. makes a "copy"). guard let highlightr = highlightr, - highlightr.setTheme(to: (newTheme ?? themeName).rawValue), + highlightr.setTheme(to: resolvedTheme.rawValue), let theme = highlightr.theme else { return false } - + + if themeChanged { themeName = resolvedTheme } + guard theme.codeFont?.pointSize != newSize else { return true } - + theme.codeFont = theme.codeFont? .withSize(newSize) theme.boldCodeFont = theme.boldCodeFont? .withSize(newSize) theme.italicCodeFont = theme.italicCodeFont?.withSize(newSize)