6cbb3b9
agent: Don't render Markdown for file names in tool calls (#49668)
Click to expand commit body
Closes #44184
Closes #45729
Before (incorrect; __init__ is bold):
<img width="391" height="87" alt="image"
src="https://github.com/user-attachments/assets/f453dbf1-224f-49fe-9d94-d0d83ad68ac5"
/>
After (\_\_init\_\_ renders correctly):
<img width="385" height="80" alt="image"
src="https://github.com/user-attachments/assets/1f7892f1-559a-436b-bde1-00c5c3bce8de"
/>
Release Notes:
- Agent: Fix rendering of filenames in edit tool header
Kavi Bidlack
created
d94aa26
editor: Fix multi-line cursor expansion when multi-byte characters are involved (#51780)
Click to expand commit body
Closes #51740
The multi-line cursor expansion operates off of byte offsets, instead of
character offsets, so multi-byte characters like the umlaut cause the
multi-line cursors to be weirdly offset. To fix we just convert the
expansion logic to rely on utf16 characters instead of bytes.
before behavior:
https://github.com/user-attachments/assets/320e24e9-0fdd-4d16-a9e8-ca17c9e21ff2
after behavior:
https://github.com/user-attachments/assets/c4f0334b-dffc-4530-91ee-577b4fab75dd
+ test to verify functionality.
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- editor: fixed multi-line cursor expansion dealing with multi-byte
characters.
---------
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
Summary
Add a new grid_cols_max_content GPUI styling API that uses minmax(0,
max-content) for grid column sizing. This allows columns to
automatically size based on their content width while remaining
responsive when the container shrinks.
Applied the fix to both markdown preview (markdown_renderer.rs) and
agent panel (markdown.rs) table rendering. Table borders now wrap
tightly around content instead of stretching to full container width.
Fixes #50044
Approach
A new grid_cols_max_content API is added (as discussed with
@MikaylaMaki):
style.rs โ New grid_cols_max_content: Option<u16> field
styled.rs โ New .grid_cols_max_content(cols) builder method
taffy.rs โ New to_grid_repeat_max_content() using minmax(0, max-content)
markdown_renderer.rs โ Swapped .grid_cols() โ .grid_cols_max_content(),
moved border to grid div, wrapped in v_flex().items_start() so border
hugs content
markdown.rs โ Applied same fix for agent panel tables:
grid_cols_max_content, border on grid div, wrapped in
div().flex().flex_col().items_start() container
Screenshots
Before (equal-width columns, border stretches full width):
<img width="1386" height="890" alt="Screenshot 2026-03-06 at 2 17 54โฏPM"
src="https://github.com/user-attachments/assets/42cf76c4-6eba-4919-9b16-78c7fc823315"
/>
<img width="2555" height="1308" alt="original issue"
src="https://github.com/user-attachments/assets/22b0fc02-5203-48bb-8f03-7aa8255197cc"
/>
After โ Markdown Preview and Agent Panel
<img width="2554" height="1317" alt="Screenshot 2026-03-07 at 2 29
28โฏPM"
src="https://github.com/user-attachments/assets/8849988e-9ba8-4388-9c29-a255e0ecc52b"
/>
Before you mark this PR as ready for review, make sure that you have:
Added a solid test coverage and/or screenshots from doing manual testing
Done a self-review taking into account security and performance aspects
Aligned any UI changes with the UI checklist
Release Notes:
Fixed markdown table columns to use content-based auto-width instead of
equal-width distribution in both markdown preview and agent panel
(#50044).
---------
Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
Closes #48917
## Summary
- Stop sending `context.only` for generic `textDocument/codeAction`
requests.
- Keep explicit kind filtered requests unchanged.
- Add regression coverage for generic code action requests so actions
like `source.addTest` remain visible.
## Root Cause
`GetCodeActions::to_lsp` populated `context.only` even when the caller
requested all code actions (`kinds == None`). That turned the normal
code actions menu into a filtered request. With `gopls`, this filtered
out `source.addTest`, so `Add test for ...` never appeared.
## Verification
- `cargo fmt --all -- --check`
- `./script/clippy -p project`
- `cargo nextest run -p project --no-fail-fast --no-tests=warn`
- `cargo test -p editor
editor_tests::test_organize_imports_manual_trigger -- --exact`
- `cargo test -p editor
editor_tests::test_context_menus_hide_hover_popover -- --exact`
## Manual Testing
- Repro'd the protocol level behavior against `gopls`: unfiltered
requests return `source.addTest`, filtered requests excluding it do not.
- Opened `zed_guild/testing_projects/act/pkg/artifactcache/handler.go`
- Triggered `Show Code Actions` on `StartHandler`
- Confirmed `Add test for StartHandler` appears
Release Notes:
- Fixed Go `gopls` code actions so `Add test for ...` appears in the
generic code actions menu.
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
Used only for the sign in callback. I've made sure it still works as
expected with a local build.
Release Notes:
- N/A
Tom Houlรฉ
created
806a72c
title_bar: Prefer most specific repository for nested git repos (#51898)
Click to expand commit body
## Context
I have a project with a nested git repo inside a parent repo (separate
`.git` directory, not a submodule). The title bar shows the parent's
branch instead of the nested repo's own branch.
The issue is in `get_repository_for_worktree()` โ it iterates
`git_store.repositories()` (an `FxHashMap`) and returns the first
`starts_with` match. Both the parent and nested repo match, and
whichever one FxHashMap iterates first wins. There's no reason it should
be one or the other.
The fix already exists elsewhere in the codebase โ
`GitStore::repository_and_path_for_project_path()` at
`git_store.rs:1826` uses `.max_by_key()` to pick the most specific
(longest path) match. This PR applies the same approach to three
functions that have the same problem:
- `TitleBar::get_repository_for_worktree()` โ branch display in title
bar
- `resolve_active_repository()` in `git_ui` โ repository selection for
the git panel
- `get_branch_for_worktree()` in `recent_projects` โ branch display in
the project switcher
Two other locations use a similar `starts_with` pattern
(`effective_active_worktree()` in `title_bar.rs` and worktree selection
in `recent_projects.rs`) but those iterate worktrees against a single
known repo, not repos against a worktree โ so first-match and
longest-match give the same result. Left those unchanged.
Closes #7566
## How to Review
All three changes are the same transformation: first-match loop (or
`.find()`) โ `.filter().max_by_key()` on path length. The reference is
at `crates/project/src/git_store.rs:1826`.
The primary fix is `get_repository_for_worktree()` in `title_bar.rs`.
The other two are the same pattern.
One difference from the reference: I used `.as_os_str().len()` instead
of `.clone()` for the `max_by_key` key โ avoids cloning an `Arc<Path>`
per comparison. Among prefix-related paths (which is all that passes the
filter), the longer path is always the more specific match, so length
comparison is equivalent.
`title_bar` has no existing test infrastructure. Happy to add a test if
you'd like โ the setup would follow the pattern in
`test_git_traversal_with_nested_repos`
(`crates/project/tests/integration/git_store.rs`).
```
cargo test -p title_bar -p git_ui -p recent_projects
./script/clippy
```
## Self-Review Checklist
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Fixed branch picker showing parent repository's branch instead of the
nested repository's branch when working in submodules or nested git
repos.
---------
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Caio Raphael
,
Piotr Osiewicz
, and
Smit Barmase
created
bb769b9
markdown: Render checkboxes in markdown table cells (#50595)
Click to expand commit body
Render `[x]` and `[ ]` as checkbox widgets when they appear as the sole
content of a markdown table cell. Previously these were displayed as raw
text. List-item checkboxes were already rendered correctly; this extends
the same treatment to table cells.
Fixes #50045.
## What this does
- Table cells containing only `[x]`, `[X]`, or `[ ]` now render as
visual checkboxes instead of plain text
- Both markdown rendering paths are covered: the `markdown` crate (agent
panel, chat) and the `markdown_preview` crate (file preview)
- Checkboxes are display-only, matching the existing list-item checkbox
behavior
## How it works
pulldown-cmark splits `[x]` in table cells into three separate `Text`
events (`[`, `x`, `]`) rather than emitting a `TaskListMarker` event
(which only fires for list items per the GFM spec). The fix operates at
each crate's natural interception point:
- **`markdown` crate**: After all text events for a table cell have been
buffered, `replace_pending_checkbox()` checks the accumulated text
before the cell div is finalized. If it matches the checkbox pattern,
the pending text is replaced with a `Checkbox` widget.
- **`markdown_preview` crate**: In `render_markdown_text()`, text chunks
whose trimmed content matches the checkbox pattern are rendered as
`MarkdownCheckbox` widgets instead of `InteractiveText`.
## Scope
Three files, purely additive:
- `crates/markdown/src/markdown.rs` โ `replace_pending_checkbox()` on
builder, called at `TableCell` end
- `crates/markdown_preview/src/markdown_renderer.rs` โ checkbox
detection in `render_markdown_text()`
- `crates/markdown_preview/src/markdown_parser.rs` โ test only
No changes to parser data models, GPUI, or any shared infrastructure.
## What's not in scope
- **HTML `<input type="checkbox">`** โ pulldown-cmark strips these as
raw HTML. Supporting them requires HTML tag parsing, which is a separate
concern.
- **Interactive (click-to-toggle) checkboxes in tables** โ table
checkboxes are display-only. List-item checkboxes in Zed support
Cmd+click toggling, but extending that to table cells would require
tracking source ranges across the split parser events, which is a
separate enhancement.
## Follow-up
Table checkbox interactivity (Cmd+click toggle) is straightforward to
add as a follow-up โ the source ranges are already available in
`markdown_preview`, and the `markdown` crate would need minor callback
plumbing.
## Screenshots
**Markdown checkbox before**
<img width="1603" height="863" alt="md-checkbox-before-1"
src="https://github.com/user-attachments/assets/8539d79d-c74f-4d14-a3e5-525e4d0083aa"
/>
<img width="1599" height="892" alt="md-checkbox-before-2"
src="https://github.com/user-attachments/assets/7badfab1-651f-4fab-8879-deb109c56670"
/>
**Markdown checkbox after**
<img width="1832" height="889" alt="md-checkbox-after-1"
src="https://github.com/user-attachments/assets/463b6334-9f50-41c0-ab7e-24d238244873"
/>
<img width="1795" height="886" alt="md-checkbox-after-2"
src="https://github.com/user-attachments/assets/57d3d9de-1d23-42ba-bc0a-5aa0c699b13d"
/>
## Test plan
**Unit tests** (2 new):
- `test_table_with_checkboxes` (markdown_preview) โ parser delivers
`[x]`/`[ ]` text into table cell structures
- `test_table_checkbox_detection` (markdown) โ parser events accumulate
checkbox text in table cells, confirming `replace_pending_checkbox`
detection logic
**Automated**:
- [x] `cargo test -p markdown` โ 27 tests pass (26 existing + 1 new)
- [x] `cargo test -p markdown_preview` โ 61 tests pass (60 existing + 1
new)
**Manual** (verified against `test-checkbox-table.md`):
- [x] Basic `[x]`/`[ ]` in a status column
- [x] Checkbox-only column alongside text
- [x] Multiple checkbox columns in one table
- [x] Left, center, and right column alignments
- [x] Uppercase `[X]` variant
- [x] Leading/trailing whitespace in cell
- [x] Checkboxes alongside other inline elements (links, bold text)
- [x] Single-column and minimal two-column tables
- [x] Normal table text unaffected by detection
- [x] List checkboxes still render correctly (regression)
- [x] Agent panel: asked agent to output table with checkbox columns
Release Notes:
- Fixed `[x]` and `[ ]` checkboxes not rendering in markdown table cells
(#50045)
iam-liam
created
945f642
bedrock: Make thinking toggle toggle thinking (#50673)
Click to expand commit body
Release Notes:
- Support for Native Thinking toggle instead of model variants
---------
Co-authored-by: Ona <no-reply@ona.com>
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Co-authored-by: Marshall Bowers <git@maxdeviant.com>
Shardul Vaidya
,
Ona
,
Bennet Bo Fenner
, and
Marshall Bowers
created
2e11564
helix: Fix pasting from the system clipboard (#51703)
Click to expand commit body
Closes #51693
Helix was unable to paste from the system clipboard, ex: `vim: paste`
would work but `helix: paste` would not work. Helix paste was silently
requiring the content it was going to paste to have selection metadata
exist, and just silently fail if it didn't, and the system clipboard
doesn't have that metadata. note: this is not necessarily for parity
with helix, as helix didn't seem to support this either in my testing,
but rather parity with the other parts of zed, editor mode and vim mode.
single-line paste:
https://github.com/user-attachments/assets/c8696032-d265-4025-9c4c-a8c35dfd2529
multi-line paste:
https://github.com/user-attachments/assets/4bf96033-e13d-4ec1-8a7e-8c56bbc12b94
I also added a new test verifying the behavior.
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- helix: fixed helix paste not pasting from system clipboard.
Finn Eitreim
created
e5dc2f0
search: Fix replace all being silently dropped (#50852)
Click to expand commit body
Fixes #50848
### Problem
When Replace All was triggered with a stale search query (i.e., the
query text had changed since the last completed search), the old code
ould restart the search and immediately return, silently discarding the
replace-all intent. This caused the Replace All action to appear to do
nothing on the first try, only working on subsequent attempts once
results were already loaded.
### Fix :
Fix this by introducing a `pending_replace_all` flag on
ProjectSearchView. When Replace All is invoked while a search is in
flight or the query is stale, the flag is set and the action is
deferred.
Once the search completes and `entity_changed` is called, the flag is
checked and `replace_all` is automatically dispatched.
Also disable the Replace Next button in the UI while a search is
underway, since it cannot meaningfully act without up-to-date results.
### Release Notes:
- Fixed "Replace All" in project search not working on the first attempt
when the search query was changed or results hadn't loaded yet.
Closes #50524
When a file is deleted while project search results are displayed, the
deleted file's buffer was kept alive by the search multibuffer and would
reappear on re-search.
**Root cause:** `Search::into_handle()` treated buffers without a
`project_entry_id()` (which happens when `DiskState::Deleted`) as
"unnamed buffers" and fed them
directly into the search pipeline. The multibuffer's strong
`Entity<Buffer>` reference kept the buffer alive.
**Fix:**
- Filter deleted-file buffers from search candidates in `into_handle()`
and `all_loaded_buffers()`
- Subscribe to `FileHandleChanged` events on the search multibuffer to
proactively remove deleted files from existing results
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
### Video:
https://drive.google.com/file/d/1pEz6JywFcZlz8aiXbLOxIdj84SQWLIiF/view?usp=sharing
Release Notes:
- Fixed deleted files persisting in project search results
## Context
Unread indicators would not show up for threads running inside a git
worktree
## Self-Review Checklist
<!-- Check before requesting review: -->
- [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
Bennet Bo Fenner
created
4db5666
editor: Open a singleton buffer when go to action results fit into a single excerpt (#51461)
Click to expand commit body
Closes https://github.com/zed-industries/zed/issues/44203
Release Notes:
- Go to definition (and similar actions) will now no longer open a multi
buffer if there are multiple results that all fit into a single excerpt
## Context
We're seeing issues where large edits (think generated, agentically or
otherwise) or edits in files with very large lines cause ep requests to
fail until they are flushed from the history due to the request body
exceeding the endpoint size limit. These edits are large enough they
would be omitted from the final prompt anyway due to budgeting so it is
safe to drop them client side.
## How to Review
<!-- Help reviewers focus their attention:
- For small PRs: note what to focus on (e.g., "error handling in
foo.rs")
- For large PRs (>400 LOC): provide a guided tour โ numbered list of
files/commits to read in order. (The `large-pr` label is applied
automatically.)
- See the review process guidelines for comment conventions -->
## Self-Review Checklist
<!-- Check before requesting review: -->
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Fixed an issue where large changes to buffers, or edits in buffers
with extremely long lines would cause edit prediction requests to fail
Ben Kunkle
created
1bca0c5
git: Use the real gitdir for checkpoints (#51563)
Click to expand commit body
## Summary
Zed's git checkpoint code was assuming that repository-local metadata
always lives under `<working-directory>/.git/...`.
That assumption breaks for repositories where `.git` is a file instead
of a directory, most notably:
- git submodules
- git worktrees
In those layouts, `.git` contains a `gitdir: ...` pointer to the real
git directory. When checkpoint creation or restore tries to build paths
like `.git/index-<uuid>.tmp` or `.git/info/exclude`, those path
operations fail with `Not a directory (os error 20)`.
In practice, that shows up as checkpoint failures in ACP threads for
worktrees and submodules.
## Root Cause
`GitBinary` tracked the repository working directory, but it did not
track the resolved git directory.
As a result, checkpoint-related helpers derived temporary index and
exclude paths from the working tree:
- temp index path creation
- copying the default index into the temp index
- exclude override handling
That works for a plain repository where `.git` is a directory, but not
when `.git` is a pointer file.
## Changes
- Thread the resolved git directory from `RealGitRepository::path()`
into `GitBinary`.
- Add a dedicated `git_directory` field to `GitBinary`.
- Use `git_directory` instead of `<working-directory>/.git` for:
- temp index file paths
- copying the default `index`
- `info/exclude` override paths
- Keep the working directory unchanged for command execution; only
metadata path resolution changes.
- Add a regression test that verifies temp index files are created under
the real gitdir, not under `<working-directory>/.git`.
## Why this approach
The minimal correct fix is to distinguish between:
- the working directory used to run git commands, and
- the actual git directory used to store repository metadata
Git itself already makes that distinction, and
`git2::Repository::path()` gives us the resolved gitdir directly.
Reusing that value keeps the fix small and avoids special-casing
submodules or worktrees elsewhere.
## User-visible impact
Before this change, checkpoint operations could fail in repositories
where `.git` is not a directory, producing errors like:
Not a directory (os error 20)
After this change, checkpoint-related git metadata is read and written
from the real gitdir, so ACP checkpoints work in submodules and
worktrees the same way they do in regular repositories.
## Testing
- `cargo fmt -p git`
- `cargo test -p git --lib`
- `cargo clippy -p git --lib --tests -- -D warnings`
Added regression coverage:
- `test_path_for_index_id_uses_real_git_directory`
If you want, I can also compress this into a more GitHub-PR-native
version with sections like `## Problem`, `## Fix`, and `## Validation`.
Release Notes
- Fixed `.git` handling when `.git` is a file instead of directory, e.g.
when using worktrees or submodules.
Stefan Junker
created
d934ba6
sidebar: Add some small design tweaks (#51936)
Click to expand commit body
- [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
Danilo Leal
created
735eb43
editor: Fix folding for unindented multiline strings and comments (#50049)
Click to expand commit body
Closes #5057
## Summary
The indent-based code fold detection does not account for lines inside
multiline strings or block comments that have less indentation than the
surrounding code. This causes the fold scanner to think the enclosing
block ends prematurely.
For example, folding `fn main()` here would fail because the raw string
content at indent level 0 gets treated as the end of the function body:
``` rust
fn main() {
let s = r#"
unindented content
"#;
}
```
This PR checks whether a low-indent line falls inside a string or
comment override region and skips it if so. This works across all
languages that define `@string` or `@comment` overrides in their
`overrides.scm`.
## Before
https://github.com/user-attachments/assets/a08e6bf8-4f25-4211-8a46-8f6da7e49247
## After
https://github.com/user-attachments/assets/cd5b36db-6d4d-420b-9d60-79f9fad8638e
## Test Plan
- Added `test_fold_with_unindented_multiline_raw_string`
- Added `test_fold_with_unindented_multiline_block_comment`
- All existing fold tests pass
- Manually tested both Rust and Python examples
Release Notes:
- Fixed code folding incorrectly collapsing when multiline strings or
block comments contained unindented content
Ryan Walker
created
e5150ab
editor: Place cursor at clicked column when clicking sticky headers (#51911)
Click to expand commit body
When clicking on a sticky header line, the cursor is now placed at the
column corresponding to the click position, rather than always at the
start of the outline item's range. The hover cursor is also changed from
a pointing hand to an I-beam to reflect that clicking behaves like
clicking in normal editor text.
Release Notes:
- Clicking a sticky header now puts the cursor at the clicked column
## Context
This allows using of Rodio's effects library within our home brewn audio
pipeline. The alternative would be inlining Rodio's effects which is
problematic from a legal stance. We would then have to make clear that
code is not owned by zed-industries while the code would be surrounded
by zed-industries owned code.
This adaptor does incur a slight performance penalty (copying into a
pre-allocated vec and back) however the impact will be immeasurably low.
There is no latency impact.
## How to Review
- Adds an adapter for Rodio effects
- Enables the adapter and effects only when the setting is enabled
-Makes the setting pub(crate) so we can use it from livekit playback
## 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:
- Added Automatic volume control to calls
Yara ๐ณ๏ธโโง๏ธ
created
09b0388
Maintain cache in `ThreadMetadataStore` (#51923)
Click to expand commit body
## Context
This makes it so that we maintain a cached state on the thread metadata
store itself, rather than storing it at other locations. Which is
similar to how `ThreadStore` works.
## How to Review
## Self-Review Checklist
<!-- Check before requesting review: -->
- [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
Bennet Bo Fenner
created
818a07d
agent_ui: Remove unnecessary spawn in thread archive (#51931)
Click to expand commit body
## Context
Unused after #51930
## Self-Review Checklist
<!-- Check before requesting review: -->
- [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
Follow up to #51809
Without it, ep_cli panics when initializing headless Zed.
Release Notes:
- N/A
Oleksiy Syvokon
created
d09b335
sidebar: Fix sidebar and archive view content display (#51930)
Click to expand commit body
- Don't filter out what we show in the archive view; unconditionally
display archived threads for all sessions
- Ensure we refresh sidebar content on startup
---
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
---------
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Co-authored-by: cameron <cameron.studdstreet@gmail.com>
Danilo Leal
,
Ben Brandt
,
Bennet Bo Fenner
, and
cameron
created
4f5596f
Fix the inability to click the highlight tree view (#51927)
## Context
Shouldn't have been committed in the first place.
## Self-Review Checklist
<!-- Check before requesting review: -->
- [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
Ben Brandt
created
99d51a4
agent_ui: Fix thread archive and agent panel for empty window threads (#51924)
Click to expand commit body
This PR ensures threads created on an empty window (i.e., no
paths/worktrees associated with it) can still be displayed in the thread
archive view. They can't be unarchived, though, as we don't know where
we'd insert it, even if we had a project on the window. Lastly, I'm also
hiding the "current worktree"/"new git worktree" menu from the agent
panel if we don't have any paths as those options don't make sense in
this case.
- [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
## Context
User keybindings using `action::Sequence` (e.g., mapping Escape in
insert mode
to a sequence of `vim::NormalBefore` + another action) don't work in the
RulesLibrary window. The `ActionSequence` handler is only registered on
the
`Workspace` view, but the RulesLibrary opens as a separate window
without a
Workspace in its element tree, so the action has no handler and fails to
dispatch.
This adds the `ActionSequence` handler to the RulesLibrary root element,
matching the same pattern used in Workspace.
Closes #51721
## How to Review
Small PR โ single file change in
`crates/rules_library/src/rules_library.rs`.
Focus on the new `.on_action()` for `ActionSequence` in the `Render`
impl.
## 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](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Fixed `action::Sequence` keybindings not working in the Rules Library
window
## Video:
https://github.com/user-attachments/assets/c6189a77-cdec-461a-8dc5-be066f14b385
Joรฃo Soares
created
9a2ed29
agent_ui: Fix panic in message editor (#51918)
Click to expand commit body
## Context
Fixes ZED-59M
We could end panicking because of a double lease in message editor. This
could happen when pasting text and this line was executed:
`PromptCompletion::try_parse(line, offset_to_line,
&self.source.supported_modes(cx))`
Since self.source is the Entity<MessageEditor> in this case, we will try
to read message editor while it's being updated.
I took this as an opportunity to refactor `prompt_capabilities` and
`available_commands` which were both passed around as Rc<RefCell<...>>.
Now we have a single struct called `SessionCapabilities` which maintains
both and we pass that around wrapped in an `Arc<RwLock<...>>`
(`SharedSessionCapabilities`)
## Self-Review Checklist
<!-- Check before requesting review: -->
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Fixed a crash when pasting text into the prompt editor in the agent
panel
Bennet Bo Fenner
created
7c21f5f
message_editor: Fix image file copied from external files paste inserting filepath text alongside image (#51575)
Click to expand commit body
What
---
Fix pasting image files copied from Finder in the Agent Panel on macOS.
Previously, pasting an image file copied with `Cmd+C` in Finder would
insert the file path as plain text instead of attaching the image as
context.
Why
---
Two bugs combined to cause this:
1. **Wrong clipboard type priority in `pasteboard.rs` (fixed in
#49367):** ~~The macOS pasteboard reader checked
`public.utf8-plain-text` first. When Finder copies a file it places the
filename as a string, the file path in `NSFilenamesPboardType`, and a
TIFF of the file icon โ all in the same clipboard event. Because strings
were checked first, Zed read the filename string and ignored the image
data entirely.~~
2. **Missing `cx.stop_propagation()` in `message_editor.rs`:** The
`paste()` handler is registered as a `capture_action`. In GPUI's capture
phase, `propagate_event` defaults to `true` โ simply `return`ing does
not stop propagation. Without an explicit `cx.stop_propagation()`, the
inner `Editor`'s bubble-phase paste handler also fired, read
`ExternalPaths` from the clipboard, converted it to text via
`ClipboardItem::text()` (which returns the file path string), and
inserted it alongside the image.
Fix
---
gpui_macos/src/pasteboard.rs`: Change clipboard read priority to **file
paths โ image data โ string**. Added `read_external_paths()` which reads
`NSFilenamesPboardType` and returns a `ClipboardEntry::ExternalPaths`.
This lets the existing `paste_images_as_context` path load the actual
file content.
- `agent_ui/src/message_editor.rs`: Add `cx.stop_propagation()` before
`task.detach()` when the image paste task is accepted, preventing the
inner editor from also handling the event.
Closes #51574
Test Plan
---
- [x] `cargo fmt --all -- --check`
- [x] `cargo build -p gpui_macos agent_ui` compiles clean
- [x] Manual verification of:
- [x] Copy an image file in Finder (`Cmd+C`), paste into Agent Panel โ
image attaches correctly
- [x] Copy image from browser ("Copy Image"), paste into Agent Panel โ
image attaches correctly
- [x] `Cmd+Shift+4` screenshot paste still works
- [x] Regular text paste still works
Release Notes
- Fixed pasting image files copied from Finder inserting the file path
instead of attaching the image in the Agent Panel
Screenshots
---
https://github.com/user-attachments/assets/edf6ba5a-6ff7-478c-a9ed-7cb5e889ccb3
<img width="801" height="388" alt="image"
src="https://github.com/user-attachments/assets/32d9321b-b0f6-47ae-a6b3-ea343cb69757"
/>
Suphachai Phetthamrong
created
b9beb94
sidebar: Move toggle to the status bar instead (#51916)
Click to expand commit body
- [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
Danilo Leal
created
a30e4d5
language_model: Clear the LlmApiToken first on org switch (#51826)
Click to expand commit body
When we switch organizations, we try and refresh the token. If the token
refresh fails, we are left with the old LlmApiToken, which is for the
wrong organization. In this commit, we make sure to clear the old token
before trying a refresh on organization switch.
Release Notes:
- N/A
---------
Co-authored-by: Neel <neel@zed.dev>
Tom Houlรฉ
and
Neel
created
8909ede
Add two guild members to github action (#51914)
Click to expand commit body
This PR is similar to this one:
https://github.com/zed-industries/zed/pull/51753
Release Notes:
- N/A
esthertrapadoux
created
5b104de
gpui: Fix macOS font render clipped bug again (#47001)
Click to expand commit body
Continue #45957 #46906 to fix font render issue again.
Release Notes:
- Fixed macOS font render clipped bug when use `.SystemUIFont`.
| .SystemUIFont | .ZedMono |
| --- | --- |
| <img width="1034" height="978" alt="image"
src="https://github.com/user-attachments/assets/96b815a1-9484-4a38-8391-a4af3db51a36"
/> | <img width="1034" height="978" alt="image"
src="https://github.com/user-attachments/assets/1aaece42-9acd-47b0-a0a0-3cb425f40301"
/> |
```bash
cargo run -p gpui --example text
```
Test in Zed with `.ZedMono` font:
<img width="815" height="844" alt="image"
src="https://github.com/user-attachments/assets/1e44d186-cee5-4f54-910a-4c4602ca010e"
/>
With `.ZedSans`:
<img width="815" height="844" alt="image"
src="https://github.com/user-attachments/assets/1e502f3e-794c-4082-9faf-5a920adc1214"
/>
`Monaco`:
<img width="815" height="844" alt="image"
src="https://github.com/user-attachments/assets/906a3fd2-715a-4f53-b6fe-4614f4c6edab"
/>
`Menlo`:
<img width="815" height="844" alt="image"
src="https://github.com/user-attachments/assets/a8f8c302-2083-477c-ae72-f6e5c7f91d00"
/>
Jason Lee
created
ec872ca
Rename `ThreadMetadataStore` to `SidebarThreadMetadataStore ` (#51913)
Click to expand commit body
## Context
Renamed ThreadMetadataStore to SidebarThreadMetadataStore.
There was some confusion yesterday on what metadata should be stored in
`ThreadMetadataStore.
Only threads that should show up in the sidebar should be stored here
(effectively all non-archived ones). Hopefully the rename + doc comment
added makes this clearer.
Unfortunately we cannot move it into the sidebar crate since we need it
in the archived history view too.
## How to Review
This is purely a cosmetical change
## 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
## Context
This PR cleans up all the sidebar impl, from the over use of agentic
tools, without regard for the sidebar's construction.
## How to Review
This PR fixes the following problems:
- Overuse of inter-event guards and state management around focus state.
Simplified to just `focused_thread `, a derived value from the current
active agent panel and thread. UI can optimistically set this value for
threads that haven't been loaded yet, and it won't be unset by
`update_entries`
- Mixing data fetching and re-derivation. `update_entries` should not be
fetching the list of threads. Rather, that list should be pulled from
the threads meta data, cached on the sidebar, and then used to compute
the new state
- Similarly, removed logical state mutation from `update_entries`. It's
job is to compile the new UI state from it's data sources, not to move
selection state around. Do that elsewhere.
- The Archive pointer should be stored in the active view enum, rather
than spread across two fields
- Finally, update_entries did several linear passes over the list of
threads in a row, I had claude consolidate these passes and am relying
on our extensive test coverage to keep it functioning. If this breaks
something you built, _put that in a test_.
## Self-Review Checklist
<!-- Check before requesting review: -->
- [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
Mikayla Maki
created
a9a85e5
Use `-e` instead of `-c` when getting environment from nushell (#51420)
Click to expand commit body
Closes #38200
Applied
[suggestion](https://github.com/zed-industries/zed/issues/38200#issuecomment-3354159899)
from issue to use `-l -e` instead of `-l -i -c` when running on nushell
because of how it treats `-l` as implying interactive session. Using
`-e` also means that command needs to end with `exit` to terminate shell
manually. With this changes everything now works fine in my testing.
Before, zed fails to load environment variables and there is error in
logs:
<img width="367" height="92" alt="image"
src="https://github.com/user-attachments/assets/9ef08d06-a509-4c96-85fe-8291bfc95b39"
/>
<img width="1711" height="115" alt="image"
src="https://github.com/user-attachments/assets/fe3a6248-6f73-4773-a2c8-db55a95aaec1"
/>
With this patch everything works fine and all language servers and stuff
loads fine:
<img width="565" height="73" alt="image"
src="https://github.com/user-attachments/assets/7477913d-42f9-41b0-a7b6-92831f406be4"
/>
Tested on nixos unstable. Nushell version 0.110.0 and 0.111.0. Zed
version 0.223.3+stable and compiled from main fail. Zed from this branch
works.
Release Notes:
- Fixed loading environment variables when nushell is used as shell
Artemiy
created
0698ecc
Save edited buffers before running a task (#48861)
Click to expand commit body
Save edited buffers before running a task
Introduces a new task field for configuring which buffers are saved. For
now, this defaults to saving all buffers, but in the future we could
have a global task template to configure this setting for dynamically
created tasks.
Needed for #10251.
Release Notes:
- Edited buffers are now saved before running a task. This can be
configured with the new "save" field in `tasks.json`.
---------
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
## Self-Review Checklist
<!-- Check before requesting review: -->
- [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
Danilo Leal
created
22f3d06
gpui_wgpu: Release surface resources during destroy (#51561)
Click to expand commit body
## Summary
Implements the fix proposed by @israelrios in
https://github.com/zed-industries/zed/issues/50269#issuecomment-4049006746.
The issue comment narrowed the hang down to X11 window teardown:
- when the Settings window is closed on X11, the UI thread can stall
while `WgpuRenderer` is dropped during final `X11WindowState` teardown
- at that point, the X11 window has already been destroyed
- the proposed fix is to make `WgpuRenderer::destroy()` release
surface-bound GPU resources eagerly so the native window is destroyed
only after the `wgpu::Surface` and related resources are gone
This PR applies that change in `crates/gpui_wgpu/src/wgpu_renderer.rs`
by calling `self.resources.take()` inside `destroy()`.
## Validation
I confirmed this fix locally on Linux Mint 21.3 Cinnamon by applying it
to the `v0.227.1` build:
- opening and closing Settings no longer causes the main window to hang
## References
- Refs #50269
- Original analysis and fix proposal by @israelrios:
https://github.com/zed-industries/zed/issues/50269#issuecomment-4049006746
Release Notes:
- Fixed a Linux/X11 issue where closing the Settings window could cause
Zed to hang.
Closes #48922
When the editor regains focus, it internally triggers the mouse_moved
logic again. This causes the hover documentation to be shown even if it
was previously dismissed due to user editing.
This change skips mouse_moved handling when the cursor is hidden,
preventing unintended tooltip popups.
[ๅฝๅฑ 2026-02-11
19-04-14.webm](https://github.com/user-attachments/assets/ea9f9438-34bf-4771-bbc8-335e9ea59dd7)
- [x] Tests or screenshots needed?
- [x] Code Reviewed
- [x] Manual QA
Release Notes:
- Fixed documentation tooltip reappearing after editor regains focus
feeiyu
created
19c8363
editor: Fix crash from stale state after prepaint depth exhaustion (#49664)
Click to expand commit body
Closes #49662
## Summary
Fixes an index-out-of-bounds crash in `EditorElement::prepaint` that
occurs when block decorations oscillate in size, exhausting the
recursive prepaint budget (`MAX_PREPAINT_DEPTH = 5`).
## Root cause
When block decorations resize during `render_blocks`, prepaint recurses
to rebuild layout state. Previously, both `resize_blocks()` and
`update_renderer_widths()` mutated the display map **before** checking
`can_prepaint()`. At max depth:
1. `resize_blocks()` mutated the block map, changing the display row
mapping
2. `can_prepaint()` returned false, skipping the recursive rebuild
3. All local state (`snapshot`, `start_row`, `end_row`, `line_layouts`,
`row_infos`) remained stale
4. Downstream code โ particularly `layout_inline_diagnostics` which
takes a **fresh** `editor.snapshot()` โ would see the new row mapping
but index into the stale `line_layouts`
5. `row.minus(start_row)` produced an index exceeding
`line_layouts.len()` โ panic
The crash is most likely to occur when many block decorations appear or
resize simultaneously (e.g., unfolding a folder containing many git
repos, causing a burst of diff hunk blocks), or when `place_near` blocks
oscillate between inline (height=0) and block (height>=1) mode, burning
through all 5 recursion levels without converging.
## Fix
Guard both mutation sites with `can_prepaint()` so the display map is
NOT mutated when we cannot recurse to rebuild state:
- **Block resize**: move `resize_blocks()` inside the `can_prepaint()`
guard. At max depth, defer the resize to the next frame via
`cx.notify()`. The resize will be re-detected because the stored height
still mismatches the rendered height.
https://github.com/jean-humann/zed/blob/021978ecf939723a6ba4ab9843572b6bcefe7cb7/crates/editor/src/element.rs#L10207-L10239
- **Renderer widths**: short-circuit `update_renderer_widths()` with
`can_prepaint()` so fold widths are not updated at max depth.
https://github.com/jean-humann/zed/blob/021978ecf939723a6ba4ab9843572b6bcefe7cb7/crates/editor/src/element.rs#L10097-L10115
In both cases the next frame starts with a fresh recursion budget
(`EditorRequestLayoutState::default()` resets `prepaint_depth` to 0) and
applies the deferred changes normally. The worst case is one frame of
slightly wrong-sized blocks โ vastly preferable to a crash.
## Test plan
- [x] `cargo check -p editor` passes
- [ ] Manual testing with many open files, inline diagnostics, hover
popovers, and git diff hunks
Release Notes:
- Fixed a crash (index out of bounds) during editor rendering when block
decorations repeatedly resize, exhausting the recursive prepaint budget.
๐ค Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Jean Humann
,
Claude Opus 4.6 (1M context)
, and
Smit Barmase
created
927cc30
project_panel: Fix appending copy marker for directory at wrong position (#48845)
Click to expand commit body
Closes #48765
Release Notes:
- Fixed appends copy marker for copied file in the wrong position of
filename
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
This release includes the OpenGL fixes which were sent upstream.
Release Notes:
- N/A
John Tur
created
b3282d9
Fix PR size check failing on fork PRs (#51902)
Click to expand commit body
Follow-up https://github.com/zed-industries/zed/pull/51876
Use `pull_request_target` for PR size check so the workflow has write
permissions to manage labels on fork PRs. Safe since we don't execute
any PR code here.
Failing example:
https://github.com/zed-industries/zed/actions/runs/23282504031/job/67698793729?pr=48845
Release Notes:
- N/A
Smit Barmase
created
08d7810
gpui_linux: Set _NET_WM_NAME during X11 window creation (#51899)
Click to expand commit body
#### Context
On X11, the Settings window title displayed as `"Zed รขโโ Settings"`
instead of "Zed โ Settings"`. The em-dash (U+2014) was garbled because
the window creation path only set the legacy `WM_NAME` property (Latin-1
encoded), but never set `_NET_WM_NAME` (UTF-8). Modern taskbars prefer
`_NET_WM_NAME`, so without it they fell back to `WM_NAME` and
misinterpreted the UTF-8 bytes as Latin-1.
`set_title()` already sets both properties, which is why windows that
update their title after creation (like the main workspace) were
unaffected.
The fix adds `_NET_WM_NAME` during window creation, matching what
`set_title()` already does.
#### Closes #51871
#### How to Review
Single change in `crates/gpui_linux/src/linux/x11/window.rs` focus on
the new `_NET_WM_NAME` property being set alongside the existing
`WM_NAME` in `X11Window::new`.
#### 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](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
#### Video
[Screencast from 2026-03-19
11-19-45.webm](https://github.com/user-attachments/assets/ff810e37-90ac-4ce2-a8f5-ad83e66aa3b8)
Release Notes:
- Fixed garbled characters in window titles on Linux X11 (e.g., Settings
window)
This seems to work better outside of just Opus. Initial experiments look
promising, going to test internally for a bit as well.
Release Notes:
- N/A
Ben Brandt
created
2aa3666
Improve clipboard support on Windows (#51807)
Click to expand commit body
- Simplify and improve Windows clipboard handler.
- Fixed components that weren't handling multiple formats on the
clipboard properly.
Closes https://github.com/zed-industries/zed/issues/51278
Release Notes:
- windows: Fixed an issue where text copied from Office applications
couldn't be pasted into Zed.
John Tur
created
54ebf32
sidebar: Add another round of UX refinements (#51884)
Danilo Leal
created
e0acae2
auto_update: Improve Linux rsync hinting (#50637)
Click to expand commit body
Previously, automatic checks could fail quietly and return to idle. This
change ensures missing dependency errors are surfaced in the update UI
with install guidance.
What Changed:
- Added a dedicated `MissingDependencyError` for dependency-related
update failures.
- Updated auto-update polling behavior so:
- automatic checks still stay quiet for transient/general errors,
- but missing dependency errors are surfaced as
`AutoUpdateStatus::Errored`.
- Improved Linux dependency hinting:
- distro checks with `/etc/os-release`,
- returns distro-appropriate install hints where possible and falls back
to a generic package-manager message when distro parsing is
unavailable/unknown.
<img width="610" height="145" alt="image"
src="https://github.com/user-attachments/assets/8bef3970-38ba-4412-9ece-7b6bb6bf903b"
/>
Closes #47552
- [x] Done a self-review taking into account security and performance
aspects
Release Notes:
- Improved Linux auto-update failure issue caused by missing `rsync` by
surfacing actionable install guidance in the update UI.
### Fixes #31865
### Problem
When navigating a picker (command palette, file finder, etc.) with the
keyboard and then hovering with the mouse, two items would appear
highlighted at the same time - one from the keyboard selection
ghost_element_selected background and one from the CSS style
ghost_element_hover background. This happened because GPUI's CSS hover
is applied at paint time independently from the Rust selection state.
### Solution
Added a keyboard_navigated: bool flag to [Picker] to track whether the
last navigation was via keyboard or mouse.
When a keyboard navigation action fires (โ, โ, Home, End, etc.),
`keyboard_navigated` is set to true. A transparent
`block_mouse_except_scroll` overlay div is added on top of each list
item, preventing the CSS style from firing on `ListItem` children.
When the mouse moves over any item, the overlay's `on_mouse_move`
handler fires, clears keyboard_navigated, moves the selection to that
item, and re-renders - removing all overlays and restoring normal mouse
hover behavior.
The `on_hover` handler also moves the selection to whichever item the
mouse enters, so mouse navigation is fully functional.
Clicks work through the overlay since `block_mouse_except_scroll` only
affects hover hit-testing, not click events on the parent div.
### Behavior
Matches VS Code / IntelliJ โ keyboard navigation suppresses hover
highlights until the mouse moves, at which point normal hover resumes.
Only one item is ever highlighted at a time.
### Video
[Screencast from 2026-03-05
19-20-16.webm](https://github.com/user-attachments/assets/7a8a543a-95f3-481f-b59d-171604e5f883)
---------
Co-authored-by: Nathan Sobo <nathan@zed.dev>