Skip to content

markdown_preview: Support anchor link for headings#53184

Merged
smitbarmase merged 17 commits intozed-industries:mainfrom
dongdong867:feat/support-heading-links-in-markdown
Apr 9, 2026
Merged

markdown_preview: Support anchor link for headings#53184
smitbarmase merged 17 commits intozed-industries:mainfrom
dongdong867:feat/support-heading-links-in-markdown

Conversation

@dongdong867
Copy link
Copy Markdown
Contributor

@dongdong867 dongdong867 commented Apr 5, 2026

What does this PR did

  • Generate GitHub-flavored heading slugs for markdown headings
  • Handle [label](#heading) same-document anchor links that scroll the preview and editor to the target heading
  • Handle [label](./file.md#heading) cross-file anchor links that open the file, scroll the preview, and move the editor cursor to the heading
markdown_heading_linking.mov

What to test

  • Create a markdown file with [Go to section](#section-name) links, verify clicking scrolls preview and editor
  • Create two markdown files with cross-file links like [See other](./other.md#heading), verify file opens and preview scrolls to heading
  • Verify duplicate headings produce correct slugs (heading, heading-1)
  • Verify external URLs (https://...) are unaffected

Self-Review Checklist:

  • I've reviewed my own diff for quality, security, and reliability
  • Unsafe blocks (if any) have justifying comments
  • The content is consistent with the UI/UX checklist
  • Tests cover the new/changed behavior
  • Performance impact has been considered and is acceptable

Closes #18699

Release Notes:

  • Added support for anchor links for headings in Markdown Preview.

@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label Apr 5, 2026
@zed-community-bot zed-community-bot Bot added the guild Pull requests by someone in Zed Guild. NOTE: the label application is automated via github actions label Apr 5, 2026
@zed-codeowner-coordinator zed-codeowner-coordinator Bot requested review from a team, nathansobo and osiewicz and removed request for a team April 5, 2026 07:12
@zelenenka zelenenka assigned smitbarmase and unassigned osiewicz Apr 7, 2026
@zelenenka zelenenka requested review from smitbarmase and removed request for nathansobo and osiewicz April 7, 2026 08:54
Copy link
Copy Markdown
Member

@smitbarmase smitbarmase left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I added a few suggestions.

Comment thread crates/markdown/src/markdown.rs Outdated
Comment thread crates/markdown/src/markdown.rs Outdated
Comment thread crates/markdown/src/markdown.rs Outdated
Comment thread crates/markdown/src/markdown.rs Outdated
Comment thread crates/markdown/src/markdown.rs Outdated
Move generate_heading_slug(), slug deduplication, and heading slug
storage from MarkdownElementBuilder (render-time) to the parser
(parse-time). Slugs are now stored as HashMap<SharedString, usize>
on ParsedMarkdownData for O(1) lookup instead of Vec with O(N) scan.
When clicking a cross-file anchor link like [text](./file.md#heading),
the editor cursor now moves to the heading position in addition to
the preview scrolling. Uses a pending slug that resolves once the
target file's parse completes.
Keep both pending_heading_scroll (ours) and search_highlights (upstream).
@smitbarmase
Copy link
Copy Markdown
Member

Thanks, taking a look.

Copy link
Copy Markdown
Member

@smitbarmase smitbarmase left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I made a few fixes on top of your commits before merging:

Have you tested it? I don't think the cross-file anchor scroll (./file.md#heading) was ever working. It was trying to scroll the current preview while opening a target editor, so the heading would never resolve. There was a bunch of dead code around this that just added complexity, so I cleaned it up. We can introduce cross-file scroll later.

I also removed the scroll logic from render. We should not handle state mutations there, it's unreliable and wrong. Render should purely be used for rendering. I moved it to a window.defer call in handle_url_click instead, which is a more deterministic way to handle it.

For separation of concern, I removed the # fragment handling from MarkdownElement. Any URL can have a # in it, so stripping it and treating it as an anchor at the shared markdown level is a bug. I fixed that handling and moved into markdown preview itself.

We now also do parsing for heading slug only for markdown preview.

Thanks again for working on this!

@smitbarmase smitbarmase merged commit b150663 into zed-industries:main Apr 9, 2026
31 checks passed
@dongdong867 dongdong867 deleted the feat/support-heading-links-in-markdown branch April 9, 2026 16:20
AzureZee added a commit to AzureZee/gpuix that referenced this pull request Apr 10, 2026
AzureZee added a commit to AzureZee/gpuix that referenced this pull request Apr 10, 2026
piper-of-dawn pushed a commit to piper-of-dawn/zed that referenced this pull request Apr 25, 2026
)

## What does this PR did

- Generate [GitHub-flavored heading
slugs](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#section-links)
for markdown headings
- Handle `[label](#heading)` same-document anchor links that scroll the
preview and editor to the target heading
- Handle `[label](./file.md#heading)` cross-file anchor links that open
the file, scroll the preview, and move the editor cursor to the heading


https://github.com/user-attachments/assets/ecc468bf-bed0-4543-a988-703025a61bf8

## What to test

- [ ] Create a markdown file with `[Go to section](#section-name)`
links, verify clicking scrolls preview and editor
- [ ] Create two markdown files with cross-file links like `[See
other](./other.md#heading)`, verify file opens and preview scrolls to
heading
- [ ] Verify duplicate headings produce correct slugs (`heading`,
`heading-1`)
- [ ] Verify external URLs (`https://...`) are unaffected

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable

Closes zed-industries#18699

Release Notes:

- Added support for anchor links for headings in Markdown Preview.

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
@mendeza
Copy link
Copy Markdown

mendeza commented Apr 27, 2026

Thanks @dongdong867

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed The user has signed the Contributor License Agreement guild Pull requests by someone in Zed Guild. NOTE: the label application is automated via github actions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Markdown Preview clickable links to headings (ToC links, for example)

6 participants