text_view: Fix code block highlighting after theme changes (#2622)
Closes #2618 ## Description This PR fixes Markdown code blocks keeping syntax colors from the theme that was active when the Markdown was parsed. The root cause was that `CodeBlock` captured the active `HighlightTheme` during Markdown parsing and cached only the computed syntax styles. Re-rendering the same `TextViewState` after a theme change therefore kept returning that theme-independent cache entry, even though the rest of the view used the new active theme. This change: - removes the highlight theme from the Markdown parsing and background update pipeline - resolves the current `ActiveTheme` when a code block is rendered - stores the theme alongside cached code-block styles and recomputes them when that theme changes - keeps the normal render path inexpensive with an `Arc` identity fast path, while treating separately allocated but equivalent themes as the same cache key and adopting the current `Arc` after an equivalent-value match - adds a focused syntax-color regression test and a GPUI render-level regression test The render-level test keeps the same parsed `CodeBlock` alive, changes the global theme from light to dark, redraws the window, and verifies that the existing block's highlight cache is updated without reparsing the Markdown. This preserves the existing behavior in which Markdown code blocks follow the current `ActiveTheme`. It does not introduce new per-view override semantics for the public `TextViewStyle::highlight_theme` field. ## Review Follow-up During a second review of the fix, I found an efficiency edge case in the initial cache implementation. When an equivalent `HighlightTheme` arrived in a separately allocated `Arc`, the cache correctly reused the computed syntax styles but retained the previous `Arc`. Every later render would therefore miss the pointer-identity fast path and repeat a full `HighlightTheme` value comparison. This did not affect rendered colors, but it made the steady-state render path unnecessarily expensive after an equivalent theme reload. The cache now adopts the current `Arc` when the theme values are equal, while preserving the already computed syntax styles. Subsequent renders then return to the O(1) pointer-identity check without re-highlighting. The focused regression test verifies that an equivalent replacement becomes the cached identity before testing a genuinely different theme. The new cache-identity assertion was also run against the initial implementation and failed because the cache still pointed to the previous `Arc`. It passes after the follow-up change. ## Branch Synchronization After contributor review, this branch was synchronized with `upstream/main@de5859b2` through merge commits `fcb4a97a` and `0554ed16`. The upstream changes touched only `crates/ui/src/input/state.rs` and `crates/ui/src/input/element.rs`, did not overlap this PR, and merged without conflict. The proposed diff relative to the current base remains limited to the three text files listed in this PR, and the relevant local validation was rerun after synchronization. ## Screenshot Both screenshots show the same persistent `TextViewState` after switching the global theme from light to dark. The Markdown source is unchanged and is not reparsed. They compare the buggy and fixed builds; both screenshots are taken in the final dark-theme state. Before the fix, the view background changed to dark, but the code block kept syntax styles cached under the light theme, producing stale and low-contrast token colors. After the fix, the existing code block detects the active theme change during rendering and refreshes its syntax styles with the dark highlighting palette. | Before | After | | ------ | ----- | | <img width="1360" height="816" alt="before-active" src="https://github.com/user-attachments/assets/e4ee16ec-d051-4ca2-8567-ae2c2ac91183" /> | <img width="1360" height="816" alt="after-active" src="https://github.com/user-attachments/assets/5dec0f5b-9904-4e19-a6ae-b4cf2e052df8" /> | ## Break Changes None. ## How to Test The regression test was first run against the old cache behavior and failed because the dark-theme render returned the light-theme number color. It passes after this change. Focused regression and render-level tests: ```bash cargo test --locked --offline -p gpui-component \ --features tree-sitter-languages theme -- --nocapture --test-threads=1 ``` Full component and workspace tests: ```bash cargo test --locked --offline -p gpui-component \ --features tree-sitter-languages -- --test-threads=1 cargo test --locked --offline -p gpui-component \ --no-default-features -- --test-threads=1 cargo test --locked --offline --all -- --test-threads=1 ``` Lint and cross-target checks: ```bash cargo clippy --locked --offline -- --deny warnings cargo clippy --locked --offline -p gpui-component --tests \ --features tree-sitter-languages -- --deny warnings cargo check --locked --offline -p gpui-component --no-default-features cargo check --locked --offline --target wasm32-unknown-unknown \ -p gpui-component --no-default-features rustfmt --edition 2024 --check \ crates/ui/src/text/node.rs \ crates/ui/src/text/format/markdown.rs \ crates/ui/src/text/state.rs git diff --check ``` Results: - `gpui-component` with tree-sitter languages: 358 passed - `gpui-component` without default features: 340 passed - full workspace tests: passed - both Clippy invocations with warnings denied: passed - native and WASM no-default checks: passed - GitHub CI on macOS, Linux, and Windows for the synchronized head: passed Manual visual verification was performed on Linux with a dedicated local story reproduction. It changed only `Theme::change(...)` after the initial parse and produced the before/after screenshots above. ## AI Assistance Codex assisted with root-cause analysis, implementation, regression tests, validation, screenshots, and drafting this PR description. The automated and manual checks listed above were run locally. The contributor reviewed the final diff, including follow-up commit `bf1483f3`, and confirmed that the AI-assisted changes are accurate. ## Checklist - [x] I have read the [CONTRIBUTING](../CONTRIBUTING.md) document and followed the guidelines. - [x] Reviewed the changes in this PR and confirmed AI generated code (If any) is accurate. - [x] Passed `cargo run` for story tests related to the changes. A dedicated local reproduction was run before and after the fix. - [x] Tested macOS, Windows and Linux platforms performance (if the change is platform-specific). Not platform-specific; the synchronized head passed CI on all three platforms, the visual behavior was manually verified on Linux, and the crate was compiled for WASM.
L
luren committed
be3c8413766cafc736a0c1c80306ff0f293e04f3
Parent: 98af891
Committed by GitHub <noreply@github.com>
on 7/30/2026, 10:27:37 AM