Sync every style field of the configuration in updateNSView - #164
Open
paulscan wants to merge 1 commit into
Open
Sync every style field of the configuration in updateNSView#164paulscan wants to merge 1 commit into
paulscan wants to merge 1 commit into
Conversation
`updateNSView` used to copy only a handful of `MarkdownEditorConfiguration` fields — `heightBehavior`, `rawSourceMode`, `lists`, and the fingerprint-gated `services` / `extensions` / `directives`. Everything else — `theme`, `paragraph`, `link`, `markers`, `codeBlock`, `inlineCode`, `taskCheckbox`, `blockquote`, `headings`, `imageEmbed`, `blockLatex`, `inlineLatex`, `thematicBreak`, `cursorFollowsSpanInk` — was captured once in `makeCoordinator` and never refreshed, so an embedder flipping between two configurations (a light/dark palette toggle, a heading-metric change, a link-ink update) kept whatever those fields were at first mount: the styler kept reading them off a stale snapshot, and each `[StyledRange]` rebuild painted the old colors and metrics back over the fresh storage. The reconcile in `updateNSView` compares the pure-style fields via an internal `styleSignature`, copies them across when they differ, and flips `didInitialFormatting` off so the rebuild path below runs and the new palette / metrics reach text storage. The fingerprint-gated paths above stay as they were — services and grammar changes still restyle through their own branches — and a configuration whose style fields are unchanged pays only a struct compare. Value-typed configuration sub-structs (`MarkdownEditorTheme`, `MarkerStyle`, `HeadingStyle`, `LinkStyle`, `ParagraphStyle`, and the rest) now conform to `Equatable` so the signature compare is a synthesized member-by-member check. `InlineLatexStyle` has a hand-written `==` because its stored `Void` placeholder can't be synthesized against. `Tests/MarkdownEngineTests/ConfigurationStyleSyncTests.swift` pins the three pieces the fix relies on: the signature flips on every pure-style field and stays put for grammar/service/lifecycle fields, `adoptStyleFields` copies exactly the style fields and leaves the rest alone, and a rebuild after swapping the theme paints body text with the new color rather than the one captured at first mount. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LNvrf6TPFQ571njp1G98wt
paulscan
marked this pull request as ready for review
August 31, 2026 00:38
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
updateNSViewcopies only a fewMarkdownEditorConfigurationfields into the coordinator. It syncsheightBehavior,rawSourceMode,lists, and it syncsservices,extensions, anddirectiveswhen a fingerprint changes. Every other field stays at whatever valuemakeCoordinatorcaptured on first mount. That includestheme,paragraph,link,markers,codeBlock,inlineCode,taskCheckbox,blockquote,headings,imageEmbed,blockLatex,inlineLatex,thematicBreak, andcursorFollowsSpanInk.An embedder that swaps configurations at runtime sees nothing change on screen. A palette change from light to dark, a change to heading metrics, or a new link color never reaches the styler. Each rebuild paints the original values back on top of the fresh storage.
What's fixed
updateNSViewcompares these fields with an internalstyleSignature. When any of them differ, it copies them across and clearsdidInitialFormattingso the rebuild path further down runs and the new values reach text storage. The existing fingerprint checks for services, extensions, and directives keep their behavior. A configuration whose style fields did not change pays only a struct compare.The style sub-structs (
MarkdownEditorTheme,MarkerStyle,HeadingStyle,LinkStyle,ParagraphStyle, and the rest) now conform toEquatable, so the signature compare is a synthesized member check.InlineLatexStylehas a hand-written==because its storedVoidplaceholder cannot be synthesized.Tests
Tests/MarkdownEngineTests/ConfigurationStyleSyncTests.swiftcovers:same for grammar, service, and lifecycle fields.
adoptStyleFieldscopies exactly the style fields and leaves therest alone.
color instead of the one captured on first mount.
swift buildandswift testare green.