Commit Graph
232 Commits
Author SHA1 Message Date
María CraigandMrSubidubi 0134fcd23a markdown: Round inline code backgrounds across all markdown surfaces (#63272)
# Objective

Inline code renders as a rounded chip in the Markdown preview (#63118)
but as a square, full-line-height background everywhere else — the agent
panel, editor hover popovers, notifications, and other markdown
surfaces.

## Solution

Inline code with a background color now always renders as a chip with a
4 px corner radius. The radius is fixed at the paint site rather than
exposed through `MarkdownStyle`, so every markdown surface uses the same
rendering without carrying configuration through the element builder and
rendered lines.

Chip backgrounds and text styling remain configurable. Only the corner
radius is fixed, removing the alternative square rendering path and
preventing surfaces from becoming inconsistent.

## Testing

- Updated `test_inline_code_chips_cover_exactly_the_code_span_glyphs` to
cover the fixed chip behavior.
- `cargo test -p markdown
test_inline_code_chips_cover_exactly_the_code_span_glyphs`
- `./script/clippy -p markdown`

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments (there are none)
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- Improved inline code to render with rounded backgrounds across all
markdown surfaces, matching the Markdown preview.

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
2026-08-28 17:13:46 +00:00
Daniel ShneyderandChristopher Biscardi adf4fbb233 markdown: Improve Markdown preview typography and inline code rendering (#63118)
# Objective

The Markdown preview has been collecting complaints about how it reads.
Body text is dimmed and shrunk, headings carry no weight, and paragraphs
sit at a 1.3 line height, so a long document turns into a wall. This
came up in the feedback on #58465, in #58364, and in the discussion at
#43384. This PR changes the defaults so the preview reads like GitHub's
rendering. It adds no settings. The feedback on #60402 and #59544 was
that a good default beats more knobs, and I agree.

## Solution

What changed in the preview:

- Body text renders at the configured `markdown_preview_font_size`.
Before, it rendered at 92% of that value in a blended muted color. It is
now full contrast at 1:1.
- Line height is 1.5 across body text, lists, and blockquotes.
Paragraphs used to override the base line height with `rems(1.3)`.
- Paragraphs, lists, blockquotes, rules, and code blocks are spaced 16px
apart.
- Headings are semibold, from h1 at 1.75rem down to h6 at 0.85rem. Only
h1 and h2 keep a bottom border, same as GitHub. Dropping the h3 border
addresses the comment on #58465 that a line under every heading is too
much.
- Inline code backgrounds are rounded chips instead of square text-run
backgrounds. The chips are tracked in rendered indices so they cover the
code glyphs exactly, and they extend only 1px past the glyphs so the gap
between words stays at full width.
- Code blocks get 12px padding and 6px corners. Links lose their
background tint. Blockquote text is muted. Table cells get 10px
horizontal and 4px vertical padding.

The first commit makes block spacing, table cell padding, and inline
code backgrounds style-driven, with defaults that keep the agent panel,
tooltips, and editor rendering exactly as they are today. The second
commit sets the preview's values. I split it this way so the mechanism
can be reviewed on its own, and so the chip painting can move to its own
PR if you would rather take it separately.

## Testing

- Added a test in the `markdown` crate that checks the inline code chips
cover exactly the code span glyphs, and that no chips are produced when
the corner radius is zero.
- Ran `cargo test -p markdown` and `cargo test -p markdown_preview`
locally, plus `./script/clippy`.
- Smoke-tested the preview on Linux (Arch) against a long document with
headings, lists, blockquotes, tables, and inline code. The screenshots
below are from that run.
- To try it, open any Markdown file and run `markdown: open preview`. It
is also worth glancing at the agent panel and a hover tooltip to confirm
those still look the same, since they share the renderer but keep the
old defaults.
- I could not test on macOS or Windows. Nothing here is
platform-specific, but the chip inset is a fraction of the line height,
so it would be good to have a second pair of eyes on a different font
stack.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments (there are none)
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

| Before | After |
|--------|-------|
| <img width="1420" height="1782" alt="zed_before"
src="https://github.com/user-attachments/assets/84382a52-99d1-43ba-9ee6-d6c3c6cf0cfa"
/> | <img width="1346" height="1800" alt="zed_afterv2"
src="https://github.com/user-attachments/assets/c73c076f-9ba4-4b7d-92dc-20855af595f5"
/> |

Release Notes:

- Improved Markdown preview styling with better typography, spacing, and
rounded inline code backgrounds.

---------

Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2026-08-25 05:42:06 +00:00
Kirill Bulatov 7dcda48fdf markdown: Restore fallback language highlighting for untagged code blocks (#63023)
Restores fallback highlights lost in
https://github.com/zed-industries/zed/pull/28217

Release Notes:

- N/A
2026-08-21 16:00:50 +00:00
Warya Wayneandzed-zippy[bot] 562346c380 Markdown preview visible find matches (#62280)
# Objective

Search in the markdown preview matches against the raw markdown source,
including text that never renders. Searching a README for a common word
reports more matches than are visible: the count says 2 when only 1 is
on screen, and navigating to the phantom match appears to do nothing.
Badge-heavy READMEs make this worse, since every badge URL contributes
searchable words (`github`, `build`, `main`, `svg`) that the reader
never sees.

## Solution

Track which source ranges produce no on-screen text and filter matches
against them:

- Link destinations (`[label](url)`, where only `label` renders)
- Images, including alt text and destination, since an image renders as
an image
- Link reference definitions, which `pulldown-cmark` consumes and never
emits events for

Ranges are returned sorted and disjoint so the preview can binary search
them. Search results also derive from the parsed markdown, which lags
the source during a background parse, so `MatchesInvalidated` now fires
once the parse lands.

## Testing

`cargo test -p markdown -p markdown_preview`. Eight new tests cover link
destinations, reference definitions, standalone images, linked images,
images between link text, parse-in-flight, and match-order independence.

Note:
`follow_preview_serialized_path_updates_when_followed_editor_changes`
fails on `main` independently of this change (sqlite `FOREIGN KEY
constraint failed` in `save_preview`, passes in isolation).

## 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 adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

Markdown preview search on the same document, installed Zed versus this
branch:

Before:
<img width="1090" height="1235"
alt="warya_wayne_zed_fix_miscounted_search_in_Markdown_preview_current"
src="https://github.com/user-attachments/assets/d2e59e12-b43e-4fea-ac9c-12631845653b"
/>

After:
<img width="1090" height="1235"
alt="warya_wayne_zed_fix_miscounted_search_in_Markdown_preview_new"
src="https://github.com/user-attachments/assets/9f681fa4-f141-41c9-af9f-675cf3a2f0bd"
/>

---

Release Notes:

- Fixed markdown preview search matching text that isn't rendered, such
as link and image destinations

---------

Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-08-19 13:07:52 +00:00
Andrew Mitchell 10087cd21b markdown: Respect buffer_line_height in code blocks (#62785)
# Objective

- Fixes #62528
- Code blocks in rendered markdown ignored the `buffer_line_height`
setting. With the line height left unset, they fell back to the ambient
default of ~1.618, so the same code was spaced more loosely in markdown
than it was in an editor or the terminal.
- The extra leading is most obvious with box-drawing characters — the
ASCII-art box from the issue renders as disconnected stripes instead of
continuous vertical rules.
- The issue also notes that the preview font "seems bigger". That part
is working as intended and is not changed here: preview code blocks size
from `markdown_preview_font_size`, which falls back to `ui_font_size`
rather than `buffer_font_size` so that temporary UI zoom doesn't resize
the preview. Users who want it to match the editor can set
`markdown_preview_font_size` explicitly.

## Solution

- Set `line_height` on the code block text style in
`MarkdownStyle::themed_with_overrides`, derived from
`theme_settings.buffer_line_height`.
- The value is `relative(...)` rather than absolute pixels so it tracks
the code font size, which some callers override after building the style
(e.g. the agent panel sets `code_block.text.font_size` downstream). An
absolute value computed from the theme's font size would be wrong for
those callers.
- Scope: this applies to every `MarkdownFont` variant — preview, agent
panel, and editor — since the code block style is shared and
`with_preview_overrides` doesn't touch line height.
- Prose leading is deliberately unchanged. It stays a per-element
typographic choice, independent of the buffer setting.

## Testing

- `cargo test -p markdown` — 145 passed, 0 failed.
- Added
`test_code_block_line_height_follows_buffer_line_height_setting`:
renders a paragraph plus a fenced code block at `buffer_line_height` 1.2
and 1.8, asserts the code block's rendered line height tracks the
setting, and asserts prose leading does *not* move.
- Added `test_code_block_line_height_tracks_overridden_code_font_size`:
overrides `code_block.text.font_size` after building the style and
asserts the line height follows the override. This is what pins the
`relative` vs. absolute choice.
- To reproduce manually, set `"buffer_line_height": { "custom": 1.2 }`
and open a markdown preview containing the ASCII-art box from #62528.
The vertical rules should join into continuous lines, matching how the
same block renders in an editor, and should visibly separate again at
`"comfortable"`.

## Self-Review Checklist:

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

## Showcase

Before
<img width="927" height="912" alt="Screenshot 2026-08-17 at 5 06 41 PM"
src="https://github.com/user-attachments/assets/be6213bf-f3aa-42fb-8784-1985b5379d74"
/>

After
<img width="915" height="994" alt="Screenshot 2026-08-17 at 5 06 54 PM"
src="https://github.com/user-attachments/assets/c9c7f395-50cb-437b-a423-2030da88e4f4"
/>



---

Release Notes:

- Fixed markdown code blocks not respecting the `buffer_line_height`
setting
2026-08-18 16:33:44 +00:00
Qiu shaoanddino 5e4c46ebe1 Fix markdown task list marker lookup (#60646)
# Objective


Fix Markdown preview task list checkboxes not rendering for task items
in
  loose or nested lists.

For example, this Markdown should render all three items with
checkboxes:

  ```markdown
  - [ ] test
  - [x] test
    - [x] test
```
  Before this change, the items after blank lines could fall back to ordinary
  list bullets instead of task checkboxes.

## Solution

Update Markdown list item rendering to detect task list markers in both tight
  and loose list event shapes emitted by pulldown-cmark.

  The previous renderer only handled:

  Item -> TaskListMarker

  Loose lists can emit:

  Item -> Paragraph -> TaskListMarker

  This PR adds a small helper to find task markers for both forms, then reuses
  the existing checkbox rendering and toggle behavior.

## Testing

  Tested on macOS with:

  rustup run 1.95.0 cargo test -p markdown
  test_task_marker_lookup_handles_loose_and_nested_lists
  rustup run 1.95.0 cargo test -p markdown test_table_checkbox

  The first test covers loose and nested task list items. The table checkbox
  tests verify that [x] and [ ] inside tables still remain text and are not
  treated as task list checkboxes.

## Self-Review Checklist:

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

## Showcase
before
<img width="927" height="275" alt="image" src="https://github.com/user-attachments/assets/a36f0b9f-8759-4593-99a9-8a256396e89e" />

after
<img width="963" height="322" alt="Snipaste_2026-07-09_12-27-05" src="https://github.com/user-attachments/assets/972fa7a7-274a-4b0a-a13c-c7e1aec27622" />



---

Release Notes:

- Fixed Markdown Preview for loose list item markers

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
2026-08-18 09:59:35 +00:00
Kirill BulatovandMrSubidubi aad8ae4b34 Fix overflowing highlights in the markdown blocks (#62714)
Before:
<img width="1728" height="1084" alt="before"
src="https://github.com/user-attachments/assets/68a33e27-7ee7-42cc-9f1b-53e541ef8d2f"
/>


After:
<img width="1728" height="1084" alt="after"
src="https://github.com/user-attachments/assets/b51df462-6457-44fd-ba83-f13c6129125d"
/>


Release Notes:

- Fixed overflowing highlights in the markdown blocks

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
2026-08-17 19:07:31 +00:00
Tim Vermeulen 63d4e29a12 markdown: Auto-size table columns to content width (#61773)
Closes https://github.com/zed-industries/zed/issues/62498
Fixes #50044:

| before | after |
| --- | --- |
| <img width="1260" height="1449" alt="before"
src="https://github.com/user-attachments/assets/84dfca5a-66da-4179-90f3-8408255346d4"
/> | <img width="1260" height="1449" alt="after"
src="https://github.com/user-attachments/assets/d63f9128-1397-4f1a-87a5-4e681e9b65f0"
/> |

~Submitted as a draft PR because it relies on
https://github.com/DioxusLabs/taffy/pull/1001. I temporarily pinned our
`taffy` dependency to that particular branch to make the new tests
pass.~ That fix got released!

This fix is similar to the original fix in #50839 which got partially
reverted by #52864 due to a regression, and
`test_table_never_renders_past_its_available_width` ensures this doesn't
regress again.

## Self-Review Checklist:

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

---

Release Notes:

- Markdown table columns are now sized based on their content.
2026-08-12 17:33:28 +00:00
Smit Barmase 2d43977f08 markdown_preview: Fix images not rendering over remote (#62490)
Closes #39860

This PR resolves relative image paths from the Markdown source file's
project path and load images through the project image store. SVG images
over remote connections remain unsupported and are left for a follow-up.

Release Notes:

- Fixed images not rendering in Markdown Preview over remote.
2026-08-12 10:44:58 +00:00
Kim SeogyuandSmit Barmase b8649f3464 markdown: Support triple-tilde Mermaid fences (#62257)
# Objective

Zed's Markdown parser accepts tilde-fenced code blocks, but Mermaid
extraction only strips backtick fences. As a result, a block like this
is parsed as Mermaid while the fence itself is still passed to the
renderer:

```markdown
~~~mermaid
graph TD;
~~~
```

## Solution

Teach the Markdown code-block helpers to recognize triple-tilde fences
alongside triple-backtick fences.

The change stays in the existing parsing path, so Mermaid rendering does
not need a separate special case. A regression test covers extraction
from a tilde-fenced Mermaid block.

## Testing

- `cargo fmt --all -- --check`
- `cargo test -p markdown` (138 tests)
- `./script/clippy -p markdown`
- `cargo build -p zed`
- Opened a `~~~mermaid` block in the built Zed Dev app on macOS and
verified that Markdown Preview renders the diagram

## Self-Review Checklist:

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

---

Release Notes:

- Fixed Mermaid diagrams in Markdown previews when they use triple-tilde
fences.

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-08-10 13:04:37 +00:00
JC DiamanteandMrSubidubi c5abddc286 markdown: Add horizontal scrollbars to wide tables (#61745)
## Objective

Add functional horizontal scrollbars to wide Markdown tables, matching
the existing code-block scrollbar pattern.

Fixes #61437

PR was talked about in https://github.com/zed-industries/zed/pull/61698

## Implementation:
- Added a `BTreeMap<usize, ScrollHandle>` to `Markdown` for table scroll
handles, keyed by source-range start.
- During `MarkdownElement` layout, each table container is connected to
a `Scrollbars` widget configured for the horizontal axis, using a stable
ID derived from `("markdown-table-scrollbar", range.start)`.
- The inner table div uses `overflow_x_scroll()` + `track_scroll()` with
`restrict_scroll_to_axis`.
- Handles for removed tables are discarded after re-rendering.
- No public API, setting, schema, or migration changes required.

## Recording


https://github.com/user-attachments/assets/cd0f635b-a485-4de8-9059-40a05f256fb1

## Release Notes:

- Improved navigation of wide Markdown tables with horizontal
scrollbars.

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
2026-08-06 15:18:02 +00:00
Cameron Mcloughlin 2c60a17676 markdown: Mermaid zoom (#62115)
Enables zooming of mermaid diagrams by supporting horizontal scroll

---

Release Notes:

- improved: Mermaid diagrams can now be zoomed and horizontally
scrolled, in both the markdown preview and the agent panel
2026-08-05 16:54:27 +00:00
Finn Eitreim d73ad3de55 gpui: Give divs (the option for) a better scrolling experience (#61797)
# Objective

Closes #56127

Right now there is an issue where in certain contexts, specifically GPUI
div elements, horizontal scrolling w/ a trackpad works very poorly, even
when trying to scroll sideways, vertical scrolling will happen.

This happens with both a trackpad and scrollwheel. The showcase video
also shows the broken behavior.

## Solution

The way that scrolling works in the editor is really nice, scrolls are
locked to the axis they started on but with enough force can change
axis. so by taking the ongoing scroll handler from the editor and moving
it up into GPUI, we can get that same functionality for GPUI.

I somewhat "take over" the functionality of the existing
`restrict_scroll_to_axis` property, because it seems like its purpose
was basically trying to fix this problem already, just unsuccessfully.
The alternative, and would make things overall nicer to look at, would
be to tie this to `allow_concurrent_scroll`, but the effect radius tied
to that option is way bigger, so im holding off on that atleast right
now.

## Testing

Theres a good number of scroll related tests generally, so I don't think
i've perturbed any common existing behaviors. attach the functionality
to `restrict_scroll_to_axis` really limits the surface. There are also
some new tests for the ongoing_scroll behaviors.
Tested on my mac w/ both trackpad and mouse. 

## Self-Review Checklist:

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

## Showcase

Video show casing all the behaviors:
broken w/ trackpad
working w/ trackpad
broken w/ scroll
working w/ scroll



https://github.com/user-attachments/assets/1935cd2d-a255-4a77-81d5-daa9f72470a6


---

Release Notes:

- markdown_preview: Fix horizontal scrolling inside certain elements
2026-07-30 16:30:13 +00:00
Smit Barmase 44f82ff260 markdown_preview: Open Markdown links in preview and scroll to linked headings and positions (#61784)
Closes #60985

Clicking a link to a Markdown file from a Markdown preview now opens the
target in a preview instead of the raw editor buffer. `alt`-click opens
the raw source editor instead.

- If there exists existing preview of that file it is reused. A link
back to the file being previewed navigates in place.
- `file.md#heading-slug` scrolls the preview to the linked heading.
- `file.md:42:5`, `file.md#L42` and `file.md#L42C5` open the preview
scrolled to that position with the cursor placed there. Non-Markdown
targets keep the existing behavior from #60864 (raw editor at the
position).

Added tests covering these and more cases.

Release Notes:

- Improved Markdown preview links: links to Markdown files now open in a
preview (scrolled to the linked heading or position) instead of the raw
file, and `alt`-click opens the raw source instead.
- Fixed GitHub-style `#L<line>C<column>` link fragments not placing the
cursor at the linked position.
2026-07-28 13:56:46 +00:00
JC Diamante 04b5738f25 markdown: Add horizontal scroll for wide tables in hover popover (#61698)
## Objective

- Fixes #61437 — Wide tables in doc comments get clipped instead of
being scrollable

## Solution

- Changed `.overflow_hidden()` to `.overflow_x_scroll()` on the table
rendering div in `crates/markdown/src/markdown.rs`
- When `table_columns_min_size` is true (as in the hover popover style),
grid columns use min-content sizing. Wide column content exceeds the
table width, and `.overflow_hidden()` clips it. `.overflow_x_scroll()`
makes the overflow scrollable.
- This same pattern is already used for code blocks in the same file
(line 2367).

## Testing

- Change is a single property affecting element rendering/layout
- Visual verification needed: hover a doc comment with a wide markdown
table, verify horizontal scrollbar appears and content is accessible
- Existing markdown tests should pass unchanged

## Recording


https://github.com/user-attachments/assets/d07aa6eb-ac9d-453f-9e51-453a33302cbd

---

Release Notes:

- Fixed wide tables in documentation hover popovers being clipped
instead of horizontally scrollable
2026-07-28 12:54:23 +00:00
Finn Evers 380f9abbeb agent_ui: Use buffer font in more places (#61738)
Release Notes:

- N/A
2026-07-27 18:53:39 +00:00
Lori HoldenandFinn Evers b38f75dcce Add agent panel font family settings (#59629)
Objective:

Allow users to configure the font families used by agent panel content
separately from the main UI and buffer fonts.

Solution:

- Add `agent_ui_font_family` for agent responses in the agent panel.
- Add `agent_buffer_font_family` for the agent panel message editor and
user messages.
- Keep context menus on the primary UI font family.
- Document the new settings and expose them in the settings UI.

Testing:

- Ran `cargo fmt`.
- Ran `cargo check -p settings_content -p theme_settings -p markdown -p
agent_ui -p settings_ui -p ui`.
- Ran `git diff --check`.
- Manually tested the agent panel font behavior in a dev build.

Release Notes:

- Added settings for configuring agent panel UI and buffer font
families.

Co-authored-by: Finn Evers <finn@zed.dev>
2026-07-27 10:34:57 +00:00
Atharva Ajmera d749d04034 Fix squashed Mermaid diagrams in markdown preview (#61260)
## Summary

Wide Mermaid diagrams in Markdown Preview were forced through
`max_w_full()`, so both width and height shrank to the pane and text
became unreadable/blurry. There was no horizontal pan.

Markdown Preview already sets `code_block_overflow_x_scroll: true` for
fenced code blocks. Mermaid ignored that flag.

This change gates layout on that style flag:

- **Preview** (`code_block_overflow_x_scroll`): keep the raster at
intrinsic size and enable `overflow_x_scroll` (with
`restrict_scroll_to_axis`) so wide diagrams stay readable and can be
panned horizontally.
- **Compact UIs** (e.g. agent): keep previous `max_w_full()` fit-to-pane
behavior.

Fixes #61051

## Test plan

- [ ] Open a markdown file with a wide ` ```mermaid ` flowchart (e.g.
multi-column TB graph) in Markdown Preview
- [ ] Confirm diagram is not crushed to pane width; text remains legible
at default scale
- [ ] Confirm horizontal scroll/pan works on the diagram without
stealing vertical page scroll
- [ ] Confirm compact surfaces that leave `code_block_overflow_x_scroll`
off still fit diagrams to width
- [ ] Confirm mermaid scale fence info still works (` ```mermaid 150 `)
- [ ] Confirm Preview/Code tabs and copy button still work

---

Release Notes:

- Fixed wide Mermaid diagrams in Markdown Preview being squashed and
illegible
2026-07-24 00:39:01 +00:00
Finn EversandBen Brandt 25632b979b language: Refactor available_languages into its own struct (#61388)
This adds a dedicated `AvailableLanguages` struct in preparation for a
more cabable language matching based on a given language config. No
functional changes, just shuffling some code around for this round.

Also made the LanguageMatcher non-cloneable in favor of wrapping it in
an Arc, since cloning is rather expensive for this and having a
reference is sufficient in all cases right now.

Release Notes:

- N/A

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-07-23 11:22:43 +00:00
Warya Wayne 4eb6383ad8 markdown_preview: Show link destinations on hover (#60942)
# Objective

Markdown Preview does not reveal where a link will navigate before it is
opened or right clicked to copy the URL.

Show a small Firefox-style URL preview in the bottom-left corner when
hovering text links or linked images.

## Solution

- Added URL hover reporting to the Markdown renderer, including hit
detection for linked images that are outside the text layout.
- Used the existing `LinkPreview` component to display the hovered
destination in the bottom-left corner of the Markdown preview.
- Cleared the destination preview when the pointer leaves a link, the
preview, or the displayed Markdown changes.

## Testing

- Confirmed the project builds successfully and manually verified the
behavior on macOS.
- Hovered text links and linked images in a Markdown preview and
confirmed their destinations appear in the bottom-left corner.
- Moved the pointer away from links and outside the preview and
confirmed the destination preview disappears.
- Reviewers can test this by opening a Markdown file containing a text
link and a linked image, opening its preview, and hovering each link.

## 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 adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

See bottom left of this image for a sample of the link preview in
action.

<img width="2240" height="1258"
alt="warya_wayne_fix_markdown_render_link_preview_zed_pr"
src="https://github.com/user-attachments/assets/7659e2ae-161d-4a41-a5b4-ba5b76951e30"
/>


---

Release Notes:

- Improved Markdown previews by showing link destinations in the
bottom-left corner when hovering links.
2026-07-20 05:47:22 +00:00
Smit Barmase aad0d05803 markdown: Improve selection copying to always yield valid markdown (#60657)
Closes https://github.com/zed-industries/zed/issues/59083
Closes https://github.com/zed-industries/zed/issues/42958
Closes https://github.com/zed-industries/zed/issues/59612

This PR improve selection copy of Agent Panel and Markdown Preview such
that copied text is always valid markdown, following how VSCode handles
it. The partial selection of styled text would not copy broken syntax
like `bold**` or ```inline code` ``` like before.

Now we follow simple rule:

> Selecting any part, no matter from where, copies it as its markdown.
Except when the selection sits entirely inside a single inline code
span, in which case we copy plain text, for terminal and code use cases.

Examples:

This is **bold** text, this is *italic* text, and this is `code` all `in
one` sentence.

- selecting only bold → `**bold**`
- selecting normal text and partial bold → `is is **bo**`
- selecting a single code span completely → `code`
- selecting partial code → `od`
- selecting partial text and code → `` his is `cod` ``
- selecting multiple code spans partially → `` `ode` all `in o` ``
- selecting multiple code spans end to end → `` `code` all `in one` ``

Nested spans, like **bold with `code` inside**:

- partial text in bold → `**ld wi**`
- partial code in bold → ``**`od`**``
- full code in bold → ``**`code`**``
- the whole sentence → ``**bold with `code` inside**``

Links, like [Visit Rust's website](https://rust.org):

- partial link text → `[bsite](https://rust.org)`
- full link text → `[Visit Rust's website](https://rust.org)`

How it works:

Selection boundaries that land inside delimiter syntax (`**`, backticks,
etc.) first snap out so no delimiter is left half-selected. Then any
spans the selection cuts through get their delimiters re-added,
outermost first, so nested styling stays balanced. Only the root blocks
containing the two selection boundaries are inspected, everything in
between is copied right as is, which also keeps this cheap on large
documents.

Release Notes:

- Improved copying selected text in Agent Panel and Markdown Preview.
Partial selections of styled text now copy as well-formed markdown, and
selections within a single inline code span copy as plain text.
2026-07-09 11:05:04 +00:00
Miguel Raz Guzmán Macedo 657962ab30 Use more .array_windows::<N>() (#58877)
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

The fight against entropy continues...

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-07-08 12:10:32 +00:00
Warya WayneandSmit Barmase e2deea1d5b markdown: Make linked images clickable (#59525)
# Objective

Make images nested inside markdown links (e.g., README badges)
clickable, so they behave like normal markdown links.

Previously, linked images rendered correctly but were not interactive in
markdown previews: they did not show a pointer cursor, could not be
clicked to open their target URL, and did not expose link actions
through the context menu.

## Solution

Changed the `MarkdownElement` to detect when an `<img>` tag is inside a
`<a>` tag during rendering. When a linked image is rendered:

- The wrapper `div` gets a `cursor_pointer` style and an `on_click`
handler that opens the link URL (or delegates to the `on_url_click`
callback if set).
- The wrapper also captures right-click events to populate the context
menu with "Copy Link" via `capture_for_context_menu`.
- The `on_url_click` closure type was changed from `Box<dyn Fn>` to
`Rc<dyn Fn>` to allow cloning across multiple handlers.
- When a linked image fails to load, the fallback element's `on_click`
now calls `cx.stop_propagation()` to prevent the event from bubbling to
the parent link wrapper and opening the URL twice.

The feature is gated behind `!self.style.prevent_mouse_interaction` so
it respects existing interaction-prevention settings.

## Testing

- `cargo test -p markdown`: 95 tests passed.
- Manually verified in markdown preview that badge/image links open
correctly and right-click shows "Copy Link".
- Verified existing markdown tests continue to pass.

## Self-Review Checklist:

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

---

Release Notes:

- Fixed images inside markdown links not being clickable.


https://github.com/user-attachments/assets/df2a8d8f-b002-47f9-b139-815ee713700b

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-07-02 08:00:19 +00:00
Danilo Leal 8955d227a4 markdown_preview: Use UI font for base font size (#60212)
This PR makes the `markdown_preview_font_size` setting be based on the
UI font size instead of the buffer UI font size. I typically use a much
smaller code font than UI font, and that made reading the markdown
preview super small. I don't think this will be uncommon because the
dimensions between mono and non-mono typefaces are different...

Release Notes:

- Changed the markdown preview to fall back to the UI font size instead
of the buffer font size when `markdown_preview_font_size` is unset.
2026-07-02 05:04:24 +00:00
Kirill Bulatov 18c28c3e63 Improve context menu experience in the markdown preview (#59993)
* removes useless "no items" pop-up and does not show any menu at all if
no actions are applicable.
This required adding `pub fn maybe_menu` into the 

* adds actions to copy rendered text and markdown text: in fact,
`cmd/ctrl-c` work already but we did not expose it

Before:


https://github.com/user-attachments/assets/906f2bfd-bf19-48de-bbb5-85bb33431f60

After:


https://github.com/user-attachments/assets/2c039c4d-2d42-4689-9ac1-12e3b10119cf

Release Notes:

- Improved context menu experience in the markdown preview
2026-06-27 10:09:13 +00:00
c2ba335b29 Keep inline code pipes inside markdown table cells (#57744)
## Summary

Fixes markdown table rendering when inline code spans contain pipe
characters. Code such as `` `a|b` `` and `` `a||b` `` now stays in one
table cell instead of being split into extra columns.

## Why

Agent output and markdown previews can include regexes, shell snippets,
and other code spans with `|` characters inside tables. Before this
change, those pipes could be parsed as table delimiters even though they
were part of inline code.

## Changes

- Masks raw pipes only inside matched inline code spans before
`pulldown-cmark` parses tables.
- Restores rendered code-span text from the original source range,
including escaped table pipes.
- Avoids masking unmatched backticks, fenced code blocks, indented code
blocks, and invalid fence closers.
- Adds parser and renderer coverage for raw pipes, escaped pipes,
unmatched inline code, invalid fences, and code-span link callbacks.

Manual check: generated agent responses across multiple models render
tables containing `` `a|b` ``, `` `(a|b)` ``, and `` `a||b` `` as single
code-span cells rather than split columns.

## Screenshots / Recordings

| Before | After |
| --- | --- |
| <img width="702" height="532" alt="Before"
src="https://github.com/user-attachments/assets/f9b7606f-15d5-41bc-980c-5e26337f9be4">
| <img width="846" height="536" alt="After"
src="https://github.com/user-attachments/assets/60a7a9bf-8417-4146-ac37-0725dd8b4e3c">
|

## Self-Review Checklist

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] 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
- [x] Performance impact has been considered and is acceptable

Closes #57683

Release Notes:

- Fixed markdown table rendering for inline code spans that contain pipe
characters.

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Co-authored-by: Tom Houlé <tom@tomhoule.com>
2026-06-26 13:31:47 +00:00
David AlecrimandSmit Barmase 4306847359 markdown_preview: Add font size settings and actions (#55489)
Add support for scaling the Markdown preview's body text and headings
with `cmd-=` / `cmd--` / `cmd-0`. Previously these shortcuts only
resized code blocks because the preview's body used `ui_font_size` and
headings used a rem-based scale anchored to it, while the keybindings
only mutated `BufferFontSize`.

The preview's scroll subtree is now wrapped in
`WithRemSize(buffer_font_size)`, so `1rem` resolves to the buffer font
size inside the preview. Body text, headings
(`text_3xl`/`text_2xl`/...), and rem-based spacing all scale together.
The outer focus root and scrollbar remain at the UI font size.

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] 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
- [x] Performance impact has been considered and is acceptable

Closes #55374

Release Notes:

- Added `markdown_preview_font_size` setting and actions to scale
Markdown preview font size separately from the editor.

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-06-26 05:12:59 +00:00
mengh04 3f1d8a706a markdown: Fix example crash on Linux (#58406)
markdown: Fix example crash on Linux by enabling wayland/x11 features

   The markdown example panics with `unreachable!()` on Linux because
   `gpui_platform`'s default features are empty, and the example doesn't
   explicitly enable `wayland` or `x11`.

Release Notes:

- N/A
2026-06-25 15:46:39 +00:00
David AlecrimandSmit Barmase 46a7d5e983 markdown: Render inline <br> tags as line breaks (#54165)
## Summary
Inline `<br>` tags in markdown (e.g. `<br>`, `<br/>`, `<br />`) were
rendered as literal text instead of line breaks when images are around.
VS Code and GitHub both treat them as hard line breaks.

The fix has two layers:

**Parser (`parser.rs`):** The text-merge loop was consuming `InlineHtml`
events as empty text. `<br>` variants are now excluded from that loop
and converted to `HardBreak` events instead, matching the semantics of a
trailing two-space or backslash line break in CommonMark.

**Renderer (`markdown.rs`):** Image paragraphs use a flex row layout, so
text `\n` has no effect. `HardBreak` inside an image paragraph now
inserts a `div().w_full().h_0()` child, which forces a flex-wrap row
break. Images also get `mr_2()`/`mb_2()` margins for spacing, replacing
the previous `SoftBreak`-as-space hack. `SoftBreak` is suppressed inside
image paragraphs to avoid phantom whitespace elements disrupting the
flex layout.

## Screenshots

### Before

How Zed WAS rendering this:
<img width="629" height="601" alt="Screenshot 2026-04-17 at 07 53 26"
src="https://github.com/user-attachments/assets/cbfa6c81-83ea-467a-b73f-a2efef953bb4"
/>

### Comparison

This is how Github renders this:
<img width="1006" height="911" alt="Screenshot 2026-04-17 at 07 06 49"
src="https://github.com/user-attachments/assets/6ee286c6-026b-4a85-a931-c61cf24370ba"
/>

This is how VS Code renders this:
<img width="1511" height="947" alt="Screenshot 2026-04-17 at 07 03 36"
src="https://github.com/user-attachments/assets/1bc41c85-bb3d-48c6-9e21-cd96327c43c6"
/>

### After

This is the end result after the changes:
<img width="821" height="807" alt="Screenshot 2026-04-17 at 07 45 32"
src="https://github.com/user-attachments/assets/8882abaa-dc07-45fb-9aaa-a908712dce65"
/>

[Created this Github repo for testing
](https://github.com/davidalecrim1/zed-md-test)

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] 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
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Fixed inline `<br>` tags in markdown previews rendering as literal
text instead of line breaks

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-06-24 10:22:36 +00:00
5727cea5be sandbox: Linux domain filtering and some more cleanup (#59790)
---

Release Notes:

- N/A or Added/Fixed/Improved ...

---------

Co-authored-by: MartinYe1234 <martin@zed.dev>
Co-authored-by: Richard Feldman <oss@rtfeldman.com>
2026-06-24 01:42:52 +00:00
Dan DascalescuandBennet Bo Fenner b5f16f69e8 agent_ui: Add in-thread search bar (#57231)
This is a narrower alternative to #54816, scoped to search only the
currently-loaded thread, excluding tool output or thinking blocks (happy
to follow up on those, see next). It uses a custom bar confined to
`agent_ui` rather than `BufferSearchBar` + `SearchableItem`, avoiding
the cross-crate plumbing that #54816 reached. Open as draft pending
direction from @benbrandt on what scope/approach would be acceptable for
in-thread search.

<img width="959" height="609" alt="image"
src="https://github.com/user-attachments/assets/8971e432-61d3-46db-a6a4-2bbd355089e7"
/>


## What this PR does

Adds a search bar to the agent panel, triggered by Ctrl+F (Cmd+F on
macOS), that lets users grep the currently-loaded thread without leaving
the agent panel; not cross-thread or cross-agent.

- Searches visible content only: user messages, assistant message
chunks, and tool-call labels. Thought blocks and rendered tool-call
content (collapsed by default) are intentionally skipped so that:
  1. The visible match count matches what the user sees.
2. The search experience is consistent between tool output blocks in the
current Zed session, ans tool output blocks from past sessions, which
are not rendered - see issue #57230
- Highlights matches inline via `Markdown::set_search_highlights` for
markdown-rendered content and
`Editor::highlight_background(HighlightKey::BufferSearchHighlights, …)`
for past user messages (rendered through `MessageEditor`'s inner
`Editor`, not through markdown).
- Next/prev navigation, case/whole-word/regex toggles (same UI as
`BufferSearchBar`).
- Returns focus to the message editor on dismiss so the user can keep
typing immediately.

<details><summary>Commits (authored by Claude 4.7 Opus, max)</summary>

### Seven logical commits

1. **`agent_ui: Add in-thread search bar`** — initial implementation:
bar UI, keymap bindings under `AcpThreadSearchBar` context, markdown
highlight plumbing, focus-restore on dismiss.
2. **`agent_ui: Add unit tests for in-thread search`** — coverage of the
matcher across entry kinds and the dismiss-clears-highlights path.
3. **`agent_ui: Limit search to visible tool-call text`** — UX fixes
from manual testing: `track_focus` so `AcpThreadSearchBar` context lands
in the editor's dispatch chain; red border on zero-match query; skip
tool-call content (only search labels).
4. **`agent_ui: Fix Esc dispatch, smart toggle, error message, skip
Thought blocks`** — round 2 of UX fixes: contribute `AcpThreadSearchBar`
context from `ThreadView` when bar is visible, smart Ctrl/Cmd+F
outside-the-bar focuses instead of closing, regex error message row,
skip `AssistantMessageChunk::Thought`.
5. **`agent_ui: Polish thread search bar — Esc routing, user-message
highlights, action forwarding`** — `search::*` action forwarders on
`ThreadView`; `cx.defer` around the activate callback (fixes a
double-borrow panic); `editor::actions::Cancel` interception so Esc
dismisses our bar instead of escaping to the workspace's
`BufferSearchBar`; user-message highlights via the inner `Editor`; muted
zero-match counter; three new gpui regression tests.
6. **agent_ui: Fix Shift+Enter shadowing in thread search bar`** —
capture-phase intercept of `editor::Newline*` on the bar's `bar_row`
element so a base keymap binding `shift-enter` at the `Editor` context
(e.g. JetBrains → `editor::NewlineBelow`) can't shadow the bar's
`agent::SelectPreviousThreadMatch`. Adds a regression test that loads
`default-linux.json` + `linux/jetbrains.json` and asserts `shift-enter`
navigates instead of inserting a newline.
7. `agent_ui: Debounce thread search, refresh on thread changes,
highlight user messages`** — last round before maintainer review: 150 ms
debounce on the match rescan; subscribe to `AcpThread` updates so
results/highlights/counter follow a streaming conversation live;
navigate the list to the entry owning the active match; `.ok()` instead
of `let _ =`; assorted cleanups; two new regression tests
(`test_thread_search_refreshes_on_new_thread_entry`,
`test_thread_search_scrolls_to_later_user_message_match`).
</details>

8 gpui tests cover the load-bearing logic (`cargo test -p agent_ui --lib
-- thread_search`). All pass.

## Manual testing

Verified on Linux against `upstream/main` `bde5c0bdc9` (full `release`
profile, with LTO and `codegen-units=1` built and tested at that
commit). Branch since merged with `upstream/main` `2106e8c`. Of the 100
intervening upstream commits, several touch files in this diff; one
produced a real conflict in `crates/agent_ui/src/conversation_view.rs`
(`gpui::{...}` import block — both sides added new, non-overlapping
symbols; resolved by union).

- Bar opens / dismisses via Ctrl+F and Esc
- Next/prev navigation via Enter / Shift+Enter / F3 / Shift+F3 / chevron
buttons
- Case / whole-word / regex toggles via buttons and via Alt+C / Alt+W /
Alt+R (Linux)
- Highlights inside past user messages render correctly on the
`MessageEditor`'s inner `Editor`
- query text turns red on no-match; bad regex shows error message;
zero-match counter stays muted (not red)
- `search::*` actions fire from outside the bar (focus in message
editor) via the `ThreadView`-level forwarders
- Workspace pane `BufferSearchBar` is unaffected; the two bars hold
independent state
- Feature looks great in light mode and dark mode, and with various
themes
- Navigating to a match in a past user message scrolls that message into
view (its top to the viewport top)
- Results update live as the agent streams new messages while the bar is
open (debounced ~150 ms, same for typing)

[Zed agent thread search subscribe to thread
updates.webm](https://github.com/user-attachments/assets/75585fee-ba25-42ac-9dde-16c8e152fb06)

<details><summary>Full manual test plan</summary>

### Setup (preconditions for every test below unless otherwise noted)

1. Launch the dev binary: `./target/release-fast/zed --user-data-dir
~/.local/share/zed-dev-feat`
2. Open the agent panel, start a thread, send 2–3 prompts so the thread
contains:
- At least one user prompt with a distinctive substring (e.g.
`watermelon`)
   - At least one assistant message with a distinctive substring
   - At least one tool call with a known label substring
   - At least one collapsed Thinking block
3. In parallel: have at least one code editor open in a workspace pane
(some tests cross-check that path).

### Core matching

#### T-001 — Ctrl+F opens the bar with focus in query

**Status:** ✅ PASS 2026-05-15 15:30

**Repro:** With focus in the agent panel's message editor, press Ctrl+F
(Linux) / Cmd+F (macOS). The search bar appears at the top of the thread
view and the query input is focused.

#### T-002a — Active match visually distinct from inactive matches

**Status:** ✅ PASS 2026-05-15 15:30

**Repro:** Type a query that produces ≥3 matches. The current ("active")
match must be visually different from the others — different highlight
color, not just position. If they look identical, this may be a theme
issue (`search_active_match_background` vs `search_match_background` too
close on the entry's background); note the theme.

#### T-002b — User-prompt text gets inline highlight, not just match
count

**Status:** ✅ PASS 2026-05-15 17:15 (fix shipped 2026-05-15 16:15;
regression-guarded by
`test_thread_search_highlights_user_message_editor`)

**Repro:** Send a user prompt containing a distinctive substring. Then
search that substring. The user prompt text **must** show yellow
highlight, not just be counted. The bar's matcher reads from
`message.content.markdown()` but the on-screen render goes through a
`MessageEditor`; the current code only highlights via
`Markdown::set_search_highlights`, which misses the editor.

**Notes:** Fix routes user-message matches through
`Editor::highlight_background(HighlightKey::BufferSearchHighlights, …)`
— the same path `Editor`'s own `SearchableItem` impl uses.
`collect_markdowns` no longer pulls the user message's markdown
(avoiding double-counting). The bar now maintains separate
`highlighted_markdowns` and `highlighted_editors` lists for clean-up.
Match-target enum (`MatchTarget::Markdown` vs `MatchTarget::Editor`)
tags each match so active-vs-inactive re-paint can dispatch correctly.
Pending runtime verification on next `release-fast` build.

#### T-003 — Enter / Shift+Enter in bar navigates matches

**Status:** ✅ PASS 2026-05-25 14:00 (verified on `release` build)

**Repro:** With focus in the query, type a query with ≥3 matches. Press
Enter → counter `1/N → 2/N → 3/N`. Press Shift+Enter → reverses (and no
`\n`s are output in the search box). F3 / Shift+F3 same.

### Option toggles

#### T-004 — Alt+C toggles case sensitivity from inside bar

**Status:** ✅ PASS 2026-05-15 07:50

**Repro:** With focus in query, press Alt+C. `Aa` button toggles state;
results re-filter.

#### T-005 — Alt+W toggles whole-word from inside bar

**Status:** ✅ PASS 2026-05-15 15:30

**Repro:** Same as T-004, with Alt+W toggling `wd` button.

#### T-006 — Alt+R toggles regex from inside bar (Linux)

**Status:** ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 06:35)

**Repro:** Press Alt+R. `.*` button toggles.

**Notes:** macOS keymap (`alt-cmd-x`) left unchanged in this session —
it matches the wider macOS Zed convention.

#### T-006a — Tooltips on toggle buttons show their hotkey

**Status:** ✅ PASS 2026-05-15 15:30

**Repro:** Hover each toggle button (`Aa`, `wd`, `.*`). Tooltip shows
action name AND keybinding (e.g. "Toggle Case Sensitive · Alt+C").

### Error / empty states

#### T-007 — Empty matches: no red border on bar input

**Status:** ✅ PASS 2026-05-15 15:30

**Repro:** Type `zzzzzzz`. Query text turns red. Counter shows `0/0`.
Bar input border stays **neutral**, no red box.

#### T-008 — Bad-regex error message

**Status:** ✅ PASS 2026-05-15 15:30 (error renders aligned with the
input)

**Repro:** Switch to regex mode, type `[`. Error message appears below
bar, aligned with the input.

#### T-019 — Zero-match counter not colored red

**Status:** ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 06:30)

**Repro:** Type a query with no matches. The counter (`0/0`) stays
muted, **not** red. MPS-parity.

### Dismissal & re-entry

#### T-009 — Esc doesn't interrupt agent generation

**Status:** ✅ PASS 2026-05-15 15:30

**Repro:** Start a long prompt; while the agent is generating, open the
search bar and press Esc. Bar closes, generation continues.

#### T-010 — Close-X button position

**Status:** ✅ PASS 2026-05-15 15:30

**Repro:** Look at the bar. Close (X) button is on the right side, after
the nav arrows (`<` `>` `1/N` `X`). NOT free-floating left of the input.

#### T-011 — Ctrl+F in bar selects all query text

**Status:** ✅ PASS 2026-05-15 15:30

**Repro:** With bar open and query containing text, press Ctrl+F. All
query text becomes selected (next keystroke replaces).

#### T-012 — Ctrl+F outside the bar (bar already open) does not crash

**Status:** ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 06:30;
regression-guarded by
`test_thread_search_select_next_from_thread_view_update_does_not_panic`)

**Repro:** Bar visible, focus in the message editor (not the bar). Press
Ctrl+F. Bar gets re-focused, query text is selected. **Must not crash.**

**Notes:** Original crash also reproducible from Enter / Shift+Enter
inside the bar after a search had matches. Fix wraps the
`on_activate_match` callback's `view.update` in `cx.defer`.

#### T-021 — Esc dismisses agent bar (not the unrelated workspace pane's
BufferSearchBar)

**Status:** ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 14:40;
regression-guarded by `test_thread_search_editor_cancel_dismisses_bar`)

**Repro:** Open a file in a workspace pane editor (e.g.
`settings.json`). Open BufferSearchBar there. Switch focus to the agent
panel, open agent search bar, type a query. Press Esc. **The agent bar
must dismiss; the workspace pane's BufferSearchBar must remain.**

**Notes:** Root cause: `Editor::cancel` in single-line mode calls
`cx.propagate()`. The propagated `editor::actions::Cancel` walked past
our bar all the way to `Workspace`, where `BufferSearchBar::register`
had registered a workspace-wide handler that dismissed the active pane's
bar. Fix: `ThreadView` now catches `editor::actions::Cancel` when the
bar is visible.

### Action routing while bar is open, focus is in the message editor

#### T-013 — F3 / Shift+F3 from outside the bar

**Status:** ✅ PASS 2026-05-15 15:30 (Enter from outside is *expected*
not to work — message editor's `enter` binding outranks. F3 is the
canonical out-of-bar nav key.)

**Repro:** Bar open with matches, focus in message editor. Press F3 →
next match. Shift+F3 → previous.

#### T-014 — Alt+C / Alt+W / Alt+R from outside the bar

**Status:** ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 02:30;
`ThreadView` forwarders for `search::ToggleCaseSensitive`,
`ToggleWholeWord`, `ToggleRegex`, `FocusSearch`)

**Repro:** Bar visible, focus in message editor. Alt+C/W/R toggles the
bar's options and re-runs search.

### Nav buttons

#### T-022 — `<` / `>` chevron buttons in the bar advance match

**Status:** ✅ PASS 2026-05-15 15:30

**Repro:** With ≥2 matches, click `<` → previous. Click `>` → next.
Wraps at ends.

### Coexistence with workspace-pane buffer search

#### T-015 — Ctrl+F in a workspace-pane editor still opens
`BufferSearchBar` (no agent-panel takeover)

**Status:** ✅ PASS 2026-05-15 15:30

**Repro:** Focus a code editor in a workspace pane, press Ctrl+F. The
pane's `BufferSearchBar` opens as before; agent panel's bar does NOT
open.

#### T-016 — Independent bars: agent vs workspace pane

**Status:** ✅ PASS 2026-05-15 15:30

**Repro:** Have both bars open simultaneously. They hold independent
state (different queries, different toggles, independent dismissal).

### Tool-call content (auto-expand on match)

#### T-017 — Auto-expand collapsed tool calls on match

**Status:** ⏸️ BLOCKED (not implemented; out of scope for current
session)

**Repro:** Have a tool call whose collapsed content contains a unique
substring. Search that substring. The tool call auto-expands so the
match is visible. After dismissal, the tool call collapses again unless
the user manually expanded it before.

#### T-018 — Auto-expand collapsed Thinking blocks on match

**Status:** ⏸️ BLOCKED (not implemented; out of scope for current
session)

**Repro:** Same shape as T-017 for a collapsed Thinking block.

#### T-019 — Streaming results automatically highlighted / live thread
search

**Status:** ✅ PASS 2026-06-08

**Repro:** Send prompt "Write a 5-paragraph story about a researcher who
hated noise. The last paragraph should be a one-sentence: "So she moved
to <name of the quietest continent on Earth>" (replace that <name> with
the actual name)", then search for `Antarctica`.
</details>


## Known limitations

1. (pre-existing, not from this PR): search highlights inside markdown
table cells can be visually offset by a few characters in columns
starting with the second. The bug lives in `crates/markdown`'s render
layer - see issue #57229
2. (excluded vs. #54816 to keep the scope tight): raw tool-call
input/output JSON and terminal scrollback are not indexed.
3. Navigating to a search hit located **below the fold of a very long
user message** highlights the match but only scrolls the message's top
into view, so the hit can stay off-screen until you scroll manually.
Past user messages render through an `AutoHeight` `Editor` inside a
virtualized `List`, which can't reliably drive intra-entry autoscroll
the way markdown content does. User messages are usually shorter than a
viewport, so this is left unaddressed.
4. Plain-text search across triple-backtick fences does not match (the
fence characters live in the markdown source; regex search with explicit
fence handling does).
5. The literal text "Thinking" rendered as the thought-disclosure header
is not searchable (rendered chrome, not markdown source).



Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- No new `unsafe` introduced; no network, file-system, or process APIs
touched; only added dep is `search` (promoted from dev-dep to runtime),
already used by this crate's tests; `MessageEditor::editor()` accessor
widening is `pub(crate)` (in-crate only). Assessment: no new attack
surface.
- [x] 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)
— partially; see "What I did NOT verify" above
- [ ] I did not verify **macOS and Windows**. Keymap entries exist for
all three platforms (`AcpThreadSearchBar` context bindings) but I only
verified Linux at runtime.
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable:
regexp-searching for "t.e" in a thread almost at the context limit (919k
tokens) felt instant, and navigation among the 2100+ results occurred at
the keyboard autorepeat rate.
   - [ ] Haven't measured against the 8ms / 120fps frame budget.

Partially closes #39338

Release Notes:

- Added in-thread search to the agent panel (Ctrl/Cmd+F)

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
2026-06-18 13:00:24 +00:00
Bennet Bo Fenner d25d2639df markdown: Add debug_asserts for search result ordering (#59483)
Follow up to #59473

The previous code could actually highlight the wrong match if you passed
in unordered ranges.
However, i realized that all codepaths are passing in ordered matches
already, so I just added some `debug_asserts` to ensure that this is
always the case.

Release Notes:

- N/A
2026-06-17 18:53:29 +00:00
Bennet Bo Fenner 2df978b11c markdown: Optimize paint_search_highlights (#59473)
Follow up to #52502

This fixes a severe hang in the markdown preview when searching for text
caused by `paint_search_highlights`. We were iterating over all lines
for each highlight, and for each highlight we called
`layout.line_layout_for_index` which internally would iterate over all
the lines of the text layout.

With this optimisation we paint all highlights in one pass. We sort the
highlight ranges, iterate through the lines and only access
`WrappedLineSegments` when we actually have a highlight in that line.

E.g. if you copy this text
(https://gist.github.com/bennetbo/e313f3023da9fec42e090177a5373152) into
the editor, open the markdown preview and search for `codex` Zed Nightly
will completely freeze. After this optimisation it is totally smooth
even in debug mode.



Release Notes:

- Improved performance when searching in markdown preview
2026-06-17 11:48:13 +00:00
Ted RobertsonandSmit Barmase d89fc86740 markdown: Render soft breaks as line breaks in agent markdown (#57376)
Agents sometimes output status lists with bullets represented by emojis
- see #57372. These currently get rendered on one line, as opposed to
bullet items like `-` or `*`, because single newlines within a paragraph
are collapsed into spaces - standard CommonMark soft-break behavior *in
prose* contexts (e.g. `README.md`). But in *comment/PR* contexts, GitHub
preserves these newlines:

✅ Did A
✅ Did B
✅ Did C

Users reasonably expect agent output to be rendered following the
comment-style convention.

## What this PR does

This PR adds a `soft_break_as_hard_break: bool` field on `MarkdownStyle`
and enables it for `MarkdownFont::Agent`, so a single newline within a
paragraph *in agent output* renders as a line break instead of a space.
The field defaults to `false` to preserves CommonMark behavior
everywhere else. In `themed_with_overrides`, sets it to `true` for
`MarkdownFont::Agent`. The rendering switch in
`MarkdownElement::request_layout` then emits `"\n"` instead of `" "` for
`MarkdownEvent::SoftBreak` when the flag is set. This matches GitHub
comments and Obsidian default behavior, and prevents emoji + trailing
newline content from being collapsed onto a single line in agent
responses.

Scoped strictly to `MarkdownFont::Agent`. Hover popovers, diagnostics,
markdown preview, README rendering, etc. are all untouched.

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] 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)
- [ ] Tests cover the new/changed behavior - visual tests completed: 
<img width="892" height="632" alt="image"
src="https://github.com/user-attachments/assets/1aacb5da-edc8-49fd-bfe9-d37a22ae2d3f"
/>

- [x] Performance impact has been considered and is acceptable

Closes #57372

Release Notes:

- Improved agent panel markdown rendering: single newlines within agent
responses now render as line breaks, matching the convention used by
GitHub comments and Obsidian.

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-06-16 16:17:06 +00:00
Danilo Leal 5695bb73f3 markdown_preview: Improve heading spacing (#59291)
Follow up to https://github.com/zed-industries/zed/pull/58465 adding
more breathing room between headings _and_ making inline code links use
the `accent` text color.

Release Notes:

- N/A
2026-06-14 12:11:15 +00:00
Albert BoguszandMrSubidubi 9aa0082ff6 Hide markdown code block scrollbar when wrapped (#58472)
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)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Follow up of #57312. Hides the scrollbar (which does not do anything)
when markdown code blocks are wrapped.

Release Notes:

- Fixed the scrollbar on wrapped code blocks in the agent chat.

(As far as I can see the wrap button only exists in the agent chat and
not regular markdown previews.)

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
2026-06-04 08:01:09 +00:00
Danilo Leal f243c91756 Use button component for Mermaid block controls (#58473)
Tiny one here, just to maintain Ui consistency as I noticed the custom
div-built buttons were not using theme tokens for coloring the different
states.

<img width="600" alt="Screenshot 2026-06-03 at 6  54@2x"
src="https://github.com/user-attachments/assets/678474f1-1807-4993-ac15-928a0033338d"
/>

Release Notes:

- N/A
2026-06-03 22:04:36 +00:00
Danilo Leal 0dfe328a23 Improve markdown preview styles (#58465)
Closes https://github.com/zed-industries/zed/issues/58364

This PR adjusts heading and body text font size (mostly reducing them a
bit), as well as colors (making the body text slightly darker than
headings), and content separation, through adding a bottom border to
headings until H3.

| Before | After |
|--------|--------|
| <img width="2620" height="2044" alt="Screenshot 2026-06-03 at 5 
01@2x"
src="https://github.com/user-attachments/assets/d10c7916-e4cb-4999-8be1-08e26793fd35"
/> | <img width="2622" height="2044" alt="Screenshot 2026-06-03 at 5 
02@2x"
src="https://github.com/user-attachments/assets/13105982-283d-436b-973e-b6198cd2503b"
/> |

Release Notes:

- Improved markdown preview styles, making it more legible and easier to
parse.
2026-06-03 20:38:23 +00:00
Remco Smits 49232d1612 markdown: Fix text selection position in centered/right-aligned markdown table cells (#57283)
Table header cells are always center-aligned. When selecting text in
them, the selection highlight was drawn at the left edge of the cell
instead of over the actual visible text. Clicking on a character also
mapped to the wrong source index.

The bug was that `bounds_for_source_range` and
`source_index_for_position` used raw layout x-coordinates (which start
at 0), without accounting for the horizontal offset GPUI applies when
rendering center- or right-aligned text.

The fix stores the `TextAlign` on each `RenderedLine` at flush time,
then uses it to compute an alignment offset per wrapped row segment.
That offset is:
- subtracted from the click position before resolving it to a source
index
- added to the x-coordinates when computing selection highlight bounds

**Before**:


https://github.com/user-attachments/assets/49fd7748-eb1b-4199-bc2f-23cddcb528c5

**After**:


https://github.com/user-attachments/assets/93657652-d548-4e5a-b011-be29bb0a3d9e


Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] 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)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Markdown: Fixed text selection highlight appearing at the wrong
position when selecting text in markdown table headers.
2026-06-01 06:54:27 +00:00
Smit Barmase 44fd8c7924 markdown: Add frontmatter metadata block rendering (#57845)
Adds opt-in rendering for Markdown frontmatter metadata blocks in
Markdown Preview and agent markdown.

- Simple `key: value` metadata blocks now render as a two-column table,
while more complex metadata falls back to a code-style block.
- Metadata block content and key/value rows are parsed in the parser
step, and the request layout simply takes over rendering.

<img width="1288" height="436" alt="image"
src="https://github.com/user-attachments/assets/b35b949a-8bc4-47db-82ef-ed835e9ac06f"
/>

Release Notes:

- Added support for rendering Markdown frontmatter metadata blocks in
Markdown Preview and Agent Panel.
2026-05-28 13:47:58 +00:00
cb1518128b markdown: Merman (#57644)
Big PR that replaces `mermaid-rs` with `merman`.

Adds a new crate `mermaid_render` that exposes a simple API for
rendering a mermaid diagram to an SVG string.

## Why is it so big?

Some of this is explained in the crate-level docs for `mermaid_render`,
but the short version is:
- `mermaid-rs` emits "good enough" SVGs for most use cases. It also
ships with a reasonable default theme
- `merman` emits *very accurate* SVGs, but with borderline unusable CSS
- Most of the new code in this PR are a series of passes to clean up the
output SVG by:
  - Injecting good CSS
  - Fixing issues in the `merman`-generated SVGs
- Tweaking the final result to avoid issues with `usvg` and `resvg`,
which are what will eventually be used to rasterize the SVG
- This code *could* be much smaller, but the following design decisions
made it take a lot more code:
  - Using a real XML parser instead of basic string manipulation
  - Avoiding allocating strings in as many places as possible

Because of this, the design is as follows:
- First, construct a `merman` theme from the user's theme, and render
the mermaid to an SVG string
- Post-process - each step is roughly a `fn(Iterator<Item =
Event<'short>>) -> Iterator<Item = Event<'short>>`, where `Event` is the
type for events produced by `quick-xml` (a pull-based XML parser)
 

## Note for reviewers

It's a big diff, sorry 😅 happy to pair review. 

The new crate is essentially a leaf crate - it does technically depend
on `gpui`, but only for the `Hsla` and `Rgba` types. Extracting a new
`gpui_color` crate felt like overkill for this already-very-big PR.

Each post-process pass is in its own submodule, and has a doc comment
explaining the before/after. Note that bugs in this code are perhaps
less serious than bugs in other parts of the code:
- The code has been thoroughly audited for potentially-panicking code
paths - as far as I know, there are none (excluding some `.expect()`s on
calls to `write!` with `String`, which is [cannot return `Err`][string
write])
- A bug in this code (given that it will not cause a panic) will, at
worst, result in an invalid diagram being rendered, or simply falling
back to showing the code.
- The current `mermaid-rs` renderer *already* does this in quite a lot
of cases, sometimes showing outright misleading information.
---

Some eye candy:
| Before (`mermaid-rs`) | After (`merman`) |
| - | - |
| <img width="1227" height="340" alt="image"
src="https://github.com/user-attachments/assets/58d6904e-64bc-478a-8d67-f75ad4ccbc9e"
/> | <img width="1169" height="482" alt="image"
src="https://github.com/user-attachments/assets/d4bb9cd5-240f-4bf6-ba7f-4862049ed8b0"
/> |
| <img width="842" height="564" alt="image"
src="https://github.com/user-attachments/assets/1668a50d-68f6-4145-8cef-359e4c6a4589"
/> | <img width="869" height="543" alt="image"
src="https://github.com/user-attachments/assets/2ec1a7eb-fc3c-4392-b577-1ad52396b87c"
/> |
| Failed to render | <img width="822" height="1123" alt="image"
src="https://github.com/user-attachments/assets/a97308a1-6b3a-48b6-9778-abf3507c6ad3"
/> |
| <img width="252" height="517" alt="image"
src="https://github.com/user-attachments/assets/dbf86274-004a-4ee4-be89-cc6ff4f6cf35"
/> | <img width="361" height="680" alt="image"
src="https://github.com/user-attachments/assets/8457b6ed-3ca9-4bed-9496-60388ba08206"
/> |
| <img width="550" height="1050" alt="image"
src="https://github.com/user-attachments/assets/c21b8513-fb86-422e-870a-015e0add783a"
/> | <img width="819" height="1148" alt="image"
src="https://github.com/user-attachments/assets/ca646165-302d-41aa-8da5-39e89c96ebb7"
/> |
| <img width="1218" height="225" alt="image"
src="https://github.com/user-attachments/assets/3006a1bf-efe6-46f5-9f9d-289a3fdf9adc"
/> | <img width="1118" height="965" alt="image"
src="https://github.com/user-attachments/assets/90d76098-bf3d-4c69-bc9b-00dd9cbf6990"
/> |
| <img width="800" height="584" alt="image"
src="https://github.com/user-attachments/assets/f688693b-df3d-4514-b105-ccaa3874e40c"
/> | <img width="1153" height="417" alt="image"
src="https://github.com/user-attachments/assets/eeb05f58-7184-4321-a47b-ea3cc53f0d02"
/> |
| <img width="539" height="464" alt="image"
src="https://github.com/user-attachments/assets/0076105d-eef9-4011-9b9a-581918575e49"
/> | <img width="638" height="556" alt="image"
src="https://github.com/user-attachments/assets/72a51966-c296-48d0-b1e2-66835b1a0d5b"
/> |
| <img width="607" height="430" alt="image"
src="https://github.com/user-attachments/assets/d3530814-532b-41ed-a2b6-fd5740d8db58"
/> | <img width="725" height="489" alt="image"
src="https://github.com/user-attachments/assets/c43687d9-f426-4cb8-8a45-23a3c0070c8f"
/> |
| <img width="869" height="577" alt="image"
src="https://github.com/user-attachments/assets/b607f3fd-136c-4f41-a88e-596520e276b9"
/> | <img width="784" height="586" alt="image"
src="https://github.com/user-attachments/assets/22305a64-b4d0-474a-b6f6-8973f2bca933"
/> |
| <img width="1214" height="263" alt="image"
src="https://github.com/user-attachments/assets/183ff0df-a6f3-470c-b271-8099c3e33044"
/> | <img width="1195" height="632" alt="image"
src="https://github.com/user-attachments/assets/868bcb7f-62c6-4d20-ba1e-3f25f8165fff"
/> |
| <img width="573" height="597" alt="image"
src="https://github.com/user-attachments/assets/6414e409-b879-4892-8ef6-89489219b56f"
/> | <img width="578" height="608" alt="image"
src="https://github.com/user-attachments/assets/8ac71b03-f603-4e32-87aa-b993317d4e29"
/> |
| <img width="543" height="472" alt="image"
src="https://github.com/user-attachments/assets/1f19929c-cf07-4287-b9cf-b976eea9faaa"
/> | <img width="760" height="599" alt="image"
src="https://github.com/user-attachments/assets/73926075-db47-4eb1-854e-7aee30522684"
/> |
| <img width="1205" height="219" alt="image"
src="https://github.com/user-attachments/assets/5f3dc936-4b89-44f4-a00a-4dbc47e06504"
/> | <img width="1133" height="349" alt="image"
src="https://github.com/user-attachments/assets/e62901ff-9d75-4fde-a30e-974ff2e783b1"
/> |


Release Notes:

- Improved: Mermaid diagrams now render faster and more accurately

[string write]:
https://doc.rust-lang.org/src/alloc/string.rs.html#3342-3354

---------

Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-05-27 16:27:18 +00:00
Xiaobo Liu 992d36b6b0 markdown: Support shift+click to extend text selection (#57586)
When shift is held during a single click, extend the existing selection
from its anchor point to the clicked position instead of starting a new
selection.

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] 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
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Added markdown support shift+click to extend text selection
2026-05-25 14:09:22 +00:00
MartinYe1234 ad8dd42ad0 Avoid linkifying non-interactive code spans (#57515)
## Summary

- Skip code-span link resolution when markdown prevents mouse
interaction
- Add regression coverage for non-interactive code spans

## Tests

- cargo test -p markdown
test_code_span_link_ignores_code_when_mouse_interaction_is_prevented

Release Notes:

- Fixed extra link styling on file paths in agent tool call labels.
2026-05-22 17:20:57 +00:00
MartinYe1234andzed-zippy[bot] 667a07ce3c Prefix read_file tool output with line numbers (#56779)
Format `read_file` tool output in `cat -n` style: each line is prefixed
with its line number right-aligned in a 6-character field, followed by a
single tab, followed by the line's original content (newlines preserved,
including CRLF). Numbering reflects the actual file lines, so a ranged
read starting at line 42 emits `42` for its first line, not `1`.

For large files, content returned by `get_buffer_content_or_outline` is
**not** prefixed:

- The symbol outline path already conveys structure via its `[L100-150]`
annotations.
- The truncated first-1KB fallback (used when a file exceeds
`AUTO_OUTLINE_SIZE` and has no parseable outline) is wrapped in a
synthetic `# First 1KB of …` header, so its lines don't correspond to
real file line numbers.

Both cases are reported via `BufferContent::is_synthetic` (renamed from
`is_outline`).

Also updates the `edit_file` tool's input doc to describe the prefix
format and tell the model to strip it before constructing `old_text` /
`new_text`, preserving the original indentation that appears after the
tab.

Updates how we render `read_file` tool call outputs in the UI
(screenshots included in comments below).
Also fixes an existing bug where `read_file` tool call outputs would not
re-render their content code block when an older thread was restored
(the tool's `replay` hook was missing).

Closes AI-226

Release Notes:

- Improved how `read_file` tool output renders in the agent panel, with
a line-number gutter, and fixed it not re-rendering on restored threads

---------

Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-05-22 15:02:17 +00:00
MartinYe1234 573f476ba9 Make file paths in backticks clickable in agent panel (#57303)
When the agent mentions a file path inside `backticks` (e.g. ``
`src/main.rs` `` or `` `src/main.rs:42` ``), the rendered code span now
becomes a clickable link in the agent panel. Clicking opens the
referenced file in the workspace, jumping to the right line and column
when present.

## How it works

- **Shared path resolution.** Extracted `OpenTarget` and the
workspace/worktree resolution logic out of
`terminal_view::terminal_path_like_target` into a new
`workspace::path_link` module so both the terminal and the agent panel
can use the same code. Includes a `sanitize_path_text` helper ported
from the terminal's URL/punctuation handling. Pure refactor — terminal
behavior is unchanged.
- **`markdown` crate hook.** Added
`MarkdownElement::on_code_span_link(callback)`. When the callback
returns `Some(url)` for a given code span's contents, the existing
`push_link` machinery wires up cmd-hover, hit testing, and the existing
`on_url_click` callback. When it returns `None`, the code span renders
as before. The hook is opt-in, so `markdown` stays workspace-agnostic.
- **Agent panel wiring.** `render_agent_markdown` constructs an
`AgentCodeSpanResolver` that snapshots the project's visible worktree
entries plus their file extensions. `try_resolve` does a cheap
synchronous heuristic check (path must contain `/`/`\` or end in an
extension present in the workspace, can't be a URL, can't be all digits,
etc.) and then looks the candidate up in the per-worktree
`HashSet<Arc<RelPath>>`. On a hit it returns a `MentionUri::File` or
`MentionUri::Selection` URI, which the existing `thread_view::open_link`
already knows how to open at the right line.

## Edge cases handled

- Code spans inside fenced code blocks stay plain (gated on
`builder.code_block_stack.is_empty()`, matching how regular markdown
links behave).
- Trailing prose punctuation (`` `src/main.rs.` ``) is stripped before
lookup.
- Identifiers like `` `String` ``, `` `await` ``, `` `npm run dev` ``
stay plain — they don't pass the path-like heuristic.
- Cross-platform path separators handled via the per-worktree
`PathStyle`.

## Tests

- `crates/markdown` — unit test asserting code spans become links when
the callback returns `Some`, and stay plain when it doesn't.
- `crates/agent_ui` — unit test for `AgentCodeSpanResolver::try_resolve`
covering hits with and without a `:line` suffix, misses, identifiers,
and trailing punctuation.
- Existing `terminal_view` tests cover the moved resolution code
(unchanged behavior).

## Notes

- There's currently a temporary `log::info!` in
`AgentCodeSpanResolver::try_resolve` that reports per-call worktree-walk
timing and a cumulative total. Kept in for now to verify the feature
isn't being called excessively during streaming renders. Can be removed
before merge.
- Resolution is sync-only against worktree entries; absolute paths
outside the workspace are not resolved (would require an async re-render
path).

Closes AI-277

Release Notes:

- Made file paths in `backticks` clickable in the agent panel; clicking
opens the referenced file at the given line when present.
2026-05-21 22:04:32 +00:00
MartinYe1234 3c89cf2a7a Skip syntax highlighting for read_file outline responses (#57287)
When `read_file` returns a file outline instead of full contents, the
result is now wrapped in a plain fenced code block rather than tagging
it with the file's path.

Previously, the outline was wrapped in a fenced block tagged with the
file path (e.g. `` ```crates/agent/src/tools/read_file_tool.rs ``).
Because the tag contains a slash, the markdown parser routed it through
`CodeBlockKind::FencedSrc`, resolved the file's language by path, and
ran the language's tree-sitter parser against the outline on every
paint. The outline is structural (e.g. `fn foo [L10-20]`), not actual
source for the file's language, so the parse was both expensive and
produced incorrect highlighting.

Because GPUI rebuilds the visible element tree on every window paint,
anything that triggers a repaint (cursor blink in the focused message
editor, animations, the turn timer, etc.) would re-run the tree-sitter
parse on the entire outline, throttling the frame rate while the tool
call was expanded.

This change adds an `is_outline_response` flag in `ReadFileTool::run`
and, when set, passes an empty tag to `MarkdownCodeBlock` so the
renderer sees `CodeBlockKind::Fenced` (no language). Plain monospace
formatting is preserved; the path tag is still used for the non-outline
(full file) case.

Adds two regression tests: one asserting the outline path uses an
untagged fenced block, and one asserting the full-file path keeps the
path tag (so the next person fixing this doesn't accidentally strip the
tag everywhere).

Also includes a small markdown-rendering follow-up:
`MarkdownElementBuilder::push_text` was recomputing the base text style
(cloning `base_text_style` and walking the style stack) twice per
highlighted token. For a code block with hundreds of highlight tokens,
that's hundreds of redundant `TextStyle` clones per paint. The style
stack does not change while runs are being attributed, so the style is
now computed once outside the loop and reused.

Closes AI-234

Release Notes:

- Improved scrolling smoothness in the agent panel when a `read_file`
tool call with a large file outline is expanded.
2026-05-21 16:16:49 +00:00
Danilo Leal 33b5efe7d2 markdown: Add ability to wrap/unwrap codeblock content (#57312)
This PR adds an icon button to Markdown codeblocks allowing to control
whether or not the content should be wrapped. At the moment, this is not
hard-persisted, meaning that 1) wrapping text in one codeblock instance
does not affect others, and 2) the codeblock will be reset every time
its view is recreated (i.e., closing and opening a Markdown Preview tab,
an agent thread, etc.). I intentionally kept it simple just to see how
it feels, but we can certainly consider a setting later on.

| Unwrapping | Wrapping |
|--------|--------|
| <img width="782" height="658" alt="Screenshot 2026-05-20 at 5  09
2@2x"
src="https://github.com/user-attachments/assets/e9151e91-32ba-40d4-9c65-535dec309291"
/> | <img width="736" height="604" alt="Screenshot 2026-05-20 at 5 
09@2x"
src="https://github.com/user-attachments/assets/157db6fd-ec4c-4c96-b44a-119273cbd0f9"
/> |

Release Notes:

- Added the ability to control codeblock content wrapping through the
UI.
2026-05-20 20:51:56 +00:00
alkinun efa63e1ef0 markdown: Fix escaping non-ASCII chars (#55782)
Fixes #55704

The `escape` function in `crates/markdown/src/markdown.rs` was calling
`c as u8` on the `char`s before passing to `MarkdownEscaper::next()`.
This strips non ASCII Unicode codepoints down to just their low 8 bits
which might be in the ASCII punctuation range and thus cause an extra
backslash to be added in front of these non ASCII chars.
 
Release Notes:

- Fixed a bug where non-ASCII chars in diagnostic messages were
incorrectly rendered with spurious `\` characters
2026-05-19 17:20:24 +00:00
Lee Nussbaum 6cf32de6c9 markdown_preview: Independent code font family (#56744)
Adds a `markdown_preview_code_font_family` setting that overrides the
font used in the markdown preview for code — inline `code` spans and
fenced code blocks.
This is the counterpart to `markdown_preview_font_family` (#54003),
which already does this for body text. Together they let you choose a
typographically matched body + code font pair for the preview without
forcing the code font onto editor buffers, where it may not be a good
coding font:

```json
{
  "markdown_preview_font_family": "Noto Serif",
  "markdown_preview_code_font_family": "Noto Sans Mono"
}
```

Behavior mirrors `markdown_preview_font_family`:
- Scoped to the markdown preview only (`MarkdownFont::Preview`). The
agent panel, notifications, hover popovers, and REPL output are
unaffected — they keep using the buffer font for code.
- Falls back to the buffer font family when unset, so existing previews
are unchanged.
- Overrides the font family only; fallbacks and features still come from
the buffer font.

Before (uses buffer font, here Iosevka):

<img width="509" height="368" alt="Screenshot 2026-05-14 at 1 39 51 PM"
src="https://github.com/user-attachments/assets/6b7e49b2-fc6e-4db1-9679-392b3447f411"
/>

After (uses specified font, here Noto Sans Mono):

<img width="508" height="368" alt="Screenshot 2026-05-14 at 1 40 51 PM"
src="https://github.com/user-attachments/assets/f911c99b-08f8-4336-83eb-54b555f11c54"
/>

Release Notes:

- Added `markdown_preview_code_font_family` to override the code font in
the markdown preview
2026-05-14 20:03:29 +00:00
Danilo Leal d6903b7f11 markdown: Fix default UI font rendering in Mermaid diagrams (#56695)
Release Notes:

- Fixed Mermaid diagrams not rendering with the default UI typeface.
2026-05-14 11:15:08 +00:00