# Objective
CSV feature needs row filtering feature by column values. This PR
provides base implementation of it with barebones ui.
> NOTE: Sleek UI with search & proper scrolling hanling is implemented
in next PR. It's stacked on top to reduce review scope
## Solution
- New `FilterEntry` / `FilterEntryState` model in
`table_data_engine/filtering_by_column.rs` tracking per-column
applied/candidate filter values
- Filtering runs in the background (`feat: Implement background
filtering`) so large CSVs don't block the UI thread while a filter is
applied
- Filter menu entries reflect live counts and support a configurable
sort order (`FilterSortOrder`, added in `renderer/settings.rs` /
`settings.rs`)
- Filter/sort trigger buttons on column headers are hidden until hover,
using `GradientFade` (new in `ui/src/components/gradient_fade.rs`) to
fade content behind them
## Testing
Filter chain tested on csv fixtures with multiple filters applied
sequentially columns.
## Self-Review Checklist: (todo)
- [ ] 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) (out of scope of this pr)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
## Showcase
<img width="664" height="249" alt="image"
src="https://github.com/user-attachments/assets/0e9b0a91-1a27-4e0f-a8d4-fdce36735131"
/>
<img width="663" height="205" alt="image"
src="https://github.com/user-attachments/assets/0428f5c6-6aaa-4891-b010-ca79803f6613"
/>
---
Release Notes:
- Added initial row filtering UI & logic
This allows us to build powerful and flexible Input and TextArea
components
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
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments (Unsafe: none)
- [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
## Summary
When the agent is streaming output, expanding the message editor can
appear to work (the container grows) but the input editor itself remains
constrained to auto-height (only a few lines). Toggling minimize →
expand makes it render correctly.
This PR ensures the message editor stays in full mode while expanded,
preventing automatic editor mode syncing on thread updates from
overriding the user's explicit expand action during streaming.
## Steps to reproduce
1. Start an agent thread and send a message that causes streaming output
2. While streaming, click “Expand Message Editor”
3. Observe the input editor still shows only a few lines (auto-height)
4. Click “Minimize Message Editor” and then expand again; it becomes
fully expanded
## Test plan
- Start an agent thread and let it stream
- Click “Expand Message Editor” while streaming
- Verify the editor actually expands (not limited to the auto-height max
lines)
- Toggle minimize/expand multiple times during streaming; verify it
remains correct
## Additional context
Repro video:
https://github.com/user-attachments/assets/6e328fa8-d431-456a-b70a-864ae617ea88
Release Notes:
- Fixed message editor not fully expanding during agent generation
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
On ordinary platforms, `Platform::run` blocks for the lifetime of the
app, and `Application::run`'s stack frame keeps the app state alive.
Embedded platforms invert that: the run loop belongs to someone else.
`Application::run_embedded` supports that shape: it starts the app
exactly like `run()`, but returns an `ApplicationHandle` holding the
strong app handle.
Release Notes:
- N/A
`update_last_checkpoint` swallows `compare_checkpoints` errors with
`.unwrap_or(true)`. The "Restore checkpoint" button silently disappears
and nothing gets logged, which is what made the linked issue painful to
track down in the first place.
The sibling `update_last_checkpoint_if_changed` a few lines up already
handles the same call with `.context(...).log_err()` and an early
return, so I did the same here. On error the checkpoint's visibility is
left alone instead of being forced to hidden. I didn't propagate the
error because the task result gets `?`'d in `run_turn`'s cleanup, and
failing there would leave the panel stuck in its generating state.
Added a regression test that breaks the comparison mid-turn (recreating
`.git` makes the fake repo forget its checkpoints) and asserts an
already-visible checkpoint stays visible. It fails on main and passes
with this change. The new log line shows up when it runs: `failed to
compare checkpoints: invalid left checkpoint: ...`
Closes#59100
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 checkpoint comparison errors silently hiding the "Restore
Checkpoint" button in the agent panel.
Co-authored-by: pstemporowski <110726755+pstemporowski@users.noreply.github.com>
Co-authored-by: Bennet Bo Fenner <bennet@zed.dev>
# Objective
Provide a means of quickly opening a permanent tab from project panel
instead of a preview tab.
Implements #51866 (_Middle click to open file in a new tab_ with 18×↑)
which is also part of #31822 (_Middle Click Improvments_) titled "middle
clicking on a file in the project panel should open the file in a
non-transient state".
With `preview_tabs.enable_preview_from_project_panel` enabled, a click
in the project panel opens a preview tab, and there's no easy gesture to
open a permanent one instead, simplest one currently being a double
click. VS Code and VSCode-based editors recognize middle mouse click as
a way to open a permanent tab since 2016 (microsoft/vscode#14453).
## Solution
Wired up an `on_aux_click` handler for project panel entries:
middle-clicking a file opens it in a permanent tab and focuses it,
regardless of the preview tabs setting.
Added a line to `docs/src/project-panel.md` to reflect the behavior.
## Testing
- Manually tested on Windows: middle click opens a permanent tab,
promotes an existing preview tab to a permanent one if already open,
does nothing for directories
- Haven't tested on macOS/Linux
## Self-Review Checklist:
- [ ] 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
<details>
<summary>Click to view showcase</summary>
https://github.com/user-attachments/assets/2de5f23d-637f-4ffc-8d03-02dc11714af4
</details>
---
Release Notes:
- Added support for middle-clicking a file in the project panel to open
it in a permanent tab instead of a preview tab
This fixes#56956.
The terminal link-open gesture was split between `mouse_down` and
`mouse_up`, but both halves only ran in the non-mouse-reporting path.
When a foreground app enabled terminal mouse reporting, a secondary
click on a URL or file path was forwarded to the PTY instead of opening
the link.
This changes secondary-click link handling so it checks for a hyperlink
before mouse reporting on press, and completes the matching hyperlink
open before mouse reporting on release. The event is only consumed when
the click actually lands on the same link, so normal clicks in
mouse-reporting TUIs continue to be forwarded as before.
Validation:
- `CARGO_BUILD_JOBS=1 cargo test -j1 -p terminal
test_hyperlink_ctrl_click_same_position_in_mouse_mode`
- `CARGO_BUILD_JOBS=1 cargo check -j1 -p terminal`
Release Notes:
- Improved terminal links: Cmd/Ctrl-click now opens links even when the
application has mouse reporting enabled (e.g. vim, opencode, claude).
Disable `terminal.open_links_in_mouse_mode` to forward these clicks to
the application instead.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
The Gentoo `ebuild` file format is a subset of a bash script, see
https://wiki.gentoo.org/wiki/Ebuild.
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
Closes #ISSUE
Release Notes:
- Changed `ebuild` files to be recognized as bash.
Signed-off-by: gcarq <egger.m@protonmail.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
# Objective
- Describe the objective or issue this PR addresses. -> ** Typo and
grammar fixes!**
## Solution
## Testing
## 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
---
Release Notes:
- N/A
Fixes#53527.
## Summary
- Suggest `untitled.<extension>` when saving an untitled editor buffer
with a selected non-Plain Text language.
- Preserve the existing title-based suggestion for existing files, Plain
Text buffers, and buffers without a language extension.
- Add a regression test for an untitled Rust buffer suggesting
`untitled.rs`.
## Testing
- `mise exec rust@1.95.0 -- cargo fmt --check -p editor`
- `mise exec rust@1.95.0 -- cargo test -p editor
test_suggested_filename_uses_language_extension_for_untitled_buffer
--lib`
## Suggested .rules additions
None.
Release Notes:
- Fixed Save As suggestions for untitled buffers with a selected
language.
---------
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)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
This fixes Go outline extraction for methods whose receiver has no name,
such as `func (v2) Method()`. These methods are now included in outline
symbols, which also feed breadcrumbs and sticky
scroll.
Tested with:
- `cargo test -p languages`
- `cargo test -p grammars`
- `./script/clippy -p languages`
- `cargo fmt --check --package languages`
Before:
[before_cut.webm](https://github.com/user-attachments/assets/91eb5cb0-703a-4496-b0dd-5369c4c219fc)
After:
[after_cut.webm](https://github.com/user-attachments/assets/76d13d88-3671-4118-99fc-c073a6e64727)
Release Notes:
- Fixed Go methods with unnamed receivers not appearing in breadcrumbs
and sticky scroll.
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
A "rename symbol" whose workspace edit also renames the file (a
`TextDocumentEdit` followed by a `RenameFile` resource operation) only
applied the text edit to the in-memory buffer. The on-disk file still
held the pre-edit content, so the blind `fs.rename` moved stale bytes to
the new path while the edited buffer was stranded at the old path,
swapping the two files' contents.
This persists a dirty buffer for the rename source before renaming, so
the new file receives the edited content and the now-clean buffer can't
be saved back to the old path.
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
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes#59077
Release Notes:
- Fixed a symbol rename that also renames the file swapping the contents
of the old and new files
When you use `anyhow::anyhow!("{error}")` to convert a preexisting error
to an `anyhow::Error`, the error source can be lost (depending on the
`Display` impl of the error). Anyhow errors can display the whole source
chain when printed. This commit makes us consistently use `context()`
instead to preserve the underlying error's source.
Release Notes:
- N/A
Was trying to debug an r-a issue and ran into this.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliabilityx
- [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 ...
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
Resolves https://github.com/zed-industries/zed/issues/55600
This diff fixes `pane::ReopenClosedItem` getting stuck when the
closed-item stack contains entries that cannot be reopened, such as
Project Search, untitled buffers, or Default Settings. Previously,
`Workspace::navigate_history_impl` would pop the newest closed entry and
stop if that item was no longer present in the pane and had no path
recorded for reopening. That made `cmd- shift-t` appear to do nothing
until enough attempts had consumed those unreopenable entries.
With this change, closed-item navigation keeps scanning when it
encounters an entry that cannot be activated or reopened by path. This
preserves the current path-based reopening behavior for normal files,
while avoiding no-op shortcuts caused by non-file items in the closed
stack.
This made me wonder whether or not we'd eventually want full reopen
support for non-traditional items like Project Search or bundled
settings editors. Supporting that properly would require storing
item-specific restoration state, such as search query/options for
Project Search or a bundled-file descriptor for Default Settings, and
teaching closed-item navigation how to recreate those items from that
state. Something definitely out of scope for this PR.
| Before | After |
| --- | --- |
| <video
src="https://github.com/user-attachments/assets/c7044423-4531-4857-84f2-4e9651826c6a"
controls width="500" title="Before"></video> | <video
src="https://github.com/user-attachments/assets/c89dcefb-1796-4cdf-bb21-f165145e678e"
controls width="500" title="After"></video> |
Release Notes:
- Fixed reopening closed tabs getting stuck on closed items that cannot
be reopened.
Decodes url escape sequences in hover preview `file:///` links like
escaped
spaces in the file path.
I'm working on an LSP and happened to be working with some files in a
directory with spaces. When adding Markdown links with `file:///` the
`%20` escape for spaces was being included verbatim in the path that Zed
tried to open.
I'm reusing the lines from `markdown_preview_view.rs` for decoding. In
the existing tests I don't see coverage for `file:///` links. If you'd
like some tests for this can you point me to any examples to start from?
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:
- Fixed decoding spaces and other escaped characters in `file://` links
used in hover popovers
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
This PR makes the `send_authenticated_json_request` method on the
`CloudApiClient` public.
This way we can use it to make requests by external callers.
The `build_request` method was also inlined into
`send_authenticated_request` to make the contract simpler.
Release Notes:
- N/A
Adds native support for AWS Bedrock's Mantle endpoint
(`bedrock-mantle`), which serves models with no `Converse`/`Invoke`
support on `bedrock-runtime`, such as GPT-5.5, GPT-5.4, and Grok 4.3 but
more importantly **open-weight** models
Closes#60471
## What's changed
- Renamed the existing `Model` enum in the `bedrock` crate to
`ConverseModel`, and added a new `MantleModel` enum for Mantle-only
models. Mantle models reuse the existing OpenAI-compatible Chat
Completions/Responses request and response plumbing
(`into_open_ai`/`into_open_ai_response`,
`OpenAiEventMapper`/`OpenAiResponseEventMapper`) already used by the
native OpenAI and OpenAI-compatible providers, rather than introducing
new marshalling code.
- Added a `BedrockMantleModel` language model that routes requests to
the `bedrock-mantle` endpoint, dispatching to Chat Completions or the
Responses API depending on the model. Mantle models appear in the model
picker alongside Converse models under the same Bedrock provider.
- Added region gating: `bedrock-mantle` is only available in a subset of
AWS Regions, so using a Mantle model outside of them surfaces a clear
error naming the current Region and the supported ones, instead of an
opaque HTTP failure.
- Implemented Bedrock bearer token authentication for Mantle requests: a
configured Bedrock API key is used as-is, and every other auth method
(IAM credentials, named profile, SSO, automatic) derives a short-term
token by locally SigV4-presigning a `CallWithBearerToken` request. This
requires no extra network round trip and no token caching, since
re-signing locally is cheap.
- Added a specific error for the 403 you get when your credentials have
`bedrock:CallWithBearerToken` but not the separate
`bedrock-mantle:CallWithBearerToken` permission Mantle models require,
since this is the most common misconfiguration.
- Added a `mantle_available_models` setting so custom models served
through `bedrock-mantle` can be configured, the same way other providers
support custom models via `available_models`.
- Documented Mantle models and the new setting in the Amazon Bedrock
section of [Use a
Gateway](https://zed.dev/docs/ai/use-a-gateway#amazon-bedrock).
## Testing
- Added unit tests covering: the local SigV4 bearer-token signing
(including a byte-for-byte cross-check against a reference
implementation), Mantle endpoint URL construction, the
Mantle-supported-regions list, thinking-effort normalization, and the
settings-to-model protocol mapping.
- `cargo test -p bedrock -p language_models -p settings_content -p
settings` passes.
- `./script/clippy` passes with no new warnings.
Release Notes:
- Added native support for AWS Bedrock's Mantle endpoint, enabling
GPT-5.5, GPT-5.4, and Grok 4.3 through the Amazon Bedrock provider.
# Objective
Fix a Windows CI flake in `extension_host
extension_store_test::test_extension_store_with_test_extension`, which
panicked in GPUI's leak detector with three leaked `LspStore` handles
([example
run](https://github.com/zed-industries/zed/actions/runs/28871529605/job/85635418351)).
## Solution
`LspAccess::ViaLspStore` held a strong `Entity<LspStore>`, cloned into
three `ExtensionHostProxy` registrations by `language_extension::init`.
The proxy sits inside an `Arc` cycle (proxy →
`LanguageServerRegistryProxy` → `LanguageRegistry` →
`ExtensionLspAdapter` → `WasmExtension` → `WasmHost` → proxy), so
whenever an extension LSP adapter was registered at app-drop time, the
cycle pinned the `LspStore` entity after its owning `Project` dropped.
The flake was purely timing: extension reload toggles the adapter
registration, and an unclean LSP pipe shutdown on Windows shifted
teardown into the pinned window.
`ViaLspStore` now holds a `WeakEntity<LspStore>`, upgraded at its sole
use site (`remove_language_server`), skipping the stop task when the
store is gone — matching the existing `ViaWorkspaces` semantics. A dead
store is the expected terminal state after the owning project drops, so
no error is logged or propagated. `Project`/`HeadlessProject` remain the
sole long-term owners of `LspStore`, which is already the convention
everywhere else (e.g. `json_schema_store`, the `lsp_store` message
handlers).
## Testing
- Ran `cargo nextest run -p extension_host
extension_store_test::test_extension_store_with_test_extension` locally:
passes.
- The flake is timing-dependent (reproduced on Windows CI), so a local
pass doesn't prove absence; the fix removes the only strong non-owner
handle, which the leak detector reported.
## 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: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
## Summary
Fixes#60288 and #60454 .
After a push, the push toast's "Create Pull Request" button fails with
`Unsupported remote URL` when the repository's remote is not a plain,
recognized host. This restores the pre-#53913 behavior as a fallback:
use the create-PR/MR link that `git push` itself prints, and only build
a URL from the provider registry when the push output had no link.
## Why this matters
#53913 made the button always appear and changed `create_pull_request`
to reconstruct the PR URL from the remote via
`git::parse_git_remote_url` against the `GitHostingProviderRegistry`.
When the remote is not recognized, parsing returns `None` and the action
errors. This affects self-hosted GitLab/GitHub, an SSH-config host alias
like `git@personal:owner/repo` (the duplicate #60076), and any
non-standard host. Before #53913, the flow used the link git prints in
the push output, which works regardless of host, so this is a regression
for anyone not pushing to a plainly-recognized GitHub URL.
## Solution
`git push` prints a `remote:` line with the hosting provider's
create-PR/MR URL (GitHub: "Create a pull request for '\<branch>' on
GitHub by visiting:", GitLab: "To create a merge request for \<branch>,
visit:", Bitbucket: "Create pull request for \<branch>:"), and we
already hold the push `RemoteCommandOutput`.
- `remote_output.rs`: add `extract_pull_request_url`, which scans the
push stderr for the first `http(s)` URL on a `remote:` line tied to a
create-PR/MR prompt. It ignores unrelated URLs (for example the OpenSSH
post-quantum warning line).
- `git_panel.rs`: capture that URL in `show_remote_output` into
`pending_pull_request_url`, and prefer it in `create_pull_request`,
falling back to the existing provider construction only when the push
output had no link. The cached URL is consumed once (`take()`) and
cleared when the active repo, the active branch/head, or the pending
remote operation changes, so a later `git: Create Pull Request` action
never opens a stale URL from an earlier push.
Recognized GitHub remotes are unaffected: they still get a link from the
push output, with the provider path as the fallback.
## Testing
Unit tests in `remote_output.rs` cover `extract_pull_request_url` for
the GitHub, GitLab, and Bitbucket prompt formats, the no-link case
(returns `None`, so the provider fallback runs), and an output
containing an unrelated URL that must not be mistaken for the PR link.
The existing remote-operation test also asserts the cached URL is
cleared when a new operation starts.
`cargo test -p git_ui remote_output` passes (5 tests). Tested on macOS.
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
---
Release Notes:
- Fixed "Create Pull Request" button in the toast shown after `git:
push` failing for repositories on unrecognized Git hosts by using the
link printed in the push output.
- Fixed the button shown on the toast after `git: push` for GitLab
branches with an existing merge request. It now shows "View Merge
Request" and links to the existing merge request.
---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: dino <dinojoaocosta@gmail.com>
# Objective
Opening and closing windows quickly on Linux could crash the renderer
with a `GPU resources not available` panic.
The `gpui_wgpu` renderer keeps its GPU resources in an `Option` that is
cleared when a window is torn down, and also while device-loss recovery
is pending. On Wayland the window's `Drop` releases those resources
synchronously but defers unregistering the surface to a later task, so a
compositor resize or transparency event can still reach the renderer in
that short gap. `update_drawable_size` and `update_transparency` assumed
the resources were always present and called an accessor that panics
when they are not.
I am not certain if there is a good case to reproduce this in zed, but I
had encountered it in my own GPUI app.
## Solution
Make `update_drawable_size` and `update_transparency` tolerate missing
GPU resources by skipping the surface reconfiguration instead of
panicking, matching how the rest of the renderer already guards this
state. The requested size and alpha mode are still recorded before the
guard, so they take effect if the renderer's resources are recreated,
for example after device-loss recovery.
## Testing
Tested on Linux with Wayland.
- Reproduced by opening and closing windows quickly, which previously
panicked with `GPU resources not available`. With this change the panic
no longer occurs. This was reproducible on a debug build or a weak/slow
device.
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
---
Release Notes (not sure if worth mentioning):
- Fixed a crash that could occur when opening and closing windows
quickly on Linux
Co-authored-by: Mikayla Maki <mikayla@zed.dev>
# Problem
Since the release of the new git UI, when `~/.gitconfig` on a remote
server is a symlink pointing to a file on a virtual filesystem (a common
setup when using [OrbStack](https://orbstack.dev/) on macOS), Zed fails
to connect with "Timed out pinging remote client".
# Cause
When setting up a file watcher for gitconfig, `fs::watch()` reads the
symlink target and adds its parent directory to the poll watcher.
`notify::PollWatcher::watch()` does a full synchronous recursive
directory scan at registration time to build an initial snapshot. If the
parent is something like a Mac home directory mounted via virtiofs, that
scan blocks the server's main thread long enough that it can't respond
to the initial ping within the 5 second timeout.
# Solution
The fix I implemented for this was to skip the parent directory watch
when using a poll watcher. As far as I can tell, it's redundant in the
poll case since the poll watcher detects changes by periodically reading
metadata at the registered path, so watching the parent doesn't add
anything for change detection. From my limited testing this seems to
work fine but if someone with more experience in this part of the
codebase would like to weigh in, that would be very much appreciated.
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:
- Fixed remote SSH connections timing out when `~/.gitconfig` is a
symlink to a file on a virtual filesystem
# Objective
Ensure that all existing panels have corresponding menu items in the
"View" menu. I was onboarding a friend to Zed yesterday that was having
a hard time figuring out how to interact with the Agent. Although he did
open the "View" menu, I noticed that the Agent panel item was missing
from there, making it hard for new users to discover it exists.
## Solution
* Add both "Agent Panel" and "Git Panel" entries to the menu items for
the "View" app menu.
* Update the action used for the "Terminal Panel" menu item from
`terminal_panel::ToggleFocus` to `terminal_panel::Toggle` to ensure we
display a shortcut for this menu item.
* Another valid option would be to update the default keymap to use
`terminal_panel::ToggleFocus` instead but that would probably break
existing user's expectations that the default shortcut toggles the
terminal panel, instead of toggling its focus.
* Introduce `zed_actions::git_panel` to be able to extract its
`ToggleFocus` action, following the existing pattern.
### Next Steps
It's worth noting that, even though there's now an "Agent Panel" item
mapped to the `assistant::ToggleFocus` action, its default keybinding is
not displayed (at least on macOS), because of the way it's defined as
`cmd-?` . Using `cmd-shift-/` instead doesn't work, so we'll likely have
to update `MacKeyboardMapper` to allow mapping between shifted and
unshifted keys equivalent, that is, when `?` is detected, it is able to
determine that, in the user's layout that is the result of `shift-/`.
## Testing
Manually tested, screenshots can be seen in the "Showcase" section.
## 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)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable
## Showcase
<details>
<summary>Before</summary>
<img width="488" height="946" alt="CleanShot 2026-07-03 at 14 24 35@2x"
src="https://github.com/user-attachments/assets/58b0497c-2929-4da3-86b6-a2e0ce0c5ca4"
/>
</details>
<details>
<summary>After</summary>
<img width="524" height="1116" alt="CleanShot 2026-07-03 at 14 24 59@2x"
src="https://github.com/user-attachments/assets/8e2c6320-97ad-4620-b595-182f6d0ded81"
/>
</details>
---
Release Notes:
- Added "Agent Panel" and "Git Panel" items to the "View" menu
# Objective
Whenever the git repository state is updated on disk (e.g., via staging,
committing, branch switching, or stashing), `reload_buffer_diff_bases`
is scheduled to reload the diff for all active buffers. This causes 2
git processes to be spawned for each open file which can become
noticeable when many files are open
5e32405669/crates/project/src/git_store.rs (L5179)
## Solution
This PR introduces `load_revisions` which uses a single `git cat-file
--batch` command to compute the diff for all files in the same git
process. This prevents the need to sequentially schedule 2 git
subprocesses per open buffer.
I also changed `load_index_text` and `load_commited_text` to rely on
`load_revisions` which simplifies the code.
## Testing
I added a unittest and manually verified that Zed now only runs a single
`git cat-file --batch` command instead of 2 `git show` processes per
open buffer.
On macOS I viewed the currently running git processes using:
```shell
sudo eslogger exec | jq --unbuffered -r '
select(.event.exec?.target?.executable?.path? | strings | contains("git")) |
(.event.exec?.args? // []) | join(" ")
'
```
## 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
/cc @Veykril
Release Notes:
- Reduced number of git processes for calculating diff of open buffers
when the repo state changes on disk
# Objective
- Make Git Panel History show commit tags so release/version markers are
visible without opening the full Git graph or commit details.
## Solution
- Store commit history entries with both the commit SHA and tag names
from existing git graph data.
- Render tag names as muted chips next to the commit subject.
- Limit visible tags to 3 per commit and show `+N` for additional tags.
## Testing
- Ran `cargo check -p git_ui`.
- Manually verified on Linux with `script/zed-local --stateful .`.
- Confirmed tags appear in Git Panel History.
## 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
Git Panel History now shows commit tags inline as muted chips next to
the commit subject.
---
Release Notes:
- Added tag labels to the Git Panel commit history.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
This PR adds adjustments to the tree view, making it more consistent
with all other tree view displays in the app (e.g., displaying indent
guides, removing chevron toggle, etc.), and also fixes an issue where
the commit message scrollbar was scrolling up with the message.
Release Notes:
- N/A
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)
(Arguably no, but it's an okay compromise methinks)
- [ ] Tests cover the new/changed behavior (I'm unsure how one would
properly test this, sorry!)
- [x] Performance impact has been considered and is acceptable
Closes#56466
To be completely honest I don't know if this is a good fix or not, it
does fix the problem I was running into where opening the large mermaid
diagram would blow up VRAM. It doesn't look amazing visually but I would
consider this behavior better, if it's not a good fix then that's okay:)
I chose 8192 because 8192 only brings VRAM usage up ~100MB in my testing
while 16384 brought my VRAM usage up to about 1GB from 150-200MB, for
lower end systems this seems unacceptable.
Before:
I can't take a screenshot of the before at this point because it eats my
system VRAM & Memory too fast. As a text description; It would show a
large empty rectangle where the mermaid diagram should be and blow up
Zed's VRAM usage from ~300MB to ~22GB (all of the available VRAM in my
system)
After:
<img width="1698" height="763" alt="image"
src="https://github.com/user-attachments/assets/62eb7c95-cca8-43f9-8257-c7e529f26e8d"
/>
<img width="1000" height="31" alt="image"
src="https://github.com/user-attachments/assets/4315c029-3cdd-44f6-ac78-971d125ab700"
/> (Up from ~150MB), the 257MiB figure is the GPU Memory.
Release Notes:
- N/A?
Co-authored-by: Lukas Wirth <lukas@zed.dev>
## Summary
- Refresh GPUI's cached mouse position when window bounds change so
hover hit-testing uses the current cursor position after live resize.
- Return X11 mouse positions in window-relative logical pixels to keep
`PlatformWindow::mouse_position()` consistent with other backends.
Fixes#57354
## Testing
- `cargo fmt -p gpui -p gpui_linux`
- `cargo check -p gpui_linux`
- `cargo check -p gpui`
## Suggested .rules additions
- In GPUI platform backends, `PlatformWindow::mouse_position()` should
return window-relative logical pixels; use separate APIs or fields for
global/device-pixel coordinates.
Release Notes:
- Fixed incorrect hover state while resizing GPUI windows.
Release Notes:
- Fixed clear drag overlay when external drag ends outside window
When dragging files from macOS Finder over the project panel and then
dragging back to Finder, the drag overlay remained visible because the
drag state was not properly cleaned up.
The root cause was that only `draggingExited:` was handled, but not
`draggingEnded:`. On macOS:
- `draggingExited:` is called when the drag leaves the window area
- `draggingEnded:` is called when the drag operation ends entirely
When a user drags a file back to Finder and drops it there,
`draggingEnded:` is called but was not being handled.
---------
Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
# Objective
The Copilot sign-in dialog was created without an `app_id` or window
title, resulting in an empty WM class/title on Linux. Tiling window
managers with class-based no-focus rules (like Hyprland's default
configuration in Omarchy) treat such windows as anonymous popups and
refuse to focus them, making the dialog impossible to interact with.
## Solution
Set both `app_id` and window title on the Copilot code verification
window, following the established pattern used in other UI components
like `agent_ui` and `settings_ui`.
Added `release_channel` as a dependency to
`crates/copilot_ui/Cargo.toml` and called
`app_id(ReleaseChannel::app_id(cx))` and `window_title("Use GitHub
Copilot in Zed")` in `open_copilot_code_verification_window`.
## Testing
Verified on Hyprland (Omarchy) by inspecting window properties with
`hyprctl clients`:
**Before (empty class/title):**
```
Window 5606ee1dd280 -> :
class:
title:
acceptsInput: 0
```
**After (with proper class/title):**
```
Window 5606ee22b660 -> Use GitHub Copilot in Zed:
class: dev.zed.Zed-Dev
title: Use GitHub Copilot in Zed
acceptsInput: 1
```
The dialog now receives keyboard focus and mouse input correctly on
Hyprland. I tested on Linux only; this fix lives in the window creation
call so it is a no-op on macOS and Windows where `app_id` is ignored.
## 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 Copilot sign-in window not being focusable on Hyprland and
similar tiling window managers
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
The unmount of the update disk image was made async-and-detached in
#38867, which introduced a race: the installer TempDir was dropped
(running remove_dir_all) while the DMG was still mounted inside it. The
removal failed silently, leaking a zed-auto-update* dir containing the
~140 MB DMG in /private/var/folders on every update.
Now the unmount is awaited before the temp dir is dropped (installation
already runs on the background executor since #58767, so this no longer
blocks the UI), with the Drop impl kept as a safety net for early exits
and cancellation. Additionally, stale installer dirs older than 24 hours
are swept from the temp dir when update polling starts, so existing
accumulated leaks get reclaimed.
Closes FR-104
Closes#58835
Release Notes:
- Fixed the macOS auto-updater leaking a copy of the downloaded update
in the system temp directory on every update, and added cleanup of
previously leaked files.
**TL;DR**: model updates + reasoning levels + fixes discovered when
working on https://github.com/zed-industries/zed/pull/60373
# Objective
Since the model auto-discovery PR was
[cancelled](https://github.com/zed-industries/zed/pull/60373#issuecomment-4886521448),
here is a manual model list update! I also copied the stand-alone
bugfixes/enhancements from that PR.
## Solution
A lot of manual work 😅
**OpenCode Zen**:
- added Fable 5 and Sonnet 5
- added models that were previously only available on OpenCode Go: GLM
5.2, Kimi K2.7 Code, and Minimax M3
- added reasoning levels for all models. I started from the data on
[`Models.dev`](https://models.dev) (the `/api.json` raw data), and then
I matched that with what is shown in the OpenCode CLI and what I know to
be true
**OpenCode Go**:
- added reasoning levels for GLM 5.2
**OpenCode in general**:
- added `protocol` validation for the settings, by moving from a random
`String` to an `enum`, for both nicer error messages (random strings or
typos will get an error instead of using `openai_chat` by default) and
to avoid issues like [folks saying non-existent protocols are a
thing](https://github.com/zed-industries/zed/issues/56869#issuecomment-4550154554)
- enabled parallel tool calls by default. As per [OpenCode developer on
Discord](https://discord.com/channels/1391832426048651334/1471233160993050918/1472020924881702912),
_"almost all models worth using support parallel tool calling
natively"_. Manual tests confirmed all OpenCode Go models support this
correctly (and was enabled by default on the OpenCode side for all but 1
model). I initially wanted to skip this from the release notes, but I
added it so folks are aware of it in case any issues are caused by this
being enabled for all models
- allegedly fixed Google thinking since reasoning levels / thinking
effort levels were added for Google models and an auto-checker LLM
highlighted that was not properly configured
- added support for the new-ish `supports_disabling_thinking` so
thinking-only models don't get a no-impact toggle to disable thinking
I have no idea if any of the Free models will disappear in 2 days or
not, so I did not update those 🤷 (as per decision in
https://github.com/zed-industries/zed/issues/56869#issuecomment-4466637648)
## Testing
The Zen and Google changes were not tested as I don't have a Zen
subscription and I stubbornly refuse to get one.
The Free&Go changes were tested by running a "_rename this variable for
me. add a function. delete the function_" test with a few different
models.
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
---
Release Notes:
- Agent: OpenCode settings now validate `protocol` values
- Agent: OpenCode only shows the "Disable thinking" toggle if thinking
can indeed be disabled/enabled
- Agent: OpenCode models now enable parallel tool calls by default
- Agent: Updated OpenCode Zen models (added Fable 5, Sonnet 5, GLM 5.2,
Kimi K2.7 Code, and Minimax M3)
- Agent: Added OpenCode Go GLM 5.2 reasoning effort levels
- Agent: Added reasoning effort levels for all OpenCode Zen models
- Agent: Fixed thinking for OpenCode Zen Google models
Fixed my PR #58753.
Change the url placeholder from http://localhost:11434 to
http://localhost:8080/v1/completions to match the URL endpoint in the
[docs](https://zed.dev/docs/ai/edit-prediction)
```json
{
"edit_predictions": {
"provider": "open_ai_compatible_api",
"open_ai_compatible_api": {
"api_url": "http://localhost:8080/v1/completions",
"model": "deepseek-coder-6.7b-base",
"prompt_format": "deepseek_coder",
"max_output_tokens": 512
}
}
}
```
Note: http://localhost:8080/v1/completions/ with an extra / does not
work.
Added the constants OPEN_AI_COMPATIBLE_API_URL_PLACEHOLDER and
OPEN_AI_COMPATIBLE_MODEL_PLACEHOLDER.
### Initial Issue
I noticed that using http://localhost:8080 doesn't work with llama.cpp.
Giving errors like this from (zed: open log):
```
2026-06-06T17:55:39+01:00 ERROR [crates/edit_prediction/src/edit_prediction.rs:2464] custom server error: 404 Not Found - {"error":{"message":"File Not Found","type":"not_found_error","code":404}}
```
After reading the docs above, I found out that I had to add
/v1/completions to the end.
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
# Objective
Prevent a macOS crash in GPUI when AppKit temporarily reports that a
visible window has no associated `NSScreen` during display
reconfiguration.
The crash can happen on this path:
```text
NSScreen::deviceDescription
gpui_macos:🪟:display_id_for_screen
gpui_macos:🪟:MacWindowState::start_display_link
gpui_macos:🪟:window_did_change_screen
```
`start_display_link` checked the window occlusion state before creating
a display link, but it still assumed `NSWindow.screen()` was non-null.
During display changes, sleep/wake, lid close/open, or monitor
reconfiguration, AppKit can transiently return `nil` for `screen`, and
passing that into `NSScreen::deviceDescription` aborts with a null
pointer dereference.
I observed this on macOS 26.5 after the system entered a rare display
state: once in that state, running GPUI applications would crash
immediately after wake. I have not identified the exact OS/display
condition that triggers it, so the full wake/reconfiguration scenario is
not deterministic, but the crash report consistently points to
`NSWindow.screen()` being `nil` when `start_display_link` tries to
create a display link.
## Solution
Make `display_id_for_screen` explicitly handle a null `NSScreen` by
returning `None`.
Callers now handle that case by either:
- returning early from `start_display_link`, because there is no valid
display id to create a display link for yet
- skipping a null screen while iterating `NSScreen::screens`
The normal non-null screen path is unchanged.
This keeps the nil-screen guard at the FFI boundary where
`NSScreen::deviceDescription` is called.
## Testing
Tested on macOS 26.5.
Commands run:
```bash
cargo fmt --check -p gpui_macos
cargo test -p gpui_macos display_id_for_screen_returns_none_for_null_screen
cargo check -p gpui_macos
```
Added a unit test covering the new boundary behavior:
`window::tests::display_id_for_screen_returns_none_for_null_screen`
## 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 a macOS crash that could occur when display configuration
changes while a GPUI window is temporarily not associated with a screen.
## Summary
- Store Windows window minimizable and resizable capabilities on
`WindowsWindowInner`.
- Prevent custom titlebar hit testing from returning minimize/maximize
button hit targets when the corresponding capability is disabled.
- Swallow disabled native non-client minimize/maximize button mouse
events so they cannot fall through to the default window procedure or
GPUI's manual `ShowWindowAsync` handling.
Fixes#52067.
## Validation
- `cargo fmt --package gpui_windows`
- `cargo check -p gpui_windows`
- `git diff --check`
Release Notes:
- Fixed disabled minimize and maximize window controls still activating
on Windows.
On macOS, `load_family` was inserting every font into
`font_ids_by_postscript_name` without checking for duplicates. When two
installed font files claim the same PostScript name — typically an older
Geist Mono left behind alongside the current brew cask — the second
insert overwrote the first. After shaping, `id_for_native_font` looked
up that PostScript name and got back the *other* font's `FontId`, so the
rasterizer drew glyphs from the wrong table
See #55472 for the screenshot
This adds a local `HashSet` to dedup within a single `load_family` call.
Scoping it to one call (rather than the global map) matters: the same
family gets reloaded under different `FontKey`s when `FontFeatures` or
`FontFallbacks` change, and a global check would skip every font on the
reload and break weight selection.
Cross-family PostScript name collisions and CoreText fallback
substitutions that re-introduce a conflict are out of scope here
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:
- Fixed glyph rendering when fonts share a PostScript name on macOS
---------
Co-authored-by: Lukas Wirth <lukas@zed.dev>
Hello, I've been loving using GPUI! Recently I noticed that calling
`.with_animiation()` would give an `AnimationElement<E>` which did not
allow `.child()` to be called on it. It was a quick fix, I hope it's a
quick easy merge but let me know if you'd like anything changed :)
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
Co-authored-by: Lukas Wirth <lukas@zed.dev>
# Objective
Wayland windows have no way to restrict which parts of the surface
accept pointer and touch input. This adds support for setting an input
region, so events outside it pass through to whatever is below the
window. This is useful for shaped or partially click-through windows.
Clicks in green area can pass through the window, clicks in red area do
not:
<img width="1057" height="395" alt="image"
src="https://github.com/user-attachments/assets/2039af62-e43b-4834-b877-edad2a8f5ccf"
/>
## Solution
Add `Window::set_input_region`, which takes `Option<&[Bounds<Pixels>]>`:
- `Some(rects)` restricts pointer and touch input to the union of the
rectangles, in window coordinates.
- `Some(&[])` is an empty region, so the window receives no input at all
and is fully click-through.
- `None` resets the region to the default, so the whole window receives
input again.
On Wayland this maps to `wl_surface.set_input_region`, building a
`wl_region` from the rectangles or clearing it for `None`, and commits
so the change applies immediately rather than waiting for the next
frame. The method is a no-op on other platforms.
## Testing
Tested on Linux with Wayland.
- Tested in my own GPUI application, which uses a fullscreen layer for
overlays while allowing clicks outside of the rendered elements to be
passed through to the underlying windows.
- No automated test was added, since this calls through to the
compositor and is checked by observing input routing.
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
---
Release Notes:
- N/A
Closes#60162.
MCP servers whose tool `inputSchema` uses `$ref`/`$defs` (e.g., Notion
MCP v2.x, and any server using Zod/Pydantic-generated schemas) are
silently rejected with:
```
ERROR Schema cannot be made compatible because it contains "$ref"
```
The affected tools are dropped from the agent panel — the user never
sees them and there is no user-visible error.
## Root cause
`adapt_to_json_schema_subset` rejects any schema containing `$ref` via
`UNSUPPORTED_KEYS`:
```rust
const UNSUPPORTED_KEYS: [&str; 4] = ["if", "then", "else", "$ref"];
```
This is hit by every provider that uses `JsonSchemaSubset` format
(Google Gemini, xAI Grok, OpenAI-compatible proxies, Vercel AI Gateway,
Copilot Chat for Google/xAI vendors, OpenRouter for gemini/grok models).
Providers using `JsonSchema` (Anthropic direct, OpenAI direct) don't hit
this check — `$ref` is passed through to the API, which may or may not
handle it correctly.
This is not an edge case. Every modern MCP server using Zod
(TypeScript), Pydantic (Python), or JSON Schema with shared definitions
generates `$ref`/`$defs` in tool schemas.
## Fix
Add a `resolve_refs` step in `adapt_schema_to_format` that dereferences
all `$ref` pointers using the document's own `$defs` (or legacy
`definitions`) map, making the schema self-contained before
format-specific processing. Applied at the entry point so both
`JsonSchema` and `JsonSchemaSubset` formats benefit.
**Scope note:** previously `JsonSchema` providers (Anthropic direct,
OpenAI direct) received the raw `$ref`/`$defs` and were expected to
handle it themselves — which most do not. After this change, both paths
receive a self-contained schema with refs inlined. This is intentional:
it fixes the same root cause for both paths and avoids provider-specific
behavior divergence.
Supported `$ref` forms:
- `#/$defs/<name>` (JSON Schema draft 2019-09+)
- `#/definitions/<name>` (draft 4-7 legacy)
Edge cases:
- **Nested `$ref`** (definition references another definition): resolved
recursively.
- **Sibling properties alongside `$ref`** (e.g. `{ "$ref": "...",
"description": "..." }`, legal under draft 2019-09+): merged onto the
resolved definition, with siblings overriding the definition's keys.
- **Cyclic references** (A → B → A, or self-referential schemas like a
Tree node): replaced with an empty schema `{}` ("any JSON value"). The
tool still works, just without type info for that recursive field.
- **Unsupported `$ref` forms** (e.g., external URLs): returns an error
with a clear message.
- **Missing definition target**: returns an error naming the missing
ref.
## Testing
Added 10 unit tests in `crates/language_model_core/src/tool_schema.rs`
that cover the patterns produced by Zod/Pydantic-generated MCP schemas:
- `test_refs_are_resolved_via_adapt_schema_to_format` — basic `$ref` →
`$defs` resolution
- `test_refs_in_defs_are_resolved` — nested `$ref` (definition
references another definition)
- `test_refs_in_array_items_are_resolved` — `$ref` inside `array.items`
- `test_legacy_definitions_prefix_is_supported` — old
`#/definitions/<name>` prefix
- `test_schema_without_defs_is_unchanged` — schemas with no `$defs` are
unaffected
- `test_refs_fail_for_unsupported_prefix` — external URL refs error
clearly
- `test_refs_fail_for_missing_definition` — missing target errors
clearly
- `test_cyclic_refs_are_replaced_with_empty_schema` — A → B → A cycle
replaced with `{}`
- `test_self_referential_ref_is_replaced_with_empty_schema` — Tree-like
self-ref replaced with `{}`
- `test_ref_sibling_properties_are_preserved` — sibling properties
alongside `$ref` are merged onto the resolved definition
Existing tests (which call `adapt_to_json_schema_subset` and
`preprocess_json_schema` directly) are unaffected — the fix is additive
at the `adapt_schema_to_format` level.
## Disclosure
I used an LLM to help draft the implementation and tests. I reviewed and
understand the change — it adds one new function (`resolve_refs`) with
two helpers (`parse_ref`, `resolve_refs_recursive`), plus unit tests.
Release Notes:
- Fixed MCP tools with `$ref`/`$defs` in their `inputSchema` being
silently rejected by providers using the JSON Schema Subset format
(Google Gemini, xAI Grok, OpenAI-compatible proxies, etc.). Tools from
servers like Notion MCP v2.x, and any server using Zod or
Pydantic-generated schemas, now work correctly.
---------
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Co-authored-by: Bennet Bo Fenner <bennet@zed.dev>
Closes#56973, Follow-up for
https://github.com/zed-industries/zed/pull/56976
When a completion's `additionalTextEdits` contained a zero-width
insertion touching the edge of the primary edit, the overlap check
treated it as overlapping and silently skipped it. This broke
rust-analyzer's ref-match completions (`&foo`), which deliver the `&` as
a zero-width additional edit at the primary edit's start (#56973). The
same root cause previously broke auto-imports at the very start of a
file (#26136), which was worked around in #37746 with a special case for
edits at position (0, 0).
This PR replaces that special case with a general rule: a zero-width
additional edit only overlaps the primary edit when it falls strictly
inside it. i.e. touching the boundary is fine.
This one check handles both the file-start auto-import case and the `&`
ref-match case, so the (0, 0) workaround from #37746 is removed.
Non-insertion edits still go through the original overlap check from
#1871.
Added three regression tests:
- the file-start auto-import (#26136)
- the `&` insertion at the primary edit's start (#56973)
- overlapping edits being skipped while non-overlapping ones apply
(general skip case)
Release Notes:
- Fixed rust-analyzer completions like `&some_var` inserting only the
variable name and dropping the leading `&` when accepted.
# Objective
Fixes#59979
With hard tabs on, expanding a multi-line snippet only re-indents the
lines that already start with a tab. Anything with no leading whitespace
(closing brackets, mostly) stays at column 0.
## Solution
Block autoindent shifts each line by the first line's delta, but only
when the line's indent kind matches the target kind. A line with no
indentation defaults to `IndentKind::Space`, so under hard tabs it never
matches and gets skipped. An empty indent doesn't really have a kind, so
I let it adopt the target kind before the check. Lines that actually
have space indentation in a tab buffer are still left alone. Normalizing
those felt like a bigger question than this bug, happy to look at it
separately if wanted.
## Testing
New `test_autoindent_block_mode_with_hard_tabs`, same shape as the
snippet in the issue. Fails on main (closing brace stays at column 0),
passes with the fix. `cargo test -p language` and `-p editor` are green,
clippy and fmt too.
## 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 multi-line snippets leaving unindented lines at column 0 when
`hard_tabs` is enabled.