## Summary
Introduces `format_on_save` variants that format only modified lines,
limiting formatting to lines changed since the last commit. This
prevents massive diffs when editing legacy codebases. Aligns with VS
Code's `editor.formatOnSaveMode` naming:
- `"modifications"` — formats only git-diffed lines. Requires source
control; skips formatting if no diff is available.
- `"modifications_if_available"` — formats only git-diffed lines,
falling back to full-file formatting for untracked files, when source
control is unavailable, or when the LSP does not support range
formatting.
Also supports importing equivalent VS Code settings
(`formatOnSaveMode`).
This PR uses the range-based whitespace/newline infrastructure from the
dependency PR above.
## Changes
<details>
<summary><b>New settings, modified ranges computation, VS Code
import</b></summary>
### New settings (`language.rs`, `default.json`, `all-settings.md`)
Two new `FormatOnSave` variants: `Modifications` and
`ModificationsIfAvailable`.
### Modified ranges computation (`items.rs`)
- `compute_format_decision()` — reads `format_on_save` setting across
all buffers, determines whether to use ranged formatting (`Ranges`),
full formatting (`Full`), or skip (`Skip`).
- `compute_modified_ranges()` — extracts modified line ranges from git
diff hunks via `BufferDiffSnapshot`.
- `is_empty_range()` — helper to detect deletion-only hunks that produce
no formatable content.
The `save()` method calls `compute_format_decision()` and dispatches
accordingly.
### Modifications mode in `lsp_store.rs`
- Adds `FormatOnSave::Modifications |
FormatOnSave::ModificationsIfAvailable` to the formatter selection match
arm.
- `ModificationsIfAvailable` falls back to full-file formatting when
ranged formatting produces no results.
### VS Code settings import (`vscode_import.rs`, `settings_store.rs`)
Imports `editor.formatOnSaveMode` mapping:
- `"modifications"` → `FormatOnSave::Modifications`
- `"modificationsIfAvailable"` →
`FormatOnSave::ModificationsIfAvailable`
- `"file"` → `FormatOnSave::On`
</details>
## Tests
- `test_modifications_format_on_save` — basic modifications mode
formatting with dirty buffer
- `test_modifications_format_no_changes` — clean buffer triggers no
formatting
- `test_modifications_format_lsp_no_range_support` — LSP without range
formatting skips entirely for `Modifications`
- `test_modifications_format_lsp_returns_empty_edits` — empty edits
handled gracefully
- `test_modifications_format_multiple_hunks` — two non-adjacent edits
produce two separate range formatting requests
---
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#16509
Depends on #53942
Release Notes:
- Added `modifications` and `modifications_if_available` options to
`format_on_save`, which format only git-changed lines instead of the
entire file
- When using modifications mode, `remove_trailing_whitespace_on_save`
and `ensure_final_newline_on_save` are also scoped to changed lines,
preventing unwanted diff jitter in legacy codebases
- Added support for importing VS Code's `editor.formatOnSaveMode`
setting
---------
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
This fixes#56956.
The terminal link-open gesture was split between `mouse_down` and
`mouse_up`, but both halves only ran in the non-mouse-reporting path.
When a foreground app enabled terminal mouse reporting, a secondary
click on a URL or file path was forwarded to the PTY instead of opening
the link.
This changes secondary-click link handling so it checks for a hyperlink
before mouse reporting on press, and completes the matching hyperlink
open before mouse reporting on release. The event is only consumed when
the click actually lands on the same link, so normal clicks in
mouse-reporting TUIs continue to be forwarded as before.
Validation:
- `CARGO_BUILD_JOBS=1 cargo test -j1 -p terminal
test_hyperlink_ctrl_click_same_position_in_mouse_mode`
- `CARGO_BUILD_JOBS=1 cargo check -j1 -p terminal`
Release Notes:
- Improved terminal links: Cmd/Ctrl-click now opens links even when the
application has mouse reporting enabled (e.g. vim, opencode, claude).
Disable `terminal.open_links_in_mouse_mode` to forward these clicks to
the application instead.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
This PR adds a bunch of design improvements to the toolbar of (tab)
views that display diffs: the uncommitted changes, branch diff, and
agent diff tabs. This involves adjusting spacing, sizing, and other
small tweaks across all of these views, including touching up the
divider component API a little bit, adjusting Git icons design, adding
diff stat numbers to the uncommitted changes tab so its consistent with
the others, and more (e.g., moving the split buttons into its own
component to ensure they look the same across all uses). Ended up also
going on a slight de-tour to make all uses of the split button in the
Git panel consistent design-wise.
All in all, this is just tidying up the design of all of these surfaces
that are all relatively similar.
| Branch Diff | Uncommitted Diff | Single-file Diff | Git Panel |
|--------|--------|--------|--------|
| <img width="800" alt="Screenshot 2026-07-06 at 11 25@2x"
src="https://github.com/user-attachments/assets/4ebf87e7-c52d-41d9-9de3-7944125114a1"
/> | <img width="800" alt="Screenshot 2026-07-06 at 11 25 2@2x"
src="https://github.com/user-attachments/assets/51ccd2eb-904b-455a-a708-b4cb50b3a7cb"
/> | <img width="800" alt="Screenshot 2026-07-06 at 11 26@2x"
src="https://github.com/user-attachments/assets/6ae7df68-d1bd-4d36-a250-ba16e43c4e8e"
/> | <img width="800" alt="Screenshot 2026-07-06 at 11 26 2@2x"
src="https://github.com/user-attachments/assets/e032bc60-4551-41f0-b578-90ed305167c2"
/> |
Release Notes:
- Added diff stat numbers to the uncommitted changes view.
the jetbrains overlay binds `ctrl-alt-l` (linux) / `cmd-alt-l` (macos)
to `editor::Format` (jetbrains "reformat code"), which collides with the
default `agent::OpenRulesLibrary` binding. the agent panel shows the
conflicting key as the rules tooltip but pressing it formats the buffer
instead of opening rules. mirrors the windows keymap by switching the
linux/macos overlays to `shift-alt-l` in the AgentPanel context (with
the colliding key explicitly null-ed), so the hint and the action stay
in sync.
closes#49764.
Release Notes:
- Fixed the JetBrains keymap so the agent panel "Rules" entry uses
`shift-alt-l` and no longer flickers a non-functional `ctrl-alt-l` /
`cmd-alt-l` shortcut.
Makes cmd-f work for terminal threads.
Since the agent panel is not part of the normal pane system we have to
manually hook up the search bar.
Closes#57309
Release Notes:
- agent: Added support for searching (cmd-f) inside of terminal threads
## Summary
Add a chevron (`Disclosure`) to each file group header in Text Finder,
letting you fold/unfold that file's matches. Fold state is cleared
whenever a new search starts.
## Test plan
- [x] Open Text Finder, run a search with matches in multiple files
- [x] Click a header's chevron, confirm its matches hide/show and
selection lands on a visible row
- [x] Start a new search, confirm folded state doesn't carry over
Release Notes:
- Added the ability to collapse per-file match groups in Text Finder
---------
Co-authored-by: ozacod <ozacod@users.noreply.github.com>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
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.
Closes AI-432
The turn-end action buttons in the agent panel (scroll to top, scroll to
most recent prompt, open as markdown, thumbs up/down, share/sync) are
now exposed as local slash commands in the message editor instead of
buttons rendered at the end of each turn. The actions themselves are
unchanged — this is just a different way to access them.
Release Notes:
- Changed some of the agent panel's turn-end action buttons into slash
commands in the message editor.
---------
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
Closes AI-159
Closes AI-434
Closes AI-435
Release Notes:
- Key agent-related settings now live in the settings editor, close to
all other settings available in Zed. This specifically includes the move
of LLM providers, external agents, and MCP servers to the settings
editor.
---------
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
This makes sure that the behaviour of the CLI matches that of the UI.
In Zed itself we always open a new window (e.g. when clicking on Open
Project in new window in the recent projects picker), but in the CLI we
where re-using existing windows even when specifying
"cli_default_open_behavior": "new_window".
This caused confusion, so this PR ensures that we always open a new
window, even if that folder is already open. We still focus the active
window in the case where the path is a subpath of a project that is
already open.
Can be tested with
```
cd crates/cli
cargo run -- --zed ../../target/debug/zed somefolder
```
Release Notes:
- cli: Ensure `zed somefolder` always opens a new window, even when
`cli_default_open_behavior` is set to `new_window` and the project is
already open
Helix's keymap to `Vertically center the line` (`align_view_center`
command) is `zc`
([documentation](https://docs.helix-editor.com/keymap.html#view-mode)).
Release Notes:
- Added Helix's `z c` keymap to editor, project panel and outline panel
to scroll cursor to center
This follows up on discussion #56551.
Right now, when Zed generates a commit message, it includes project
rules files like `AGENTS.md`, `CLAUDE.md`, and `.rules` in the prompt
alongside the git diff. That can add a lot of extra context for a task
that is really just summarizing the changes in a commit.
This PR adds an `include_project_rules` option to
`agent.commit_message_model`. When it is set to `false`, Zed skips
loading project rules when generating commit messages. If the option is
omitted, the current behavior stays the same.
Example:
```json
{
"agent": {
"commit_message_model": {
"provider": "anthropic",
"model": "claude-3-5-haiku",
"include_project_rules": false
}
}
}
```
I also updated the settings plumbing so this option is only used for commit message generation and defaults to true when not specified.
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:
- agent: Added setting to exclude project rules files from commit message generation prompts (`agent.commit_message_include_project_rules`)
---------
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
# Objective
The objective is to improve Helix's default keymap within Zed as a few
are still missing.
These are all [default
keymaps](https://docs.helix-editor.com/keymap.html) i was using within
Helix but dissapointed they weren't working in Zed
There's more info in [Are we Helix
yet?](https://github.com/zed-industries/zed/discussions/33580#top)
## Solution
- Add `] g` and `[ g` for hunk navigation in helix mode, in helix this
is go to next/previous change which maps nicely to Zed's go to
next/previous hunk. (it was set to `c` here but this is incorrect and
doesn't match Helix's keymap.
- Add `alt-b` and `alt-e` for larger syntax node navigation in helix
mode, i use this a few times to go to the top of a function within the
body and Zed doesn't have it mapped.
- Add `] space` and `[ space` for inserting empty lines in helix mode.
This one was incorrectly implemented previously, after the `space` Zed
is waiting for input. It needs to be a direct chord added rather than on
`helix_next` mode.
- This means the space binding from the helix_next operator context is
redundant, so ive removed it
- Add `*` to use selection for find in helix mode. Helix mode is
slightly different and doesn't "go to next" on `*`, instead that becomes
the `/` register. This is pretty fundamental to helix navigation so
should be ported to Zed also.
- Move `] d` and `[ d` diagnostics navigation into helix_normal context.
Vim was already using this one but it wasn't shared with Helix. I've
moved it to the shared Vim and Helix block.
## Testing
I've tested these changes with a local build and each one works as
expected
## 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:
- Added `alt-b`/`alt-e` in Helix mode to move to the start/end of the
larger syntax node.
- Added `*` in Helix mode to set the current selection for search.
- Fixed Helix `[`/`]` navigation so `c` goes to the previous/next
comment and `g` to the previous/next hunk, and single-key follow-ups
like `g` no longer hang.
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
Hi there, I'm Celina from Hugging Face! Opening this PR to add
[llama.cpp](https://llama.app) as a model provider
# Objective
Today Zed users running llama.cpp have to fall back to the generic
OpenAI-compatible provider, which means no auto-discovery (the router
mode (`llama serve`) discovers models from the cache and loads them on
demand) and manual configuration of every model and its capabilities.
This PR makes `llama.cpp` a first-class provider with the same
auto-discovery experience.
## Solution
- Add a `llama_cpp` client crate with the OpenAI-compatible chat types
(`/v1/chat/completions`, including `reasoning_content`) and the
discovery types (`/v1/models`, `/props`), mirroring the existing
`ollama` crate.
- Add the provider in
`crates/language_models/src/provider/llama_cpp.rs`, modeled on the
Ollama provider (settings, configuration view, event mapping).
- Auto discover served models and their context length and tool/vision
support from `/props`. Set `auto_discover: false` to list models
manually instead.
- An unloaded model can't be inspected without loading it, so it is
listed with optimistic defaults (large context, tools enabled) and is
usable from the first message; its real context length and tool support
are filled in once it loads. These live behind a shared map, so a model
already selected in an open conversation picks them up without being
re-selected.
- Show load progress. The provider subscribes to `/models/sse` and
surfaces each model's load progress (e.g. "Loading weights 42%") in its
display name, reconciling stale labels against `/v1/models`. Builds
without `/models/sse` degrade gracefully - no progress, and no
capability refresh after the initial discovery.
- Add settings (`api_url`, `auto_discover`, `available_models` with
per-model `max_tokens` / `supports_tools` / `supports_images`,
`context_window`, `custom_headers`), the provider icon, a `default.json`
entry, and documentation under "Use a Local Model".
No new dependencies: the crate reuses existing workspace dependencies,
and shared state uses `std::sync::RwLock`.
## Testing
- Unit tests in both new crates cover wire/response parsing, model
discovery for single-model and router shapes, the cold-start optimistic
defaults, the in-place capability refresh once a model loads, and the
`/models/sse` event handling (state changes, load failure, load
progress).
- Built Zed locally and ran it against a local `llama serve` router:
confirmed models are discovered without manual configuration, that the
first message works before a model has finished loading, that load
progress is shown in the model's display name while it loads, and that
the reported context length and tool support refine to the model's real
values once it finishes loading.
- Platforms: tested on macOS (Apple Silicon).
## 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
The generation speed (tokens/sec) depends on the machine you're running
the model, here it's a Apple M3 Max 64GB running a 4-bit quant of
https://huggingface.co/Qwen/Qwen3.5-35B-A3B. For the load progress
status, make sure to upgrade your llama.cpp version to the latest build.
https://github.com/user-attachments/assets/0254f6ef-abe9-42ed-810b-ef1a5b8fa3bd
---
Release Notes:
- Added llama.cpp as a language model provider
---------
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
Adding a series of UI tweaks to refine how we display whether a thread
is covered by sandbox. Most notably, separating all the tooltip UI stuff
into a dedicated component so we can get a preview and iterate more
easily on all of its states.
Release Notes:
- N/A
# Objective
Prevent the unexpected modification of files which do not have
established formatting conventions.
Enabling format-on-save by default can cause changes in ecosystems that
don't have established official formatting conventions, or when the
formatting conventions came later through new tools (like JavaScript).
fixes#59427
## Solution
This PR inverts the default, choosing to disable format-on-save by
default, and allowing it to be enabled by users at a global or language
level for any language which has an official formatter. However, any
ecosystem which has an official formatter has been left enabled.
This means languages like Rust, Go, and Zig have `format_on_save`
enabled because they come with official formatting tools, while
JavaScript, C/C++, and Markdown have it disabled by default.
For existing users, this means their custom configurations will stay,
but any values that were previously "default" will be updated.
## Testing
- open a file for the language being tested (ex: `python`)
- formatting should only be enabled if the default for the *language* is
enabled
- formatting can be enabled or disabled at the language level or the
global level in the settings
## 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:
- Disable format-on-save by default, except for languages with official
formatters
# Add status bar location for inline git blame
## Objective
- Closes#12133 by implementing the VS Code-like behavior for status bar
git blame
## Solution
Adds a VS Code–style option to render the current-line git blame in the
status bar instead of inline at the cursor.
Whats new
- A new location setting: Under the inline_blame configuration, you can
now choose between two options:
- `inline` (Default) — Keeps things exactly as they are, showing the
blame details at the end of your current line.
- `status_bar` — Moves the blame info down to the bottom status bar.
- The Status Bar Item: When you choose the status bar option, a clean
new button appears at the bottom left of your window. It features a Git
icon, the author's name, how long ago the change was made, and the
commit summary
- Behaves as it does before, but displayed at a different location
- Clicking the status bar item will instantly open up the full Git
commit details like at vscode
- Settings UI:
- The "Location" control is now a `DynamicItem` nested under "Enabled",
so it only appears when inline blame is enabled.
- Registers a dropdown renderer for `InlineBlameLocation`.
- Updates `all-settings.md` and `visual-customization.md` for the new
option.
## Testing
- Manually tested both modes by toggling `git.inline_blame.location`
between `inline` and `status_bar`:
- `inline` keeps the existing behavior unchanged.
- `status_bar` shows the blame for the focused line in the status bar,
hides the inline blame, updates on cursor movement, clears when no
editor is focused, and opens the blame commit on click.
- Verified the settings UI shows the "Location" dropdown only when
inline blame is enabled.
- Tested with `show_commit_summary` toggled when location is
`status_bar` (for inline location, nothing is changed)
Areas that could use more testing:
- Remote (collab) editors ?
Reviewers can test by setting the following in `settings.json` and
moving the cursor across blamed lines:
```json
{
"git": {
"inline_blame": {
"enabled": true,
"location": "status_bar"
}
}
}
```
## Showcase
<details>
<summary>Click to view showcase</summary>
### Video
https://github.com/user-attachments/assets/6d9f490d-7bf3-473c-9562-8351546dfaf9
### Screenshots
<img width="894" height="749" alt="image"
src="https://github.com/user-attachments/assets/c6a49008-899d-4a0c-9098-1ffb9e28252b"
/>
</details>
Release Notes:
- Added a `git.inline_blame.location` setting to render current-line git
blame in the status bar instead of inline.
Add `ExpandAllEntries` action, keybinding, and right-click context menu
entries for expand/collapse all in the project panel.
- Add `ExpandAllEntries` action + handler + `expand_all_entries()`
method
- Add `cmd-right` / `ctrl-right` keybinding for `ExpandAllEntries`,
mirroring
the existing `cmd-left` for `CollapseAllEntries`
- Add "Expand All" to root-entry and folder right-click context menus
- Add keybinding hint to root-entry "Collapse All" context menu entry
- Per-worktree behavior: context menu actions affect only the selected
worktree,
subfolder "Expand All" expands from that folder down
# Objective
The project panel had no discoverable way to expand or collapse all
entries. The only ways were keyboard shortcuts (`cmd-left` for collapse
all)
or the right-click context menu. The global `ExpandAllEntries` shortcut
(`cmd-right`) was also missing. This PR adds that shortcut and exposes
both actions in the context menu so users learn the keybindings while
keeping the UI minimal.
## Solution
- Add `ExpandAllEntries` action + handler + `expand_all_entries()`
method
- Add `cmd-right` / `ctrl-right` keybinding for `ExpandAllEntries`
(global),
mirroring the existing `cmd-left` for `CollapseAllEntries`
- Add "Expand All" to the right-click context menu for both root entries
and
subfolder entries
- Update root-entry "Collapse All" to show its keybinding hint via
`.action(Box::new(CollapseAllEntries))`
- **Per-worktree behavior**: each root entry's context menu actions
affect
only that worktree, subfolder "Expand All" expands from that folder down
## Testing
- Added 6 GPUI tests in `project_panel_tests.rs`:
- `test_expand_all_entries`: single worktree
- `test_expand_all_entries_multiple_worktrees`: global expand across
worktrees
- `test_expand_all_entries_via_window_dispatch`: action dispatch path
- `test_per_worktree_expand`: expand only the clicked worktree
- `test_per_worktree_collapse`: collapse only the clicked worktree, keep
root visible
- `test_expand_all_entries_with_auto_fold`: expand with auto_fold_dirs
- Ran `cargo test -p project_panel`: 106 pass
**Manual testing for reviewers:**
1. Open a project with nested directories and open the Project Panel
2. Right-click a root entry, confirm "Expand All" and "Collapse All"
appear
with their keybinding hints (`⌘→` / `⌘←`)
3. Right-click a subfolder, confirm "Expand All" and "Collapse All"
appear
4. Click "Expand All" on a subfolder, confirm only that folder's subtree
expands
5. Click "Collapse All", confirm children collapse but the root stays
visible
6. Open a multi-folder workspace. Right-click the second root and click
"Expand All", confirm only that folder expands
7. Press `cmd-right` (or `ctrl-right`), confirm all worktrees expand
globally
Tested on macOS only. Linux and Windows should behave the same since
there
is no platform-specific code.
## 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
https://github.com/user-attachments/assets/adc501d7-8e3a-4687-aef0-dc00426d232d
---
Release Notes:
- Added `Expand All` and `Collapse All` to the project panel right-click
context menu with keybinding hints.
- Added `cmd-right` / `ctrl-right` keybinding to expand all entries.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Closes AI-367
This PR significantly refactors the queue feature so that we don't rely
on indexes being counted and synced across various state points of the
thread view. Instead, I'm introducing a dedicated message queue module
where we control through a stable queue entry ID all the states of a
given queued message.
Additionally, it's relevant to note that I changed the default behavior
of queued messages on this PR so that they get sent only at the end of
the generation. This makes the out-of-the-box, default behavior of the
feature consistent across the native and external agents, given we never
could pull off the feature with the latter. I personally never liked
that behavior anyway, but I do appreciate how some people do. Because of
that, though, for the Zed agent, a "Steer" toggle button is available
for whenever you'd like to signal that a queued message should be sent
at the turn boundary. This is not a setting, though; decided to go
simpler at this moment. It's something you can choose on a per-message
basis.
Ultimately, I think this implementation makes the overall shape of the
feature much more stable and easier to maintain overtime.
Release Notes:
- Agent: Changed the default behavior of queued messages for the Zed
agent so that they get send at the end of the generation. The ability to
steer them (i.e., send the message at the end of a turn boundary) is
still possible to be toggled.
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>
Release Notes:
- Agent: Fixed a bug where trying to open the profile configuration
modal through the picker in the agent panel's message editor wouldn't
work through the keybinding.
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:
- Added initial coverage set of Helix debugger keybindings.
The recent "pickers with previews" overhaul left the picker
sizing/presentation API spread across several overlapping knobs that
every call site had to set correctly — and many didn't, causing pickers
across the app to render at the wrong width, lose their container, or
stop dismissing. This PR consolidates that surface into a small,
hard-to-misuse API and makes correct sizing the default.
Net effect: a plain `Picker::uniform_list(delegate, …)` now renders
correctly out of the box (standard width, standard max-height, shrinks
to fit, dismisses properly), and the ~35 call sites only specify what
genuinely differs.
## API changes
**Presentation** — three overlapping booleans (`is_modal`, `is_popover`,
`is_resizable`) collapsed into one enum, with resizability living inside
the only variant where it's meaningful:
```rust
enum Presentation {
Modal { resizable: bool }, // own chrome, dismisses on blur, optionally resizable
Popover, // own chrome, dismisses on blur, never resizable
Embedded, // host container owns chrome + dismissal
}
```
- `modal(bool)` is **removed** in favor of explicit, self-documenting
builders:
- *(default)* → `Modal` (resizable iff it has a preview)
- `.popover()` → `Popover` (menu-attached surfaces)
- `.embedded()` → `Embedded` (pickers nested in a larger modal/view)
- Dynamic callers use `.when(cond, Picker::embedded)` (added `impl
FluentBuilder for Picker`).
**Sizing** — preview-vs-not now drives everything; the manual padding
knob is gone:
| Before | After |
|---|---|
| `vertical_padding` field + `no_vertical_padding()` | removed — derived
from whether a preview is visible |
| `height(...)` (ambiguous: fixed vs max) | `max_height(...)` (plain
pickers shrink-to-fit, capped here) |
| `minimum_results_width(...)` | removed — a plain picker's min width
tracks its opening width; preview pickers use standard internal pane
mins |
| default size = 60% viewport | default = `DEFAULT_MODAL_WIDTH` (34rem)
× `DEFAULT_MODAL_MAX_HEIGHT` (24rem, max) |
| resize handles gated on `is_modal` | gated on `is_resizable` (new
`resizable(bool)` builder; auto-`true` for preview pickers) |
Call sites now only override the exceptions: narrow popover selectors
(`initial_width`), the taller outline view (`max_height`), and preview
pickers (constructed via `*_with_preview`).
## Behavior fixes
- **Wrong widths everywhere**: pickers were falling back to
60%-of-viewport because the original migration set
`minimum_results_width` but never `initial_width`. Fixed at the source
via the new defaults.
- **Popovers had no container and wouldn't dismiss**: `is_modal=false`
was suppressing both the elevated background *and* blur-dismiss. Split
out so popovers keep their chrome and dismiss on click-away/escape. This
fixed the agent-panel model/profile selectors, sidebar recent projects,
and the settings theme/font/icon/ollama pickers (which were incorrectly
using `modal(false)`).
- **Sidebar recent projects stretched to full height**: was missing the
shrink-to-fit behavior; now capped and content-sized like other
popovers.
- **Preview crash**: removed an over-strict `debug_assert!` that
panicked when previewing an empty file (`message == None && editor
empty` is valid).
- **Preview-aware default size**: pickers open at standard width with
the preview hidden, and expand to the larger "telescope" size when a
preview is shown. Fixes the text finder rendering super-wide by default,
and makes the file finder expand (rather than cram its results) when you
toggle the preview.
---
Release Notes:
- N/A
# Objective
The current behavior of the git panel is that when you click a file it
will open the multi-buffer view that shows all files with changes. If
you use CMD+Click or CTRL+Click, it will open the solo-file experience
where you only see the diff of the file you have selected. But, there is
no way to customize this behavior.
Related to:
https://github.com/zed-industries/zed/pull/56152#issuecomment-4641971669
## Solution
This MR adds a setting that allows you to customize the default click
behavior. The alternate behavior will always be accessible via CMD+Click
or CTRL+Click.
## 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:
- Added a setting to control default click behavior for git panel files
---------
Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
Self-Review Checklist:
- [x] I have reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed 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
## Summary
This updates the Git Panel view controls so the panel can independently
model:
- whether entries are shown as a list or tree
- whether flat entries are sorted by path or name
- whether entries are grouped by status or shown as one combined set
It also keeps the Project Diff order consistent with the Git Panel,
including tree ordering, status grouping, and flat name/path sorting.
## Why This Is Useful
The previous sort_by_path boolean overloaded two separate ideas: sorting
and grouping. That made it hard to represent the view users actually
wanted, especially a single tree where tracked and untracked files are
not split into separate sections.
This change replaces that boolean with explicit enum settings:
- git_panel.sort_by: path or name
- git_panel.group_by: none or status
That keeps the settings mutually exclusive, easier to extend, and closer
to the UI model.
## Implementation Notes
- Adds a dedicated Git Panel View Options menu using the sliders icon.
- Moves view, sort, and group controls out of the overflow actions menu.
- Disables sort options in tree view because tree order is folder-first
rather than pure path/name sorting.
- Removes the Tracked heading when grouping is disabled.
- Keeps Git Panel tree expansion state when switching view options.
- Recomputes Project Diff sort prefixes from tree_view, sort_by, and
group_by so diff cards follow the same top-to-bottom order as the Git
Panel.
- Preserves Project Diff open/closed file state across view option
changes by carrying fold state by repo path instead of by synthetic sort
key.
- Updates settings UI renderers and docs for the new enum settings.
## Testing
- [x] cargo fmt --package git_ui --package settings_ui
- [x] cargo check -p git_ui
- [x] Verified settings UI enum dropdown rendering for Git Panel
sort/group settings
Closes https://github.com/zed-industries/zed/issues/53555
Closes https://github.com/zed-industries/zed/issues/56039
Closes https://github.com/zed-industries/zed/issues/45438
Release Notes:
- Improved Git Panel view options and Project Diff ordering.
---------
Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
Overhauls Zed's pickers to make them resizable and give them a preview.
Closes#8279
### Background
The most requested Zed feature has the last year has been a [Telescope
like search box](https://github.com/zed-industries/zed/issues/8279)
[discussion](https://github.com/zed-industries/zed/discussions/22581).
To understand why this is so popular we need to understand search can
serve thee goals:
- Navigation: fuzzy search is faster & easier then clicking in a file
tree
- Exploration: example, find a function by a word in its doc comment
- Collecting: example, getting a list of functions to change
The project search which shows results in a multibuffer is the perfect
way to operate on a list of items. Navigation and Exploration need a lot
of context around each result and offer fast navigation between them.
For both of these live searching is also critical.
The `telescope UI` is a picker with a preview to the right or below.
It's offered in various editors and IDE's most famously Neovim (through
the Telescope plugin), IntelliJ (natively), Helix (natively) and of
course VScode (plugins) and it's _many_ forks.
While having a UI like that for text search (our project search) is most
requested the UX pattern is applied widely, from `find_all_references`
to `bookmarks`. It enhances most pickers. Note that we have over 50
different picker modals!
The community has tried to build something like this for Zed:
- https://github.com/zed-industries/zed/pull/44530
- https://github.com/zed-industries/zed/pull/45307
- https://github.com/zed-industries/zed/pull/46478
- https://github.com/zed-industries/zed/pull/43790
These all became huge PR's that we could not merge for various reasons.
This is a really hard feature to integrate in Zed!
This PR got started as https://github.com/zed-industries/zed/pull/46478
and supercedes that.
### Design
- Extend pickers to support an optional preview with minimal changes to
the pickers themselves.
- Make pickers resizable.
- Complement the existing search do not replace it by having both UI's
share the underlying search and allow freely switching between them.
- Allow extending the preview to things other then files.
- Maintain a clean design on all the pickers.
### Heigh level Implementation overview
- Adds an `Option<Preview>` to `Picker`
- Gives `PickerDelegate` a method to communicate a preview to the Picker
- Overhaul the way pickers are drawn to allow for resizing them.
Implemented on the `Shape` and `SizeBouds` structs.
- Adds a high level way to draw the `footer` and `editor` so we do not
need to change much to the pickers.
- Adds a new text finder Picker
- Adds a way to take a running search from project search and hand it to
the text finder Picker and the other way round
- Give the file finder a preview
### Next steps
A more detailed list and how to help out will be added to the tracking
issue for [Pickes with
previews](https://github.com/zed-industries/zed/issues/56037)
- Add more previews to more pickers!
- Enable selectioning multiple items in pickers and performing actions
on those
- Open selected items in a multibuffer
- Add a way to restore the last picker
- Make popovers (picker attached to some menu) resizable as well
## 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
TODO (will be done post merge)
---
Release Notes:
- Added resizing via dragging to all picker modals.
- Added a preview to the File finder, the preview can be to the right or
below.
- Added a Text finder picker with a preview as alternative project
search UI. The search is shared and allowes switch between UIs while
running.
---------
Co-authored-by: ozacod <47009516+ozacod@users.noreply.github.com>
Co-authored-by: ozacod <ozacod@users.noreply.github.com>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
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` `13e7c11768` (full `release`
profile, with LTO and `codegen-units=1` built and tested at that
commit). Branch since merged with `upstream/main` `a6780a5`. 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>
This PR introduces a markdown preview max-width setting in which we
allow to limit by a given pixel number how wide the content within the
preview tab should go. Before this, content would render edge-to-edge
and if you're reading long markdown docs with no split panes, having it
be full width like that was a horrible reading experience.
So, right now, you can control that through the
`zed://settings/markdown_preview.max_width` setting.
<img width="600" alt="Screenshot 2026-06-18 at 1 24@2x"
src="https://github.com/user-attachments/assets/7f0216e1-e4ac-47f7-975b-5de7a0dd4c6d"
/>
Release Notes:
- Added setting to control max-width of content within the markdown
preview.
## Summary
- Adds an `agent.terminal_init_command` setting for Terminal Threads.
- Runs the configured command automatically when creating a new Terminal
Thread, while skipping restored terminal threads.
- Documents the setting and exposes it in the AI settings page.
Closes https://github.com/zed-industries/zed/issues/58697
Closes AI-337
Release Notes:
- Added a setting to automatically run a command when opening a new
terminal thread in the agent panel.
---------
Co-authored-by: Anant Goel <anant@zed.dev>
Fix `cmd-c` not copying text inside macOS notebook cell editors.
Previously, the macOS notebook keymap bound `cmd-c` to
`notebook::InterruptKernel` in notebook contexts, including
`NotebookEditor > Editor`. This shadowed the normal editor copy shortcut
while editing notebook cells.
## Solution
Move the macOS notebook interrupt shortcut from `cmd-c` to `ctrl-c`.
This keeps the notebook interrupt shortcut available while allowing the
normal editor keybindings to handle:
- `cmd-c` for copy
- `cmd-x` for cut
- `cmd-v` for paste
inside notebook cell editors.
- This change is macOS-specific.
Release Notes:
- N/A
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
## Summary
Add keyboard shortcut for macOS, in the ACP Permission dialog, for
"Always Allow", following what is available in both Linux and Windows.
### 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
- [ ] Performance impact has been considered and is acceptable
Release Notes:
- Added missing `AllowAlways` keybinding on macOS (`cmd-alt-y`).
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
This is a bit too opinionated to be turning on for everyone by default.
We could consider bringing back a default-enabled setting with a less
intrusive UI.
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:
- Warnings about the lengths of commit message titles are now disabled
by default.
Adds `default_open_behavior` which let's users control which action
should be the default (add to existing window/open a new window)
TODO:
- [x] Use sensible icon (not `IconName::Screen`) when
`default_open_behavior` is set to `new_window`
- [x] Tweak wording for actions in recent projects menu
<img width="420" height="59" alt="image"
src="https://github.com/user-attachments/assets/69ef112e-bf20-4dd1-9994-e4442266ef87"
/>
Release Notes:
- Added `default_open_behavior` which controls which action (add to
sidebar/open in new window) should be the default when selecting a
project from the recent projects menu
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
<img width="325" height="201" alt="Screenshot 2026-06-09 at 1 38 32 PM"
src="https://github.com/user-attachments/assets/a6518073-1e17-41ff-a8fc-cb279fcd4436"
/>
Adds support for Anthropic's Claude Fable 5 model when using your own
Anthropic API key. Because Fable 5 cannot be offered under Zero Data
Retention (Anthropic retains inference logs for 30 days), this gates the
model behind an explicit data-retention consent: a new
telemetry.anthropic_retention setting (default off, surfaced in the
Privacy section of the settings UI), and a hard, non-retryable check in
the cloud completion path that raises a typed error when consent is
missing.
When Fable 5 declines a request, it transparently falls back to Claude
Opus 4.8 (matching Anthropic's server-side behavior), and the agent
panel shows a callout for the consent error with "Switch to Opus 4.8" /
"Accept" actions that resume the failed turn so the user's message
continues without retyping.
Closes AI-382
Release Notes:
- Add Claude Fable 5 to Anthropic BYOK
---------
Co-authored-by: Mikayla Maki <mikayla@zed.dev>
Here are the things I tried to tackle on this PR:
- Make the compaction call stand out a bit more from other regular tool
calls
- Make text size of the compaction's markdown output be consistent with
the thread body text
- Don't show regular thread loading spinner while compaction is in
progress, given that has its own spinner
- Add a different icon than scissors for compaction and add it to the
autocomplete menu so its consistent w/ skills items
<img width="600" alt="Screenshot 2026-06-09 at 10 57@2x"
src="https://github.com/user-attachments/assets/5c3d25af-aa49-42e1-b6b6-c3f95c664456"
/>
Release Notes:
- N/A
Adds two new agent settings nested under `auto_compact`, `enabled` and
`threshold`, which control automatic compaction of the agent's context
window as part of the handoff feature. Both surface in the settings UI
under Agent Configuration, gated behind the `handoff` feature flag so
they only appear for users on that flag.
The `threshold` accepts three forms: a percentage string ending in `%`
(e.g. `"80%"` or `"95.5%"`) measured against the model's context window,
a positive integer to compact after that many tokens have been used, or
a negative integer to compact once that many tokens remain in the
window. `0` and bare non-integer numbers are rejected. It deserializes
from either a JSON string or integer and resolves to a typed enum,
falling back to the `"80%"` default (with a logged warning) when the
configured value is invalid. In the settings UI the threshold is a
free-form text field so all three forms can be entered.
Release Notes:
- N/A
---------
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Resolves https://github.com/zed-industries/zed/issues/55617
This diff makes the standard Reveal in Finder/File Manager shortcut work
when an image tab is focused. Image tabs already expose the reveal
action from the tab context menu, but the keyboard shortcut was only
bound in the `Editor` context, so pressing `cmd-k r` on macOS or `ctrl-k
r` on Linux/Windows did nothing while focus was in the image viewer.
With this change, `ImageView` handles the existing
`editor::RevealInFileManager` action, and the default keymaps bind the
same reveal shortcut in the `ImageViewer` context. This keeps image tabs
consistent with text editor tabs while reusing the same project path
reveal path used elsewhere.
Release Notes:
- Fixed Reveal in Finder/File Manager shortcuts not working when an
image tab is focused.
Co-authored-by: Joseph T. Lyons <JosephTLyons@gmail.com>
Closes AI-344
Closes AI-342
Moves agent skills management out of the agent panel and into the
settings UI. The skill creator (previously its own crate) now lives in
`settings_ui` as a settings page, alongside the skills setup page. The
agent panel's ellipsis menu now links to the settings page instead of
hosting skill management directly.
Release Notes:
- Improved agent skills management by moving it into the settings UI
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Neither really panned out, removing for now.
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:
- N/A
For the longest time, we've had a labeled "Share" button on the title
bar whenever you're in a call. However, it was extremely easy to click
that button thinking you'd be sharing _your screen_ instead of your
project. At the end of the day, there wasn't any specific cue that'd
allow you to know what you'd be sharing. This is why people just assumed
you'd share the screen, which is arguably way more common than sharing
the project. We've seen users bump into this confusion countless times,
and this also even happens to us (the whole Zed staff) weekly whenever
we're in meetings.
So, this PR changes that button to be an icon button instead, using a
folder icon to better communicate it means sharing the project. I also
took advantage of the opportunity to change the approach we use for
adding these buttons, using `when` instead of `children.push`; I think
the former is just easier to understand, allowing to more easily picture
the UI in your (my) head. Lastly, also improved what we display in the
tooltip for the project share button, by showing the names of all
projects you'll be sharing, as well as the tooltip that displayed call
diagnostics.
| Before | After |
|--------|--------|
| <img width="778" height="360" alt="Screenshot 2026-06-05 at 3 48
2@2x"
src="https://github.com/user-attachments/assets/363593fb-79f8-42e9-83b9-345bc731846f"
/> | <img width="778" height="360" alt="Screenshot 2026-06-05 at 3 48
3@2x"
src="https://github.com/user-attachments/assets/32afc412-a1fb-45a4-a19e-74e4923c0c8b"
/> |
Release Notes:
- Improved call controls design, making it clearer what button shares
_the project_ vs. _the screen_.