markdown_preview: Refactor to use shared markdown crate#52008
Merged
smitbarmase merged 12 commits intomainfrom Mar 26, 2026
Merged
markdown_preview: Refactor to use shared markdown crate#52008smitbarmase merged 12 commits intomainfrom
smitbarmase merged 12 commits intomainfrom
Conversation
This was referenced Mar 20, 2026
mac9sb
pushed a commit
to mac9sb/zed
that referenced
this pull request
Mar 23, 2026
Merge the markdown preview refactor (PR zed-industries#52008) which replaces the custom markdown_elements/markdown_parser/markdown_renderer modules with the shared markdown crate. Port the navigation features (link click behavior settings, back/forward nav history, navigate-to-markdown-file) to work with the new MarkdownElement API.
This was referenced Mar 23, 2026
8752ef7 to
774f03a
Compare
📏 PR Size: 8278 lines changed (Size XL)Please note: this PR exceeds the 400 LOC soft limit.
|
1ab80cc to
d423928
Compare
d423928 to
6798ec4
Compare
osiewicz
approved these changes
Mar 26, 2026
|
Closes #16727 |
1 task
5 tasks
|
@smitbarmase thanks a lot, also wondering how hard it would be adding markdown preview mode search (Find) support too? |
11 tasks
cppcoffee
pushed a commit
to cppcoffee/zed
that referenced
this pull request
Apr 24, 2026
Closes zed-industries#53587 Follow-up to zed-industries#50595. [zed-industries#50595](zed-industries#50595) added display-only checkboxes when `[x]` / `[X]` / `[ ]` appears as the sole content of a markdown table cell. That PR called out interactivity as a later step — this PR delivers it. https://github.com/user-attachments/assets/c666ee4c-7e31-4450-ab33-c07c82949818 ## What this does When a consumer of `MarkdownElement` supplies an `on_checkbox_toggle` callback, table-cell checkboxes now invoke it on click with the source range of the `[x]` / `[ ]` marker and the new checked state. This mirrors the existing list-item checkbox path. For markdown preview (`markdown_preview_view.rs`) the callback is already wired to edit the source buffer, so clicking a checkbox in a previewed `.md` file now flips `[x]` to `[ ]` and back in the file, the same as it already did for list checkboxes. ## How it works `replace_pending_checkbox` previously took the cell's outer source range and always built a visualization-only checkbox. It now takes the optional toggle callback instead, and reconstructs the marker's exact source range from `pending_line.source_mappings` — pulldown-cmark emits `[x]` in a table cell as three separate `Text` events, so the per-chunk mappings are needed to recover the 3-character range to rewrite. If a callback was supplied, the checkbox attaches an `on_click` that invokes it with that range and `!checked`; otherwise it falls back to the prior visualization-only rendering. Two free helpers (`source_range_for_rendered` / `source_index_for_rendered`) were extracted so the mapping logic is unit-testable. ## Scope One file: `crates/markdown/src/markdown.rs`. No changes to `markdown_preview` — since zed-industries#52008 it renders through the shared `MarkdownElement`, so its existing `on_checkbox_toggle` wiring picks up table checkboxes for free. ## Relation to zed-industries#53587 [zed-industries#53587](zed-industries#53587) reports that markdown checkboxes in the **agent panel** can't be clicked. This PR is a necessary piece of that fix — without it, even if the agent panel wired `on_checkbox_toggle`, its table checkboxes would stay inert. It does not fully close zed-industries#53587 on its own: the agent panel's `MarkdownElement` instances in `conversation_view.rs` / `thread_view.rs` don't currently wire `on_checkbox_toggle`, and wiring it there requires deciding how clicks should mutate the in-memory agent response (no source file to edit into). That's a follow-up. ## Test plan **Unit tests** (2 new, both in `crates/markdown/src/markdown.rs`): - `test_table_checkbox_marker_source_range` — walks parser events for a table with checkboxes, replays what the builder accumulates, and asserts the reconstructed source range slices to exactly `[x]` / `[ ]` in the original markdown (including a padded-whitespace case). - `test_source_range_for_rendered_handles_split_chunks` — pins the mapping helper against the three-chunk layout pulldown-cmark produces. **Automated**: - [x] `cargo test -p markdown` — 46 tests pass (44 existing + 2 new) - [x] `cargo test -p markdown_preview` — 3 tests pass - [x] `./script/clippy -p markdown` — clean **Manual** (against a preview of a markdown file with checkbox tables): - [x] Click a checked `[x]` table cell — it becomes `[ ]` in the source and rerenders as unchecked - [x] Click an unchecked `[ ]` — becomes `[x]` - [x] Uppercase `[X]` toggles on click (replacement writes `[x]` / `[ ]`, matching the list-item behaviour) - [x] Padded-whitespace cells still target just the three marker characters - [x] Multiple checkbox columns in one table all independently clickable - [x] Alignment variants (left/center/right) behave the same - [x] Non-checkbox table text unaffected - [x] List-item checkboxes continue to work (regression) Release Notes: - Made table-cell markdown checkboxes clickable in markdown preview, matching list-item checkbox behavior Co-authored-by: Lukas Wirth <lukas@zed.dev>
piper-of-dawn
pushed a commit
to piper-of-dawn/zed
that referenced
this pull request
Apr 25, 2026
…es#52008) We now use the parser and renderer from the `markdown` crate for Markdown Preview, instead of maintaining two separate code paths. How it works: `markdown_preview_view.rs` is now a consumer of `MarkdownElement`. It acts as a thin wrapper, handling things like resolving URL clicks and image URLs, which can vary between consumers. It also handles syncing the editor selection with the active block in the preview. The APIs for this are provided by `MarkdownElement`. All the heavy lifting like parsing HTML, rendering block markers on hover, handling the active block, etc. is done by `MarkdownElement`. Everything is opt-in. For example, markdown in the Agent Panel can choose not to enable block marker rendering or HTML parsing, while Markdown Preview opts into those features. Final outcome: For Markdown Preview View: - Added: - Selection support in the preview - Stays: - Syncing between editor and preview - Autoscroll - Hover and active block markers - Checkbox toggling - Image rendering - Mermaid rendering For the `markdown` crate: - No changes for existing consumers like the Agent Panel - Consumers can now opt into: - HTML rendering - Block marker rendering - Click event handling - Custom image resolvers - Mermaid rendering Release Notes: - N/A
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.
We now use the parser and renderer from the
markdowncrate for Markdown Preview, instead of maintaining two separate code paths.How it works:
markdown_preview_view.rsis now a consumer ofMarkdownElement. It acts as a thin wrapper, handling things like resolving URL clicks and image URLs, which can vary between consumers. It also handles syncing the editor selection with the active block in the preview. The APIs for this are provided byMarkdownElement.All the heavy lifting like parsing HTML, rendering block markers on hover, handling the active block, etc. is done by
MarkdownElement. Everything is opt-in. For example, markdown in the Agent Panel can choose not to enable block marker rendering or HTML parsing, while Markdown Preview opts into those features.Final outcome:
For Markdown Preview View:
Added:
Stays:
For the
markdowncrate:Release Notes: