Commit Graph
39797 Commits
Author SHA1 Message Date
yenru0 2d1430ada5 workspace: Add background image setting with offline-resilient loading
Issue Triage Queue Board / Sync triage queue board (push) Has been cancelled
release_nightly / check_nightly_tag (push) Has been cancelled
release_nightly / run_tests_linux (push) Has been cancelled
release_nightly / bundle_linux_aarch64 (push) Has been cancelled
release_nightly / bundle_linux_x86_64 (push) Has been cancelled
release_nightly / build_static_bwrap_linux_aarch64 (push) Has been cancelled
release_nightly / build_static_bwrap_linux_x86_64 (push) Has been cancelled
release_nightly / bundle_mac_aarch64 (push) Has been cancelled
release_nightly / bundle_mac_x86_64 (push) Has been cancelled
release_nightly / bundle_windows_aarch64 (push) Has been cancelled
release_nightly / bundle_windows_x86_64 (push) Has been cancelled
release_nightly / build_nix_linux_x86_64 (push) Has been cancelled
release_nightly / build_nix_mac_aarch64 (push) Has been cancelled
release_nightly / update_nightly_tag (push) Has been cancelled
release_nightly / notify_on_failure (push) Has been cancelled
Update All Top Ranking Issues / update_top_ranking_issues (push) Has been cancelled
Hotfix Review Monitor / check-hotfix-reviews (push) Has been cancelled
Stale PR Review Reminder / check-stale-prs (push) Has been cancelled
Update Weekly Top Ranking Issues / update_top_ranking_issues (push) Has been cancelled
Bump collab-staging Tag / update-collab-staging-tag (push) Has been cancelled
Update Duplicate Magnets Issue / update-duplicate-magnets (push) Has been cancelled
Guild Stale Assignments / sweep (push) Has been cancelled
Community PR Cleanup / cleanup (push) Has been cancelled
PR Board Meta Fields Refresh / refresh (push) Has been cancelled
Track duplicate bot effectiveness / classify-closed-issue (push) Has been cancelled
Track duplicate bot effectiveness / classify-open (push) Has been cancelled
Close Stale Issues / stale (push) Has been cancelled
Adds a workspace background image that renders behind all UI, configured
via a new `background` settings section (path, fit, opacity).

The image is loaded asynchronously with a 2-second timeout and is never
read on the render path, so an unreachable source (e.g. a dead network
mount) cannot block or freeze the workspace. The first successful read is
cached under the data directory (written once, never rewritten), and when
the source is unavailable the cached image is served from that cache, so
the background keeps working offline.
2026-09-02 19:12:22 +09:00
John Tur 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
2026-09-02 02:14:38 +00:00
Jakub Konka 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
2026-09-01 21:42:01 +00:00
Mikayla Maki 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
2026-09-01 21:39:47 +00:00
Kirill Bulatov 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
2026-09-01 21:20:46 +00:00
Mikayla MakiandConrad Irwin 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>
2026-09-01 19:59:31 +00:00
Mikayla Maki 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
2026-09-01 18:58:47 +00:00
Jakub Konka 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
2026-09-01 16:28:50 +00:00
Reinier Millo Sánchez 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
2026-09-01 16:07:40 +00:00
Matei Oprea 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.
2026-09-01 15:53:33 +00:00
Cole Miller 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.
2026-09-01 15:53:08 +00:00
Ben Kunkle 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
2026-09-01 15:52:33 +00:00
Conrad Irwin 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
2026-09-01 15:40:02 +00:00
Jakub Konka 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
2026-09-01 14:20:13 +00:00
f8c278352f 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>
2026-09-01 12:59:39 +00:00
Cameron Mcloughlin a66fb6aebd 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 ...
2026-09-01 12:43:44 +00:00
Aliandzed-zippy[bot] ce48461eaa 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>
2026-08-31 18:47:00 +00:00
Smit Barmase 9785475caa 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.
2026-08-31 17:38:52 +00:00
Conrad IrwinandBen Kunkle ee6badf4b0 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>
2026-08-31 17:37:00 +00:00
Cameron Mcloughlin 76b1096cbd 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 ...
2026-08-31 17:08:14 +00:00
Conrad Irwin 3f00b5d75d 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.
2026-08-31 16:38:42 +00:00
Conrad Irwinandmorgankrey 81df6f4af0 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>
2026-08-31 15:29:14 +00:00
Conrad Irwin ff020dd053 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
2026-08-31 15:07:24 +00:00
František GažoandKirill Bulatov e8fbacb6d7 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>
2026-08-31 14:36:04 +00:00
tidely a60addb9a9 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 ...
2026-08-31 14:31:41 +00:00
Lukas Wirth 98c6c1403b 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.
2026-08-31 13:35:07 +00:00
Lukas Wirth ef075910c9 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
2026-08-31 13:07:22 +00:00
Kirill Bulatov adc72a5a49 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
2026-08-31 12:04:06 +00:00
Oleksandr KholiavkoandSmit Barmase 7aa903ef25 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>
2026-08-31 11:59:43 +00:00
Kirill Bulatov 24254879b7 Stop re-resolving editorconfig sections on every language settings lookup (#63323)
Closes https://github.com/zed-industries/zed/issues/59689

Symbolicating the reporter's profile (21s of typing, Windows) showed
`Window::draw` taking 63% of the main thread at ~62 redraws/s (p95 draw
= 40ms), and 30.9% of the *entire* main thread inside
`EditorconfigStore::properties()`:
every `LanguageSettings` lookup — several per frame via
`DisplayMap::tab_size`, `MultiBuffer::language_settings`, indent guides,
and `LspStore::supports_range_formatting` — re-ran the full editorconfig
resolution (ancestor walk plus `ec4rs::Section::apply_to` over every key
of every section) and then cloned the whole `LanguageSettings` struct.
Real-world `.editorconfig` files carry hundreds of irrelevant keys
(`dotnet_*`, `ij_*`, ...), so the per-call map assembly dominated:
`RtlAllocateHeap` 7.3%, `memcmp` 7.0%, `memcpy` 6.6%,
`Properties::find_idx` 5.9% self time.

## Commit 1: resolve only the editorconfig properties Zed reads

- `EditorconfigStore::properties()` now applies only the 7 keys Zed
consumes (`indent_style`, `indent_size`, `tab_width`, `end_of_line`,
`max_line_length`, `insert_final_newline`, `trim_trailing_whitespace`)
instead of materializing every key of every matching section.
- Worktrees with no editorconfig at all now return `None` early instead
of allocating an empty `Properties` and forcing a `LanguageSettings`
clone on every lookup.
- Adds an `editor_render_with_editorconfig` benchmark: maximized window,
file-backed buffer at `src/app/components/editor_pane.ts`, a root
`.editorconfig` shaped after [the second
report](https://github.com/zed-industries/zed/issues/59689#issuecomment-5475124891)
(no `root = true`, a `[*]` section with ~3200 keys, 25 sections with
large `{...}` alternation lists) plus a 4-level nested chain, and a
typing workload (insert/delete + cursor moves).

```
main (770aac345c):      time: [37.905 ms 38.005 ms 38.107 ms]
                        time: [38.069 ms 38.157 ms 38.248 ms]
this commit:            time: [2.8547 ms 2.8618 ms 2.8702 ms]
                        time: [2.8372 ms 2.8435 ms 2.8510 ms]
```

The candidate is ~13x faster.
GPUI frame report over the same workload: window draw p50 12.71 ms →
0.76 ms, p99 23.38 ms → 1.22 ms; frame budget overruns 556 → 0.

## Commit 2: cache resolved `LanguageSettings` per buffer

- `Buffer` and `BufferSnapshot` now hold `resolved_settings:
Arc<LanguageSettings>`, recomputed by a `SettingsStore` global observer.
- Global methods for retrieving the settings are still there, but buffer
only uses them for multi buffer's `language_settings_at` with an
injected language different from the buffer's primary; cold scopes such
as extension API, LSP workspace configuration, server startup still use
the global resolution

Same benchmark, same method, on top of commit 1 (alternated runs, quiet
machine):

```
commit 1:               time: [2.8547 ms 2.8618 ms 2.8702 ms]
                        time: [2.8372 ms 2.8435 ms 2.8510 ms]
this commit:            time: [1.6256 ms 1.6325 ms 1.6403 ms]
                        change: [-42.685% -42.270% -41.854%] (p = 0.00 < 0.05)
                        time: [1.6221 ms 1.6284 ms 1.6352 ms]
```

Window draw p50 0.76 ms → 0.47 ms, p99 1.22 ms → 0.69 ms, max 1.02 ms;
zero frame-budget overruns on both sides.
Combined, the benchmark's per-keystroke cost drops ~23x vs `main`
(37.9–38.2 ms → 1.62–1.64 ms).


Release Notes:

- Improved typing and rendering performance in projects that use
`.editorconfig` files.
2026-08-31 11:58:50 +00:00
Oleksandr Kholiavko e6690f38cc tabular_data_preview: Revive filter funnel icon (#63266)
# Objective

Originally, `IconName::Filter` was a funnel glyph and
`IconName::Sliders` was used for settings/controls.

In #60937 (commit `a496bf0ff6`), `filter.svg` was replaced with the
sliders glyph, and `sliders.svg` / `Sliders` enum variants were deleted.
Consequently, `IconName::Filter` has become a sliders-shaped icon used
across 8+ surfaces in Zed (git_ui, search, debugger_ui, keymap_editor,
language_tools, quick_action_bar, editor view settings).

When moving tabular data preview settings to follow the editor's
convention (using `IconName::Filter` sliders for table view settings),
column filter buttons in the table header were left using the same
sliders icon instead of a traditional funnel.

Repurposing `IconName::Filter` back to a funnel would break all other UI
surfaces across Zed.

## Solution

- Restored the funnel icon under a new dedicated
`IconName::FilterFunnel` variant (`assets/icons/filter_funnel.svg` and
`crates/icons/src/icons.rs`).
- Updated `tabular_data_preview` column filter trigger buttons
(`table_header.rs`) to use `IconName::FilterFunnel`.
- Left all existing `IconName::Filter` (sliders) usages across the app
untouched.

Before:
<img width="363" height="156" alt="image"
src="https://github.com/user-attachments/assets/84ac5f87-c0f7-4de9-94ea-e4040e3b4a4a"
/>

After:
<img width="361" height="151" alt="image"
src="https://github.com/user-attachments/assets/38514f3a-0710-4273-b227-4623bf78410b"
/>

## Testing

- `cargo check -p icons -p tabular_data_preview` and `./script/clippy`
build clean.
- `cargo test -p tabular_data_preview --lib` passes.
- Verified column filter button renders the funnel icon in tabular data
preview and highlights correctly when filters are active.

## 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:

- Replace column filter icon in tabular data preview with filter funnel
2026-08-31 11:43:50 +00:00
Kirill Bulatov ded896cc91 Keep first match selecting during type on search (#63375)
Follow-up to https://github.com/zed-industries/zed/pull/62506

Before:


https://github.com/user-attachments/assets/19f6f0df-c5e3-417e-a351-13a09ccb726b

After:


https://github.com/user-attachments/assets/0b302ed7-a98d-4db4-81bc-d67f5cc7db87


* Fixes type on search not selecting the very first result as the
regular search does.
* Unifies the flicker freezing state better in the editor

Release Notes:

- N/A
2026-08-31 11:41:34 +00:00
Kirill Bulatov 6840b8d2fc Fix repo docs (#63486)
* ensures The Rule cannot be accidentall removed
* fixes the perf command example to capture call graphs, to avoid
round-trips like
https://github.com/zed-industries/zed/issues/59689#issuecomment-5453623044
(samples without call graphs are not quite usable for investigating bugs
like these)


Release Notes:

- N/A
2026-08-31 11:00:40 +00:00
那思路(なしろ) bce0c5785b Recognize .bash_login as shell script (#63466)
Added `.bash_login` to the list of recognized shell script files for
syntax highlighting.

Shoutout: [acidx27x](https://github.com/acidx27x) for #62720

Release Notes:
- Added shell script language detection for `.bash_login` files.
2026-08-31 09:04:16 +00:00
9a76a39d7d project: Underline diagnostics reported past the end of a line (#63125)
Closes #22473.

Some language servers report a syntax error whose range starts at the
end
of one line and ends at the start of the next — e.g.
Pyright/ruff/ty/pyrefly
on a Python function missing its trailing `:`:

```
range: { start: { line: 0, character: 11 }, end: { line: 1, character: 0 } }
```

That range spans nothing but the line terminator, so there's no glyph
left
for the editor to underline. The diagnostic is real (it shows up in the
status bar and the diagnostics panel) but never gets a visible squiggle
in
the buffer, which makes it very easy to miss — especially since a
missing
`:` is one of the most common Python typos.

## Fix

`update_buffer_diagnostics` already collapses *empty* ranges onto an
adjacent character. This adds a sibling case for ranges that are exactly
`line_start..next_line_start` (i.e. cover only the terminator): they're
pulled back onto the last character of the line they actually concern,
the same way empty ranges are. Ranges are only touched when the end
position is precisely the start of the next line, so genuinely
multi-line
diagnostics that happen to *start* at an end-of-line position are left
untouched.

## Testing

Added `test_diagnostic_range_spanning_line_terminator` in
`project_tests.rs`, modeled on the neighboring
`test_empty_diagnostic_ranges`,
asserting the closing `)` of `def main()` gets the error highlight
instead
of the range being invisible.

Verified against real language servers: reproduced the exact same
`start..next_line_start` range on ruff 0.16.4, ty 0.0.74, and pyrefly
1.2.0
for a missing `:`, matching the LSP trace pyright produced in #22473.

🤖 Generated with [Claude Code](https://claude.com/claude-code)


Release Notes:

- Fixed diagnostics not being underlined when their range covers only a
line terminator (e.g. a missing `:` in Python)

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
2026-08-31 08:11:59 +00:00
Remco Smits 770aac345c cloud_api_client: Add yield point to prevent background task hangs (#63105)
Follow-up: https://github.com/zed-industries/zed/pull/62874

# Objective

After having Zed open for a while I'm getting some foreground and
background hang warnings, like this one.

```
2026-08-19T11:25:45+02:00 INFO [zed::reliability::hang_detection::logging] New foreground hang detected: Tasks(s) that ran too long 215.24375ms          - crates/cloud_api_client/src/websocket/native.rs:34:23
```

## Solution

My solution is to add yield points so a single task doesn't block the
executor thread for too long.

## 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
2026-08-31 05:45:47 +00:00
Kirill Bulatov 68b6504506 Enable share-generics in release bundle builds (#63432)
Cargo joins `build.rustflags` across config sources, so the base
`symbol-mangling-version=v0` and `tokio_unstable` flags still apply
after the newly added config.

With sccache disabled, `cargo build --release -p zed` on macOS: 
Before: zed binary 420677880 bytes
After: zed binary 375109048 bytes (-10.8%, -45.6MB)

After `strip -x` of both
(https://github.com/zed-industries/zed/pull/63429):
313879024 -> 307727432 bytes (-2.0%, -6.2MB)
The rest of the delta is the smaller symbol table. `drop_glue`
instantiations: 101778 -> 65041.

Release Notes:

- N/A
2026-08-31 05:42:11 +00:00
Kirill Bulatov 399258feea Reduce LLVM IR bloat in closure funnels (#63426)
Follow-up to https://github.com/zed-industries/zed/pull/63232

Cuts closure monomorphization in settings and editor: settings file
updates now share one boxed write-pipeline instantiation instead of
inlining the `SettingsContent` clone, both `serde_json::to_value` calls,
and the JSON diff at every call site; `Editor::register_action` and the
settings enum dropdown get the same treatment. Behavior and public
signatures are unchanged; thin generic shims remain.

Symbol table of the release binary:
Before: `update_settings_file_inner` 229 instantiations, inlined
`serde_json` `SerializeMap` machinery 6547 copies
After: 3 instantiations, 673 copies (-89.7%); `render_dropdown` is no
longer instantiated at all

With sccache disabled, `cargo clean` and `cargo build --release -p zed`:
Before: zed binary 420677880 bytes
After: zed binary 396999464 bytes (-5.6%, -23.7MB)

Release Notes:

- N/A
2026-08-29 22:51:20 +00:00
Jonathon Anderson 19e458b78a context_server: Include requested scopes in OAuth DCR flow (#63370)
# Objective

Fixes https://github.com/zed-industries/zed/issues/63363

The OAuth DCR flow would register an OAuth app with default (unset)
`scope`. This was incompatible with some MCP servers, including GitLab's
Orbit MCP server, which require OAuth scope(s) that are not part of the
default assigned to DCR apps.

## Solution

The OAuth DCR request now registers with the same set of `scope`
selected for the entire flow, matching the authorization prompt used
later. If the server advertises/requests no particular scopes for
authentication, this field is elided to request a default set of scopes
decided by the server.

## Testing

- Successfully logged in via OAuth to the GitLab.com Orbit MCP server
([ref](https://docs.gitlab.com/orbit/remote/access/mcp/#connect-your-mcp-client))
and MCP server
([ref](https://docs.gitlab.com/user/model_context_protocol/mcp_server/#connect-a-client-to-the-gitlab-mcp-server))
on Linux
- Unit tests confirm `scopes` are preserved in the DCR request body

## 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 OAuth authentication failure with MCP servers that require
non-default scopes to access MCP endpoints

Signed-off-by: Jonathon Anderson <anderson.jonathonm@gmail.com>
2026-08-29 22:33:39 +00:00
Dom PoradaandMrSubidubi 9dbc9e76c1 Stop prompting to migrate settings that contain no deprecations (#62818)
## Objective

Zed can report that a settings file uses deprecated settings even when
it contains no deprecations. A context server configured with only a
`url` is enough to trigger the prompt, although the backup Zed offers to
write is identical to the current file.

Fixes #24967.

## Solution

Two text-edit migrations cancel each other on `context_servers` entries:
one adds a `source` key and a later one removes it. The round trip
reindents the entry, and the migrator mistakes the leftover whitespace
for a migration.

Remove `m_2025_06_16` rather than comparing around that whitespace. It
wrote `source` and `settings` into every entry, but
`ContextServerSettingsContent` contains neither field today. `settings`
is worse than inert: an empty entry such as `{ "settings": {} }` matches
neither the `Stdio` nor `Http` variant of the untagged enum.

Update `m_2025_06_27`, the only remaining consumer of the generated
`"source": "custom"`, to detect legacy entries from the shape of
`command` itself. This continues to flatten settings written before
`source` existed. It also deliberately flattens an object `command`
beside `"source": "extension"`, which the old migration skipped. The
command shape is invalid regardless of the declared source, and a test
pins the new behavior. `m_2025_11_25` remains unchanged because it still
removes `source` from settings that genuinely carry it.

This deletes one migration and edits another despite the warning at the
top of `migrator.rs`. That warning protects later migrations that depend
on earlier output, but this output has no remaining consumer. I left the
policy unchanged rather than adding an exception in the same PR that
relies on it, but I can document the exception if preferred.

## Testing

- `cargo test -p migrator` passes, 86 tests. The suite loses the three
tests that only exercised the deleted migration and gains
`test_flatten_context_server_command_alongside_source`, covering a
legacy entry that carries both `source` and an object `command`.
- Restoring the `source` requirement on `m_2025_06_27` with the deletion
in place turns `test_flatten_context_server_command` red. Its input is a
pre-`source` entry, which is what makes the relaxation load-bearing
rather than incidental.
- To check by hand: add `"context_servers": { "grep": { "url":
"https://mcp.grep.app" } }` to user settings and confirm no migration
prompt appears. Add `"show_inline_completions": true` alongside it and
confirm the prompt returns and leaves the context server block
untouched.
- I have not run those steps in a built editor. The tests call
`migrate_settings`, which is all `should_migrate_settings` checks before
raising the prompt, so that call is the whole untested gap. It’s all
platform-independent text processing, so I did not test Linux or
Windows.

## 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 the migration prompt appearing for settings that contain no
deprecations. Context servers configured with only a `url` no longer
trigger it.

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
2026-08-29 22:33:35 +00:00
Petros Amoiridis 82aeef2d8f fs: Stop FakeFs deleting files it should leave alone (#63416)
# Objective

`FakeFs::rename` deletes files in two cases where `RealFs` leaves them
alone. Tests written against the fake see a file vanish where the real
filesystem keeps it, so the behavior cannot be tested at all and
anything relying on it drifts unnoticed.

There is already a test for the first case for `RealFs`,
`test_realfs_rename_ignore_if_exists_leaves_source_and_target_unchanged`,
but the fake had no counterpart.

## Solution

Return early in both cases instead of falling through to the removal.

For `ignoreIfExists` onto an existing target, `RealFs` reports success
and does not move anything. The fake kept the target but removed the
source. The fix also stops recording a move that never happened, which
would otherwise leave an open file handle pointing at the wrong path.

For a rename onto itself with `overwrite`, POSIX requires success with
no action. The fake assigned the entry onto itself and then removed it.
I found this while fixing the first one, and included it.

## Testing

I extended an existing test, and added two new ones. Each fails on
`main` and passes here.

I found this issue while working on #5369, where an LSP rename can send
`ignoreIfExists` and the fake made the resulting bug impossible to write
a test for.

Ran the tests only on macOS as the area seems platform agnostic, but
please let me know if I need to run them across all 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

---

Release Notes:

- N/A
2026-08-29 22:18:44 +00:00
Dipendra Sharma 31a3267183 theme: Show bundled Docker icon for .dockerignore files (#63398)
## Objective

Fixes #63227 — `.dockerignore` files display a generic icon instead of
the Docker icon.

## Solution

Added `.dockerignore` to the list of filenames mapped to the Docker icon
in `crates/theme/src/icon_theme.rs`.

## Testing

- No automated tests added; the change is a static mapping.
- Manually verified by opening a project with a `.dockerignore` file in
Zed.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments (none)
- [x] The content adheres to Zed's UI standards (single icon mapping)
- [ ] Tests cover the new/changed behavior (not required for static
mapping)
- [x] Performance impact has been considered and is acceptable

## Showcase

> This section is optional. If this PR does not include a visual change
or does not add a new user-facing feature, you can delete this section.

- Help others understand the result of this PR by showcasing your
awesome work!
- If this PR includes a visual change, consider adding a screenshot,
GIF, or video
- A before/after comparison is very useful for changes to existing
features!

While a showcase should aim to be brief and digestible, you can use a
toggleable section to save space on longer showcases:

<details>
  <summary>Click to view showcase</summary>

My super cool demos here

</details>

---

- `.dockerignore` now shows the Docker icon for the bundled icon theme.
2026-08-29 22:00:45 +00:00
Albert Bogusz 1662f5f3f6 Fix searching for full SHA-256 commit hashes in Git graph (#63371)
# Objective

Search in the Git graph does not support full commit hashes in SHA-256
formatted repos, while SHA-1 formatted repos work fine.

## Solution

Use existing constants in the `git` crate instead of hardcoded values
when checking for a commit hash query.

## Testing

Added a regression test for valid SHA-1 and SHA-256 commit hash lengths,
plus rejection of hashes longer than the max length.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

<details>
  <summary>Click to view showcase</summary>

The screenshots below show the commit that is being searched for open in
the Git graph.

Before:
<img width="1153" height="536" alt="before"
src="https://github.com/user-attachments/assets/e47c4523-a046-4c47-ac75-cd00845b968f"
/>

After:
<img width="1153" height="536" alt="after"
src="https://github.com/user-attachments/assets/72eeaa16-d0ec-48cb-8ca2-c2bb26f02a10"
/>

</details>

---

Release Notes:

- Fixed searching for full SHA-256 commit hashes in the Git graph.
2026-08-29 12:11:25 +00:00
Kirill Bulatov e3adf43f37 Show last recently used commands on top of the picker's list (#63388)
Closes #8106
Closes #8107


https://github.com/user-attachments/assets/2aba378a-657d-4de9-a45a-6106325281e5

Release Notes:

- Improved command palette ordering: commands are sorted by recency of
use, and previously used commands rank above unused ones while
filtering.
2026-08-28 22:35:33 +00:00
Kirill Bulatov 2890c340e0 Restore the rule (#63384)
Release Notes:

- N/A
2026-08-28 20:04:24 +00:00
Miguel Raz Guzmán Macedo ca2b5741bc lints: Add map_lookup_then_insert lint (#62681)
## Objective

Sometimes we can do a hash lookup twice, which is slow and unidiomatic.
We should use the Entry API instead.

## Solution

Add another `dylint` lint called `map_lookup_then_insert` that catches
those cases.

This works with HashMap, BTreeMap, HashSet, BTreeSet and
entry-compatible ADTs.

## What it catches

See the examples in the `tooling/lints/ui/map_lookup_then_insert.rs`.

It's mostly things of the form

```rust
if let Some(value) = map.get(&key) {
    *value
} else {
    map.insert(key, 1);
    1
}
```

which should be 

```rust
*map.entry(key).or_insert(1)
```

The two key expressions are matched up to borrows/derefs,
value-preserving
conversions (`clone`, `to_owned`, `to_string` on string types, `to_vec`
on
slices, `String::from` on `&str` — each resolved by definition, not by
name),
and immutable local aliases. So looking up `&key` and inserting
`key.clone()`
is caught too. When a conversion had to be peeled, the diagnostic
carries a
note that an entry-API rewrite would perform that copy on hits as well
as
misses.

## What it deliberately does not catch

Forms Clippy already catches.

## Findings

A `--workspace` run finds 31 warnings at 30 unique sites in `zed`:
the 16 the plain key matching finds, plus 15 more that require the
conversion/alias matching (e.g. `tiles_by_key.get(key)` followed by
`tiles_by_key.insert(key.clone(), tile)` in `metal_atlas.rs`).

Will post those fixes in a follow up PR.

## Testing

UI tests cover every `Entry` method positively and negatively, BTreeMap
mirrors, set cases, and the Clippy-deferral boundary. The
key-normalization logic is covered by nine positive cases (cloned keys,
UFCS forms, `to_owned`/`to_string`/`to_vec`/`String::from`, deref
layers, local aliases, sets) and six negative cases (inherent methods
merely named `clone`/`to_owned`, mutated aliases, a clone of a different
key, `to_string` on a non-string key, and side-effecting initializers).

## 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
2026-08-28 20:01:28 +00:00
Casey Avila aa347c3025 debugger: Fix breakpoint list not showing breakpoints in single files (#63348)
# Objective

- Currently there is a bug where breakpoints in single files (not in
folder/worktree) are not shown in the debug panel breakpoint list. They
visually make the breakpoint list empty
- This is because we try to create a `RelPath` from `breakpoint.path`,
which is an absolute path

## Solution

- Create the fallback directory string in a valid way
- Because breakpoint directories can now be absolute, the first part of
the path isn't always the worktree root, so we can't blindly skip this
in the UI code anymore
- Instead, only prepend the worktree root if there multiple worktrees,
matching behavior of other UI elements. This simplifies the code overall

## Testing

- Manually tested

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase
Before:
<img width="978" height="645" alt="image"
src="https://github.com/user-attachments/assets/334176fd-3ad3-4bc7-b7bc-bf1568be6d76"
/>

After:
<img width="962" height="755" alt="image"
src="https://github.com/user-attachments/assets/e4259c7f-679b-4ac9-807e-d8787d43d067"
/>



---

Release Notes:

- Fixed breakpoint list not showing breakpoints in single files
2026-08-28 18:59:38 +00:00
Cole Miller a61e2609c1 Normalize ranges returned by language servers in more cases (#63372)
Previously, we'd panic when constructing multibuffer excerpts in
response to "find all references" if a language server returned a
reversed range. This PR makes it so we normalize those ranges using the
existing `range_from_lsp` helper before passing them to
`set_excerpts_for_path`. It also replaces several other places where we
were calling `point_from_lsp` on each endpoint of a range separately
with `range_from_lsp`.

Closes ZED-79W

Co-authored-by: Mikayla <mikayla@zed.dev>

Release Notes:
- Fixed a crash with some languages servers when handling
`editor::FindAllReferences`.
2026-08-28 18:06:41 +00:00
49469000f0 Ensure that multibuffer anchor ordering is stable over time and consistent with resolution (#62636)
Digging into ZED-7G6 ("buffer snapshot not found for excerpt boundary",
171 events) revealed some bugs in the implementation of multibuffer
anchors that landed in #52364. Specifically:

- In the presence of multibuffer excerpt changes, it was possible for
two anchors to satisfy `a1 < a2` but `a1.to_offset() > a2.to_offset()`.
This happened in particular when a `PathKey` was reused for two
different buffers at different times, and could cause crashes in code
that sorted anchors by `cmp` and expected the resulting offsets to be
sorted.
- Changes of diff base and normal buffer edits could cause two anchors
to sort `a1 < a2` against one snapshot and `a2 < a1` against a later
snapshot. This could also cause crashes in downstream code that
(reasonably) expected anchors to have a stable ordering.

This PR adds a property test asserting that multibuffer anchor ordering
is stable over time and consistent at every moment in time with the
ordering obtained from resolving the anchors, and fixes the bugs in
anchor resolution and comparison that are revealed by that test. It also
includes tests downstream for specific cases that previously crashed.

Closes ZED-7G6
 
Release Notes:

- Fixed a crash that could occur when inlay hints were present while a
multibuffer replaced the contents of a file, such as a diff view whose
base changed.
- Fixed crashes that could occur when a file's contents were replaced in
a multibuffer (such as a diff view refreshing) while highlights, inlay
hints, or other positions still referenced the old contents.

---------

Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-08-28 18:05:57 +00:00
Miguel Raz Guzmán Macedo a3f6b96ced Avoid redundant string allocations (#63377)
Remove unnecessary intermediate `String` allocations when constructing
`Arc<str>` and `SharedString` values. Use static `SharedString` storage
for fixed worktree picker identifiers.

Validation:

- `cargo fmt --all -- --check`
- `tooling/lints/single-lint owned_string_into_shared -p editor -p
git_ui_core -p toolchain_selector`
- `cargo test -p editor -p git_ui_core -p toolchain_selector`

Release Notes:

- N/A
2026-08-28 17:31:36 +00:00