In the interactive MCP OAuth flow, the MCP client registers itself with
the authorization in one of three ways:
- Client ID Metadata Document aka CIMD (recommended default). This is
already implemented: https://zed.dev/oauth/client-metadata.json.
- Dynamic Client Registration (DCR). This is the traditional method.
Also already implemented in Zed.
- Pre-registration: the client is registered out of band, typically in
the IdP or SaaS provider's UI. You get a client id and maybe a client
secret, that have to be provided by the MCP client when it wants to
exchange an access token. This is what this pull request is about.
This PR has two main parts:
- Allow users to configure a client id and optional client secret for an
MCP server in their configuration, under a new `oauth` key, and take it
into account
- Make the MCP server state and the configuration modal aware of the
intermediate states (client secret missing) and error cases stemming
from client pre-registration.
The client secret can be stored either in the system keychain or in
plain text in the MCP server configuration. The UI tries to steer user
towards the more secure option: the keychain.
<img width="715" height="201" alt="Screenshot 2026-04-10 at 16 48 06"
src="https://github.com/user-attachments/assets/5e64103e-6746-4ef0-8bd9-533d492b6912"
/>
<img width="884" height="544" alt="Screenshot 2026-04-10 at 16 47 07"
src="https://github.com/user-attachments/assets/0e35bb3c-cbc4-4e8c-a713-66323597b2e2"
/>
<img width="785" height="558" alt="Screenshot 2026-04-10 at 16 47 23"
src="https://github.com/user-attachments/assets/03339187-1508-461a-87ae-a7c2647df9a5"
/>
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
https://github.com/issues/assigned?issue=zed-industries%7Czed%7C52198
**Note for the reviewer: I know how busy the AI team is at the moment so
please treat this as low priority, we don't have signal that this is a
highly desired feature. It's a rather large PR, so I'm happy to pair
review / walk through it.**
Release Notes:
- Added support for OAuth client pre-registration (client id, client
secret) to the built-in MCP client.
Adds a `markdown_preview_code_font_family` setting that overrides the
font used in the markdown preview for code — inline `code` spans and
fenced code blocks.
This is the counterpart to `markdown_preview_font_family` (#54003),
which already does this for body text. Together they let you choose a
typographically matched body + code font pair for the preview without
forcing the code font onto editor buffers, where it may not be a good
coding font:
```json
{
"markdown_preview_font_family": "Noto Serif",
"markdown_preview_code_font_family": "Noto Sans Mono"
}
```
Behavior mirrors `markdown_preview_font_family`:
- Scoped to the markdown preview only (`MarkdownFont::Preview`). The
agent panel, notifications, hover popovers, and REPL output are
unaffected — they keep using the buffer font for code.
- Falls back to the buffer font family when unset, so existing previews
are unchanged.
- Overrides the font family only; fallbacks and features still come from
the buffer font.
Before (uses buffer font, here Iosevka):
<img width="509" height="368" alt="Screenshot 2026-05-14 at 1 39 51 PM"
src="https://github.com/user-attachments/assets/6b7e49b2-fc6e-4db1-9679-392b3447f411"
/>
After (uses specified font, here Noto Sans Mono):
<img width="508" height="368" alt="Screenshot 2026-05-14 at 1 40 51 PM"
src="https://github.com/user-attachments/assets/f911c99b-08f8-4336-83eb-54b555f11c54"
/>
Release Notes:
- Added `markdown_preview_code_font_family` to override the code font in
the markdown preview
With long lines or a small viewport, the stage/restore buttons often
cover code.
Adds a setting to hide the buttons altogether. Defaults to showing them.
Release Notes:
- Added: Setting to hide Git Stage/Restore buttons
## Background: Amazon Bedrock Guardrails
AWS Bedrock Guardrails enables configurable safety and compliance
controls for generative AI applications:
- Evaluates both user inputs and model responses against policies.
:contentReference[oaicite:8]{index=8}
- Can block or filter content based on harmful categories, denied
topics, PII, or hallucination criteria.
:contentReference[oaicite:9]{index=9}
- Guardrails are applied during inference API calls by specifying
`guardrailIdentifier` and `guardrailVersion` in the request.
:contentReference[oaicite:10]{index=10}
Relevant AWS documentation:
- User Guide:
https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html
- How Guardrails Works:
https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-how.html
- API Reference (GuardrailConfiguration):
https://docs.aws.amazon.com/bedrock/latest/APIReference/API_GuardrailConfiguration.html
Some AWS environments enforce IAM policies that require a guardrail to
be specified on every Bedrock API call (via a `StringEquals` condition
on `bedrock:GuardrailIdentifier`). Without this, Zed returns
`AccessDenied` and Bedrock models are completely unusable in those
environments.
This adds two optional settings, `guardrail_identifier` and
`guardrail_version`, to the Bedrock provider config. When set, a
`GuardrailStreamConfiguration` is attached to every `converse_stream`
request. When unset, behaviour is identical to before.
```json
{
"language_models": {
"bedrock": {
"guardrail_identifier": "arn:aws:bedrock:us-east-1:123456789012:guardrail/abc123",
"guardrail_version": "DRAFT"
}
}
}
```
`guardrail_version` defaults to `"DRAFT"` if omitted.
Release Notes:
- agent: Added `guardrail_identifier` and `guardrail_version` settings
for AWS Bedrock, enabling use in environments where IAM policies require
a guardrail on all model requests
---------
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Closes#52042
Release Notes:
- agent: Added setting `subagent_model` to specify which model is used
when subagent is spawned
---------
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
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 https://github.com/zed-industries/zed/issues/52585
Release Notes:
- Fixed local zeta2 edit predictions using the wrong prompt format.
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 #ISSUE
Release Notes:
- Added a setting
[vim.show_edit_predictions_in_normal_mode](zed://settings/vim.show_edit_predictions_in_normal_mode)
to control whether edit predictions are shown in normal mode.
This PR makes editor diff hunk colors configurable from themes, instead
of hardcoded values.
It introduces 6 new optional theme keys:
- `editor.diff_hunk.added.background`
- `editor.diff_hunk.added.hollow_background`
- `editor.diff_hunk.added.hollow_border`
- `editor.diff_hunk.deleted.background`
- `editor.diff_hunk.deleted.hollow_background`
- `editor.diff_hunk.deleted.hollow_border`
When a theme omits these keys, each color falls back to the existing
version-control color with the previous hardcoded opacity values:
- Light defaults:
- background_opacity = 0.16
- hollow_background_opacity = 0.08
- hollow_border_opacity = 0.48
- Dark defaults:
- background_opacity = 0.12
- hollow_background_opacity = 0.06
- hollow_border_opacity = 0.36
There is an existing feature request
https://github.com/zed-industries/zed/discussions/51667
## Screenshots
I used `Modus Themes` (Modus Vivendi) since these themes provide highly
accessible themes.
Original version:
<img width="3248" height="2120" alt="CleanShot 2026-03-17 at 20 26
41@2x"
src="https://github.com/user-attachments/assets/730be802-835d-436e-a1fc-4c60dcb5fce8"
/>
This version:
<img width="3248" height="2120" alt="CleanShot 2026-03-17 at 20 23
09@2x"
src="https://github.com/user-attachments/assets/785c86d3-147e-437f-9624-9576bc201551"
/>
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- Added theme keys for configuring editor diff hunk colors.
---------
Co-authored-by: MrSubidubi <finn@zed.dev>
The `opencode` built-in provider is registered in the language model
registry
but missing from the JSON schema enum in `LanguageModelProviderSetting`.
<img width="724" height="399" alt="image"
src="https://github.com/user-attachments/assets/33da4626-eb44-443e-b656-65533b3a85f1"
/>
<br>
OpenCode is one of the "first class" providers, so I was surprised it
was missing from the auto-complete for the provider fields in the
settings file.
## 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
OpenCode API endpoints for DeepSeek were [moved from
Anthropic-compatible to
OpenAI-compatible](https://github.com/anomalyco/opencode/pull/24500) and
DeepSeek requires interleaved reasoning enabled to work. I ran a
_"rename this variable to potato"_ test and I can confirm DeepSeek V4
Flash and Pro both work now 🎉
Some other OpenCode Go models were marked [on
models.dev](https://github.com/anomalyco/models.dev/tree/dev/providers/opencode-go/models)
as supporting `interleaved_reasoning` so they too got that enabled. Kimi
K2.5 and Kimi K2.6 continue to fail with
https://github.com/zed-industries/zed/issues/51743
(https://github.com/zed-industries/zed/pull/55085 seems to hint at this
being [an OpenCode
issue](https://github.com/zed-industries/zed/issues/51743#issuecomment-4336785765)?),
but all other models seem to work fine both with `interleaved_reasoning`
and without it 🤷 I assume it's better to have that turned on? Again, the
intersection of OpenAI Chat Completions API, different models, different
inference providers, how they all work together is something I know
nothing about!
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:
- OpenCode Go: use correct DeepSeek endpoints
- OpenCode: add support for interleaved_reasoning
The [Parallel Agents release](https://zed.dev/blog/parallel-agents)
introduced a new default layout: the agent panel now docks on the left,
while the project, git, outline, and collaboration panels now dock on
the right. The rustdoc comments in `crates/settings_content` were not
updated to reflect this change.
This PR corrects the `Default:` values in the following structs:
- `ProjectPanelSettingsContent.dock`: `left` → `right`
- `GitPanelSettingsContent.dock`: `left` → `right`
- `PanelSettingsContent.dock` (collaboration panel): `left` → `right`
- `OutlinePanelSettingsContent.dock`: `left` → `right`
- `AgentSettingsContent.dock`: `right` → `left`
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
Instead of manually handing hiding the cursor on keyboard input at the
editor level, GPUI will now take care of it.
This makes it significantly easier to handle the edge cases, and allows
delegating the cursor restoration to the platform itself in the macOS
case. On Linux and Windows, we still have to restore the cursor on
movement ourselves, but this now happens at the platform-specific level.
Bugs fixed by this change:
- No cursor when "Unsaved edits" prompt appears
- Cursor disappears when clicking a panel button if it contains a search
bar (e.g. collab panel)
### Setting rename
The `hide_mouse` setting value `"on_typing_and_movement"` has been
renamed to `"on_typing_and_action"` to better reflect what it actually
does — it hides the cursor when a keystroke resolves to an action (e.g.
cursor movement, deletion). Existing settings are migrated
automatically.
### Tested platforms
- [x] macOS
- [x] Wayland
- [x] X11
- [x] Windows
- [x] Web
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:
- Renamed the `hide_mouse` setting value `on_typing_and_movement` to
`on_typing_and_action` to better describe its behavior (existing
settings are auto-migrated)
- Fixed a few situations where the mouse cursor would be incorrectly
hidden
cc: @danilo-leal
This setting is from when we had the git worktree picker in the agent
panel, now that it is in the menu bar it doesn't make sense to keep it.
We plan to add a similar feature in the future to handle the "new thread
== new git worktree" workflow
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 #ISSUE
Release Notes:
- N/A
Removes the Vercel v0 Provider, as the v0 API has been
depredated/removed (https://api.v0.dev/v1)
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:
- agent: Removed Vercel v0 provider as it has been deprecated by Vercel
These changes attempt to expand on the work introduced by
https://github.com/zed-industries/zed/pull/54778 by introducing a new
`GoToDefinitionScrollStrategy::Preserve` variant that attempts to keep
the cursor at the same vertical offset within the viewport when
navigating to a definition.
Most of the machinery for this was already in place. To support cases
where the user's scroll position isn't snapped to an exact display row,
for example, after scrolling with the mmouse, `Autoscroll::TopRelative`
and `Autoscroll::BottomRelative` were updated from `usize` to
`ScrollOffset`, allowing fractional offsets.
When the cursor is offscreen at the moment the `editor: go to
definition` action is invoked, `Preserve` falls back to
`Autoscroll::center`, matching the existing default for
`go_to_definition_scroll_strategy`. This avoids attempting to preserve
an offset where the cursor isn't visible which would lead to the cursor
being offscreen when jumping to the definition.
Documentation has also been updated to reflect this new strategy value.
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
Relates to #52173
Release Notes:
- Added a new `preserve` option to `go_to_definition_scroll_strategy`
that keeps the cursor at the same vertical position within the viewport
when navigating to a definition
Leftovers after https://github.com/zed-industries/zed/pull/53651
Updated models:
- **Zen**: GPT 5.5 and GPT 5.5 Pro - not tested because I don't have a
Zen subscription and I stubbornly refuse to get one
- **Go**: DeepSeek V4 Pro and DeepSeek V4 Flash - failing due to
https://github.com/anomalyco/opencode/issues/24224
- **Go**: MiMo V2.5 and MiMo V2.5 Pro - tested, confirmed working
- **Free**: Ling 2.6 Flash, [available for "a limited
time"](https://x.com/opencode/status/2046717718028513694) - tested,
confirmed working
- **Free**: Hy3 Preview, [available until May
8](https://x.com/opencode/status/2047328981435756824) - tested,
confirmed working
When testing the new models and comparing with OpenCode CLI, I realized
the
[variants](https://opencode.ai/docs/models/#built-in-variants)/thinking
effort configuration was not supported by the Zed Agent implementation.
I added that for OpenCode Go models, after manually checking what each
model supports in OpenCode. Reasoning levels and everything seems to
work (UI looks good, model works) but I have no idea how to specifically
test reasoning levels without doing a full benchmark 🤷
I did not add the same thing for OpenCode Zen models because I could not
figure out a way to get the supported variants.
@benbrandt let me know if you want me to take this out of this PR and to
keep just the model 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 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:
- OpenCode: add new models (GPT 5.5, DeepSeek V4, MiMo V2.5, Ling 2.6,
Hy3)
- OpenCode Go: add support for configurable reasoning effort levels
---------
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
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 #ISSUE
Release Notes:
- N/A or Added/Fixed/Improved ...
**TL;DR**: add support for OpenCode Go (flat-rate monthly subscription)
along the already-implemented OpenCode Zed (pay-as-you-go billing).
> [!WARNING]
> This code was written by LLMs, under the supervision of a so-called
developer that never wrote Rust profesionally and that spends more time
in Pages&Keynote than in an IDE.
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
## Background
OpenCode offers a few different ways to access models:
- **free access to 3 models**, with feedback and data used to improve
the model. These models use the OpenCode Zen API endpoints, but have
different usage limits (200 requests per 5 hours) and have a different
privacy policy. Some people disable or block the free models, some
people are super-excited to have access to LLMs for free, and some
people like using the free models to test new LLMs (at launch MiMo-V2
had 2 free weeks of usage, for example).
- **pay-as-you-go access to 30 models** as part of the [OpenCode
Zen](https://opencode.ai/zen) subscription. These models use the same
OpenCode Zen API endpoints.
- **flat-rate monthly access to 7 models** as part of the [OpenCode
Go](https://opencode.ai/go) subscription. These models use the OpenCode
Zen API endpoints with an extra `/go` appended to the path. There are
5-hour, weekly, and monthly usage limits and, additionally, users can
toggle a switch in the OpenCode Console to use Zen models with their
pay-as-you-go billing after the Go limits are hit.
There's also a currently-paused [OpenCode
Black](https://opencode.ai/black) flat-rate subscription with way higher
usage limits and with access to more models, with $100 and $200 monthly
plans.
The whole thing is a bit messy, but it's great value and highly reliable
LLM access!
<br>
https://github.com/zed-industries/zed/pull/49589 added support for
OpenCode Zen by implementing a new `opencode` provider. OpenCode Go
[could be used by overriding the API
URL](https://github.com/zed-industries/zed/pull/49589#issuecomment-4130300454),
but that is a terrible user experience: some models have to be manually
added, the model list always shows the 30-something OpenCode Zen models,
and free models cannot be used at all.
I was annoyed by the experience of using OpenCode Go with Zed and this
past week I had to test a bunch of LLMs and providers and harnesses, so
I took this on as a test case 🙂
## Implementation
This PR makes the OpenCode provider more general (not just for Zen) and
adds an `OpenCodeModelSubscription` concept which is then used to
implement support for OpenCode Go. The free models are also broken out
into their own subscription for a prettier model list.
For a better user experience, the different subscriptions can be enabled
or disabled, both in the settings file and in the UX:
<img width="434" height="176" alt="Screenshot showing the OpenCode
provider configuration, with the newly added toggles"
src="https://github.com/user-attachments/assets/3520e114-00c8-4794-84bf-35cd72d9c57e"
/>
The code was written by LLMs, but I do understand it and I did a bunch
of "manual" iterations and "manual" tweaks. Still, my Rust experience is
non-existent so **I won't feel offended if y'all reject this PR**! I did
consider alternatives (adding a new `opencode-go` provider and renaming
this to `opencode-zen`, for example, or adding support for custom API
URLs in OpenCode custom models which would've been the smallest code
change but a terrible user experience, and so on) but all alternatives
would have been, in my opinion, a worse user experience.
**Tests I did**:
- confirmed OpenCode Go models work as expected
- confirmed OpenCode Zen Free models work as expected
- confirmed I get an error when trying to use OpenCode Zen models since
I don't have that subscription
- confirmed the subcription toggles work as expected (model are
shown/hidden, settings file is updated)
**Notes**:
- this PR is best reviewed commit-by-commit. I did not create a separate
PR for the model updates to minimize delays
- my exeprience with Rust is roughly zero, but I tried to strike a
balance between idiomatic Rust and easy-to-read code
- users of the OpenCode provider might have to do some re-configuration
after this PR is merged since the model identifiers now include the
subscription, eg `claude-haiku-4-5` is now `zen/claude-haiku-4-5`. Since
this is a relatively new provider and the impact is small, I preffered
that rather than adding complex migration/mapping logic.
- does changing the provider name from "OpenCode Zen" to "OpenCode"
break anything for y'all at Zed?
- does changing the telemetry id from `"opencode/<model-id>"` to
`"opencode/<subscription>/<model-id>"` break anything for y'all at Zed?
---
Release Notes:
- OpenCode provider: add support for OpenCode Go
---------
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
Allows to reconfigure behavior, including the previous one, `top`
Closes https://github.com/zed-industries/zed/issues/52173
Release Notes:
- Reworked go to definition to open its target in the center of the
editor. Can be reconfigured with `go_to_definition_scroll_strategy`.
## Summary
Users who add custom OpenAI models under
`language_models.openai.available_models` can set `capabilities.images:
true` to declare that the endpoint accepts image inputs. Today, that
setting is silently ignored: the Agent panel's image-attach button stays
disabled regardless, and the only workaround is to switch to a built-in
OpenAI model, attach the image, and switch back.
Root cause: `Model::Custom` does not carry a `supports_images` field,
and the OpenAI provider's `supports_images()` for the `Custom` arm
hardcodes `false`.
## Changes
1. `crates/settings_content/src/language_model.rs`: add `images: bool`
to `OpenAiModelCapabilities` with `#[serde(default)]` so existing
settings.json files keep working unchanged.
2. `crates/open_ai/src/open_ai.rs`: add `supports_images: bool` to
`Model::Custom` with a matching serde default.
3. `crates/language_models/src/provider/open_ai.rs`: pass
`model.capabilities.images` into the `Model::Custom` variant in
`provided_models`, and return the stored value from `supports_images()`
for `Custom`.
Existing `Model::Custom { .. }` match sites (`completion.rs:829`,
various in `open_ai.rs`) all use `..` so they continue to compile
without change.
## Testing
- `cargo check -p settings_content -p open_ai -p language_models`:
clean.
- I was not able to complete `./script/clippy` locally: the build
stalled on the first-time `webrtc-sys` download for livekit-rust-sdks
(TLS close_notify failure on docs.rs mirror). Happy to rerun once CI has
cached artifacts.
- Manually verified the capability plumbing by tracing: settings.json ->
`OpenAiModelCapabilities.images` -> `Model::Custom { supports_images }`
-> `supports_images()` -> `Thread::prompt_capabilities` ->
`SessionCapabilities.supports_images()` -> `build_add_context_menu` gate
in `thread_view.rs`.
## Related Issues
Closes#50752
Release Notes:
- Fixed custom OpenAI models ignoring the `capabilities.images` setting
in `language_models.openai.available_models`.
This contribution was developed with AI assistance (Codex).
---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
No, sadly, the title is not a typo. See
https://www.githubstatus.com/incidents/zsg1lk7w13cf for the context.
I'll read with joy and popcorn through that root cause analysis.
It makes literally zero sense what happened here, but for some completly
bonkers reason GitHub completely messed up the merge queue with
https://github.com/zed-industries/zed/pull/54632.
I have no idea how it happened. It makes literally zero sense. A PR
going into the merge queue should have the same LoC when getting out of
it. GitHub obviously does not check this. GitHub causes extra work with
a feature that is supposed to save time.
Thanks, I guess.
Release Notes:
- N/A
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
## Summary
Adds two user-facing settings that let the markdown preview render with
a font family and theme independent from the editor. Both are optional
and fall back to the editor defaults when unset.
```json
{
"markdown_preview_font_family": "Georgia",
"markdown_preview_theme": "Solarized Light"
}
```
## Details
- New `MarkdownFont::Preview` variant, used only by the preview surface.
- New `MarkdownStyle::themed_with_overrides()` that accepts explicit
`ThemeColors` and `SyntaxTheme` so the preview can render with a theme
other than the active editor theme. Existing `themed()` callers are
unchanged.
- The preview pane background adopts the chosen theme's
`editor_background`.
- Follows the pattern already used by `agent_ui_font_size` /
`agent_buffer_font_size`.
## Scope
Sizing-related changes (`markdown_preview_font_size`,
`markdown_preview_line_height`, typography tweaks, responsive max-width
container) were in an earlier revision of this PR and have been removed
per review feedback — they interact with the Cmd+/- zoom behavior in
ways that still need design work, and will land in a follow-up.
## Files Changed
- `crates/settings_content/src/theme.rs` — schema
- `crates/theme_settings/src/settings.rs` — runtime + accessor
- `crates/markdown/src/markdown.rs` — `MarkdownFont::Preview` +
`themed_with_overrides()`
- `crates/markdown_preview/src/markdown_preview_view.rs` — theme
resolution, style selection, background
- `crates/markdown_preview/Cargo.toml` — `theme` dependency
- `crates/settings/src/vscode_import.rs` — new fields in struct literal
Release Notes:
- Added `markdown_preview_font_family` and `markdown_preview_theme`
settings to customize the markdown preview independently from the
editor.
Co-authored-by: Chris Biscardi <chris@christopherbiscardi.com>
Needs https://github.com/zed-industries/zed/pull/54635 for the profile
overrides added into default settings json to work.
Part of https://github.com/zed-industries/zed/issues/48968
Another part of the fix related seems to be
https://github.com/zed-industries/zed/pull/45669 ?
Using the steps from the issue and profiling on macOs had shown that Zed
has 2 memory "leaks" in play when a certain file is being rewritten a
lot of times.
* First, the thread profiler registers a lot of tasks' data and fills
its buffer to the limit:
<img width="3456" height="2158" alt="image"
src="https://github.com/user-attachments/assets/f183312d-4389-4072-8915-d54e60419b08"
/>
* Second, if the buffer gets open, the undo history fragments start to
creep up infinitely:
<img width="3456" height="2158" alt="image"
src="https://github.com/user-attachments/assets/61a2b66b-81fd-4973-9c3c-c339f886d9b2"
/>
The PR aims to solve the first issue by disabling the profiling by
default, yet leaving the way to turn in on quickly with settings.
The memory usage profiling shows that the memory usage is now
dynamically affected by the new setting:
<img width="2032" height="1136" alt="image"
src="https://github.com/user-attachments/assets/8a6c76b9-6fb7-44bc-ac1d-3c34afe7c575"
/>
While the test directory being thrashed with the script from the issue,
* first, Zed starts with the profiling disabled
* then gets the profiling enabled which results in the memory growth
close to 1 minute mark of the screenshot
* last, the profiling gets disabled again, releasing all the memory
accumulated
Release Notes:
- Improved Zed's default memory usage
This PR brings back the button to filter remote branches when accessing
the title bar's branch picker with the mouse. It was unintentionally
removed when we introduced the new worktree picker.
Release Notes:
- N/A
# Helix Amp Jump Navigation
## Overview
Implements Helix-style "amp jump" (`g w`) navigation for jump-to-word
functionality. This feature displays two-character labels on each word
in the visible area, allowing users to quickly jump to any word by
typing its label. Labels alternate between forward and backward
directions (same algorithm as in the Helix) from the cursor position,
giving closer jump targets easier-to-type labels.
## Context
- **Request:** Implement "amp jump" navigation similar to Helix editor's
jump-to-word feature.
- **Scope:** Full implementation including label generation, UI
rendering, and input handling.
- **Inspiration:** Helix editor's "amp jump" and vim-easymotion/hop.nvim
plugins.
## How It Works
1. Press `g w` to activate "amp jump"
2. Two-character labels appear on all words in visible area
3. User types the two-character label shown on the target word
4. Cursor jumps to that word

Release Notes:
- Added in Helix mode the "amp jump" navigation (`g w`) that displays
two-character labels on words for quick cursor navigation. Labels
alternate between forward and backward directions from the cursor,
prioritizing closer targets with easier-to-type labels. The color of the
labels can be controlled via a new `helix.jump_label_accent` setting
---------
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
Closes#48394
Moves the data collection preference for Zed's Edit Predictions out of
the internal KV store and into `settings.json` as a proper
`allow_data_collection` setting under `edit_predictions`.
**Migration:** Existing users' choices are preserved. When
`allow_data_collection` is absent from `settings.json`, the resolved
value falls back to the legacy KV entry
(`zed_predict_data_collection_choice`). Once the user toggles the
setting or sets it explicitly, the new setting takes precedence and the
KV entry is ignored.
**Bug fixed:** The original implementation of `toggle_data_collection`
read the raw (unresolved) settings content to determine the current
state. When `allow_data_collection` was absent from `settings.json` but
the KV store held `"true"`, the raw read returned `None → false`,
causing the first toggle click to write `Some(true)` (re-enabling)
instead of `Some(false)` (disabling). The fix reads the resolved
`is_data_collection_enabled()` value before entering the
`update_settings_file` closure.
## Manual testing
**Setting takes effect:**
1. Open settings (`cmd+,`) and add `"allow_data_collection": true` under
`edit_predictions`. Save.
2. Open a file — the data collection indicator in the editor should
reflect the enabled state.
3. Flip to `false` and confirm it updates.
**Toggle correctly disables from KV-enabled state (migration bug fix):**
1. Remove `allow_data_collection` from `settings.json`.
2. Write the legacy KV entry directly:
```
sqlite3 ~/Library/Application\ Support/Zed/db/0-dev/db.sqlite \
"INSERT OR REPLACE INTO kv_store(key,value)
VALUES('zed_predict_data_collection_choice','true');"
```
3. Restart Zed. The data collection toggle should show as **enabled**
(reading from KV store).
4. Click the toggle once to disable. `allow_data_collection` should
appear as `false` in `settings.json` — not `true`, which was the pre-fix
behaviour.
**Upsell modal still appears for new users:**
1. Clear both KV keys and restart:
```
sqlite3 ~/Library/Application\ Support/Zed/db/0-dev/db.sqlite \
"DELETE FROM kv_store WHERE key IN
('zed_predict_data_collection_choice','dismissed-edit-predict-upsell');"
```
2. Open any file so the status bar is visible.
3. Click the edit prediction button (bottom-right status bar) — it
should have a muted dot indicator.
4. The upsell modal should appear. Dismissing it should prevent it from
reappearing.
## Release Notes:
- `allow_data_collection` for Zed's Edit Predictions can now be set
explicitly in `settings.json` under `edit_predictions`. Existing
preferences stored in the internal database are preserved as a fallback.
---------
Co-authored-by: Ben Kunkle <ben.kunkle@gmail.com>
Added support for `credentials_url`, falling back to `server_url`, to be
used as the key for storing information inside Keychain Access. This
allows two copies of Zed to be used side by side if the other is
launched with a custom `--user-data-dir`.
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
Release Notes:
- Added support for `credentials_url`, falling back to `server_url`, to
be used as the key for storing information inside Keychain Access.
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
Followup to #47531 to use the gpui feature in Zed. This just plumbs the
"system bell" feature into the terminal, behind a new setting (enabled
by default, like most other terminal applications).
Closes#5303
Relates to
https://github.com/zed-industries/zed/issues/40826#issuecomment-3684556858
Release Notes:
- Added audible BEL to Terminal; can be enabled by setting
`terminal.bell` to `"system"`.
---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Ben Kunkle <Ben.kunkle@gmail.com>
Closes#49581
Adds a `line_ending` language setting that controls how line endings are
handled for new files and during format/save:
- `detect` (default) — detects existing line endings; new files use the
platform default
- `prefer_lf` / `prefer_crlf` — sets LF or CRLF for new files and files
with no existing convention, while preserving existing files
- `enforce_lf` / `enforce_crlf` — normalizes all line endings to LF or
CRLF on every format/save
The setting can be configured globally, per-language, or via
`.editorconfig`'s `end_of_line` property (which maps to `enforce_lf` /
`enforce_crlf`).
Release Notes:
- Added `line_ending` setting to control how line endings are handled
for new files and normalized on save.
- Added support for `.editorconfig` `end_of_line` property to enforce
line endings.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
The `project_name` worktree setting was added in #36713 to let users
override the name shown in the window title. Its description ("The
displayed name of this project. If left empty, the root directory name
will be displayed.") suggests broader coverage, and #46440 reports the
reasonable expectation that it should also apply in the project
switcher. In practice the setting has only ever affected
`Workspace::update_window_title`, so everywhere else (recent projects,
the multi-worktree pane, ...) keeps falling back to the worktree root
name.
Rather than plumb the setting through each of those surfaces, I'm
removing it. Having a project-level setting control how your editor
displays the project has downsides. For example it means a checkout can
dictate UI in someone else's Zed. The natural home for a custom display
name is the workspace DB, set from the UI, which is what we should do if
we want this feature back.
If you want this back, the path forward is to store the display name in
`WorkspaceDb`, expose a UI affordance to edit it, and read it from
`update_window_title`, `recent_projects::get_recent_projects` /
`get_open_folders`, and any other places that currently derive a display
name from the worktree root.
Closes#46440
Release Notes:
- Removed the `project_name` project setting. It only ever affected the
OS window title, and the expectation that it would show up in the
project switcher and elsewhere is better served by a future UI-driven,
per-workspace setting stored locally.
Update the JSON schema generated for the settings file in order to be
able to provide the list of valid actions when editing the values for
the `command_aliases` setting.
While reviewing https://github.com/zed-industries/zed/pull/52892 , I
noticed that, even though we already have support for this in the keymap
file, we don't support it for the `command_aliases` setting, so went
ahead and refactored this a bit such that the existing functionality for
the keymap file JSON schema could also be re-used for the
`command_aliases` setting.
Here's a quick big-picture breakdown of the relevant changes:
* Add `settings_content::ActionName` newtype, representing a simple
named action without arguments. The
`settings_content::ActionName::build_schema` function can be used to
build the schema of all possible action names.
* Add `settings_content::ActionWithArguments` newtype, representing an
action with arguments. This was mostly done so as to keep both action
without arguments and action with arguments newtypes together,
even though we don't have
`settings_content::ActionWithArguments::build_schema`, as it is only
used by the keymap schema generation logic and probably doesn't warrant
moving it here right now.
* Update both
`settings_content::WorkspaceSettingsContent::command_aliases` and
`workspace::workspace_settings::WorkspaceSettings::command_aliases` to
now be of type `HashMap<String, ActionName>` such that, when the json
schema for `command_aliases` is generate, it'll now reference the
`#/$defs/ActionName` schema.
* Update `SettingsStore::json_schema` so as to populate the
`#/$defs/ActionName` schema at runtime, replacing it with the actual
list of valid action names.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Added support for auto-completing action names on `command_aliases`
setting
Release Notes:
- Added interleaved_reasoning option to openai compatible models
---
This PR adds the interleaved_reasoning option for OpenAI-compatible
models, addressing the issue described in
https://github.com/ggml-org/llama.cpp/issues/20837.
In my testing, enabling interleaved_reasoning not only resolved the
tool-calling issues encountered by Qwen3.5 models in llama.cpp, but also
appeared to improve the model's coding capabilities. I have also
verified the outgoing requests using a proxy to ensure the parameter is
being sent correctly.It is also likely that this change will benefit
other models and providers as well.
Note: While I used AI to assist with the implementation, I have reviewed
and tested the changes. As I am relatively new to Rust and the Zed
codebase, I would appreciate any feedback or suggestions for
improvement. I am happy to make further adjustments if needed.
Thank you all for building such an amazing editor!
Co-authored-by: Oleksiy Syvokon <oleksiy@zed.dev>
Closes#54313
**Before:**
- Favoriting a model only stored `provider`, `model`, and hardcoded
`enable_thinking` to `false`.
- Selecting a favorited model would not restore your preferred
`enable_thinking`, `effort`, or `speed` settings.
This means that if you'd like to use, say, GPT 5.4 your favorite model
on `xhigh` effort every single time, switching to it would set effort to
`medium` (the default for the model) instead.
**After:**
- Favoriting a model captures your current `enable_thinking`, `effort`,
and `speed` when it matches the currently-selected model. Otherwise, it
falls back to the model's own defaults, i.e. thinking-capable models are
no longer favorited with `enable_thinking` forced to `false`.
- Selecting a favorited model applies its stored thinking / effort /
speed.
- Toggling thinking, changing effort, or toggling fast mode on a
favorited model updates the favorite entry in settings (along with the
existing `default_model` setting), so the preference doesn't drift.
Release Notes:
- Agent favorite models now remember and restore per-model thinking,
effort level, and fast mode preferences.
Follow up to https://github.com/zed-industries/zed/pull/52730.
This PR adds a boolean setting `limit_content_width` in the Agent Panel
settings that allows turning off the content max-width entirely, which
was added for better readability. We had a handful of requests for it,
so it feels fair.
<img width="500" alt="Screenshot 2026-04-20 at 8 57@2x"
src="https://github.com/user-attachments/assets/d2540b35-3fa8-4424-895d-dc499ac4839c"
/>
Release Notes:
- Agent: Added a new `limit_content_width` setting in the agent panel
that allows turning off the content max-width limit.
This PR makes Zed only have one worktree picker, as opposed to a flavor
of it in the title bar and another in the agent panel. It then moves it
to the title bar, making it always present, so that its trigger is
separate from the branch picker (which now contains only two views:
branches and stashes). For the worktree picker, I'm mostly favoring the
behavior we've introduced in the agent-panel-flavored version.
It also updates the title bar settings migration to use the JSON
`migrate_settings` helper instead of a shallow Tree-sitter rewrite, so
old `show_branch_icon = true` values are promoted to
`show_branch_status_icon = true` across root, platform, release-channel,
and profile settings scopes.
- [x] Move worktree creation logic to the `git_ui` crate to make this
more generic and less agent-specific
- [x] Double-check the remote use case and ensure nothing broke there
- [x] Improve the UX for the detached HEAD state; better invite people
to create a branch
- [x] Migrate `show_branch_icon = true` to `show_branch_status_icon =
true` across nested settings scopes
Suggested .rules additions
When migrating renamed settings keys that can appear in platform
overrides, release-channel overrides, or profiles, prefer the JSON
`migrations::migrate_settings` helper over shallow Tree-sitter key
rewrites unless tests explicitly cover every nested scope that can
contain the key.
Release Notes:
- Improved migration of the title bar branch status icon setting.
---------
Co-authored-by: Nathan Sobo <nathan@zed.dev>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
This PR revamps our feature flag system, to enable richer iteration.
Feature flags can now:
- Support enum values, for richer configuration
- Be manually set via the settings file
- Be manually set via the settings UI
This PR also adds a feature flag to demonstrate this behavior, a
`agent-thread-worktree-label`, which controls which how the worktree tag
UI displays.
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
We had an internal report of soft wrap not working in git panel's commit
editor. Given the following settings:
```json
{
"languages": {
"Git Commit": {
"preferred_line_length": 80,
"soft_wrap": "preferred_line_length",
},
},
}
```
We would not soft-wrap in narrow viewports. As it turned out, the
problem was that we were always prefering a `preferred_line_length` as
our soft wrap boundary over the actual width of the editor.
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 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 #ISSUE
Release Notes:
- Fixed git commits editor not respecting soft wrap boundaries.
- settings: Removed `"soft_wrap": "preferred_line_length"` in favour of
`"soft_wrap": "bounded"`. Soft wrap now always respects editor width
when it's enabled.
Adds basic bookmark functionality to the editor, allowing users to mark
lines and later navigate between them. This is an MVP and will later be
expanded with a picker, vim marks integration and syntax tree based
bookmark positions. In this MVP bookmarks shift under external edits.
# UI
## Adding/Removing bookmarks
To add a bookmark:
- run the toggle bookmark action
- hold secondary and click in the gutter
- open the context menu by right clicking in the gutter and select add
bookmark To remove a bookmark:
- run the toggle bookmark action
- click on the bookmarks icon in the gutter
- open the context menu by right clicking in the gutter and select
remove bookmark
remove all bookmarks with `workspace: clear bookmarks`
# Implementation
This mirrors the implementation of breakpoints. The rendering of the
gutter was refactored to make place for bookmark icons and buttons:
- Code was extracted to a `Gutter` struct
- Runnables, breakpoints and bookmarks are now collected ahead of
layouting. Just before layouting we remove the items that collide and do
not have priority.
- The `phantom_breakpoint` is replaced by a `gutter_hover_button`
## In depth phantom breakpoint discussion:
This was phantom_breakpoint. It worked as follows:
- A fake breakpoint was added to the list of breakpoints.
- While rendering the breakpoints it a breakpoint turned out to be fake
it would get a different description and look.
- The breakpoint list was edited run_indicators ("play buttons")
rendering to removes the fake breakpoint if it collided.
This would not scale to more functionality. Now we only render
breakpoints, bookmarks and run indicators. Then we render a button if
there is not breakpoint, bookmark or run indicator already present. We
can do so since the rendering of such "gutter indicators" has been
refactored into two phases:
- collect the items.
- render them if no higher priority item collides.
This is far easier and more readable which enabled me to easily take the
phantom_breakpoint system and use it for placing bookmarks as well :)
Note: this was previously merged but it needed a better squashed commit
message. For the actual PR see: 51404. This reverts commit
7e523a2d2b.
Release Notes:
- Added Bookmarks
Co-authored-by: Austin Cummings <me@austincummings.com>
Closes#4526
Adds basic bookmark functionality to the editor, allowing users to mark
lines and later navigate between them.
### What's new
**Toggling bookmarks**
Users can toggle a bookmark on the current line(s) via the `editor:
toggle bookmark` action. A bookmark icon appears in the gutter for each
bookmarked line.
**Navigation**
Two new actions, `editor: go to next bookmark` and `editor: go to
previous bookmark`, navigate between bookmarks in the current buffer,
wrapping around at the ends of the buffer.
**Viewing all bookmarks**
`editor: view bookmarks` opens all bookmarks across the project in a
multibuffer, similar to how references and diagnostics are surfaced.
**Clearing bookmarks**
`workspace: clear bookmarks` removes all bookmarks in the current
project.
**Persistence**
Bookmarks are persisted to the workspace database and restored when the
workspace is reopened. They are stored as `(path, row)` pairs and
resolved back to text anchors. Out of range or unresolvable bookmarks
are skipped with a logged warning.
**Gutter rendering**
Bookmark icons are rendered in the gutter using the existing gutter
button layout system, consistent with breakpoints. They are suppressed
on lines that already show a breakpoint or phantom breakpoint indicator.
A new `gutter.bookmarks` setting (defaulting to `true`) controls their
visibility.
### What's left
- [x] Lazily load buffers that have bookmarks
- [x] Clean up test boilerplate
- [ ] Assign default keybindings
- [ ] Compare line of saved bookmarks with current buffer (gray out the
"stale" bookmarks)
### What's next (and nice to haves)
- [ ] Resilience against external edits
- [ ] Save column position with the bookmark
- [ ] Bookmarks attached to syntactic structures?
- [ ] Labeled bookmarks?
---
Release Notes:
- Added bookmarks: toggle bookmarks on lines with `editor: toggle
bookmark`, navigate with `editor: go to next bookmark` / `editor: go to
previous bookmark`, view all bookmarks with `editor: view bookmarks`,
and clear with `workspace: clear bookmarks`. Bookmarks are shown in the
gutter and persisted across sessions.
---------
Co-authored-by: Yara <git@yara.blue>
This fixes a regression where `zed -n .` in a subdirectory of an
already-open
project would redirect to the parent window instead of creating a new
one.
The root cause was that commit 66d2cb20c9 ("Adjust `zed -n` behavior")
made
`-n` run the worktree matching loop with subdirectory matching enabled,
when
previously `-n` skipped matching entirely.
## Changes
### Bug fix
- **Restore `-n` to always create a new window.** No worktree matching,
no
exceptions. This matches the behavior from when `-n` was first
introduced.
### New `--classic` flag
- Adds a hidden `--classic` CLI flag that explicitly selects the
pre-sidebar
default behavior: new window for directories, reuse existing window for
files already in an open worktree.
- The `cli_default_open_behavior` setting now toggles between `-e` (add
to
sidebar) and `--classic` behavior. When set to `new_window`, the classic
logic is used instead of unconditionally opening a new window.
### Refactor CLI open options
Replaces the old grab-bag of `open_new_workspace: Option<bool>`,
`force_existing_window: bool`, `classic: bool`, and `reuse: bool` with:
- **`cli::CliOpenBehavior` enum** — a single enum on the IPC boundary
with
variants `Default`, `AlwaysNew`, `Add`, `ExistingWindow`, `Classic`, and
`Reuse`.
- **`workspace::WorkspaceMatching` enum** — describes how to match paths
against existing worktrees (`None`, `MatchExact`, `MatchSubdirectory`).
- **`workspace::OpenOptions`** — uses `WorkspaceMatching` plus a simple
`add_dirs_to_sidebar: bool` instead of overlapping boolean flags.
The translation from CLI enum to workspace options happens in
`open_listener.rs`, keeping both layers clean and independent.
Release Notes:
- N/A
This fixes an issue reported by @Veykril where the "Try Now" button
would open a different panel than the agent panel. The bug was caused by
us attempting to focus the agent panel before layout settings updates
had been applied.
This should also make all programmatic settings updates more responsive,
because they won't have to wait for FS watchers to take effect.
Release Notes:
- N/A
---------
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
follow up #47471
As described in #47471, we introduced a direction-aware strategy to
improve user experience when interacting with hover popovers. In this
follow-up, we are adding `hover_popover_sticky` and
`hover_popover_hiding_delay` to control whether the feature introduced
in 47471 enabled, and to let users configure the delay to balance
responsiveness . Also `hover_popover_sticky` can now be imported from
`editor.hover.sticky`, as well as `hover_popover_hiding_delay` from
`editor.hover.hidingDelay` in VSCode.
Also this PR adds several tests:
- `test_hover_popover_cancel_hide_on_rehover`: when the cursor returns
to the hover after leaving once within the hiding delay, the hover
should persist while canceling the existing hiding timer.
- `test_hover_popover_enabled_false_ignores_sticky` : when
`hover_popover_enabled` is false, the `hover_popover_sticky` and
`hover_popover_hiding_delay` have no effect(since no hover is shown).
- `test_hover_popover_sticky_delay_restarts_when_mouse_gets_closer`:
when mouse gets closer to hover popover, we expect the timer to reset
and the hover remains visible.
- `test_hover_popover_hiding_delay`: check if the delay(in test, that's
500ms) works.
- `test_hover_popover_sticky_disabled`: when hover_popover_sticky is
false, the hover popover disappears immediately after the cursor leaving
the codes.
- VSCode import test in `settings_store.rs`
Release Notes:
- Added `hover_popover_sticky` and `hover_popover_hiding_delay` settings
to balance responsiveness of hover popovers.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This PR adds the `cli_default_open_behavior` setting and a first-run TUI
prompt
that appears when `zed <path>` is invoked without flags while existing
windows are
open and the setting hasn't been configured yet.
## What it does
### Setting and prompt
- Adds a new `cli_default_open_behavior` workspace setting with two
values:
`existing_window` (default) and `new_window`.
- When the user runs `zed <path>` for the first time with existing Zed
windows
open, a `dialoguer::Select` prompt in the CLI asks them to choose their
preferred behavior. The choice is persisted to `settings.json`.
- The prompt is skipped when:
- An explicit flag (`-n`, `-e`, `-a`) is given
- No existing Zed windows are open
- The setting is already configured in `settings.json`
- The paths being opened are already contained in an existing workspace
### IPC transport abstraction
- Introduces a `CliResponseSink` trait in the `cli` crate that abstracts
`IpcSender<CliResponse>`, with an implementation for the real IPC
sender.
- Replaces `IpcSender<CliResponse>` with `Box<dyn CliResponseSink>` /
`&dyn CliResponseSink` across all signatures in `open_listener.rs`:
`OpenRequestKind::CliConnection`, `handle_cli_connection`,
`maybe_prompt_open_behavior`, `open_workspaces`, `open_local_workspace`.
- Extracts the inline CLI response loop from `main.rs` into a testable
`cli::run_cli_response_loop` function.
- Switches the request channel from bounded `mpsc::channel(16)` to
`mpsc::unbounded()`, eliminating `smol::block_on` in the bridge thread.
### End-to-end tests
Seven new tests exercise both the CLI-side response loop and the
Zed-side
handler connected through in-memory channels, using `allow_parking()` so
the
real `cli::run_cli_response_loop` runs on an OS thread while the GPUI
executor
drives the Zed handler:
- No flags, no windows → no prompt, opens new window
- No flags, existing windows, user picks "existing window" → prompt,
setting persisted
- No flags, existing windows, user picks "new window" → prompt, setting
persisted
- Setting already configured → no prompt
- Paths already in existing workspace → no prompt
- Explicit `-e` flag → no prompt
- Explicit `-n` flag → no prompt
Existing tests that previously used `ipc::channel()` now use a
`DiscardResponseSink`, removing OS-level IPC from all tests.
Release Notes:
- Added a first-run prompt when using `zed <path>` to choose between
opening
in an existing window or a new window. The choice is saved to settings
and
can be changed later via the `cli_default_open_behavior` setting.
---------
Co-authored-by: Nathan Sobo <nathan@zed.dev>