9be65a8dfec1844e3b91e2948e1adea39bdf6931
39818
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9be65a8dfe |
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%) |
||
|
|
8b32975a05 |
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 |
||
|
|
bfad3a6108 |
docs: Document focus_follows_mouse (#63646)
Release Notes: - N/A |
||
|
|
cdee8dd547 |
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> |
||
|
|
bd46f70cfd |
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 ... |
||
|
|
e0c38940d5 |
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 |
||
|
|
1a1d00988e |
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 ... |
||
|
|
b80f016f89 |
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 |
||
|
|
74f3fa1454 |
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 |
||
|
|
7e7087a589 |
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. |
||
|
|
f15a5dac90 |
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 |
||
|
|
c784b96b33 |
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> |
||
|
|
0d31bb3e06 |
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 |
||
|
|
af2c5b36c7 |
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> |
||
|
|
73d8912639 |
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 |
||
|
|
e75564a92a |
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. |
||
|
|
ca3f453f79 |
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> |
||
|
|
16a55e429a |
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 |
||
|
|
24f9172064 |
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 |
||
|
|
d1a6db1bc6 |
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 |
||
|
|
b1c306668b |
Stop labeling reopened triaged issues as 'needs triage' (#63615)
Release Notes: - N/A |
||
|
|
265ea4e838 |
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 |
||
|
|
49f5fe7750 |
Fix misaligned borders around avatars with fractional display scale (#63595)
Before and after: https://github.com/user-attachments/assets/b165d525-c368-4245-a246-2522e67ff3a0 --- Release Notes: - N/A |
||
|
|
a13d872bff |
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 |
||
|
|
810f8313f1 |
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 |
||
|
|
91c7b84774 |
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 |
||
|
|
d89930207f |
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> |
||
|
|
cd0241b7e3 |
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 |
||
|
|
966ba1f92a |
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 |
||
|
|
6c4441c5d9 |
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 |
||
|
|
04fc4edf86 |
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. |
||
|
|
ad0d789038 |
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. |
||
|
|
aecaacdb44 |
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 |
||
|
|
99f85efa71 |
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 |
||
|
|
16da2ea125 |
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 |
||
|
|
6d0f8c93d8 |
git_ui: Add multi-select to git panel for bulk stage, unstage, and discard (#60340)
Closes #26430 Complements: #52935 by Jacob Binnie Enables multi-select in the Git Panel, following the Project Panel rules. https://github.com/user-attachments/assets/2892c1e2-3071-47f9-af1a-48e1c69dbb8a **Core selection gestures:** 1. Click one file, shift+click a file deeper in the list: all files between highlight. 2. Click one file, then ctrl/cmd+click another file: it joins the selection; or removes it when selected. 3. Shift+down extends the selection from the current row; shift+up shrinks it back and re-extends past the anchor. 4. Escape with a selection clears it and keeps focus; Escape again toggles focus as before. 5. Plain click collapses selection to file and opens its diff; double-click triggers the alternate open action. 6. Shift+click on a checkbox still performs the pre-existing range staging. **Bulk operation gestures:** 1. Select multiple files, press space: if any member is unstaged, all become staged; press space again: all unstaged. 2. Right-click a file inside the selection: menu reads Stage/Discard/Trash N files, depending on context. 3. Select multiple files, press delete: confirmation prompt. Mixed selections: untracked = trashed, staged = unstaged. **Folders, in tree view:** 1. Ctrl/cmd+click a folder row behaves like its checkbox does: selects it as a unit, expands operations to descendants. 2. Folder rows inside a shift range join the selection. A collapsed folder is selected including its hidden files. 3. The same directory under Tracked and Untracked is two independent selections (so marks are section-qualified). 5. Plain click on a folder still expands/collapses it and clears the selection. **Implementation notes:** 1. Selection is stored as repo paths plus section-qualified tree keys to survive status refreshes.* 2. Stale entries are pruned on rebuild, selection is cleared on active repository change. 3. Range selection follows visual order in both flat and tree view. 4. Bulk operations batch into a single git operation. \* Not sure if this is the best option for storing it. **Why this is necessary** - Multi-select has been an ongoing feature wish since 2025 with various upvotes - Current state of the art IDEs offer this (VSCode, IntelliJ, VS) - It greatly increases efficiency using the diff panel **Why is the PR from #52935 not enough?** This PR builds on its approach. Thanks to @jacobbinnie. But I noticed a few things: - never clears the selection when the active repository changes - a failed checkout or trash disappears silently - hardcodes single-click = project diff and double-click = file diff, ignoring the entry_primary_click_action setting - its context menu still reads "Stage File" / "Discard Changes" (singular) - discard prompt always says "Discard" even for an all-untracked selection that will actually trash files - no shift+arrow range extension, no Escape to clear - it skips directory rows entirely, in tree view you can't act on a folder's subtree at all - its range_select only ever accumulates, consecutive shift+clicks grow the set and nothing shrinks it - Uses Vec<RepoPath> on marks, linear contains scans -> This PR uses HashSets, relevant for huge repos. - doesn't ship any tests -> This PR covers the whole range with tests too* \* Tests dominate this PR (~850 lines). The actual feature sits around 400. Release Notes: - Added multi-select to the git panel --------- Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com> Co-authored-by: Jacob Binnie <jacob.b@linktr.ee> Co-authored-by: Andrea Leone <andrealeone@hey.com> |
||
|
|
c940c0c669 |
gpui_web: Tighten up web keyboard feel (#63533)
Fixes a few edge cases where we weren't correctly tracking whether to hide the keyboard when touch events happen Also forces a synchronous render on web after the viewport resizes (which happens when the keyboard appears/disappears). This prevents a 1 frame delay where the browser would use the old bitmap, stretched to the new size --- Release Notes: - N/A or Added/Fixed/Improved ... |
||
|
|
7378a7f36d |
util: Prevent panic when parsing a malformed shell variable (#63446)
# Objective
`to_cmd_variable` and `to_powershell_variable` removed the last byte of
a
`${...}` argument assuming it was the closing brace, without checking
one was
there
```rust
// If the input starts with "${", remove the trailing "}"
format!("$env:{}", &var_str[..var_str.len() - 1])
```
# Solution
Use strip_suffix('}') and pass the input through when it isn't a
variable reference
## Testing
added tests to cover this
To reproduce on Windows, add a context server with a malformed argument
to settings.json:
```
"context_servers": {
"crash-repro": {
"command": "does-not-matter",
"args": ["${"]
}
}
}
````
Opening the agent panel and zed will crash
Release Notes:
- Fixed a panic when converting a malformed `${` shell variable
reference on Windows
---------
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
|
||
|
|
7402d91b26 |
sidebar: Add title renaming for Terminal Threads (#63494)
The Agent Panel already lets users rename Terminal Threads. This adds the same option to the Threads Sidebar. A rename in either place updates the other. <p> <img width="321" height="89" alt="image" src="https://github.com/user-attachments/assets/189a8598-f0da-4622-a5b0-b6a18a5750b7" /> </p> <p> <img width="324" height="77" alt="image" src="https://github.com/user-attachments/assets/2fc9f7aa-c791-4568-8729-fd3a78322d63" /> </p> Release Notes: - Added support for renaming Terminal Threads from the Threads Sidebar. |
||
|
|
72dc742101 |
Support building with corgi (#63396)
[corgi](https://github.com/ConradIrwin/corgi) is a cargo-compatible build tool that runs `build.rs` scripts and proc-macros in a sandbox (no network, no ambient env, reads limited to a package's own `.rs` sources unless declared). This makes Zed buildable under it. Cargo builds (dev and release) are unaffected. ### Changes - **`scratch` patch**: patch `scratch` to a small local copy (`corgi-patches/scratch`) that reads `OUT_DIR` at runtime instead of baking it in at compile time. `cxx-build` writes its shared cxxbridge headers into `scratch::path(...)`; upstream returns a single global dir (outside any action's `OUT_DIR`) that the sandbox can't grant, while this patch gives each build script a private, writable dir in its own entry. webrtc-sys is self-contained, so per-crate scratch dirs are sufficient. Kept local rather than a cxx git fork because a git checkout of cxx needs symlink support that Windows cargo CI lacks. - **Dev asset loading**: add `util::dev_fs_embed!` and switch dev-mode `rust_embed` asset sources (`assets`, `settings`, `grammars`, `agent`, `edit_prediction_cli`) to read from the checkout at runtime, locating the repo root by walking from the executable up to the enclosing `.git`. This avoids baking `CARGO_MANIFEST_DIR` into the binary (corgi rejects artifacts that embed the build-time checkout path, and it's wrong in any other worktree). Release builds still embed via `#[derive(RustEmbed)]`. - **Stop baking checkout paths into artifacts**: drop `gpui::GPUI_MANIFEST_DIR`; resolve `../gpui` from `gpui_apple`'s build script; stage the metal shader into `OUT_DIR` before compiling so the `.metallib` records the output dir, not the checkout; resolve the repo root at runtime in `remote` and `inspector_ui` (removing `inspector_ui`'s `build.rs` / `ZED_REPO_DIR`). - **corgi.toml**: declare the pinned tools (`cmake`, prebuilt libwebrtc via `LK_CUSTOM_WEBRTC`), a release-only `ZED_COMMIT_SHA` probe, and the non-`.rs` / cross-package reads each package performs. ### Validation - `corgi check` + `corgi build`, dev and release, for `zed` (plus `cli`, `remote_server`, `ep`) with a warm C++ cache — clean; built binaries embed no checkout path. - `corgi fmt --check`, `corgi clippy`, and `corgi test` on the changed crates (922 tests pass). - `cargo check -p util` locally; relying on CI for the full cargo build/test matrix. ### Notes for the reviewer - Per the repo rule, the first two lines of `README.md` are the review-confirmation marker; remove them before merging (this is what Danger is failing on). - `remote_server` cross-compilation (linux-musl via zigbuild) is not yet covered by `corgi.toml` — host (macOS arm64) only for now. ### Suggested .rules additions Only if the team wants corgi guidance in `.rules` (it recurred several times here): dev builds must not bake the checkout path into artifacts — no `env!("CARGO_MANIFEST_DIR")` or `file!()`-derived absolute paths in library/binary output. Resolve the repo root at runtime via `util::dev_repo_root()` (walks to `.git`), and use `util::dev_fs_embed!` for dev-mode `rust_embed` sources. Release Notes: - N/A --------- Co-authored-by: Ben Kunkle <ben@zed.dev> |
||
|
|
87222d1d29 |
gpui: Platform-specific scroll physics (#63505)
Adds platform-specific scroll behaviour, and also exposes predicted events for better latency --- Release Notes: - N/A or Added/Fixed/Improved ... |
||
|
|
29a2ce8d46 |
editor: Limit row highlight expansion to viewport (#63395)
## Summary - Limit row-highlight expansion during editor rendering to ranges that intersect the visible viewport. - Use the stable multibuffer anchor ordering established by #62636 to binary-prune every highlight group, including ranges with diff-base anchors. - Preserve exact-boundary highlights for custom blocks and add regression coverage comparing viewport results with the full-editor result. This is stacked on #63394 so the benchmark fixture and batched conflict anchor conversion are available independently. ## Performance The severe synthetic workload contains 128 conflicted files, 256 conflict regions per file, and 163,840 accumulated row-highlight ranges. In the initial paired measurement, viewport filtering reduced: - project-diff refresh from 67.6–87.8 seconds to 13.47–13.53 seconds; - cumulative row-highlight expansion from 53–74 seconds to about 7.7 milliseconds; - the longest individual expansion from 817–875 milliseconds to 0.063–0.071 milliseconds; - examined highlight ranges from 10.7–15.6 million to about 2,500. After isolating this commit from the separate block-insertion experiment and hardening the anchor-boundary behavior, two severe-workload runs completed in 17.75 and 20.51 seconds. Those isolated runs are not a direct A/B comparison with the initial numbers because they intentionally omit the block-insertion fast path. ## Validation - `cargo test -p editor test_highlighted_display_rows_in_range` - `./script/clippy -p editor` - `git diff --check` - Two independent code reviews focused on viewport boundaries and anchor ordering Release Notes: - Improved project diff performance for repositories with many merge conflicts. |
||
|
|
c293b18fd7 |
crashes: Replace user info with generic Sentry tags (#63344)
The crash handler models the crashing user as a fixed `UserInfo` struct of `metrics_id` and `is_staff`. That is a reasonable fit for Zed and a poor extension point in general: reporting any further piece of session state with a crash means changing this crate, and every embedder along with it. The limitation has already produced a workaround in another consumer of this crate. Wanting one field that `UserInfo` has no room for is enough to push an embedder off the IPC channel entirely, onto persisting that state beside the minidump and correlating it back at upload time. That needs an atomic write, a retention window for records whose minidump never uploads, and a cross-check so a stale record cannot be attributed to the wrong crash — none of which the existing socket would have required. This replaces the `UserInfo` message with a generic `SetTags` message carrying one or more updates. Each key is the Sentry submission field the value is uploaded under, so an application can attach its own session state and reach any part of Sentry's event schema without this crate modelling what it means. Updates merge by key, and a `None` value removes one, which is how an application withdraws state from crashes it has not produced yet. A batch is applied while holding the tag-map lock once, so a crash cannot observe part of one logical state change. `set_user_info` keeps its signature and is now shorthand for setting the two identity tags in one batch, so Zed's call site is unchanged. `upload_minidump` loses its two bespoke user blocks in favour of forwarding the map, and keeps its installation-id fallback by checking whether the session ever reported a user. Two consequences worth flagging for review. The first is that this crate now knows it reports to Sentry, where previously it emitted neutral data that `reliability.rs` translated. I think that is honest rather than regrettable — its consumers upload to Sentry, and pretending otherwise is what gave `UserInfo` a shape that fits only one of them. The alternative considered was a well-known-key mapping table in the uploader, which keeps the crate agnostic at the cost of a translation layer that can silently file a value under the wrong namespace. The second is a one-time compatibility loss. A crash is uploaded by the build that starts after it, so an upgrade always reads crash data written by the previous build. Crashes pending across this change carry `user_info` and no `tags`, and will upload without user attribution. They still parse and still upload; only the identity is dropped, for one release. A test covers that. Testing: - New unit test for batch, merge, and removal semantics, driven through `on_message` so it exercises the real wire format. - New unit test that crash data written before `tags` existed still deserializes. - `cargo test -p crashes`, `./script/clippy -p crashes -p zed`, `cargo check -p zed -p remote_server`, `cargo fmt --check`. Release Notes: - N/A --------- Co-authored-by: morgankrey <morgan@zed.dev> |
||
|
|
37083e77dd |
git_ui: Batch merge conflict anchor resolution (#63394)
Improves merge-conflict loading by resolving ordered conflict anchors with a single excerpt sweep instead of restarting the excerpt scan four times per conflict. The pull request also adds `script/generate-merge-conflict-benchmark`, which creates validated small, medium, or severe repositories with real unresolved Git merges. On the severe workload (128 files × 256 conflicts), anchor conversion decreased from 483.5 ms to 5.9 ms, saving about 478 ms, or roughly 5% of the total refresh. Closes https://linear.app/zed-industries/issue/FR-174/improve-git-panel-performance-for-large-merge-conflicts ## Testing - `cargo test -p multi_buffer test_ordered_buffer_anchor_ranges_to_anchor_ranges` - `cargo test -p git_ui conflict` - `./script/clippy -p multi_buffer -p git_ui` - Generated and validated the small synthetic merge-conflict workload Release Notes: - Improved performance when opening large merge conflicts |
||
|
|
bb501d9221 |
outline_panel: Add setting to hide symbols in multi-buffer views (#63404)
Closes https://github.com/zed-industries/zed/issues/60242 # Objective When reviewing a branch diff — or project search results — the outline panel lists every affected excerpt and symbol beneath each file. On a diff touching more than a handful of files, this consumes so much vertical space that you cannot see the list of changed files at all, which is usually the thing you want the panel for. Existing settings don't cover this: - `expand_outlines_with_depth: 0` still renders excerpt rows and top-level symbol rows. - Collapsing a file row in the panel is coupled to folding that buffer in the editor, so it can't be used purely to tidy the panel. ## Solution A display-only mode that reduces multi-buffer views to just the directory/file tree. - New `outline_panel.multi_buffer_hide_symbols` setting (default `false`). When enabled, multi-buffer views render only directory, file and folded-directory rows — excerpt, symbol and search-match rows are hidden. - New `outline panel: toggle symbols` action, plus a button in the panel footer, which toggles an in-memory per-panel override of the setting (the same pattern as `editor: toggle inlay hints`). Changing the setting clears the override, so the setting wins. - Single-file views are exempt, and the footer button is not shown there — the panel contains only symbols in that case, so hiding them would leave it empty. - The filter is display-only: `collapsed_entries` and editor buffer folding are never touched. - Outline fetching is skipped while the mode is active, so large diffs don't pay for outlines that will not be rendered. Turning the mode off re-triggers fetching. This adds one new icon, `file_code_off`, used by the footer button when symbols are hidden. cc @zed-industries/design for review per the icon guidelines — it is `file_code` with the slash and outline gaps from `file_ignored`, keeping the parts of the chevrons that fall on the near side of the slash. ## Testing Three new tests in `crates/outline_panel/src/outline_panel.rs`: - `test_hide_symbols_in_multibuffer` — outline rows are present by default; only `Fs`/`FoldedDirs` entries remain once the mode is enabled via the setting (which also exercises the settings observer) and via the action; outline rows return when it is toggled off, confirming outlines are re-fetched; asserts `collapsed_entries` is unchanged at every step, covering the display-only guarantee. - `test_hide_symbols_exempts_singleton` — a single-file view still renders its outline with the setting enabled. - `test_hide_symbols_hides_search_matches` — project search match rows are hidden while files and directories still render, and return when toggled off. `cargo test -p outline_panel` (15 passing), `cargo test -p icons`, `cargo test -p settings_ui -p settings_content`, and `./script/clippy` on the touched crates are all green. Tested manually on macOS against a branch diff, project search results, and single-file buffers, checking both the setting and the action (from the panel footer button and from the command palette with focus outside the panel), and that expanding/collapsing directories and editor folding still behave as before. ## 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 <!-- Screenshots go here: branch-diff before/after, footer button icon states, search before/after, single-file exemption --> | | Symbols shown (default) | Symbols hidden | | --- | --- | --- | | **Footer toggle** | <img src="https://github.com/user-attachments/assets/393f128d-1a7c-43a8-97b8-8176a07b45c7" width="260"> | <img src="https://github.com/user-attachments/assets/87c60dd4-d5b7-48f8-9255-226c4a94a586" width="260"> | | **Branch diff** | <img src="https://github.com/user-attachments/assets/79357325-7d7d-40f7-8067-4ae59a824f87" width="420"> | <img src="https://github.com/user-attachments/assets/8a3bbc7e-90d4-4638-9f1d-1ba3091eccfd" width="420"> | | **Project search** | <img src="https://github.com/user-attachments/assets/76e3cf18-d624-42f8-8801-f496bf54a552" width="420"> | <img src="https://github.com/user-attachments/assets/2a34e899-b9f4-465e-b571-75d3d54d00eb" width="420"> | Single-file views are unaffected — symbols still render, and the toggle is not offered: <img src="https://github.com/user-attachments/assets/76c47884-96db-4071-bcc1-931c4283e36f" width="640"> --- Release Notes: - Fixed too many outlines shown per excerpt in the outline panel. Added an `outline_panel.multi_buffer_hide_symbols` setting and an `outline panel: toggle symbols` action to show only files and directories in the outline panel for multi-buffer views. --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
fd35a813e9 |
gpui_macos: Migrate PlatformWindow::prompt to objc2 on MacOS (#59572)
# Objective Rust 1.96 emits a warning when compiling the `block` crate, that it will no longer compile past some future version of Rust. The `block` crate provides `ConcreteBlock` and `RcBlock`, which are stack- and heap-based functions often passed as callbacks to MacOS. The old `objc` crate family is deprecated and no longer maintained. The goal of the PR is to replace one call to `block::ConcreteBlock` by migrating a standalone portion of code to the objc2 crate family. A full migration to `objc2` by Zed has been long on the horizon (#22408) Additional benefits: The new code is completely typed, uses automatic memory management, and reduces lines of unsafe Rust from 50+ to 1. The lingering unsafe converts a raw pointer stored by `self` to the respective `objc2` type, since the rest of the window implementation does not use the new crates yet. ## Solution Migrate `PlatformWindow::prompt`'s MacOS implementation to `objc2`. ## Testing Direct platform code is quite fragile and hard to test, however you can exercise the codepath by running the following `gpui` example and clicking on the prompt buttons. ```sh cargo run -p gpui --example window ``` I've also built Zed with these changes and tried codepaths which activate prompts, such as deleting a file. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content 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 or Added/Fixed/Improved ... |
||
|
|
1344a8a846 |
gpui: Gate blocking executor APIs on WebAssembly (#63484)
GPUI's scheduler exposed synchronous blocking APIs on WebAssembly even though the platform implementation could only panic. This became an implicit crash when cancellation dropped a scoped background operation: preserving the borrowed task lifetime called `Scheduler::block`, which panicked with `Cannot block on wasm`. This change removes blocking scheduler and executor APIs from WebAssembly builds, including borrowed background scopes and the separate `pollster::block_on` export. Native behavior remains unchanged. Application shutdown now runs WebAssembly quit handlers asynchronously as best-effort cleanup rather than blocking the browser event-loop thread. Release Notes: - Fixed a GPUI Web crash caused by synchronous executor blocking. |
||
|
|
ab1c37a4ef |
gpui_web: Let applications provide fonts (#63493)
`gpui_web` currently embeds IBM Plex Sans and Lilex into every browser application during platform construction. Applications such as Delta already provide their own fonts, so those binaries contain overlapping font bundles and register the same faces twice. This change starts the web platform with an empty font database, matching the ownership boundary used by native applications: the application selects and registers its fonts before opening a window. Delta already follows that sequence. GPUI's browser-capable examples now load the former eight-face bundle explicitly through shared example support, while the standalone `hello_web` example demonstrates registering a minimal application font directly. Testing performed: - `cargo check -p gpui --examples --target wasm32-unknown-unknown` - `cargo check -p gpui --examples` - `cargo check -p gpui_web --target wasm32-unknown-unknown` - `cargo check --manifest-path crates/gpui_web/examples/hello_web/Cargo.toml --target wasm32-unknown-unknown` - `./script/clippy -p gpui_web --target wasm32-unknown-unknown` - `cargo fmt -p gpui -p gpui_web --check` Release Notes: - N/A |
||
|
|
7ea8eb3f2e |
Support CSV preview in project-less set-ups (#63350)
Closes https://github.com/zed-industries/zed/issues/63265 Release Notes: - Fixed CSV preview not showing in project-less set-ups |
||
|
|
75917d2f73 |
tabular_data_preview: Add shortcut to open tabular data preview (#63369)
## TL;DR Adds `cmd-shift-v` / `cmd-k v` (ctrl on linux/windows) to open the tabular data preview for `csv`/`tsv`/`ssv`/`psv` files, mirroring the existing `markdown::OpenPreview(ToTheSide)` and `svg::OpenPreview(ToTheSide)` bindings/context pattern already in the default keymaps. Extension check kept explicit (not just `"Editor"`) so it doesn't compete with the `md`/`svg` blocks bound to the same keys on their own extensions. ## Testing - Manually verified `cmd-shift-v` / `cmd-k v` open tabular data preview on `.csv`/`.tsv`/`.ssv`/`.psv` files, no-op on other extensions. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [x] UI standards followed - [ ] Tests cover the new/changed behavior - [x] Performance impact considered, acceptable Release Notes: - Added shortcuts to open the tabular data preview for CSV/TSV/SSV/PSV files (similar to md/svg preview) --------- Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com> |