63e31fb7af375fdcb179ffeb9de04590aec8d3b2
39833
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
63e31fb7af |
Add issue upvotes to the community PR board (#63692)
We already had the PR's upvotes (all the positive reactions, deduplicated by user); this commit adds the issue-closed-by-the-PR's upvotes (deduplicated against the PR's upvoters too). The code got even uglier because I'm trying to avoid extra API calls. Release Notes: - N/A |
||
|
|
73ee8fa038 |
agent_ui: Wrap long ask_user options (#63656)
# Objective Fixes #62955 Long `ask_user` option labels are currently truncated with an ellipsis, which can hide part of the response text. ## Solution Remove truncation from the shared elicitation option label so it uses the label's default multiline wrapping. This affects both single- and multi-select options without changing selection behavior. ## Testing - `cargo fmt --all -- --check` - `cargo test -p agent_ui -- --nocapture` — 429 passed, 0 failed - `cargo build -j 2 -p zed --bin zed` - Manually reproduced the issue using a long `ask_user` option label. - Verified that the complete label wraps without an ellipsis at wide and narrow panel widths. --- Release Notes: - Fixed long `ask_user` options being truncated instead of wrapping. |
||
|
|
ed8d600464 |
Add a history list key context to the Git panel (#63689)
# Objective The Git Panel exposes the `ChangesList` key context while its list is focused, including when the History tab is active. This causes Changes-only keybindings to match in History and provides no context for History-specific bindings. This is a fresh submission of the revised change from #63669, as requested in that PR's discussion. Fixes #61012 ## Solution Select the list key context from the active Git Panel tab. Changes exposes `ChangesList`, while History exposes `HistoryList`. The shared `GitPanel` and `menu` contexts remain unchanged. Preserve compatible keyboard behavior by sharing navigation, confirmation, and cancellation bindings between `ChangesList` and `HistoryList` on macOS, Linux, Windows, and Vim. File, staging, restore, and commit-editor bindings remain exclusive to `ChangesList`. Extend the dispatch-context test to verify that the list contexts are mutually exclusive and absent while the commit editor is focused. ## Testing - `cargo fmt --package git_ui -- --check` - `./script/check-keymaps` - `git diff --check` - `cargo test -p git_ui test_dispatch_context_with_focus_states -- --nocapture` - `cargo test -p git_ui` (153 passed) - `cargo build -p zed` - Manually verified on macOS that History reports `HistoryList` without `ChangesList`, arrow navigation selects commits, and Enter opens the selected commit - Linux and Windows keymaps were updated and checked, but not manually exercised on those platforms ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase The Keyboard Context view shows `GitPanel`, `menu`, and `HistoryList` while the History tab is focused. `ChangesList` is absent.  --- Release Notes: - Fixed Git Panel keybindings matching the Changes tab while the History tab is active. |
||
|
|
e621c4f441 |
git_ui: Fix git::FileHistory action in diff views (#63539)
# Objective
The `git::FileHistory` action ("View File History") silently does
nothing when a diff view is the active item (single-file or multibuffer
project diff).
## Solution
Diff views wrap their inner `Editor` and expose it via `act_as`, but
`resolve_file_history_target` used a strict `active_item_as::<Editor>`
downcast, which returns `None` for these wrappers. Resolve through
`act_as` instead.
## Testing
Added a regression test which opens a `ProjectDiff`, dispatches
`git::FileHistory`, and asserts the file's history graph opens. I've
verified it fails without the `act_as` fix, and confirmed the fix
manually (see Showcase).
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
## Showcase
Left is before, right is after:
https://github.com/user-attachments/assets/39972bdf-b24f-4583-afd7-d6eb5226f50f
---
Release Notes:
- Fixed viewing a file's Git history when in a diff view.
|
||
|
|
801c087af2 |
git: Separate revisions from paths in git commands (#63666)
Closes #63665 A branch whose name also matches a path in the working tree, such as a branch `docs/rewrite` in a repository that also has a `docs/rewrite` directory, was passed to git as a bare argument, so git could not tell the revision from the path: ``` fatal: ambiguous argument 'docs/rewrite': both revision and filename ``` The git panel's History tab showed "Failed to load commit history", commit search returned no results, branch diff failed, and opening a commit by ref failed. The revision lists are now terminated with `--`. That also required moving `--no-ext-diff` in `build_command`. It was appended after the caller's arguments, so once a terminator was present it landed past the separator and git read it as a pathspec. The diff then came back empty with exit status 0 and no error, which broke three existing `merge_base_worktree` tests. It now goes directly after the subcommand, where it cannot fall past a terminator. This also means it is no longer swallowed as a pathspec by `diff_stat`, which already ended its arguments with `--` and a path list. `git merge-base` takes no pathspec, so it was never ambiguous and is unchanged. This also fixes the `fatal: ambiguous argument` error reported in #61186. That report additionally shows an `error: invalid option: --merge-base` failure when the base branch does not exist locally, which is a separate problem and is not addressed here. ### Tests Three regression tests, one per affected surface, each building a repository whose branch name matches a directory. All three fail on `main` with the ambiguity error. A fourth test pins that every revision-taking `LogSource` terminates its revision list, and that `LogSource::Path`, which states its own separator, does not gain a second one. `cargo test -p git`: 76 passed. Clippy and `cargo fmt` clean. ### Before <img width="542" height="950" alt="Screenshot From 2026-09-03 09-15-13" src="https://github.com/user-attachments/assets/c54577c7-5066-4cdd-a03c-c67c6803ad33" /> ### After <img width="386" height="471" alt="Screenshot From 2026-09-03 10-08-42" src="https://github.com/user-attachments/assets/b985bb16-60a2-4f50-ad2a-609c6a126bfb" /> Release Notes: - Fixed the git panel's History tab, commit search, branch diff, and opening a commit by ref failing when the branch name matches a path in the working tree |
||
|
|
55c0cc36d1 |
remote_servers: Dismiss picker on Open Folder click (#63628)
# Objective - Clicking "Open folder" on a remote server entry in the remote projects picker did not close the picker itself. The picker was staying underneath the new opened modal for folder/project picker. ## Solution - Emit `DismissEvent` immediately when `RemoteMatch::OpenFolder` is confirmed. This mirrors the existing pattern in `open_remote_project_entry` which already dismisses immediately before proceeding with the async connect flow. ## Testing - Did you test these changes? If so, how? - Are there any parts that need more testing? - How can other people (reviewers) test your changes? Is there anything specific they need to know? - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Fixed the remote projects picker not closing when opening a folder on a remote server |
||
|
|
33375c34b9 |
git_graph: Show time in commit details (#62679)
# Objective The Git Graph list shows the full commit timestamp in its constrained date column, while the more spacious commit details view only shows the calendar date. Include the time in the details view so it does not provide less information than the graph itself. ## Solution Reuse the existing `format_timestamp` helper from the Git Graph `Date` column when rendering the selected commit details. This gives both views the same local date and time format without a separate formatting path. ## Testing - `cargo check -p git_ui` ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - Improved Git Graph commit details to show the same full commit timestamp as the `Date` column. Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
d85eade7ab |
which_key: Add a pending key binding indicator (#63343)
This PR makes Zed's one-second key binding delay visible. Say both ctrl-w and ctrl-w left have bindings. After you press ctrl-w, Zed waits to see whether left follows. The PR shows that wait in the status bar with a countdown. Hovering the indicator shows which bindings can still match. It also adds a setting to hide the indicator. It does not change how Zed resolves key bindings. <img height="100" alt="dyn-db84a840272e2f6250a3f527a59b1efd" src="https://github.com/user-attachments/assets/e42c6a6c-4677-499f-a1d3-835960ebb21a" /> <br/> <img height="100" alt="dyn-8012278d030b41bc8ebfae1540504eff" src="https://github.com/user-attachments/assets/250928d5-f913-40f0-9068-00ccb5cdf59f" /> <br/> <img height="100" alt="file-5e6ffa90944faa294e7870f471b4e65b" src="https://github.com/user-attachments/assets/c250e6eb-a269-4e2c-a5a0-0be9b5006f99" /> Release Notes: - Added a status bar countdown for pending multi-stroke key bindings. --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
f0d8b0b0cd |
gpui: Add an option to keep hover listeners active after keyboard input (#63614)
While working on https://github.com/zed-industries/zed/pull/63343, I ran into a problem with the pending key binding indicator. Hovering pauses its countdown, but pressing the next key made `on_hover` report false even though the mouse had not moved. The countdown then resumed while the pointer was still over the indicator. `on_hover` currently follows GPUI's normal hover rules. GPUI clears hover after keyboard input so the item under a stationary mouse does not interfere with keyboard navigation, for example list popover navigation with keyboard. This PR adds `HoverListenerMode` and `hover_listener_mode`. Callers that need to track the pointer across key presses can opt in like this: ```rs div() .hover_listener_mode(HoverListenerMode::InputModalityIndependent) .on_hover(|is_hovered, window, cx| { // ... }) ``` `InputModalityAware` remains the default. Release Notes: - N/A |
||
|
|
d7b9b38584 |
Fix Keymap Editor "Search by Keystrokes" shortcut shadowed by the text finder (#63376)
# Objective Fixes #62361. In the Keymap Editor, focus lands on the "Filter action names" input, which is wrapped in a `BufferSearchBar` key context (`crates/keymap_editor/src/keymap_editor.rs`). Its `cmd-alt-f → text_finder::Toggle` binding (added in #60677) shadows the `KeymapEditor` context's `cmd-alt-f → keymap_editor::ToggleKeystrokeSearch`, because `BufferSearchBar` sits deeper in the focus stack — so `cmd-alt-f` in the filter opens the file finder instead of toggling "Search by Keystrokes". Same collision on Linux (`ctrl-alt-f`); Windows is unaffected (it uses `alt-f`). ## Solution Add a `KeymapEditor > BufferSearchBar` binding mapping the chord back to `keymap_editor::ToggleKeystrokeSearch`, in `default-macos.json` and `default-linux.json`. It's more specific than the plain `BufferSearchBar` binding and placed after the `KeymapEditor` block, so it wins the same-depth tie-break (gpui precedence: depth, then definition order) — restoring the shortcut inside the Keymap Editor without affecting the global text finder. I gave the `KeymapEditor` binding precedence rather than rebinding "Search by Keystrokes" to a non-conflicting default (e.g. `cmd-alt-k`), since it's less invasive and doesn't change a documented default. Happy to switch to the rebind if the team prefers. ## Testing Built and ran locally on macOS: opened the Keymap Editor (`cmd-k cmd-s`), pressed `cmd-alt-f` with focus in the filter → "Search by Keystrokes" toggles instead of opening the file finder; confirmed the file finder still works normally in a regular editor. `cargo test -p zed keymap` passes (validates the bundled keymaps parse and all actions resolve). ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Tests cover the new/changed behavior (bundled-keymap validation exercises the new binding; runtime behavior manually verified — no logic to unit-test in a default-keymap change) _Unsafe blocks / UI standards / performance: N/A for a keymap default change._ Release Notes: - Fixed the Keymap Editor's "Search by Keystrokes" shortcut (`cmd-alt-f` / `ctrl-alt-f`) being shadowed by the file finder. |
||
|
|
b1a7ef0cf6 |
gpui: Snap recomputed padding to the device pixel grid before clamping scroll (#62296)
# Objective Follow-up to #62135, taking the approach suggested there: fix the error at its source in GPUI instead of hiding it in the scrollbar. At fractional rem sizes (`py_1` at an odd UI font size), a container whose content fits becomes scrollable by a sub-pixel amount, and every uniform-list picker grows a full-height scrollbar thumb for that phantom range. ## Solution Taffy lays boxes out with every authored length snapped to the device pixel grid (`to_taffy`), and the final bounds are snapped again after layout. However, `Interactivity::clamp_scroll_position` recomputed the padding from the raw style with no snapping at all, so the padded content size exceeded the snapped bounds by up to half a device pixel, far past the existing two-decimal float-noise rounding, and `scroll_max` came out positive. The fix snaps the recomputed padding with the same `pixel_snap` helper the rest of the pipeline uses, so both operands of the subtraction sit on the same grid and the phantom range never comes into existence. Two neighbouring cases are deliberately left out to keep this scoped, both are follow-up candidates: percentage-based padding resolves inside Taffy without pre-snapping, so a discrepancy is still theoretically possible there; and `ListState::max_scroll_offset` (the older `list()` element) has no rounding protection at all. ## Testing - New regression test: a 50px container with `py(4.25)` padding and a child that fits exactly. It fails on main (`max_offset` comes out at 0.5px) and passes with the fix; verified in both directions. - Full gpui suite: 241 tests pass. - Reviewers can see the original symptom by opening any picker at a UI font size that makes `py_1` fractional in device pixels: a spurious full-height scrollbar thumb appears on main and is gone with this change. The math is logical-pixel only, so the behavior is platform-independent. ## 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 (one pixel-snap per padding edge per clamp, negligible against existing per-frame layout work) cc @MrSubidubi Release Notes: - Fixed containers becoming scrollable by a sub-pixel amount, with a phantom full-height scrollbar thumb, at fractional UI font sizes. Co-authored-by: MrSubidubi <finn@zed.dev> |
||
|
|
5f2d7ad735 |
extension_cli: Error on unrecognized files and queries in language directories (#63080)
This ensures that we do not copy over resources we do not need for languages. We enforce this at this stage so that potential contributors to these extensions do not think these files might be needed for the given language. Release Notes: - N/A |
||
|
|
003826320f |
agent_ui: Hide manage skills command when AI is disabled (#63598)
# Objective Fixes #63495 When `"disable_ai": true` is set, `agent: manage skills` still appears in the command palette. The action was exposed by the `else` branch of the `disable_ai` check in `update_command_palette_filter`, which called `show_action_types` on it — overriding the `hide_namespace("agent")` applied when AI is disabled. ## Solution Moved `filter.hide_action_types(&manage_skills_action)` out of the conditional so it applies regardless of the `disable_ai` setting. Skills are surfaced through the settings UI now, so the command should never appear in the palette. Added test coverage in `test_agent_command_palette_visibility`: - Asserts `ManageSkills` is hidden even when AI is enabled (the invariant). - Asserts `ManageSkills`, `OpenSkillCreator`, and `NewThread` are hidden when AI is disabled. ## Testing - `cargo test -p agent_ui` (398 passed) - `./script/clippy -p agent_ui` - `cargo fmt --check` - Manual verification: set `"disable_ai": true`, open the command palette, filter `agent` — `agent: manage skills` should be absent. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments (no unsafe blocks) - [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 `agent: manage skills` still appearing in the command palette when AI is disabled |
||
|
|
b3326e13c1 |
gpui: Add TouchDragEvent API (#63645)
Adds `TouchDragEvent` and coresponding APIs. This allows web/touch-based code to capture long press events without having to go through scroll-like APIs --- Release Notes: - N/A or Added/Fixed/Improved ... |
||
|
|
23aca9895c |
lsp: Honor dynamic LSP document selectors (#59243)
Zed previously discarded the documentSelector from dynamically registered textDocument capabilities and treated those capabilities as applicable to every buffer attached to the server. This could route requests for documents outside a registration selector. Track dynamic textDocument registrations by method and registration ID, and use their selectors when routing local requests, checking capabilities, and deriving completion triggers. Static capabilities continue to apply to every attached buffer. Language and URI scheme matching are supported, while unsupported pattern matching remains fail-open. Keep document color, symbol, link, code lens, and folding range caches aligned with the selector-aware server set so incapable or non-matching servers do not leave caches perpetually incomplete. Require an advertised diagnostic provider before sending pull diagnostic requests, and add integration coverage for selector-aware dynamic completion registration and trigger updates. --- Release Notes: - Improved language server request routing to respect dynamically registered document selectors. --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
8a4bd132a6 |
Strip local symbols from macOS and Linux release bundles (#63429)
Not sure if this PR is 100% good, since it removes symbols from local traces, leaving addresses only — but this what Windows seem to do already, and we have those symbols on Sentry to restore from, which were needed to normally read Linux perf traces already (see `perf.zip` in https://github.com/zed-industries/zed/issues/59689#issuecomment-5452720248) On the upside, uncompressed binaries' are now ~100MB less, which is a lot — hence decided to open the PR for the review ------------------- Strips debug info and local symbols from shipped macOS and Linux binaries, matching what Windows already does with PDBs: `bundle-mac` now always runs `dsymutil` before a new `strip -x` step, and `bundle-linux` adds `--discard-all` plus `zed.dbg`/`remote_server.dbg` extraction via `--only-keep-debug`. Sentry uploads are unchanged and precede stripping. The macOS binary UUID and the GNU build id survive stripping, so user-provided traces stay recoverable without rebuilding at the reporter's commit: `sample` output resolves via `atos` against the archived `zed.dwarf`, and `perf.data` via `perf buildid-cache` against the Sentry-archived binary. zed binary: macOS (2026-08-29 nightly): 420478976 -> 316503984 bytes (-24.7%, -104.0MB) Linux (v1.17.2 aarch64): 439417448 -> 336967256 bytes (-23.3%, -102.5MB) Downloads shrink far less, symbols compress ~7:1: the macOS DMG loses only ~15MB. Release Notes: - Improved installed size on macOS and Linux by stripping debug symbols from release binaries (roughly -25%) |
||
|
|
ab7d21d444 |
Fix workspace diagnostics polling (#63336)
Closes https://github.com/zed-industries/zed/issues/62391 Workspace diagnostics were polled incorrectly: * Workspace pulls were cancelled and re-sent every 120s. Pyright-family servers hold the request open forever and re-analyze the whole workspace on every new one, so the retry loop leaked memory; the request is now kept open (long-poll), as the spec recommends. * No re-trigger after a server closed a workspace pull. ty closes the request when diagnostics change and expects the client to re-pull * `ServerCancelled` / `retriggerRequest` was ignored. The spec defaults cancellation data to `{ retriggerRequest: true }`, so these errors now retrigger workspace pulls and retry document pulls instead of failing them. * LSP error codes were erased with `anyhow!(message)` Errors now carry a typed `lsp::ResponseError` through the chain, replacing four copies of `ends_with(...)` matching against rust-analyzer's literal message texts. * Workspace partial results were not tied to their request. Stale or numeric-token `$/progress` reports were applied as current data and could poison `previousResultIds` until a server restart; reports are now matched against the exact in-flight token. * `interFileDependencies` was never read. Every edit re-pulled all other open buffers even for servers declaring no inter-file dependencies (e.g. ruff); cross-buffer pulls are now gated on that capability. * Cross-buffer pulls were unpaced. All open buffers were pulled back-to-back after each edit debounce; they are now paced at one document per 500ms. * The failure valve killed workspace pulls permanently. 51 hard errors over a server's lifetime silently stopped its workspace pulls until restart * Concurrent refresh waiters could be dropped instantly. The capacity-1 refresh channel resolved a second concurrent waiter to `false` immediately, and request errors dropped queued refreshes; waiters now queue and carry over to the retried pull. Release Notes: - Fixed basedpyright memory leak caused by incorrect workspace diagnostics polling |
||
|
|
ad251e0a04 |
docs: Document focus_follows_mouse (#63646)
Release Notes: - N/A |
||
|
|
f8000a30f9 |
Properly clear diagnostics data for stopped servers (#63460)
# Objective Diagnostics published by a language server survive the buffer being detached from that server, so a file keeps showing errors from a server that is no longer reading it. To reproduce: 1. Install the [GitHub Actions extension](https://zed.dev/extensions/github-actions). 2. Open a composite action definition, `.github/actions/<name>/action.yml`. 3. Select the GitHub Actions language for it in the language selector. That server validates the file as a workflow, so it reports `on` and `jobs` as missing and `inputs`, `outputs` and `runs` as unexpected. 4. Select YAML again, since GitHub Actions was not what you wanted here. 5. The errors are still there. `editor: restart language servers` does not clear them either. They go away only once the buffer is dropped, in practice by switching to another project and back. Two things keep them alive: - `LocalLspStore::unregister_buffer_from_language_servers` drops the snapshot bookkeeping and sends `didClose`, but never clears what that server already published. `LspStore::set_language_for_buffer` calls it, so a language change detaches the buffer while leaving the old verdict on it. - Restarting does not reach the server either. `stop_local_language_servers_for_buffers` collects servers through `language_server_ids_for_buffer`, evaluated against the language the buffer has *now*. The old server no longer matches, so it is never stopped, and it is typically still running legitimately for other files in the project. Only `stop_local_language_server` clears diagnostics, and it is never reached for that server. ## Solution The first commit cleared the detached server's diagnostics inside `unregister_buffer_from_language_servers`, on `didClose`. Review pointed out that publishes are applied by path regardless of registration, so a running server can legitimately describe a file that is no longer open in it, and that this clearing also left `diagnostic_summaries` and the worktree's per-path diagnostics stale. The second commit reworks this. Detaching a buffer now only drops the buffer's entry in `buffers_opened_in_servers` and the path's pull-diagnostics result ids for the servers it left, two pieces of per-server state that previously leaked. After the buffer is registered with the servers of its new language, the server tree is rebuilt through `refresh_server_tree`, the same pruning that runs on settings changes: every server no registered buffer maps to any more is stopped through `stop_local_language_server`, whose path already clears buffer diagnostic sets, `diagnostic_summaries` and worktree diagnostics. A detached server that other buffers still map to keeps running and keeps everything it published. An earlier revision judged orphanhood by `buffers_opened_in_servers`, which is only filled in once a server runs, so it stopped servers that were still starting; `test_context_completion_provider_mentions` caught that. ## Testing Added `test_selecting_a_language_clears_the_old_servers_diagnostics`: a Rust buffer gets a diagnostic from a fake server, the buffer is switched to JavaScript, and afterwards both the buffer's diagnostics and the project-level `diagnostic_summary` must be empty. It fails on `main`, where the message survives the switch: ```text < ["unused constant"] > [] ``` The test passes with the rework and fails without it. The `project` test suite, `script/clippy` and style checks ran green on the reworked change in CI. Tested on Linux; the change is platform independent. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase The buffer is back on YAML, as the status bar shows, while the workflow schema's complaints from the GitHub Actions server are still on screen: `on` and `jobs` reported missing, and `inputs`, `outputs` and `runs` reported as unexpected values. <img width="2514" height="2008" alt="Screenshot From 2026-08-30 21-52-12" src="https://github.com/user-attachments/assets/040898a6-cc61-41b6-88c6-f346666e8e13" /> --- Release Notes: - Fixed diagnostics from the previous language server staying on a file after changing its language. --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
a85cf449ec |
gpui: Prevent touch mispredict jitter (#63638)
When scrolling, mispredicted touch events could cause scroll jitter. We now ignore predictions that are "travelling the wrong direction". --- Release Notes: - N/A or Added/Fixed/Improved ... |
||
|
|
60bf47b9f2 |
lsp: Scope logs and status updates to their projects (#61221)
The language registry and LSP log store are shared by every workspace in a Zed process. The LSP Logs selector enumerated the shared log store without filtering by project, while each activity indicator consumed global binary status updates. This exposed servers from other windows as "Unknown worktree" entries and surfaced their startup failures or timeouts in unrelated status bars. Key each logged server by its owning project or LSP store together with its process-local language server ID. Use that identity consistently when adding, removing, streaming, selecting, opening, and reselecting log entries so local, remote, SSH, and supplementary servers cannot collide across ownership domains. Model Copilot and other servers outside the project LSP store as project-scoped supplementary servers, while matching SSH servers by their owning LSP store. Tag project-originated binary status updates with the owning LSP store entity ID. Carry that source through extension worktree delegates and every worktree-based WASM language-server call, then let each local LSP store forward only statuses for its project. Activity indicators rely solely on their project LSP store, and remote projects continue to receive host statuses through the existing protocol path instead of subscribing to local registry events. Own each binary-status subscription task in its local LSP store and unregister its broadcaster sender when the store is dropped, so closing windows cannot leave detached status tasks or stale senders behind. Add regression coverage for duplicate process-local server IDs across ownership domains, filtering remote, supplementary, and SSH servers from other projects, retaining servers owned by the current project or LSP store, preserving extension status sources, and unregistering dropped status subscriptions. Release Notes: - Fixed language servers from other projects appearing in the LSP Logs view and their statuses showing in unrelated windows' status bars |
||
|
|
9decdcc1f2 |
gpui_web: Drive IME mirror focus state from GPUI (#63629)
Previously, we manually synchronized the keyboard state in response to tap events, but this meant that several common cases were unreliable. Now, we use GPUI's focused element as the source of truth, and use `sync_virtual_keyboard` in cases where they have gotten out of sync (i.e. a user manually dismisses a keyboard while the input is still focused). --- Release Notes: - N/A or Added/Fixed/Improved ... |
||
|
|
6b5e15ed46 |
Bump more dependencies (#63379)
* 1st commit fixes bumps `quinn-proto` and `serde_with` to fix the dependabot alerts * 2nd commit deduplicates more dependencies `cargo tree -d` listing: 194 -> 187 top-level entries on the host target, 298 -> 287 unique duplicated crate-versions across all targets. <details> <summary>Deduplicated list</summary> ``` accesskit_consumer (v0.35.0, v0.37.0 -> v0.38.0) bindgen (v0.71.1, v0.72.1 -> v0.72.1) nix (v0.28.0, v0.29.0, v0.30.1 -> v0.28.0, v0.30.1) ordered-float (v2.10.1, v4.6.0 -> v5.5.0) quick-xml (v0.30.0, v0.37.5, v0.38.3, v0.39.3, v0.41.0 -> v0.30.0, v0.37.5, v0.39.3, v0.41.0) sysinfo (v0.31.4, v0.37.2 -> v0.31.4, v0.39.6) wasm-encoder (v0.252.0, v0.254.0 -> v0.254.0) wasmparser (v0.252.0, v0.254.0 -> v0.254.0) windows-registry (v0.4.0, v0.5.3, v0.6.1 -> v0.4.0, v0.6.1) ``` `ordered-float v4.6.0` remains in the lockfile only as an inactive optional dependency of `sea-query`; the compiled graph is fully deduplicated to v5.5.0. </details> Release Notes: - N/A |
||
|
|
769d0befa7 |
Support Emmet's wrap with abbreviation (#63383)
Closes https://github.com/zed-industries/zed/issues/15588 https://github.com/user-attachments/assets/2813d235-6dac-4fe6-9ae0-2783e16270ac Release Notes: - Added Emmet's wrap with abbreviation support |
||
|
|
810c6a04a6 |
Add on_new_window setting (#63522)
> [!NOTE] > This is a remake of #63335 as it's unlikely to be reopened just from my [mention](https://github.com/zed-industries/zed/pull/63335#issuecomment-5452544138). Apologies for the noise! # Objective Closes #59368, where users (including me) are asking for a way to show the Launchpad instead of an empty tab when opening a new window. As per advice from https://github.com/zed-industries/zed/issues/60720#issuecomment-4936162420, adding a separate setting from `restore_on_startup` is more ideal. `on_new_window` allows for two values: - `empty_tab` - `launchpad` (default) ## Testing Added a regression test which opens a new window with `on_new_window` set to `launchpad` and asserts that no item gets opened in the window's pane. I've verified it fails without the setting gate, and confirmed configuring this setting works manually (see Showcase). ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase https://github.com/user-attachments/assets/bf339bd1-8c62-4243-ac9d-1045d1a14865 --- Release Notes: - Added `on_new_window` setting to configure the opening of new windows. |
||
|
|
cff4edce88 |
nix: Include corgi patches in build sources (#63644)
The local `scratch` override lives under `corgi-patches`, but the Nix build source filter omitted that directory. As a result, `nix develop` failed while loading the patched dependency. Include `corgi-patches` in the filtered source and preserve the patch implementation in Crane's dummy dependency source. The latter is required because `cxx-build` calls `scratch::path` while dependency artifacts are built. ## Testing - `nix fmt -- --ci nix/build.nix` - `nix develop --command true` - `nix develop --command cargo fmt --check` Release Notes: - N/A |
||
|
|
ff68a64caf |
Bump Zed to v1.20.0 (#63636)
Release Notes: - N/A Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com> |
||
|
|
2b0562a825 |
ui: Allow hiding keybinding labels (#63616)
`KeyBinding` elements currently always render their shortcut labels. Applications with a touch-oriented interface cannot remove those keyboard-only visual affordances without changing each consumer or unregistering the shortcuts themselves. This adds an application-wide visibility policy to the reusable `KeyBinding` component, so context menus and other consumers follow the same setting. Registered keybindings and `aria-keyshortcuts` remain intact, and labels remain visible by default. ## Testing - `cargo nextest run -p ui --lib` - `cargo fmt --check` - The final unused-override cleanup was not rerun because `nix develop` currently fails while building the existing `zed-editor-deps` derivation: `corgi-patches/scratch/Cargo.toml` is absent from its Nix source. Release Notes: - N/A |
||
|
|
8514ce3ba1 |
Unify language model event stream handling (#63520)
Closes https://github.com/zed-industries/zed/issues/63314 Closes https://github.com/zed-industries/zed/issues/42584 Follow-up to https://github.com/zed-industries/zed/pull/62652 Removes a lot of duplicated code in favor of throwing it into`language_core` as well as removing duplicate struct definitions that were only different because of entirely unused fields. Furthermore, improves error-messages so that these untagged enum errors are no longer a thing in an effort to make this more maintainable in the future. Lastly, includes a small but nice improvement changing a `Value` to a `RawValue` so that we don't have to clone for deserialization in that specific case. Release Notes: - Improved streaming for OpenAI-compatible providers. --------- Co-authored-by: Anant Goel <anant@zed.dev> |
||
|
|
c3cf80c0d1 |
git_ui: Fix 'Go Back' skipping the Git Graph view (#63597)
# Objective - "Go back" behaved inconsistently when navigating from the Git Graph view: opening a commit diff (double-click on a commit) and then using "Go Back" would not return to the Git Graph — instead it jumped to whatever file was open before the Git Graph was opened. - Fixes #63293 ## Solution - `GitGraph`'s `Item` implementation never hooked into the pane's navigation history (missing `deactivated` / `set_nav_history`), unlike every sibling diff view (`CommitView`, `ProjectDiffEditor`, `MultiDiffView`, `BranchDiff`). Because of this, when a commit diff was opened on top of it, deactivating Git Graph never pushed an entry onto the pane's back-stack, so "Go Back" skipped straight past it to the previously active file. - Added a `nav_history: Option<ItemNavHistory>` field to `GitGraph` and implemented `set_nav_history`/`deactivated` to push a nav-history entry when the Git Graph tab is deactivated, matching the pattern used by other `git_ui` diff views. ## Testing - Added `test_go_back_from_commit_view_returns_to_git_graph` in `crates/git_ui/src/git_graph.rs`, which opens a file, then Git Graph, then a commit diff, and asserts that `Pane::navigate_backward` returns to the Git Graph view rather than the file. - Verified the test actually catches the regression by temporarily reverting the fix and confirming the test fails, then restoring the fix and confirming it passes. - `cargo test -p git_ui --lib git_graph::` — all 28 tests pass. - `./script/clippy -p git_ui` — clean, no warnings. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase <details> <summary>Click to view showcase</summary> Open the Git Graph and double click on any commit to see the details, after that press go back button, it should return to the Git Graph instead of previos opened file. https://github.com/user-attachments/assets/15f659a7-a60b-4d43-ad59-8be69a94cb31 </details> --- Release Notes: - Fixed "Go Back" not returning to the Git Graph view after opening a commit diff |
||
|
|
6309c72213 |
language_model_core: Classify Anthropic prompt-too-long 400s as context overflow (#63596)
Anthropic reports a context-window overflow with HTTP 400 and a message of the form `prompt is too long: N tokens > M maximum`. The `BAD_REQUEST` arm of `ProviderErrorCategory::from_http_status` only recognized OpenAI's phrasings (`context_length_exceeded`, "exceeds the context window"), and `parse_prompt_too_long` only ran for HTTP 413, so these rejections were classified as `InvalidRequest` instead of `PromptTooLarge`. This affects every wire path that classifies by upstream HTTP status, including Zed cloud's `upstream_http_400` code, and it silently disables any downstream handling keyed on the `PromptTooLarge` category. This change sniffs the Anthropic phrasing on 400 responses too, carrying the provider-reported token count. Closes AI-462 Release Notes: - Fixed Anthropic "prompt is too long" errors reported with HTTP 400 not being recognized as context-window overflows. |
||
|
|
dbfeae7735 |
Ensure stale git commit template are not persisted (#63604)
## Objective Fixes #63478 Git commit templates were being persisted as pending commit message drafts. As a result, if the commit template changed, the previously applied template could be restored after restarting Zed instead of loading the updated template. ## Solution Do not persist the active commit message buffer as a draft when its contents exactly match the currently applied commit template. This preserves the existing behavior for genuine user drafts while allowing the current commit template to be loaded when the panel is restored. ## Testing Added tests covering: * Applying a new commit template after the template changes and the panel is restored. * Preserving a user-edited commit message when the commit template changes. Validated with: * `cargo test -p git_ui -- test_commit_template_applied_fresh_after_template_file_change test_user_draft_preserved_when_template_changes --nocapture` * `cargo fmt -p git_ui` * `cargo check -p git_ui` * `cargo test -p git_ui --lib` * `cargo clippy -p git_ui --tests -- -D warnings` ## 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 --- Release Notes: - Fixed stale git commit templates being restored as pending commit message drafts. --------- Co-authored-by: MrSubidubi <finn@zed.dev> |
||
|
|
480d81bf6a |
language_models: Allow cancelling ChatGPT Subscription setup (#63627)
On `main`, the only way to interrupt ChatGPT Subscription setup is to restart Zed. --- Release Notes: - Add a button to cancel ChatGPT Subscription setup |
||
|
|
a24cafa942 |
editor: Fix completion menu label overlapping documentation text (#63581)
Closes #63301 The completion label row set `min_w_0()`, which removes a flex item's automatic minimum size and lets it shrink below its own content width. The label inside is `flex_none` and never shrinks, so for long completion labels the text overflowed the row and, with GPUI's default `Overflow::Visible`, painted directly on top of the right-aligned documentation text. Removing `min_w_0()` restores the row's automatic minimum so it no longer shrinks past the label. The documentation label already has `flex_shrink(1.0)`, `min_w_0()` and `truncate()`, so it is now the only element that gives way, shrinking and ellipsizing as intended. The resulting layout is `[full label] [documentation, ellipsized when it overflows]`. ### Before <img width="687" height="426" alt="Screenshot From 2026-09-02 00-48-03" src="https://github.com/user-attachments/assets/b734b632-fd05-4afc-8b02-b231922646ef" /> ### After <img width="853" height="526" alt="Screenshot From 2026-09-02 02-23-41" src="https://github.com/user-attachments/assets/60281115-5a8d-4f4e-bfe0-c037ff7244e3" /> Release Notes: - Fixed completion menu labels overlapping the documentation text for long completion items |
||
|
|
837264129f |
workspace: Fix captured focus when opening modals (#63512)
# Objective - This PR fixes the captured focus in modals. - Fixes #63480 (and actually this was not specific to the task modal. it was generic and applied to all modals) ## Solution - Previously when a modal was opened the `previous_focus_handle` was stealing the focus because it was captured in `show_modal`. The fix was to capture it before calling `show_modal` or `reveal_stashed_modal` and pass it to `show_modal`. That fixes the bug :) (yuhuu). ## Testing - Tested by running the build and trying to reproduce the bug. I couldn't reproduce it anymore. - For testing, a reviewer also needs to test the revelal stashed modal functionality. I did it with the file finder. ## 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 previous window focus handle not being captured correctly when opening modals |
||
|
|
d56dca8084 |
Stop labeling reopened triaged issues as 'needs triage' (#63615)
Release Notes: - N/A |
||
|
|
97b1e64a17 |
gpui: Record hang trigger class and set the release frame budget to 24ms (#63586)
Hang incidents come in two classes that consumers could only tell apart by comparing `stall_ms` against the hang threshold, which is not recorded in the event: a single event over the threshold, or an interval whose cumulative foreground spend reached the frame budget. This PR makes the class explicit and re-tunes the budget. - `HangIncident` and `SerializedHangIncident` gain `trigger: HangTrigger` (`threshold` | `budget`). - The `Hang Incidents` telemetry event reports `threshold_incidents` and `budget_incidents` alongside the existing `total_incidents` (kept for existing queries; it is now the sum of the two). - The release frame budget moves from 8 ms to 24 ms. At 8 ms almost every busy 60 Hz frame qualified, so the budget class dominated incident counts without saying much. 24 ms is above every refresh period, so a budget incident now means the interval dropped at least one frame on any display. Frame smoothness below that is measured per-frame by `Frame Duration Report`. `budget_incidents` is the signal for lowering it further as hangs get fixed. Debug builds already used 100 ms and are unchanged. Part of a series on hang-telemetry data quality; #63588 handles withheld-frame `dirty_at`, and marking OS prompt waits so they stop registering as task-poll hangs is next. Release Notes: - N/A |
||
|
|
520d8bdaeb |
Fix misaligned borders around avatars with fractional display scale (#63595)
Congratsbot / congrats (push) Has been cancelled
deploy_nightly_docs / deploy_docs (push) Has been cancelled
run_tests / orchestrate (push) Has been cancelled
run_tests / check_style (push) Has been cancelled
run_tests / clippy_windows (push) Has been cancelled
run_tests / clippy_linux (push) Has been cancelled
run_tests / clippy_mac (push) Has been cancelled
run_tests / clippy_mac_x86_64 (push) Has been cancelled
run_tests / run_tests_windows (push) Has been cancelled
run_tests / run_tests_linux (push) Has been cancelled
run_tests / run_tests_mac (push) Has been cancelled
run_tests / miri_scheduler (push) Has been cancelled
run_tests / doctests (push) Has been cancelled
run_tests / build_visual_tests_binary (push) Has been cancelled
run_tests / check_wasm (push) Has been cancelled
run_tests / check_dependencies (push) Has been cancelled
run_tests / check_docs (push) Has been cancelled
run_tests / check_scripts (push) Has been cancelled
run_tests / check_postgres_and_protobuf_migrations (push) Has been cancelled
run_tests / extension_tests (push) Has been cancelled
run_tests / tests_pass (push) Has been cancelled
Congratsbot / check-author (push) Has been cancelled
run_tests / check_workspace_binaries (push) Has been cancelled
run_tests / check_licenses (push) Has been cancelled
Before and after: https://github.com/user-attachments/assets/b165d525-c368-4245-a246-2522e67ff3a0 --- Release Notes: - N/A |
||
|
|
2551721adb |
util: Embed fs_embed assets with debug-embed (#63583)
Zed's `fs_embed!` macro normally reads assets from the checkout in debug builds. The new `util/debug-embed` feature is intended to compile those assets into debug binaries, but it previously changed only the `rust_embed::Filenames` variant while leaving file loading on the runtime path. That breaks downstream workspaces such as Delta: the runtime loader identifies Delta as the repository root, then looks for Zed grammar assets under Delta's checkout. Tests consequently panic when language configuration files cannot be found. This makes `util/debug-embed` select a compile-time `RustEmbed` expansion in every profile. Builds without the feature retain live filesystem loading in debug mode. The runtime iterator no longer depends on a feature-specific `rust_embed::Filenames` variant, so Cargo feature unification remains safe when another package enables `rust-embed/debug-embed` directly. The regression fixture uses a deliberately invalid runtime path when `debug-embed` is enabled, so it proves that the embedded path is used rather than passing only because the Zed checkout contains the test assets. Testing performed: - `cargo fmt --all -- --check` - `cargo nextest run -p util --lib` - `cargo nextest run -p util --lib --features debug-embed` - `cargo check -p remote_server --features debug-embed` - `./script/clippy -p util` - Delta's previously failing `tools::edit_file::tests::test_edit_file_rejects_scratch_paths_as_read_only` against this PR's head commit Release Notes: - N/A |
||
|
|
ac5af8b9e1 |
Relicense zlog, ztracing, and ztracing_macro under Apache-2.0 (#63573)
Relicenses `zlog`, `ztracing`, and `ztracing_macro` from GPL-3.0-or-later to Apache-2.0. GPUI depends on `ztracing`, which depends on `zlog`, so these crates have to be non-copyleft for GPUI to ship as a permissively licensed project. - Switched the `license` field to `Apache-2.0` in all three manifests. - Added the `LICENSE-APACHE` symlink to `zlog`, and dropped the `LICENSE-GPL` symlinks from all three. `ztracing` and `ztracing_macro` already carried both symlinks; now the on-disk license matches the manifest. - Declared `license = "Apache-2.0"` for `gpui_util`, which had a `LICENSE-APACHE` symlink but no `license` field. `script/check-licenses` doesn't catch that, since it only inspects symlinks. No source changes; none of these crates carry GPL headers or in-source license references. Checked the rest of the subtree while here: the only first-party crates reachable from `ztracing` via `cargo tree -e normal` are `collections`, `gpui_util`, `zlog`, and `ztracing_macro`, all Apache-2.0 now. Third-party deps (`tracing`, `tracing-subscriber`, `chrono`, `log`, `anyhow`, `tracy-client`) are MIT/Apache. `script/check-licenses` passes. Release Notes: - N/A |
||
|
|
239d0aa158 |
Download wasi-sdk before cleaning the target directory (#63579)
Fix flacks like https://github.com/zed-industries/zed/actions/runs/33546906778/job/99987145940?pr=63573 `test_extension_store_with_test_extension` gives the extension builder `target` as its cache at `crates/extension_host/src/extension_store_test.rs:801`. `install_dev_extension` performs a real extension and grammar build at `crates/extension_host/src/extension_host.rs:1139`. When `target/wasi-sdk` is absent (e.g. after `target/` cleanup), the builder downloads and extracts it at `crates/extension/src/extension_builder.rs:511`. In the failed run, downloading and extracting the SDK consumed 59 seconds, grammar compilation began at 60 seconds, and the timeout fired immediately. Release Notes: - N/A |
||
|
|
d3e54c97f4 |
util: Make fs_embed! compatible with rust-embed's debug-embed feature (#63577)
Zed's `fs_embed!` macro hand-implements rust-embed's `RustEmbed` trait in its dev arm so debug builds read assets from the checkout at runtime (introduced with corgi support in #63396). That trait returns `rust_embed::Filenames`, an enum with exactly one variant per compilation context: `Dynamic` when rust-embed's `debug-embed` feature is off, `Embedded` when it is on. The dev arm constructed `Filenames::Dynamic` unconditionally. Cargo unifies features across the entire build graph, so a downstream workspace that consumes Zed's crates by git dependency and enables `rust-embed/debug-embed` anywhere (Delta did, for self-contained debug binaries) changes the enum's shape for `util` itself, and `util` stops compiling with `E0599: no variant named Dynamic`. Zed's own CI can never catch this because nothing in Zed's graph enables the feature; it only surfaces in embedding workspaces, where it blocks any dependency bump past #63396. This change makes the combination supported. `util` gains a forwarding `debug-embed` feature, and `__fs_embed_iter` now has two implementations under cfgs that mirror rust-embed's variant availability: the existing boxed-iterator path when the feature is off, and an `Embedded` path when it is on, which scans the checkout once per embed site and leaks the cached name list (the `Embedded` variant requires `'static` names; a per-process list matches the macro's documented contract that dev edits appear on the next launch, and `get` still reads file contents fresh on every call). Consumers must enable the feature through `util/debug-embed` rather than directly on rust-embed — enabling it behind util's back still breaks, which only rust-embed itself could fix; the feature's documentation says so. A new test exercises the dev arm's `iter` and `get` through the macro, and running util's suite with `--features debug-embed` covers the other variant; both configurations pass 133 tests, plus clippy and fmt. Release Notes: - N/A --------- Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com> |
||
|
|
283460f5df |
anthropic: Handle Claude Fable 5.1 API changes (#63571)
Claude Fable 5.1 introduces two breaking Messages API changes that produce 400 errors with request shapes Zed currently sends. This change adapts the shared Anthropic request path so the model works out of the box, without restructuring how requests are built. The first change is thinking-block prefix binding. Fable 5.1 binds each thinking block to the exact conversation prefix that produced it, and replaying a block after anything earlier changed (the system prompt, the tools array, or an edited turn) fails the whole request with a 400 reading "The block is bound to a different conversation". Zed routinely rebuilds the system prompt and tool list between requests (rules file changes, profile switches, MCP servers coming online), so this would surface as a hard error mid-thread. Requests to Fable 5.1 now send the `thinking-binding-controls-2026-08-01` beta header with `thinking.block_binding.prefix_mismatch_behavior: "drop_block"`, which makes the API drop invalidated blocks and continue instead of rejecting the request. Claude Mythos 5.1 doesn't run this check and is excluded. The cloud and Copilot Chat paths pass `block_binding: None` since their proxies control the upstream beta headers; opting in there belongs server-side. The second change is that forced tool use (`tool_choice: "any"` or `"tool"`) now returns a 400. Zed sends `"any"` from inline assist's streaming-tools path, which is on by default. The Anthropic and Zed-cloud providers now report `tool_choice: any` as unsupported for Fable/Mythos 5.1, and inline assist already degrades gracefully to prompt-guided auto tool choice, which is Anthropic's recommended migration. Finally, `claude-fable-5-1` and `claude-mythos-5-1` are added to the compaction model list. This matters more than a routine table update: with prefix binding, server-side compaction is the sanctioned way to trim history without invalidating thinking blocks. Everything else already carries over via the existing `claude-fable-5` id prefix logic (data-retention consent, Opus 4.8 refusal fallback, which remains a permitted fallback target for 5.1). Bedrock is intentionally untouched. Deeper follow-up work is deferred: keeping conversation history append-only so blocks aren't invalidated in the first place (turn-scoped system messages, mid-conversation tool changes) and monitoring `input_transformations` for drop reporting. Testing: - New unit tests covering the `block_binding` wire format (sent for `claude-fable-5-1` only) and beta-header wiring in `Model::from_listed`. - `cargo nextest run` for `anthropic`, `language_models`, `language_models_cloud`, and `copilot_chat`; `cargo fmt --check`. Release Notes: - Improved support for Claude Fable 5.1 |
||
|
|
0855410ccd |
gpui: Add long-press gesture recognition (#63561)
GPUI's touch gesture recognizer handles taps and pans, but its long-press event was only a placeholder. Applications therefore could not distinguish a deliberate press-and-hold from a tap or scroll using the portable touch path. This adds deadline-driven long-press recognition and dispatches a phased event stream through GPUI's existing capture and bubble listener path. A listener claims the gesture by preventing the initial event's default behavior and capturing it for an entity. Unclaimed gestures remain eligible for the existing tap and pan behaviors, while claimed gestures receive movement and termination events without also producing taps or scrolling. The timer is cancelled when the pending gesture resolves. `gpui_web` now translates reusable browser pointer identifiers into touch identifiers that remain unique for each touch lifetime, preventing an old timer from acting on a newer touch. Native macOS trackpad scrolling remains on its existing `ScrollWheelEvent` path and does not enter touch gesture recognition. Testing performed: - `cargo fmt --all -- --check` - `cargo nextest run -p gpui --lib long_press` (10 passed) - `RUSTC_BOOTSTRAP=1 cargo check -p gpui_web --target wasm32-unknown-unknown` Release Notes: - N/A |
||
|
|
d1446d66e0 |
edit_prediction: Adjust to support Ollama to be used for AI edit prediction (#63519)
# Objective Fix two related bugs in the Ollama edit-prediction provider config (`Settings > AI > Edit Prediction > Configure Providers`): 1. The Ollama model dropdown showed only a single model (the currently-configured one), regardless of what models were actually available on the configured server. 2. Ollama never appeared as a selectable option in the "Active Provider" list, even when fully configured. Both bugs shared the same root cause: several places in the edit-prediction code path read from the Assistant's separate Ollama *language model* provider (`language_models.ollama.*`, used by the AI panel/agent) instead of the edit-prediction-specific `edit_predictions.ollama.*` settings. These are two independent Ollama connections that can point at different servers, so the edit-prediction UI was effectively showing/gating on the wrong provider's state. This changes fixes #47393 ## Solution - **Model dropdown**: Added `edit_prediction::ollama::fetch_models_from_server`, which queries `/api/tags` directly against the edit-prediction's own configured `api_url`, independent of the Assistant's Ollama provider. The dropdown now re-fetches from that URL every time it's opened, so changing the server URL and reopening the dropdown shows the new server's models. - **Model filtering**: Fetched models are filtered to those Zed can infer a completion prompt format for (`infer_prompt_format`), so chat-only and embedding models (e.g. `nomic-embed-text`, `llama3:70b`) no longer clutter the list. This function was extracted from `edit_prediction_registry.rs` (previously private, used only for prompt-format resolution) into `edit_prediction::fim` so it can be shared between the dropdown filter and the existing routing logic — same behavior, no duplication. - **Provider visibility**: `get_available_providers` now gates Ollama's visibility on `edit_predictions.ollama.is_some()` (i.e. whether the user has configured a model), matching the existing pattern already used for the OpenAI-Compatible provider, instead of checking the unrelated Assistant provider's authentication state. Removed the now-dead `ollama::is_available`/`ensure_authenticated` functions and the startup call that existed solely to make that broken check eventually pass. ## Testing - Added unit tests for `infer_prompt_format` covering all known model families (qwen/codellama/deepseek-coder/starcoder/codestral/glm/zeta/sweep) and confirming unsupported models (chat/embedding) correctly return `None`. - Added an async test for `fetch_models_from_server` using a fake HTTP client, verifying it filters to FIM-capable models and returns them sorted. - Added a regression test, `test_ollama_provider_routes_to_fim_model`, verifying that Ollama + a known model (`qwen2.5-coder:3b`) resolves to `EditPredictionProviderConfig::Zed(EditPredictionModel::Fim { format: Qwen })` — this exercises the exact routing path underlying the provider-visibility fix. - Manually verified end-to-end against a real local Ollama server: configured a custom `api_url`, confirmed the model dropdown populated with the server's actual models, selected one, and confirmed Ollama appeared in and could be selected from the Active Provider list, with predictions successfully returned. - Ran `cargo check` and `./script/clippy` on all touched crates (`edit_prediction`, `settings_ui`, `edit_prediction_ui`, `zed`); no warnings. - Not tested: the `get_available_providers` gating change itself has no direct test (it's a one-line settings check whose underlying resolution is covered by the `zed`-crate regression test above); Windows/Linux were not tested, only 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] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [X] Tests cover the new/changed behavior - [X] Performance impact has been considered and is acceptable ## Showcase <details> <summary>Click to view showcase</summary> Now when we open the dropdown model selector on Ollama section we will see the available models in the current server that we are trying to use <img width="903" height="755" alt="image" src="https://github.com/user-attachments/assets/873c662b-3624-4530-811c-6f07ab518e35" /> Now Ollama will be displayed as provider in the edit prediction providers dropdown <img width="903" height="755" alt="image" src="https://github.com/user-attachments/assets/9dfe737d-6527-4ecd-9803-3d0959075c34" /> </details> --- Release Notes: - Fixed Ollama edit predictions not appearing as a selectable provider and the model dropdown showing only a single model instead of the models available on the configured server |
||
|
|
8ce383f221 |
Improve visibility and wording around close panel on toggle setting (#63548)
# Objective - Improve documentation for `close_panel_on_toggle` setting. ## Solution - Previous docs were a bit ambiguous and since refactoring the setting name is not possible at the time, I improved the documentation. ## 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 - [ ] Performance impact has been considered and is acceptable Release Notes: - Added the`close_panel_on_toggle` setting to the settings UI and improved its documentation. |
||
|
|
a49de953a8 |
gpui_linux: Prevent panic while reporting Wayland errors (#63159)
`wayland-backend` falls back to `eprintln!` when its optional `log` feature is disabled. If a Wayland connection fails while standard error is unavailable, that fallback panics while trying to report the original error. Closes ZED-8BW Enable the existing `log` feature on `gpui_linux`'s direct `wayland-backend` dependency. `gpui_linux` already depends on the `log` facade, so this introduces no new logging system; it routes backend errors through the configured logger and avoids the secondary standard-error panic. Testing performed: Release Notes: - Fixed a Linux crash when reporting a Wayland connection error while standard error is unavailable. |
||
|
|
229450844d |
git: Move diff hunk operations onto buffer diffs (#63556)
# Objective Keep Git-specific diff-base knowledge in `GitStore`, where Git operations are defined. Related to FR-135. ## Solution Give each `BufferDiff` its supported hunk operations. Keep editor hooks limited to rendering custom controls. ## 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 |
||
|
|
c4bc69e576 |
corgi: Use globs for extra-inputs (#63558)
Corgi 0.1.43 changes how `[extra-inputs]` in `corgi.toml` is read: entries are glob patterns rather than plain paths, and they select files rather than directories. Handing corgi a bare directory name used to mean "everything under here, hashed as a tree"; now it matches nothing and reports that appending `/**` is the fix. This updates each directory entry accordingly, and rewords the section comment to describe the new rules. The practical gain is that the readable set and the hashed set are now exactly the same set of files. Each matched file is granted to the sandbox individually and hashed under its workspace-relative path, so adding, removing, or renaming a file that a pattern covers changes the package's source hash even when no file's contents changed. Reading a file that no pattern matches is denied rather than silently allowed because it happened to sit inside a granted directory. Three reads that corgi has been denying all along now have entries. `eval_cli`'s build script reads `crates/zed/Cargo.toml`, `gpui_wgpu` includes its WGSL shaders through `include_str!`, and `zed_extension_api` includes its own `wit` tree through `wit_bindgen::generate!`. Each of those units fails on `main` today under `corgi check --workspace`. The last one could not be declared at all until corgi 0.1.43, because `[extra-inputs]` is keyed by package name and this workspace resolves three packages named `zed_extension_api` — the member at 0.8.0 plus published 0.1.0 and 0.7.0 that extensions depend on — so the declaration reached the published copies and failed the workspace-escape check. Corgi now applies extra inputs only to local packages, which is safe because a registry package is hashed as a whole directory and reads its own root freely. `corgi_version` is pinned to 0.1.43 so everyone picks up the matching corgi automatically; older corgi releases cannot read these entries. Testing: - `corgi check --workspace` passes with no failing units, which it did not do before this change. - `corgi build -p zed` links the binary. - `corgi check --workspace --all-targets` goes from 16 failing units to 13. The remaining 13 are pre-existing undeclared reads in test targets (font files under `assets/`, `test_data` fixtures and similar) that this change does not attempt to fix. Release Notes: - N/A |
||
|
|
5e28272c14 |
gpui: Lock touch scrolling to the dominant axis (#63553)
Touch pans currently preserve small amounts of movement on both axes, including in the synthetic momentum generated after release. In a nested scrolling layout, a mostly vertical fling that starts over a horizontally scrollable child can therefore move the child horizontally while its ancestor moves vertically. This locks each touch pan to the dominant axis of its accumulated movement when it crosses the touch-slop threshold. Initial movement, predicted updates, release correction, velocity, and momentum are projected onto that axis, so every scroll listener sees the same one-dimensional gesture for its full lifetime. The existing trackpad and wheel behavior remains unchanged; the new rule is applied by the portable raw-touch recognizer before it emits semantic scroll events. Testing: - `cargo nextest run -p gpui --lib gestures::tests` - `cargo fmt --all -- --check` - `./script/clippy -p gpui` - Built Delta Web for `wasm32-unknown-unknown` with this GPUI worktree and reached a successful Trunk release build Release Notes: - N/A |