HighlightedTextEditor
HighlightedTextEditor copied to clipboard
Initial caret size is wrong when using the `.all` rule to set the default editor font (macOS)
DO NOT DELETE THIS TEMPLATE
If you do not fill out this template, your issue will be automatically closed.
Describe the bug
I'm using the .all
convenience to set the default editor font size (as per https://github.com/kyle-n/HighlightedTextEditor/issues/63). When the editor view is first displayed, the caret size still matches the built-in default font size and doesn't adjust to the correct size until the first character is typed, causing it immediately change size as you type. I've only tested this on macOS.
To Reproduce
Please provide a small snippet of sample code and steps to reproduce the behavior. Write them like:
- Set up the editor with rules which specify a custom editor font:
static var customRules: [HighlightRule] { let editorFont = NSFont.monospacedSystemFont(ofSize: 20.0, weight: .regular) return [ HighlightRule(pattern: .all, formattingRule: TextFormattingRule(key: .font, value: editorFont)), /* ... */ ] }
- Run the app.
- Focus the editor and observe the caret size.
- Start typing and notice that the caret size jumps to the larger font size.
- Interestingly, deleting the newly typed characters leaves the caret at the correct size, but Cmd+Z / Undo makes it small again.
Expected behavior
I expect the initial caret size to match the font provided with the .all
regex.
Screenshots
Initial state with a small caret:
State after typing with the expected caret size:
Environment
- macOS Sonoma 14.4.1
- Xcode 15.3 (15E204a)
- AppKit (native macOS app)
Additional context
I took a quick look at how this could be implemented by setting the initial editor font size to match that in a .all
regex if one existed in the rules. Not sure I like the approach, but I thought I'd include it here for completeness:
public struct HighlightedTextEditor: NSViewRepresentable, HighlightingTextEditor {
/* .... */
public func makeNSView(context: Context) -> ScrollableTextView {
let textView = ScrollableTextView()
textView.delegate = context.coordinator
let emptyString = ""
let defaultRuleEditorFont = highlightRules
.first { $0.pattern == NSRegularExpression.all }?
.formattingRules
.first { $0.key == .font }?
.calculateValue?(emptyString, Range(uncheckedBounds: (lower: emptyString.startIndex, upper: emptyString.endIndex))) as? NSFont
textView.textView.font = defaultRuleEditorFont ?? defaultEditorFont
runIntrospect(textView)
return textView
}
/* ... */
}