Quick follow up to https://github.com/zed-industries/zed/pull/61397,
where there was a bug in background color for the extra controls on each
item flashing as a click on any item's disclosure occurred.
Release Notes:
- N/A
This PR converts the collab panel list from a GPUI list into a uniform
list, which was a requirement for the indent guides to be displayed. I
have been wanting to add that to the channels list for a while, and
finally carved out some time. Ended up adding some more tweaks here and
there as overall improvements (e.g., using a lock icon for private
icons) and to make the indent guide fully work design-wise given we have
the chevron buttons rendering on top of them.
Here's how it looks:
<img width="600" alt="Screenshot 2026-07-21 at 10 08@2x"
src="https://github.com/user-attachments/assets/351b7e0f-aeb4-4c79-8177-7f1cdf635fbe"
/>
Release Notes:
- N/A
---------
Co-authored-by: MrSubidubi <finn@zed.dev>
Reverts zed-industries/zed#60892
Realised this is probably not the desired behavior. Context menu is not
really useful when the app is full canvas. I think it's better to not
have the browser context menu on web at all. My bad and sorry for the
hassle!
# Objective
This change fixes an issue where once a single file has had it
diagnostics disabled, it will permenently make re-enabling diagnostics
in that specific file, no longer possible by either command or keybind.
This fixes issue #60958.
## Solution
This solution is quite simple. The logic used for registering the action
in the editor used a one way flip. The editor read the `cx` and then
checked its `diagnostics_enabled()` and `inline_diagnostics_enabled()`
and if they were disabled they would not register the corrosponding
`Editor::toggle_diagnostics` and `Editor::toggle_inline_diagnostics`
respectively. This meant once toggled off, the editor was no longer able
to register the action as it was already disabled, and thus made the
"toggle" part impossible. The fix simply removes the state checks for
the current editor and will leave the actions registered.
## Testing
This has been both manualy tested as well as had an `editor_tests.rs`
test added. Simply taking in the the `EditorTestContext`, then checks
the starting state, then toggles the diagnostics off and checks that it
correctly shows the state change, and then proceeds to re-enable the
diagnostics state, and check its again to make sure the appropriate
state has been set.
I manually tested this on windows_11_x64/x86(Desktop),
archlinux_7.0.10_x64/x86(Laptop), and it has **not** been tested on my
mac mini **yet**. However, the change 'should' be platform agnostic. If
someone wants to review this, they can simply open their settings file
with the JSONC lsp `on` and then disable their diagnostics and then, the
option to re-enable them, toggle, will now show up and also be able to
be executed by the keybinds too.
## 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
<details>
<summary>Click to view showcase</summary>
Original Behaviour:
[Zed Diagnostic Toggle (Original
Behaviour).webm](https://github.com/user-attachments/assets/bca860cd-f7e9-42b9-9456-56b9b1d2604f)
New Behaviour:
[Zed Diagnostic Toggle (New
Behaviour).webm](https://github.com/user-attachments/assets/e3629491-abb5-4e29-95ab-e8f0464db726)
</details>
---
Release Notes:
- Fixed `editor::ToggleDiagnostics` & `editor: toggle diagnostics`
permanently turning off diagnostics for the current file/editor,
addressing issue #60958.
---------
Signed-off-by: Counterfit IQ <logicye@proton.me>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
## Summary
- Open relative file links with GitHub-style line fragments at the
referenced line
- Support line navigation from agent responses and Markdown previews
- Preserve decoded-first path resolution with literal percent-escape
fallback
## Testing
- cargo test -q -p util test_source_line_from_fragment -- --nocapture
- cargo test -q -p acp_thread test_hyperlink_percent_escapes_are_decoded
-- --nocapture
- cargo test -q -p agent_ui test_open_link -- --nocapture
- cargo test -q -p markdown_preview -- --nocapture
- cargo fmt --all -- --check
Release Notes:
- Improved relative file links with line numbers to open at the
referenced line.
# Objective
Follow-up to #60898 (as suggested by @tomhoule ). That PR marked
`mistral-medium-latest` as supporting thinking, but the flag is
currently a no-op: unlike Magistral, whose reasoning was native, Mistral
Medium 3.5 and Small 4 only emit thinking chunks when the request sets
`reasoning_effort: "high"` (see [Mistral's reasoning
docs](https://docs.mistral.ai/studio-api/conversations/reasoning)), and
the `Request` struct had no such field.
Related: #57581
## Solution
- Add a `ReasoningEffort` enum and an optional `reasoning_effort` field
to the Mistral `Request`. The field is skipped during serialization when
`None`, so requests for non-reasoning models (Codestral, Large,
Ministrals) are byte-identical to before.
- Set `reasoning_effort: "high"` in `into_mistral()` when the model
supports thinking and the request allows it. The rest of the pipeline
already works: `MistralEventMapper` handles `MessagePart::Thinking`
deltas, and `into_mistral` replays thinking parts into history, matching
Mistral's requirement to replay the reasoning trace across turns.
- Add `mistral-small-latest` to `supports_thinking()`: it now points to
Mistral Small 4, a hybrid reasoning model like Medium 3.5.
- Cover the Ministral variants in `Model::from_id()`, which previously
rejected `ministral-3b-latest` / `ministral-8b-latest` /
`ministral-14b-latest` as invalid ids even though the enum defines them.
## Testing
- Added `test_into_mistral_reasoning_effort` covering the three cases:
thinking model with thinking allowed (sends `high`), thinking model with
thinking disallowed (omits the field), and non-thinking model (omits the
field).
- Existing Mistral provider tests pass (`cargo test -p language_models
mistral`); both touched crates are clippy-clean.
- Reviewers can test by configuring a Mistral API key, selecting
`mistral-medium-latest` or `mistral-small-latest` in the agent panel,
and confirming thinking blocks stream in; with a non-reasoning model
like Codestral, requests are unchanged.
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] 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 thinking not being triggered for Mistral Medium 3.5 and Mistral
Small 4, and fixed custom Mistral configurations rejecting Ministral
model ids
Tiny tiny tweak just adjusting the thinking icon color so its consistent
with the fast mode icon. Icons that are _toggled_ on and off should be
displayed in a colorful way so its obvious in which state they're in.
---
Release Notes:
- N/A
When testing Zed on our team's Devcontainer I found some missing
features/bugs/spec mismatches. Commit messages were written by hand,
code reviewed and tested manually, but everything was written by
Claude/Codex based on:
- https://github.com/devcontainers/cli
- https://github.com/devcontainers/spec
The main use case of the metadata is that you can `devcontainer exec`
and `devcontainer up` into a container Zed started (and vice versa). The
same with VSCode, it will reuse Zed's created devcontainer correctly
now. This is useful when using LLMs so they can run commands in the same
devcontainer you have open.
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 Dev Container compatibility and lifecycle behavior.
# Objective
Fixes#61391Fixes#60876
Fix Agent Panel prompt text and controls being clipped when the panel is
narrow.
## Solution
- Allow the message editor and ACP configuration controls to shrink and
wrap.
- Use a dynamic minimum panel width based on the active Agent's prompt
text.
- Cap that dynamic width so long prompts, such as Zed Agent's, do not
prevent the panel from being resized narrower.
## Testing
- `cargo fmt --all -- --check`
- `cargo check -p agent_ui`
- `cargo test -p agent_ui --lib
conversation_view::tests::test_restored_threads_keep_available_commands`
- `cargo test -p agent_ui --lib config_options::tests`
Manual UI testing is still recommended for Zed Agent and third-party
Agent Panels at narrow widths.
## 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
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
## Showcase
https://github.com/user-attachments/assets/71825d64-6e5d-40fe-98a4-dcb13903e06b
---
Release Notes:
- Agent: Fixed agent panel placeholder and controls overflowing when the
panel width was narrow.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Allows you to click on the zoom percent to edit it. Right clicking the
percentage resets to 100%.
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
Release Notes:
- Added support for editing image viewer zoom levels directly from the
toolbar.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
# Objective
Delay picker refreshes for entry updates so bursty filesystem events
trigger only one search refresh, while still refreshing immediately when
worktrees are added or removed.
Update tests to advance both the watch latency and refresh debounce, and
add coverage for coalesced worktree updates.
## 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:
- N/A
---------
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
Typing a backtick over selected text in Rust, C, and C++ comments
replaced the selection instead of wrapping it. Markdown already supports
this via its backtick bracket pair.
Add a backtick bracket pair for these languages:
- `surround = true` wraps selections in backticks
- `close = false` avoids auto-closing lone backticks
- `not_in = ["string"]` enables it in comments but not strings
Self-Review Checklist:
- [X] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [X] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [X] Tests cover the new/changed behavior
- [X] Performance impact has been considered and is acceptable
Closes#58538
Release Notes:
- Added support for surrounding selected text with backticks in Rust, C,
and C++
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
## Context
Closes#58571
When editing `settings.json`, typing a new key under `languages`
triggers language-name autocomplete. The same did not work for
`file_types`, even though both keys map language names to configuration.
The root cause: the JSON schema generator uses `replace_subschema` to
inject installed language names as the allowed properties of a named
type. The `languages` field backed by `LanguageToSettingsMap` (a named
newtype) got this treatment; `file_types` was backed by a raw
`HashMap<Arc<str>, ExtendingVec<String>>` with no named type to target.
The fix introduces a `FileTypeMap` newtype parallel to
`LanguageToSettingsMap` and wires it into the same schema-injection
path.
Video of manual test below :
[Screencast from 2026-06-05
00-04-16.webm](https://github.com/user-attachments/assets/5d8afb60-d566-4c99-ad2a-66ebbb47ed2e)
## How to Review
- `crates/settings_content/src/language.rs` : Adds
`FileTypeMap(HashMap<Arc<str>, ExtendingVec<String>>)` with the full set
of derives (`Debug`, `Clone`, `Default`, `PartialEq`, `Serialize`,
`Deserialize`, `JsonSchema`, `MergeFrom`) and an `IntoIterator for
&FileTypeMap` impl so existing call sites
(`all_languages.file_types.iter().flatten()`) continue to work without
changes. Changes the `file_types` field in `AllLanguageSettingsContent`
from the raw HashMap to `Option<FileTypeMap>`.
- `crates/settings/src/settings_store.rs` : In
`configure_schema_generator`, adds a `replace_subschema::<FileTypeMap>`
call mirroring the existing `LanguageToSettingsMap` one: injects
installed language names as the allowed properties, with
`ExtendingVec<String>` (array of glob patterns) as the value schema.
Adds `test_file_types_schema_generation` to verify the injected
properties.
- `crates/settings/src/vscode_import.rs` : Updates `file_types()` to
return `Option<FileTypeMap>` and wraps the constructed map accordingly.
- `crates/language/src/buffer_tests.rs` : Updates the existing custom
`file_types` test setup to extend the inner map of the new `FileTypeMap`
wrapper explicitly, keeping the language crate test build passing after
the type change.
## 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
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
**Release Notes :**
- Fixed language name autocomplete not working in the `file_types`
setting
---------
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
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
Closes#42353
Release Notes:
- Fixed extension building failing on systems where Rust is installed
without rustup (e.g., NixOS, distro packages)
---------
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
Closes#10045
follow repro steps:
1. Open the command palette cmd-shift-p.
2. Locate and click language selector: toggle.
3. cmd-shift-p.
4. Click language selector: toggle.
5. Notice that the command palette is closed.
When the command palette is reopened on top of the already-open language
selector, the palette captures previous_focus_handle before the old
modal is hidden. In that case, previous_focus_handle refers to the
language selector picker, which is the correct previous focus at that
moment. The problem is that this modal is immediately dismissed (as the
language toggle gets hidden and command palette is shown in 3rd step)
and no longer exists by the time the selected command is confirmed.
Fix
Updated CommandPalette::toggle so that if another modal is already open,
it is dismissed first. Only after that dismissal completes does the
command palette capture window.focused(cx) as its previous_focus_handle.
This means the command palette now stores the real pre-palette focus
target, such as the editor or workspace, instead of storing focus from a
modal that is about to be removed.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content is consistent with the [UI/UX
checklist](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:
- N/A or Added/Fixed/Improved ...
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Closes FR-130
Builds compiled from source at a release tag report a non-dev release
channel, so they used to install the crash handler and write minidumps
into the shared logs directory. An official Zed launched later would
find and upload those dumps to Sentry, where they can never be
symbolicated (their debug UUID matches no uploaded debug files).
Gate the crash handler on having somewhere to send the dumps: either the
compile-time ZED_MINIDUMP_ENDPOINT baked into official builds, the
runtime ZED_MINIDUMP_ENDPOINT override, or an explicit
ZED_GENERATE_MINIDUMPS opt-in for debugging the crash pipeline locally.
Release Notes:
- N/A
# Objective
Unify dependencies inside of the root `Cargo.toml` to prevent versions
from going out of sync and creating copies of dependencies.
## Testing
- All tests pass, nothing touches the `Cargo.lock`
## Review
Review is easiest by going through commit by commit.
Release Notes:
- N/A or Added/Fixed/Improved ...
Fixes what https://github.com/zed-industries/zed/pull/57748 does for
buffer search.
When project search is deployed with regex mode enabled and the query is
seeded from the editor's selection or the word under the cursor, that
text is literal, so regex chars in it (e.g. `.` in `z.d`) are now
escaped instead of being interpreted as regex syntax. This follows how
VSCode handles it.
Release Notes:
- Fixed project search queries seeded from the current selection being
interpreted as a regular expression instead of literal text when regex
mode was enabled.
# Objective
Fixes#44529
## Solution
Earlier, the container holding the right side of the title bar applied a
conditional right padding depending on the whether the user was signed
in or not. This PR removes the conditional padding and replaces it with
a constant.
## Testing
The changes where visually verified by replicating the issue and seeing
if the fix works.
## 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
## Showcase
[](https://github.com/user-attachments/assets/017099c3-224e-4e32-9f28-66961e244d1b)
---
## Release Notes:
Fixed drop down arrow shifting upon logging in.
with `hard_tabs: true` and `tab_size: 4`, shift-alt-down off a
tab-aligned column drops the cursor in the wrong spot:
```
current.rgb.r ˇ= p[0] >> 8; <- cursor here
residuals[run].rˇgb.r = p[0] & 0xff; <- lands here, not on the =
```
both `=` render at column 48 but sit at buffer columns 22 and 27, since
a different number of tabs pads each row. shift-alt-down is
`skip_soft_wrap: true`, which placed the cursor by utf16 column where a
tab counts as one.
so count the column with tabs expanded instead. still a column and not a
pixel position, so the buffer-column behaviour
`test_add_selection_skip_soft_wrap_option` pins doesn't change (without
tabs the expanded column *is* the buffer column). tried pixels first and
it breaks that test, since x is measured inside a wrapped segment.
heads up that the existing tests here all pass `Default::default()`,
which is `skip_soft_wrap: false` (the `default_true` only applies to
deserializing), so nothing covered the branch the keybinding actually
uses.
Closes#60752.
Release Notes:
- Fixed added cursors landing in the wrong column when using tabs to
align code
Closes#34698
The buffer search query input is itself an editor, so dispatching
`editor::ToggleSoftWrap` from the command palette while the search bar
had focus toggled soft wrap on the single-line query editor (with no
visible effect) and never reached the searched editor.
This intercepts the action on the search bar in the capture phase and
applies it to the active searchable item, the same way `ToggleFoldAll`
is already relayed. Focus stays in the search bar, so you can keep
typing your query. `Editor::toggle_soft_wrap` and
`Editor::soft_wrap_mode` become `pub` (matching
`fold_all`/`has_any_buffer_folded`, which the existing `ToggleFoldAll`
relay already uses).
Includes a regression test that fails without the fix: it deploys the
search bar, dispatches `ToggleSoftWrap` with the query editor focused,
and asserts the searched editor's wrap mode changes while focus remains
in the search bar.
Release Notes:
- Fixed `editor: toggle soft wrap` doing nothing when invoked while the
buffer search bar was focused
---------
Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
Adds a title_bar.show_worktree_name setting (default: true) that hides
the worktree picker button in the title bar, mirroring how
show_branch_name gates the branch picker. The "/" separator only renders
when both buttons are visible, and the container is omitted entirely
when both are hidden.
The setting is hide-only: it deliberately does not join the
render_project_items gate, so configurations with show_branch_name and
show_project_items both disabled keep hiding the whole group as before.
Requested in discussion
[zed-industries/zed#54902](https://github.com/zed-industries/zed/discussions/54902).
# Objective
The worktree name is always present in the title bar even when unused.
Unlike the branch name it has no dedicated option to disable it.
Requested in discussion
[zed-industries/zed#54902](https://github.com/zed-industries/zed/discussions/54902).
## Solution
Adds a `title_bar.show_worktree_name` setting (default: true) that hides
the worktree picker button in the title bar, mirroring how
show_branch_name gates the branch picker. The "/" separator only renders
when both buttons are visible, and the container is omitted entirely
when both are hidden.
The setting is hide-only: it deliberately does not join the
render_project_items gate, so configurations with show_branch_name and
show_project_items both disabled keep hiding the whole group as before.
## Testing
I tested the setting added by running the application by adding,
removing and toggling the `title_bar.show_worktree_name` setting in the
`settings.json`
## 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
- [ ] Performance impact has been considered and is acceptable
## Showcase
<img width="1496" height="982" alt="title_bar.show_worktree_name =
false"
src="https://github.com/user-attachments/assets/b2c502de-a8d8-4409-ba04-5ab807c77a8e"
/>
<img width="1496" height="982" alt="title_bar.show_worktree_name = true"
src="https://github.com/user-attachments/assets/6cea7eb5-0e88-454c-9c97-3b4ad62aed51"
/>
---
Release Notes:
- title_bar: Added title_bar.show_worktree_name (default: true) to hide
worktree picker button
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
on linux with the emacs keymap, holding `ctrl-n` at the end of the
buffer opens a new file every press. `ctrl-p` at the top opens the file
finder.
the keymap already tries `"ctrl-n": null`, but `null` only breaks
resolution in a *user* keymap, so from a base keymap
`workspace::NewFile` still resolves. a targeted unbind works regardless
of source:
```json
"ctrl-p": ["zed::Unbind", "file_finder::Toggle"],
"ctrl-n": ["zed::Unbind", "workspace::NewFile"],
```
left the MoveDown/MoveUp propagation alone, it's load bearing (agent
panel uses it for up-to-edit-last-message). tests cover the fix plus the
narrower ctrl-n/ctrl-p bindings still winning, since the unbind only
targets the one action.
ctrl-g/ctrl-x in that block are still null and probably just as broken,
but ctrl-x is a prefix key so i left them.
Closes#45010.
Release Notes:
- Fixed `ctrl-n` opening a new file and `ctrl-p` opening the file finder
at the ends of a buffer when using the Emacs keymap on Linux
# Objective
- Make runnable task results visible directly in the editor gutter after
running a test or task.
- This makes it easier to see whether the last run passed or failed
without looking at the terminal output.
## Solution
- Track the completion result for scheduled runnable tasks.
- Show the last runnable result in the gutter:
- running task: accent play icon
- successful task: success check icon
- failed/cancelled task: error icon
- Apply the same status update path when running from the gutter play
button and from inline code lens actions such as `Run Test`.
## Testing
- Ran `cargo check -p editor -p workspace`.
- Ran `cargo test -p workspace
test_schedule_resolved_task_with_completion_reports_success`.
- Manually tested running a GPUI test from the gutter play button.
- Manually tested running a GPUI test from the inline `Run Test` code
lens.
- Verified the gutter icon updates after completion in both cases.
## 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="1897" height="691" alt="before"
src="https://github.com/user-attachments/assets/614c2811-ee0a-43c0-8619-d0301836aa62"
/>
After:
<img width="1897" height="691" alt="after"
src="https://github.com/user-attachments/assets/a3db19f2-71e6-4c9b-824d-43a4f020a6b7"
/>
---
Release Notes:
- Improved runnable tasks by showing the last run result in the editor
gutter.
## Objective
Prevent a use-after-free when a macOS pasteboard wrapper outlives the
autorelease pool in which it was created.
Pasteboard cached its NSPasteboard and custom zed-text-hash and
zed-metadata NSString objects as raw ids. These constructors return
autoreleased objects. A later clipboard read could therefore pass a
dangling type identifier to dataForType and crash in objc_msgSend.
## Solution
- Retain the pasteboard and custom type objects for the Pasteboard
lifetime with StrongPtr.
- Copy NSData contents into owned Rust byte buffers before the
autoreleased data object can expire.
- Add a regression test that drains the creation autorelease pool and
then accesses the retained custom types.
## Testing
- cargo test -p gpui_macos --features runtime_shaders
test_custom_types_survive_creation_autorelease_pool --lib
- Built an optimized macOS embedder against the patched GPUI checkout.
## Self-Review Checklist:
- [x] I have reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks have justifying comments
- [x] The content adheres to Zed UI and icon standards; this change has
no UI
- [x] Tests cover the changed lifetime behavior
- [x] Performance impact has been considered and is acceptable
---
Release Notes:
- Fixed a macOS crash that could occur when reading from the clipboard.
---
AI Disclosure: I ran into this bug on a project where I'm using GPUI.
For my purposes I patched it on my fork I maintain. I had codex (gpt
5.6-sol) send this PR because I think this fix should be upstreamed.
# Objective
Make solo diff views show the full file by default while preserving an
easy way to focus on changed hunks. This addresses a recurring request
across issues and pull requests for full-file context in single-file Git
diffs.
## Solution
- Initialize the solo diff with a singleton multibuffer so the entire
file is visible on open.
- Keep the existing toolbar toggle available for switching to
changes-only excerpts.
- Use the singleton path key when replacing excerpts so toggling remains
reliable.
- Preserve Git change indicators in the scrollbar; the editor generates
those markers for singleton buffers.
## Testing
- Ran `cargo fmt -p git_ui`.
- Ran `git diff --check`.
- Ran `cargo check -p git_ui --no-default-features` successfully.
- Manually reviewed the full-file and changes-only state transitions in
`SoloDiffView`.
## 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, solo diffs opened with only changed hunks and surrounding
context. They now open with the complete file, retain Git change
indicators in the scrollbar, and can still be toggled to changes-only
from the toolbar.
---
Release Notes:
- Improved solo diffs to show the full file by default while retaining
Git change indicators in the scrollbar.
Follow up to https://github.com/zed-industries/zed/pull/61245. That PR
introduced a bug where the thread controls would appear at seemingly
random tool boundaries as opposed to only at the end of each turn. It
caused this sort of behavior, where we'd have many instances of those
buttons showing up:
<img width="500" alt="Screenshot 2026-07-20 at 4 03 2@2x"
src="https://github.com/user-attachments/assets/6e6f716e-adb5-4532-9f89-e955398cda23"
/>
Alongside with fixing it, this PR is also making the "scroll to top"
only show up only at the very last turn. I think that makes more sense
given you'd be most likely interested to go to the top when you're at
the bottom, rather than at every turn, but I could be persuaded
otherwise; not holding that too strongly.
Release Notes:
- N/A
Just a small tweak ensuring the description truncates nicely. I think
this was a recently-introduced regression, as I am pretty sure it was
truncating well not too long ago.
Release Notes:
- N/A
Also, unifies the naming of the variable naming for the target entry in
both the git graph and git panel history tab.
Release Notes:
- Improved the git panel's history tab to keep an entry highlighted
while its context menu is open
TLDR: Opus 4.6 has been falling back to standard speed. Opus 4.7 fast
mode API will error after July 24th.
This will likely need to be cherry-picked to stable for either
Wednesday's release, or be pushed out separately on the 24th to maximize
availability. Although I don't think there are many Opus 4.7 fast mode
users, so Wednesday seems better to me.
> Fast mode for Claude Opus 4.7 is deprecated as of June 25, 2026, and
will be removed on July 24, 2026. After removal, requests to
claude-opus-4-7 with speed: "fast" will return an error; unlike Claude
Opus 4.6 (see the following note), Claude Opus 4.7 does not fall back to
standard speed. The model itself remains available at standard speed. To
continue using fast mode, migrate to Claude Opus 4.8.
Source: https://platform.claude.com/docs/en/build-with-claude/fast-mode
Release Notes:
- Deprecated Fast Mode for Opus 4.6 and Opus 4.7
Fixes an issue where toggling an MCP server on/off in Settings → AI →
MCP Servers does not update the toggle state in the UI immediately.
## Root Cause
There were two issues:
1. `ContextServerStore::update_server_state()` and `remove_server()`
emitted `ServerStatusChangedEvent` but did not call `cx.notify()`, so
Settings UI observers were not informed to re-render.
2. `render_toggle_switch()` was bound to `is_running` (runtime status)
instead of `is_enabled` (settings state).
## Solution
- Add `cx.notify()` in both methods after emitting the status event.
- Change toggle to read `settings.enabled()` and rename parameter from
`is_running` to `is_enabled`.
## Testing
- `cargo check -p settings_ui -p project` passes.
- `cargo fmt --check` passes.
- Manual verification: open Settings → AI → MCP Servers, toggle a
server, observe immediate UI update.
---
Release Notes:
- Fixed MCP server toggle not updating immediately in Settings UI.
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
# Objective
Docker Compose devcontainers currently resume only the primary container
when an existing environment is stopped. Supporting services listed in
`runServices`, such as databases and caches, remain stopped.
Fixes#60779
## Solution
Reuse the Docker Compose startup path when resuming an existing
Compose-based devcontainer.
The resume path now:
- Runs `docker compose up -d --no-recreate`.
- Targets the services configured in `runServices`.
- Uses the original Compose files and project name.
- Avoids recreating the existing devcontainer.
- Preserves the existing `docker start` behavior for non-Compose
devcontainers.
A regression test verifies that the requested services are resumed,
unrelated services are excluded, and the existing container is not
recreated.
## Testing
Tested on macOS with:
- `cargo fmt --all --check`
- `cargo test -p dev_container`
- `cargo clippy -p dev_container --tests -- -D warnings`
All 112 `dev_container` tests pass.
Also tested against a multi-service Docker Compose devcontainer
containing a workspace, web server, PostgreSQL, Redis, and Celery. All
configured services resumed while the workspace container retained the
same container ID.
## 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 Docker Compose dev containers not starting all configured
services when resuming an existing environment.
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
This reverts commit a98c7e2fa8.
# Objective
language detection is firing very often in channel notes, often picking
YAML instead of markdown, causing some language-detection flickering.
cc/ @amtoaer (author of the original PR)
## Objective
The doc comment links for `Settings::PRESERVED_KEYS` point to
`[FileContent](Self::FileContent)` but that associated type was removed
by the settings refactor in
https://github.com/zed-industries/zed/pull/38367.
`Settings::from_settings` now takes `&SettingsContent` directly. The
dead link causes `rustdoc::broken_intra_doc_links` warnings when
building docs for the `settings` crate:
```
warning: unresolved link to `Self::FileContent`
--> crates/settings/src/settings_store.rs:61:53
|
61 | /// The name of the keys in the [`FileContent`](Self::FileContent) that should
| ^^^^^^^^^^^^^^^^^ the trait `Settings` has no associated item named `FileContent`
```
Fixes#57310
## Solution
Replaced both `[FileContent](Self::FileContent)` occurrences in
`crates/settings/src/settings_store.rs` with `[SettingsContent]`, which
is already in scope via the existing `use` at the top of the file and
resolves correctly. Docs-only change, no runtime behavior change.
## Testing
- Verified with `cargo doc -p settings --no-deps`, which now completes
without any `broken_intra_doc_links` warnings (previously emitted two).
- No runtime code touched — doc comments only, so no other testing
applies.
## 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:
- N/A
The diff already has a constant-time accessor to get the counts of
added/removed rows, use that instead of iterating hunks on the
foreground.
Release Notes:
- Improved performance in agent threads with many file changes.
Closes#61141
Follow-up https://github.com/zed-industries/zed/pull/58791
# Objective
Currently after https://github.com/zed-industries/zed/pull/58791 landed,
we now always ask for the gpg passphrase on every commit which is not
ideal, since some people have a bigger **ttl** configured so they don't
have/want to re-enter their passphrase everytime on every commit. So we
should cache the signature so the user does not have to re-enter their
passphrase everytime, which also fixes the case for unprotected keys
which obviously don't have a passphrase. So we pre-check if we can sign
the commit if so we should not ask for the passphrase at all.
## Solution
The solution was also suggested inside this
https://github.com/zed-industries/zed/issues/61141 issue, to first check
if the signature was cached, if that is is the case use that to sign the
commit. If that fails we should fallback to the loopback mode and Zed
should prompt for your passphrase once and your signature should be
cached again.
## Testing
**The basic setup for gpg signing**:
1. Create a key `gpg --full-generate-key`
2. Run `git config --global user.signingkey <KEY ID>`
3. Run `git config --global commit.gpgsign true`
4. Run & copy result from `gpg --armor --export <KEY ID>` and submit
your public key to github https://github.com/settings/gpg/new
**Testing the new flow were the signature is cached**:
5. Run `gpgconf --reload gpg-agent` to reset cached signature
6. Make a change and try committing
7. See that it promts for your passphrase
8. enter passphrase
9. Make a change and try committing
10. Notice it does not re-promts for your passphrase
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [ ] 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
## Showcase
**Before** (**Note** before you were prompted everytime when you commit)
https://github.com/user-attachments/assets/0a967bb1-5eff-4224-9e9a-995e411f8d3a
**After** (**Note** you are only prompted once and using the keychain
after instead)
https://github.com/user-attachments/assets/5eee6afb-5972-44d8-afdd-6416a189db32
---
**Note**: I used AI as an assistance to write this PR.
Release Notes:
- Git: Fixed the GPG signing passphrase prompt appearing on every commit
even when gpg-agent had the passphrase cached or the key was
unprotected.
## Summary
Seed the text_finder's query from the focused pane's item instead of
only the active center editor. Selecting text in the terminal or
markdown_preview and opening text_finder now seeds that selection; the
item next to focus wins when both it and a center editor have
selections. If the focused item has no selection, the center item is
tried, then the last persisted search as before.
## Test plan
- Select a word in the terminal, open Text Finder, confirm it's
pre-filled and searching
- With a selection in both terminal and editor, confirm the focused one
wins
- Focus the terminal without a selection, confirm an editor selection
still seeds
- No selection anywhere, confirm the last search is restored
- Confirm a selection in a markdown preview seeds too
Release Notes:
- Improved the Text Finder to seed its query from the focused item's
selection, including the terminal
---------
Co-authored-by: ozacod <ozacod@users.noreply.github.com>
When `active_pane_modifiers.border_size` is set in `settings.json`, both
the active editor pane and the active terminal pane would display a
border simultaneously, making it impossible to tell which pane actually
has focus. The pane opacity dimming also renders simultaneously before
this fix.
1. Before fix: impossible to tell which pane has focus
<img width="901" height="732" alt="image"
src="https://github.com/user-attachments/assets/cbcad798-0d72-420c-9585-2dafa867ff2b"
/>
2. After fix: only one pane has focus
<img width="902" height="731" alt="image"
src="https://github.com/user-attachments/assets/97f2238e-4789-41b3-97e3-98cb9a0c82ef"
/>
The root cause is that both the workspace center and the terminal panel
pass their own `active_pane` to `PaneRenderContext`, so each pane group
unconditionally marks its active pane for border rendering. The fix adds
a focus check so `active_pane_ix` is only set when the pane actually has
keyboard focus, ensuring only the truly focused pane gets the border
(and the inactive_opacity dimming applies correctly to unfocused
groups).
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 active pane border being drawn on both the editor pane and
terminal pane simultaneously
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
`NotebookItem::try_open` only checked the worktree-relative path's
extension, which is empty for single-file worktrees. As a result,
opening a notebook directly (`zed foo.ipynb`, or any open outside a
folder worktree) fell through to the text editor and showed raw JSON,
while the same file opened from within a folder workspace opened in the
notebook editor. Fall back to the absolute path when detecting
notebooks.
Tested locally (macOS, with the notebook feature enabled via
`LOCAL_NOTEBOOK_DEV`): `zed /tmp/solo.ipynb` now opens the rendered
notebook view; folder-workspace behavior unchanged.
Release Notes:
- Fixed notebooks opened as single files (e.g. `zed foo.ipynb`)
rendering as raw JSON instead of opening in the notebook editor
(preview-only).
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Closes#61312
In `parse_choices`, the escape branch only appended the escaped
character to `current_choice` when parsing the first choice, because the
push was placed inside the `!found_default_choice` guard. That guard is
only meant for `text` (the default value inserted into the buffer) — the
plain-text branch below handles it that way. As a result, `${1|a,b\,c|}`
offered the choices `a` and `bc` instead of `a` and `b,c`, and the same
applied to any `\,`, `\|`, or `\\` in choices after the first.
Moved `current_choice.push(c)` out of the guard and added a regression
test covering escaped comma, pipe, and backslash in non-first choices.
Escapes in the first choice were already covered by the existing test
and are unchanged.
Before / after (snippet body `"${1|a,b\\,c|}"`): the choice dropdown
showed `a` / `bc`, now shows `a` / `b,c`.
Release Notes:
- Fixed escaped characters (`\,`, `\|`, `\\`) being dropped from snippet
choice options after the first one
Sometimes when creating Git worktrees, it's necessary to set things up
so the new worktree is ready. For example, copying env.vars, installing
dependencies, etc. That was already possible in Zed through the tasks
system, but you'd only maybe know about that if you read the
documentation or is super familiar with it already; nothing in the
product in the context of worktrees told you about that. This is what
this PR does.
Now, in the worktree picker, there's a "" button that opens the
`tasks.json` file exposing the `create_worktree` hook, which allows you
to plugin all sorts of things to be run by the time of a worktree
creation. If you don't already have a `tasks.json` file, we will create
a new one for you with a worktree-creation template. Otherwise, we
either append the `create_worktree` hook content to it or just open the
file.
Here's a quick video:
https://github.com/user-attachments/assets/21908be4-306b-4cf3-bed0-50d52cad9d79
Release Notes:
- Git Worktrees: Improved discoverability of the `create_worktree` hook
for setting up things that need to happen by the time of worktree
creation.