When a linked worktree receives fs events for its .git directory, the
event path resolves to the per-worktree git dir (e.g.
main_repo/.git/worktrees/<name>), not the .git directory itself or the
common dir. The existing match only checked common_dir_abs_path and
repository_dir_abs_path, causing the repository entry to be missed and
then removed as stale.
Add dot_git_abs_path to the match, and fix the staleness metadata check
to use dot_git_abs_path (the actual .git entry) rather than
common_dir_abs_path (which may be outside the worktree root).
Extracted from https://github.com/zed-industries/zed/pull/53453
Release Notes:
- N/A or Added/Fixed/Improved ...
---------
Co-authored-by: Kieran Freitag <kfreitag@kieran.ca>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
`create_terminal_task` and `create_terminal_shell_internal` previously
built their toolchain candidate list as `[active_editor_entry.path,
...visible_worktrees]` and used the first one with a persisted
toolchain. A Python toolchain persisted for worktree A would leak into a
terminal opened in worktree B of the same window: with a conda env
selected for one project, every terminal in every other project of the
window inherited that env's activation at startup.
This scopes the candidate list to the worktree that contains the
terminal's CWD. Both call sites now derive candidates from
`find_worktree(path)`, where `path` is the terminal's resolved CWD
(`spawn_task.cwd` or `active_project_directory`). If the path lives in a
worktree, lookup runs scoped to that worktree's id. If not, no toolchain
is applied.
## Design decision
The previous fallback chain (active editor's worktree, then all visible
worktrees) is removed entirely. Both fallbacks were sources of the leak:
- "Active editor's worktree" is order-dependent: opening a terminal in
worktree B picks up worktree A's toolchain because a file in A is
focused.
- "All visible worktrees" is worse, since the first worktree with any
persisted toolchain wins.
Workflows that relied on either fallback need to set the toolchain
explicitly on the worktree where the terminal is opened.
## Coverage
`cargo check -p project` is clean. There is no unit test for the
cross-worktree case; that would require a multi-worktree Project fixture
with persisted toolchains, which doesn't exist in the test suite today.
Reproduction is straightforward: open a workspace with two folders,
select a Python toolchain in one, open a terminal in the other, and
observe the leaked activation script in the spawned shell.
Release Notes:
- Fixed Python toolchains persisted for one worktree leaking into
terminals opened in other worktrees of the same workspace.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
I encountered this bug while building my app with GPUI where tooltips
were getting stuck when i move my mouse away from the origin element.
Zed kinda gets away with it because tab close buttons use
`visible_on_hover`, so when the mouse leaves the tab, close button
disappears. This triggers a redraw which makes GPUI recheck and hide the
tooltip.
In the "Before" version i had to trigger the recheck by moving my mouse
over an element with hover styles to make the tooltip disappear.
### Before
https://github.com/user-attachments/assets/f405620f-6d6d-4a24-8992-214180bc7b76
### After
https://github.com/user-attachments/assets/2e41fbca-af61-4f34-bd5d-ab288f34e73a
Stops the `conda activate base` fallback in
`PythonToolchainProvider::activation_script` for two cases:
1. A Conda toolchain whose `environment.name` is `None`.
2. A Conda toolchain whose name is `Some(...)` but `shell.try_quote`
rejects it.
Previously both cases pushed `conda activate base` into the activation
script. With miniforge installed and no env explicitly selected, every
terminal silently activated `(base)`. The user didn't pick `base`;
injecting it is contamination.
Both branches now log a warning and emit no activation line. Users who
want `(base)` can select it as the toolchain explicitly.
Two unit tests cover the new behavior:
`test_conda_activation_skips_when_name_missing` (name=None) and
`test_conda_activation_skips_unquotable_name` (name=Some but unquotable,
exercised with an embedded NUL byte that `shlex::try_quote` rejects).
The existing `test_conda_activation_script_injection` still verifies
that quotable names get activated.
Release Notes:
- Fixed Zed silently injecting `conda activate base` into terminals when
a Conda manager (miniforge/miniconda) was installed but no specific
environment was selected.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes#47585
Release Notes:
- Improved display of related diagnostic entries in hover popovers to
include diagnostic source and code.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes#55503
In #28752, to support case-insensitive search for non-ASCII queries, Zed
internally falls back to a regex search. However, this also affected the
replacement behavior, as the replacement code implemented a simple match
logic:
https://github.com/zed-industries/zed/blob/ae6b48c423d3e429ffd242c2771d65ae450640af/crates/project/src/search.rs#L452-L457
Since the regex fallback is an internal implementation detail (the user
never enabled regex mode), the replacement should behave the same as a
normal text replacement. This PR fixes that.
Release Notes:
- Fixed replacement text being treated as a regex pattern when
performing case-insensitive text search with non-ASCII characters.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes#49178
The context for this change is covered in #49178. Some language server
adapters are lazily registered; in remote development or collab
sessions, the local client fails to register these adapters, may causing
certain LSP features to function incorrectly. This PR is intended to
address that.
Release Notes:
- N/A
The current text is a bit wordy and puts the actually important
information at the end:
<img width="607" height="120" alt="image"
src="https://github.com/user-attachments/assets/26f998dd-1801-4e6c-a40c-acb58f8f3efc"
/>
The button already shows as disabled, so the text just needs to explain
why.
I don't think this affects accessibility, because a screen reader should
be able to tell that the button is disabled.
Self-Review Checklist:
- [ ] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable
Release Notes:
- N/A
If for some reason we do not manage to find any shas, we were showing an
incorrect loading message before despite not being in a loading state
anymore.
Release Notes:
- N/A or Added/Fixed/Improved ...
Closes#4864
Adds a `file_finder::OpenWithoutDismiss` action that opens the selected
file without closing the finder, so multiple files can be opened in one
session. Pressing right arrow when the cursor is at the end of the
search query triggers it — matching VS Code and Sublime Text behaviour.
A "Keep Open" button in the footer provides mouse access and serves as a
discoverability hint.
Each opened file becomes the active tab without stealing keyboard focus
from the finder, preserving the search state between opens. Refactors
the existing `confirm` implementation into a shared `open_selected_file`
helper parameterised by `dismiss_after_open` to eliminate duplicated
file-opening logic.
## What's different from PR #38914
- Uses `right` arrow at `end_of_input` context instead of
`cmd-shift-enter` (better ergonomics, matches VS Code/Sublime — the
`end_of_input` context that was added after that PR makes this possible)
- Each opened file is activated as the current tab (`activate: true`,
`focus_item: false`), giving visual feedback on every open without
stealing focus from the modal
- Cleaner refactor: single `open_selected_file` helper instead of
duplicated logic
Release Notes:
- Added ability to open files from the file finder without dismissing
it, using right arrow at end of input or the "Keep Open" footer button
---------
Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
Many projects are switching to main as the default branch name. Prefer
it over master, in case both are present.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- N/A or Added/Fixed/Improved ...
There's currently no way to customize AI-generated commit messages on a
per-commit basis. You can put instructions in AGENTS.md or a project
rules file, but those get fed into every agent interaction, not just
commit generation. The built-in "Commit message" prompt used to be
editable in the Rules Library, but that was replaced by Skills, which
aren't used when generating commit messages.
This PR adds an `agent.commit_message_instructions` setting. Its
contents are added to the commit message prompt in their own section,
alongside any project rules, so you can ask for a specific format
(Conventional Commits, a ticket prefix, etc.) without changing how the
agent behaves elsewhere:
```json
{
"agent": {
"commit_message_instructions": "Use the Conventional Commits format: <type>(<scope>): <description>."
}
}
```
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Addresses #26503
Release Notes:
- Added an `agent.commit_message_instructions` setting to customize
AI-generated git commit messages.
---------
Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes#55880
This improves the work on #56569 by allowing the user to choose the base
branch to compare with directly, instead of having to open the default
branch diff and only after, picking the new base branch.
Additionally, this changes the existing item finder to also match by
base (oid). This allows to have multiple branch diff open with different
base branches.
Demo:
https://github.com/user-attachments/assets/8abdc08f-6181-4a74-a50b-e5f2b891663e
Release Notes:
- Added new `git: compare with branch` action to directly compare the
current branch with an arbitrary branch.
Resolves https://github.com/zed-industries/zed/issues/55552
Git blame can be initialized for buffers that are not backed by any Git
repository. Previously, that path still called into
`Project::blame_buffer`, which returned an error because there was no
repository for the buffer. When blame was user-triggered, that error was
surfaced as a toast even though this is an expected “not applicable”
state rather than a failed Git operation.
This diff checks whether the buffer belongs to a repository before
requesting blame data. Buffers outside Git repositories now produce no
blame entries without emitting an error, while real blame failures
inside repositories continue to use the existing error notification
path.
Release Notes:
- Improved Git blame to quietly ignore files that are not part of a Git
repository.
Co-authored-by: Cole Miller <cole@zed.dev>
Patterns in `.git/info/exclude` that contain a slash (e.g.
`.claude/worktrees`) are anchored: Git matches them relative to the
project root. Zed was instead matching them relative to the `.git/info/`
directory that the file lives in, so they matched nothing and had no
effect.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Support anchored patterns in .git/info/exclude
---------
Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes#54209
Release Notes:
- Fixed vim `%` (matching bracket) motion not working in multibuffers
---------
Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes#55287
This fixes the SSH remote case where restarting a language server left a
stale entry in the LSP Logs panel.
The root cause was that the remote client learned about the replacement
language server, but never received an explicit removal update for the
previous server id. As a result, the old status and log-store entry
remained visible even though only the new server continued producing
logs.
Tested with:
- `cargo test -p collab --test collab_tests
remote_editing_collaboration_tests::test_ssh_restarting_language_server_replaces_remote_status
-- --exact`
Release Notes:
- Fixed stale duplicate entries in the LSP Logs panel after restarting
an SSH remote language server.
Co-authored-by: Lukas Wirth <lukas@zed.dev>
## Summary
In the keymap editor, the search input at the top used `size_full()`
while the
adjacent button row had `min_w_96()`. On narrow panes (e.g. side-by-side
splits), this caused the action buttons — including "Create keybinding"
— to
overflow and clip out of the editor.
This change lets the search input flex and shrink (`flex_1()` +
`min_w_0()`),
and makes the button row `flex_none()` so it keeps its natural width and
stays visible at any pane size.
## Before / After
<img width="2227" height="475" alt="Screenshot 2026-04-23 215511"
src="https://github.com/user-attachments/assets/f3d79922-13e4-486b-b2b0-62ffa5d5b1a2"
/>
## Test plan
- [x] Open the keymap editor (`zed: open keymap editor`)
- [x] Confirm the "Create keybinding" and other action buttons remain
visible
- [x] Confirm the search input shrinks gracefully instead of pushing
buttons off-screen
Co-authored-by: Lukas Wirth <lukas@zed.dev>
## Context
This fixes incorrect syntax highlighting inside Rust `json!` macros when
a JSON value is an empty string. In the current Rust tree-sitter
injection setup, most macro bodies are reparsed as nested Rust, which
works for macros like `vec!` but breaks down for JSON-shaped `json!({
... })` content. When the nested Rust parse loses sync at `""`, later
values can inherit incorrect highlighting.
Closes#54838
The fix treats `json!` as an exception to the generic nested-Rust macro
injection rule. That keeps the outer Rust layer responsible for
token-level highlighting inside the macro body, which is enough to
correctly color JSON keys, string values, and booleans without
introducing a brittle JSON-specific injection for Rust token trees.
Manual test after the fix below :
[Screencast from 2026-04-29
00-53-01.webm](https://github.com/user-attachments/assets/26453acf-1d72-4a97-9969-3f8e236dc0cd)
## How to Review
- `crates/grammars/src/rust/injections.scm`: Start here. This is the
functional fix. The generic Rust macro injection rule now excludes
`json`, so `json!` and `serde_json::json!` bodies are no longer reparsed
as nested Rust. Existing special cases like `view!`, `html!`, `sql!`,
and regex-related behavior are left unchanged.
- `crates/language/src/syntax_map/syntax_map_tests.rs`: This adds a
regression test covering the reported case. It verifies that an empty
string inside `serde_json::json!({ ... })` does not break subsequent
highlighting, and that the expected string and boolean captures still
appear for the later JSON entries.
## 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 is consistent with the UI/UX checklist
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Fixed incorrect Rust syntax highlighting after empty string values
inside `json!` macros.
The join sounds get annoying in large meetings, let's not play it
anymore when the meeting get's really big. The guest joined sound is
plays regardless of group size so participants get a heads-up when
someone external joins.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- Improved join sound no longer plays in large meetings
This change gets rid of the tree traversal overhead by batching the
anchor resolution
> Create highlight endpoints/text_highlights/100
> time: [298.43 µs 298.55 µs 298.69 µs]
> Create highlight endpoints/text_highlights/100
> time: [40.347 µs 40.386 µs 40.427 µs]
> change: [-86.492% -86.481% -86.471%] (p = 0.00 < 0.05)
> Performance has improved.
This is especially important given that `CustomHighlightsChunks::seek`
tends to get called a lot, which re-creates highlight endpoints a lot.
Release Notes:
- N/A or Added/Fixed/Improved ...
Editor prepaint previously used the full parent content mask height when
deciding which rows to lay out, while only accounting for top clipping.
Embedded, content-sized editors in agent tool cards could therefore ask
the display map to highlight rows below the editor's visible
intersection with the list viewport. Compute the vertical intersection
between the editor bounds and the content mask instead, so highlighted
chunks and custom highlight endpoints are built only for rows that can
actually be painted.
Release Notes:
- N/A or Added/Fixed/Improved ...
Implements the previously-`unimplemented!()`
`TestPlatform::prompt_for_paths` so tests can drive the platform Open
dialog deterministically.
Adds `TestAppContext::simulate_path_prompt_response` and
`did_prompt_for_paths`, mirroring the existing `prompt_for_new_path`
test helpers (`simulate_new_path_selection`). The simulated response
validates that callers don't return multiple paths when
`PathPromptOptions::multiple` is false.
Release Notes:
- N/A
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Addresses https://github.com/zed-industries/zed/discussions/33773.
This changes git panel file activation so double-clicking or
secondary-opening a changed file opens a dedicated full-file diff tab
backed by a `SplittableEditor`.
The per-file diff reuses the project diff staging and restore controls,
respects the configured diff view style, and focuses an existing
per-file diff tab when one is already open instead of creating
duplicates.
Verified with `cargo run`.
Release Notes:
- Improved git panel file diff opening.
---------
Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
Self-Review Checklist:
- [X] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable
Release Notes:
- N/A
References
[FR-28](https://linear.app/zed-industries/issue/FR-28/task-modal-does-not-show-runnable-rust-test).
The bug this PR aims to fix is
> I can click the play button beside a rust test function, but it does
not show up in the task modal.
I wasn't able to reproduce it, but I suspect this was caused by the task
system preferring LSP code actions by default. It checked that an LSP
was queried for a task instead of checking if the queried LSP actually
returned any tasks. So the fix was just adding the below if statement as
a check.
```rust
if !new_lsp_tasks.is_empty() {
lsp_tasks
.entry(source_kind)
.or_insert_with(Vec::new)
.append(&mut new_lsp_tasks);
}
```
I also added a regression test for this
Self-Review Checklist:
- [x] I have reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the UI/UX checklist
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Fixed task modal failing to show language tasks in some cases
Adds `scheduler::spawn_dedicated_thread` (and inherent `spawn_dedicated`
methods on `PlatformScheduler` and `TestScheduler`) so single-threaded
actors that own `!Send` state can run on their own OS thread and freely
do blocking I/O without disturbing any other executor.
### Why
A single-threaded actor that needs to do blocking syscalls is currently
stuck: it can't run on the shared foreground executor (blocking would
stall every other foreground session), and it can't move to the
background pool because its state isn't `Send`. `spawn_dedicated` gives
each such actor its own thread and its own `LocalExecutor`, while still
participating in the same testable scheduler infrastructure as
everything else.
### Shape
- `pub fn spawn_dedicated_thread(session_id, scheduler, f) -> Task<_>`
in `scheduler`. Owns the OS thread, the per-session runnable channel,
and the `LocalExecutor` setup.
- Inherent `spawn_dedicated` on `PlatformScheduler` (allocates its own
`SessionId`, delegates to the free function).
- Inherent `spawn_dedicated` on `TestScheduler` (no real thread — runs
as a fresh local session driven by the test scheduler's run loop, so
determinism under `many` is preserved).
- Renames `Scheduler::schedule_foreground` → `schedule_local` and
`scheduler::ForegroundExecutor` → `scheduler::LocalExecutor` to reflect
that these are session-pinned queues rather than "the main thread" (a
dedicated session runs on its own thread). GPUI's wrapper
`gpui::ForegroundExecutor` and the `foreground_executor` field/method
names are unchanged to keep blast radius small.
- `LocalExecutor::new` now takes an explicit dispatch closure, so the
routing decision (default session, dedicated thread, or something else)
lives at the construction site.
### Tests
- `TestScheduler` side: round-trip, `!Send` future, `Send` closure
capturing shared state, inner `executor.spawn`, determinism under `many`
seeds, drop-cancels-future, detached child runs after root completes.
- `PlatformScheduler` side: real separate thread (blocking syscalls
don't stall the test), `!Send` future output, drop-cancels-future,
thread tears down after work completes, detached child outlives root.
cc @as-cii
Release Notes:
- N/A
---------
Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Now that customisation of this prompt was moved to `AGENTS.md`, we don't
want to load the customised prompt, and instead just use the default
prompt, so that we don't include the same instructions twice
Release Notes:
- git: Improve performance when generating git commit message with LLM
This updates our WebRTC configuration to enable gain normalization in
the
recording flow, which should help normalize the effective volume of
participants
in calls.
Release Notes:
- Added volume equalizations to participants in collab calls
Follow up to https://github.com/zed-industries/zed/pull/57632, uses
changes from https://github.com/zed-industries/zed/pull/58061
Previously the floating permission popover only appeared when the inline
permission prompt was scrolled below the viewport. It now also appears
when the prompt is scrolled above the viewport, with the scroll button
pointing in the right direction.
Release Notes:
- Fixed the agent permission popover not appearing when the inline
prompt was scrolled above the viewport.
Bumps the workspace `convert_case` dependency from 0.8 to 0.11 (already
in the tree) so the `zed` binary includes only one copy.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
Adds the handoff feature flag with staff disabled by default, giving the
rest of the auto-compaction stack a rollout gate without changing
behavior for users outside the flag.
Release Notes:
- N/A
In prep for handling the above-viewport case in
https://github.com/zed-industries/zed/pull/57632, which currently only
handles below case.
This PR adds `ListState::item_is_above_viewport` and
`ListState::item_is_below_viewport` methods, which report whether a
given list item is entirely outside the current viewport. Both return
`None` when the list has not measured enough layout to answer.
Release Notes:
- N/A
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable
Release Notes:
- N/A
cc @SomeoneToIgnore
## Summary
Follow-up to [this
comment](https://github.com/zed-industries/zed/discussions/55352#discussioncomment-16961889).
This extracts the buffer header and breadcrumb rendering helpers out of
`element.rs` into a `header.rs` and mouse related things to `mouse.rs`
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
## Summary
While profiling agent sessions that make a lot of `edit_file`
operations, I noticed the LSP `textDocument/didChange` handler firing
excessively. Looking into this, I found out that the streaming edit
pipeline was applying each `CharOperation` from `StreamingDiff` as its
own `buffer.edit` transaction, and every transaction emits a
`BufferEvent::Edited` event. Each event can trigger several other
expensive events depending on whether the buffer is being rendered in an
editor or is registered with a language.
For example, there are `didChange` LSP events, the editor's on edit work
(matching brackets, bracket colorization, code actions, outline), and
more. A single `edit_file` could trigger hundreds of these at the higher
end in a single synchronous app update, which would block the foreground
thread for a bit and cause Zed to drop frames.
I fixed this by collecting all of a chunk's `CharOperation`s and
applying them in one `buffer.edit` call, so only a single
`BufferEvent::Edited` event gets emitted. This is safe because
operations are non overlapping by design of streaming diff (the edit
cursor only advances).
## Why this wasn't caught earlier
The cost only fully appears when a buffer is both registered with a
language server and rendered in an editor. Without that, most of the per
transaction observers never run, so the existing `edit_file_tool`
benchmark (which ran the tool against a bare buffer) didn't surface it.
I reworked the benchmark to open the edited buffer in an editor view,
register a fake language server with per edit diagnostics, and lay out a
frame, so it exercises the same cascade as the real editor. I also added
a larger fixture.
## Results
Measured with the `release-fast` profile on the reworked benchmark:
| Fixture | Initial file | Before | After | Improvement |
| --- | --- | --- | --- | --- |
| `tiny_function_rewrite` | 1.4 KB | 31.1 ms | 12.1 ms | −61% |
| `small_function_rewrite` | 3.0 KB | 42.4 ms | 19.3 ms | −55% |
| `medium_many_small_changes` | 4.6 KB | 309.2 ms | 151.5 ms | −51% |
| `medium_insertions` | 4.6 KB | 171.8 ms | 126.1 ms | −27% |
| `large_multi_edit` | 44 KB | 9,549 ms | 919 ms | −90% |
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the UI/UX checklist
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Improved agent's edit file tool performance