Add lazy-loaded syntax highlighting with terminal-style code blocks - #169
Merged
Conversation
Highlight.js core and per-language grammars load on demand from the CDN only when a tagged fence appears, so unused languages ship no JS. Highlighting rewrites happen synchronously and re-anchor comment highlights afterward, keeping inline review pinning intact. Dark mode gets a near-black code background with a One Dark-inspired token palette, Hack as the leading monospace font, and a terminal-style sticky header showing the language on tagged fences only. Amp-Thread-ID: https://ampcode.com/threads/T-019fd3fa-05f6-7588-b621-3086d45b334a Co-authored-by: Amp <amp@ampcode.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds client-side, lazy-loaded syntax highlighting for fenced code blocks in plan Markdown while preserving comment-anchor behavior after DOM rewrites (highlighting + Mermaid). This fits the CoPlan “native-feel, secretly HTML” UI goal by improving readability without bundling large JS payloads up front.
Changes:
- Wrap rendered Markdown with a new
coplan--syntax-highlightStimulus controller that loads highlight.js core + per-language grammars on demand from jsDelivr and dispatches a “settled” event for re-anchoring comment highlights. - Unify post-transform re-anchoring by replacing
handleMermaidSettledwithhandleContentSettledand wiring both Mermaid and highlighting “settled” events to it. - Update styling and docs: terminal-style language header on tagged fences, Hack as the primary monospace font, and expanded agent instructions + seed content to exercise multiple language fences.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| spec/helpers/markdown_helper_spec.rb | Updates expectation to include both Mermaid + syntax-highlighting controllers on rendered Markdown wrapper. |
| engine/app/views/layouts/coplan/application.html.erb | Adds jsDelivr preconnect to support external font/grammar/Mermaid loads. |
| engine/app/views/coplan/plans/show.html.erb | Wires both Mermaid and highlighting “settled” events to the updated text-selection handler. |
| engine/app/views/coplan/agent_instructions/show.text.erb | Instructs agents to tag fenced code blocks using highlight.js canonical language names. |
| engine/app/javascript/controllers/coplan/text_selection_controller.js | Renames/expands the post-transform handler to cover Mermaid + syntax highlighting DOM rewrites. |
| engine/app/javascript/controllers/coplan/syntax_highlight_controller.js | New Stimulus controller: lazy-load highlight.js + grammars and rewrite code blocks, then dispatch a re-anchor event. |
| engine/app/helpers/coplan/markdown_helper.rb | Bumps markdown render cache version and adds syntax-highlighting controller to the rendered wrapper. |
| engine/app/assets/stylesheets/coplan/application.css | Adds Hack font-face, code-block theming variables, terminal-style language header, and highlight.js token color mapping. |
| db/seeds/development.rb | Adds a development seed fixture that exercises multiple fenced languages (Ruby/TS/SQL/Bash/diff/Mermaid + untagged). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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.
Why
Fenced code blocks in plans rendered as flat monochrome text. Plans are dense with service code, schemas, and rollout commands — they deserve real highlighting, without shipping a pile of JS for languages nobody uses or breaking inline comment anchoring.
What
syntax_highlightStimulus controller: highlight.js core + per-language grammars lazy-loaded from jsDelivr only when a tagged fence actually appears on the page; unknown languages stay plain::beforeso DOM/text is untouched — untagged fences and Mermaid get noneRisk Assessment
Low — rendering-only changes scoped to the markdown view layer; highlighting failures degrade to plain code blocks. Full suite green (1318 examples, 0 failures).
Generated with Amp