# Objective
When developing remotely, when I close the uncommitted changes tab, I
need some time to load before I can copy the path. Or have to switch to
the project panel to find the specific file. All of this is annoying, so
I added a copy path action to the git panel's context menu and key
bindings consistent with the project panel.
## Solution
Already described in the Objective section.
## Testing
I wrote a unit test and tested it manually.
## 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
<img width="411" height="535" alt="showcase"
src="https://github.com/user-attachments/assets/a17e7633-eb92-4737-aa30-958fe58bb99f"
/>
<img width="717" height="427" alt="showcase"
src="https://github.com/user-attachments/assets/d067e892-17de-4527-ac20-16cad6f38015"
/>
---
Release Notes:
- Added "Copy Path" and "Copy Relative Path" actions to the Git Panel's
context menu
The hosted-model reference now includes Claude Opus 5. This closes the
gap between the public documentation and the models that `cloud`
currently offers to Zed Pro and Zed Business customers.
The pricing table lists the provider price and Zed price for input,
output, cache-write, and cache-read tokens. The context-window table
lists the current 1M-token hosted limit. This change does not alter
model access or billing behavior.
Testing performed:
- `cd docs && npx prettier --check src/account/zed-hosted-models.md`
- `cd docs && mdbook build`
Release Notes:
- N/A
GPUI's input-latency histograms only sample frames that were preceded by
input, so a window that janks while animating or while streaming content
(agent panel output, terminal scrollback) never shows up in the fleet's
latency reports. Hang detection catches outright stalls, but frames that
are merely late — stutters in the 30–100ms range during animation —
currently aren't visible anywhere.
This adds a `frame-duration-histogram` feature to GPUI with a per-window
tracker recording two histograms: the duration of every `Window::draw`,
and the interval between consecutively presented frames while the window
is animating (a next-frame callback was already scheduled at the
previous present, so frames are being produced back-to-back and a
stretched interval means frames were missed). Intervals are only
recorded for active windows, since inactive windows are deliberately
throttled to a lower frame rate, and re-presents of unchanged frames
(e.g. sustaining the display's refresh rate during high-rate input) are
excluded. Zed enables the feature and reports both histograms every five
minutes as a "Frame Duration Report" telemetry event alongside the
existing "Latency Report", bucketed at roughly the 120Hz/60Hz/30Hz frame
budgets so dropped-frame rates can be aggregated across the fleet.
Release Notes:
- Added frame rendering performance to the diagnostics Zed collects when
telemetry is enabled, to help find and fix stutters and dropped frames.
> “Smart quotes” are the ideal form of quotation marks and apostrophes,
and are commonly curly or sloped. "Dumb quotes," or straight quotes, are
a vestigial constraint from typewriters when using one key for two
different marks helped save space on a keyboard.
Also helps us be consistent. I’m going to make a PR to our marketing
site to fix these issues as well, to bring further consistency to our
copy (docs / marketing / otherwise). Starting with v0.5.0 and up,
[`smart-punctuation`](6bf7fadc29/CHANGELOG.md (config-changes))
is enabled by default, so we just need this temporarily.
Good read: https://smartquotesforsmartpeople.com/
---
Release Notes:
- N/A
Closes https://github.com/zed-industries/zed/issues/61208
Before, Zed showed no toasts on startup when tasks.json contained
malformed entries, also if there were two top-level arrays, the last one
was silently discarded without any toasts too.
The PR fixes both.
Release Notes:
- Fixed error toast not showing for malformed tasks.json
# Objective
Zed's Markdown parser accepts tilde-fenced code blocks, but Mermaid
extraction only strips backtick fences. As a result, a block like this
is parsed as Mermaid while the fence itself is still passed to the
renderer:
```markdown
~~~mermaid
graph TD;
~~~
```
## Solution
Teach the Markdown code-block helpers to recognize triple-tilde fences
alongside triple-backtick fences.
The change stays in the existing parsing path, so Mermaid rendering does
not need a separate special case. A regression test covers extraction
from a tilde-fenced Mermaid block.
## Testing
- `cargo fmt --all -- --check`
- `cargo test -p markdown` (138 tests)
- `./script/clippy -p markdown`
- `cargo build -p zed`
- Opened a `~~~mermaid` block in the built Zed Dev app on macOS and
verified that Markdown Preview renders the diagram
## 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 Mermaid diagrams in Markdown previews when they use triple-tilde
fences.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
# Objective
Ensure that, when users undo project panel operations, we don't trash
files with unsaved edits as that could lead to data loss, as outlined
[here](https://github.com/zed-industries/zed/issues/62243#issuecomment-5203625087).
Closes#62243
## Solution
Update `UndoManager::trash` to require confirmation before moving files
to the trash. For files with unsaved edits, users can save, discard, or
cancel the operation while clean files receive a standard trash
confirmation, same as shown when trashing a file through the Project
Panel.
This helps avoid the issue where, if an user undoes a file creation for
a file that has unsaved edits and then quits Zed, the edits that were
saved in memory, as well as the Project Panel history, will now be gone
and there's no way to recover the data.
Batch operations have also been updated to now show a single
confirmation before making filesystem changes, preventing partial
execution when cancelled and warning about unsaved edits.
Lastly, the trash/delete prompt building has been refactored in order
for the Project Panel and Undo Manager to share the same wording,
file-list truncation, and unsaved-change warnings.
## Testing
Tested both manually as well as added the following tests:
* `project_panel::tests::undo::undo_create_cancel_trash`
* `project_panel::tests::undo::undo_create_dirty_file`
* `project_panel::tests::undo::cancel_partial_trash_batch`
* `project_panel::tests::undo::batch_trash_warns_about_unsaved_changes`
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
## Showcase
The screen recording below shows the trash confirmation dialog on both a
clean and dirty files, on both undo and redo flows.
https://github.com/user-attachments/assets/0f9b96f5-0357-4e3f-8ec2-141486942c89
---
Release Notes:
- Fixed issue with undoing or redoing project panel operations that
could lead to a file with unsaved edits being trashed without
confirmation.
Now, this is one of these beautiful cases where GitHubs API ist just so
pleasant to work with: Because PRs are treated as issues, assigning an
assignee to a PR suddenly requires issue write permissions, despite the
issue in question being a PR. Not having that permission resulted in
some missing assignees on zed zippy bumps and failures of the workflows
as seen in
https://github.com/zed-industries/zed/actions/runs/31339736929/job/93311493258.
In comparison, labelling PRs requires PR write permissions as seen in
https://github.com/zed-industries/zed/pull/61525🤡
Beautiful API and a pleasure to work with, 10/10 would recommend.
Release Notes:
- N/A
Recommends GPT-5.6 Sol for both OpenAI BYOK and OpenAI subscription.
Also unifies the naming so that we use the same OpenAI model names for
the Zed/OpenAI BYOK and OpenAI subscription providers.
Release Notes:
- N/A
This reverts commit 6297c88f42.
---
fixes#62286fixes#62095https://github.com/zed-industries/zed/pull/61467 fixed its intended bug,
but at the same time introduced an issue where running tasks that would
cause new tasks to be terminated immediately.
https://github.com/zed-industries/zed/pull/62322 tried to fix that
forward, but was unsuccessful. In the mean-time I am going to revert the
original PR.
We can try to re-land the original bugfix in a future PR.
Release Notes:
- N/A
Follow-up to #59838, implementing what was discussed at the end of
#59829: cmd-click navigation now respects `lsp_results_location` when
go-to-definition falls back to find-all-references (invited in
https://github.com/zed-industries/zed/issues/59829#issuecomment-4989966493:
"It would! Feel free to hook that up if you'd like to!").
## Problem
Cmd-clicking a symbol's definition falls back to find-all-references,
but the results always open in a multibuffer even with
`"lsp_results_location": "picker"`. The hover-link click path calls the
editor navigation methods directly, so the action handlers registered by
`lsp_locations` never get a chance to intercept.
## Solution
- `handle_click_hovered_link`'s fallback now dispatches the
`FindAllReferences` action (with `open_results_in: None`, deferring to
the global setting) instead of calling the method, so the
`lsp_locations` handler can intercept it, or propagate to the editor's
built-in handler when the setting is `multi_buffer`, preserving today's
behavior exactly.
- The plain cmd-click arm of `cmd_click_reveal_task` now runs the
definition query via `go_to_definition_of_kind` (no internal references
fallback) instead of `go_to_definition`, so the click path has a single
fallback decision point: the dispatching one. Without this, the method's
baked-in fallback opened a multibuffer before the dispatch could run.
- `go_to_definition_of_kind` visibility widened to `pub(crate)` for the
call from `hover_links.rs`.
Shift/alt click variants (type definition, splits) are untouched.
Keyboard invocations were already intercepted and are unchanged.
## Testing
- New test `test_cmd_click_fallback_honors_lsp_results_location` in
`lsp_locations`, following the module's existing test patterns: fake LSP
returning no definition and two references, `lsp_results_location:
picker`, simulated cmd-click at the cursor's pixel position, asserts the
picker opens. The test fails without this change.
- `cargo nextest run -p lsp_locations`: 6/6.
- `cargo nextest run -p editor -E 'test(hover) or test(fallback) or
test(go_to_definition) or test(references)'`: 54/54.
- `cargo fmt` and `./script/clippy` clean.
- Verified manually in a release build: with the setting on,
cmd-clicking a definition opens the picker; with it off, behavior is
unchanged.
Per the contributing guidelines' note on AI assistance: this change was
developed with heavy AI assistance (Claude Code). I have reviewed and
understand the full diff and the reasoning behind each hunk, and I'm the
one answering review feedback.
Release Notes:
- Fixed cmd-click go-to-definition falling back to a references
multibuffer even when `lsp_results_location` is set to `picker`.
# Objective
The `gpui::img` element always overrides the `aspect_ratio` field, so if
you have an image element that applies its own `.aspect_ratio()` it just
gets wiped out.
## Solution
Only apply the aspect ratio default if one is not already set.
## Testing
It's a very minor change but I did add a small test to ensure it
actually gets overridden.
## 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
This came from an issue where vertical images inside an element (square
in this case, as you'd see in an image gallery) do not behave correctly
with `object_fit` values of `ObjectFit::Contain` or
`ObjectFit::ScaleDown`.
This was simply because despite the image element having a fixed square
size (`img().size(px(200.))`), the aspect ratio would be forced to the
ratio of the image itself, so vertical images weren't being properly
fitted into their containers.
Minimal repro for that issue:
https://github.com/zaknesler/gpui-object-fit
So with this change, you can set `.aspect_square()` and the object fit
will behave as you'd expect:
<img width="1237" height="986" alt="image"
src="https://github.com/user-attachments/assets/5b1045a8-bd71-4b77-8bbd-c3b12112bcb0"
/>
---
Release Notes:
- gpui: Fix image element's aspect ratio overriding existing value
## Summary
- Add `terminal.starts_open` setting so the terminal panel can open
automatically in new workspaces, like project and git panels already can
- Expose the setting through terminal settings docs, default settings,
Settings Editor metadata, and the terminal panel implementation
- I also added a matching settings page item for the existing
`git_panel.start_open` setting
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 behaviour
- I decided not to add tests as the behaviour seems covered by the
existing settings tests, and similar areas don't seem to have their own
explicit tests.
- [x] Performance impact has been considered and is acceptable
Related to #51542 (issue mentions possibly adding for all panels, closed
with implementation for `git_panel`)
Release Notes:
- Added `terminal.starts_open` to control whether the terminal panel
opens automatically in new workspaces
# Objective
Follow-up to zed-industries/extensions#7062.
## Solution
Add `("windows-batch", &["bat", "cmd"])` to
`SUGGESTIONS_BY_EXTENSION_ID`
## 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:
- Added a suggestion to install the `windows-batch` extension when
opening `.bat` and `.cmd` files.
## Context
This is a rebase of #52302, which was approved by @Veykril in May but
still needed a rebase before it could be merged — it seems the original
author @MostlyKIGuess forgot about it. I rely on this fix daily for REPL
over SSH on an unstable connection and need it rather urgently, so I
cherry-picked the original commit (with authorship preserved) and
resubmitted it as a new PR.
Closes#51834
Supersedes #52302
## How to Review
The code itself was already reviewed and approved in #52302. This PR
only rebases it onto latest `main`, with one simple conflict resolution
against #53014: when all retries are exhausted, the error now uses the
improved message from that PR (suggesting `pip install ipykernel` on the
remote host) instead of the plain one. Comparing this diff against the
original PR's diff should make the review straightforward.
## 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:
- repl: Fixed iopub connection failures over SSH on slow or unstable
connections by retrying with exponential backoff.
Co-authored-by: mostlykiguess <bruvistrue93@gmail.com>
the buffer search and project search bars both already load the `regex`
language and put it on their query buffer when the regex filter is on.
the text finder never got that, so a regex you type in there is just
plain text.
did the same thing here. the only slightly annoying part was that the
picker's head editor is `pub(crate)`, so text_finder couldn't get at it.
added a small `query_editor()` accessor to `Picker` for that.
`adjust_query_regex_language` mirrors the two existing ones.
test asserts the query buffer's language is regex with the filter on,
and gone once it's off.
Closes#59945.
Release Notes:
- Improved the text finder by highlighting the query as a regex when the
regex filter is on
---------
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
# Objective
- Zed can hang (and eventually get force-killed) when opening certain
binary files, because `analyze_byte_content`'s UTF-16 heuristic
misclassifies them as UTF-16LE/BE text.
- Reproduced with a real-world case: a ~92 MB OTBM game map file (the
binary map format used by OpenTibia/Tibia servers), which interleaves
short ASCII strings with small u16 length/type fields. Its byte pattern
(mostly-zero high bytes, very few control characters) passed the
existing check, so Zed read the entire file, decoded it as UTF-16, and
opened it as an editable buffer with tens of millions of characters and
effectively no line breaks — a pathological case for the text
layout/renderer that hangs or crashes the app (most noticeably on
Windows).
## Solution
`is_plausible_utf16_text` in `crates/language/src/file_content.rs`
previously only rejected the UTF-16 hypothesis when too many code units
were control characters (> 2%). That's not sufficient on its own: binary
formats that interleave short ASCII fragments with small numeric fields
can have a very low control-character ratio while still not being real
text — most of their "characters" land on stray symbol/high-byte values
rather than letters, digits, or spaces.
This PR adds a second, independent requirement: at least 30% of the
analyzed code units must be letters, digits, or spaces (the bulk of any
real UTF-16 text sample). Both conditions now have to hold for a byte
sequence to be classified as UTF-16 text — otherwise it falls through to
`ByteContent::Binary`, and file loading is rejected early, as intended
for binary files, instead of decoding the whole file as garbled text.
## Testing
- Added `test_length_prefixed_binary_not_misdetected_as_utf16le` in
`crates/worktree/src/worktree.rs`, using a synthetic byte pattern that
reproduces the same statistical shape as the real file (null high bytes,
low control-character ratio, no word-like low bytes) — asserts it is now
classified `Binary`.
- Verified against the real 92 MB `.otbm` file that triggered the bug
(not committed, since it's user data): before the fix it was classified
`Utf16Le`, after the fix it's classified `Binary`.
- Ran the full existing `analyze_byte_content` /
`is_plausible_utf16_text` test suite (`cargo test -p worktree --lib
tests::`) — all 7 tests pass, including the pre-existing positive
UTF-16LE/UTF-16BE detection tests, so legitimate UTF-16 files are
unaffected.
- Built a full `--release` binary on Windows and confirmed opening the
real file now shows "Binary files are not supported" immediately instead
of hanging.
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments — N/A, no unsafe
code
- [x] The content adheres to Zed's UI standards — N/A, no UI change
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable — only
affects classification of the first 1 KB of a file, negligible cost
---
Release Notes:
- Fixed: Zed no longer hangs when opening certain binary files (e.g.
game asset/map formats) that were previously misdetected as UTF-16 text.
---------
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
RPC log grouping only tracked whether consecutive messages had the same
transport direction. This made an untimed request appear beneath the
duration header of an unrelated response when both were sent in the same
direction.
Before:
// Send (took 53.0ms):
{"jsonrpc":"2.0","id":"##CodeLensRefreshRequest#1226","result":null}
{"jsonrpc":"2.0","id":53,"method":"textDocument/diagnostic"}
After:
// Send (took 53.0ms):
{"jsonrpc":"2.0","id":"##CodeLensRefreshRequest#1226","result":null}
// Send:
{"jsonrpc":"2.0","id":53,"method":"textDocument/diagnostic"}
Apply the same boundary handling to received messages while continuing
to group consecutive untimed messages.
---
Release Notes:
- N/A or Added/Fixed/Improved ...
Closes#62007
Adds Gemini 3.6 Flash to the Google AI provider so it can be selected in
the agent, alongside the existing Gemini 3.5 Flash.
Google released Gemini 3.6 Flash on July 21, 2026. It keeps the 1
million token context window, has a 64k output limit, and supports
thinking. The model is added with the same capabilities and thinking
levels as 3.5 Flash (Minimal, Low, Medium, High, defaulting to Medium).
The provider builds its model list from `google_ai::Model::iter()`, so
adding the enum variant is enough for it to show up in the model
dropdown. The thinking behavior in `completion.rs` keys off the
`gemini-3` id prefix, so it already applies to this model.
Release Notes:
- Added Gemini 3.6 Flash to the Google AI models
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
GPUI's declarative hover styles are recomputed from the current frame's
hit test, but `on_hover` listeners previously updated only in response
to mouse movement or the pointer leaving the window. When layout moved a
different element beneath a stationary pointer, the new element looked
hovered without receiving its hover-start callback.
This change reconciles each hover listener against the current hit test
during painting and defers transitions until after the paint cycle, when
application callbacks can safely update state. Reconciliation pauses
while a mouse press is pending so hover-only controls remain mounted
between mouse-down and mouse-up.
The regression coverage moves an element beneath and away from a
stationary pointer and verifies both transitions. It also verifies that
repainting during a stationary mouse press does not generate a spurious
hover exit.
Testing:
- `cargo test -p gpui --lib`
- `cargo fmt --check -p gpui`
- `cargo check -p delta --bin delta` with Delta temporarily patched to
the local GPUI checkout
Release Notes:
- Fixed hover interactions not updating when interface elements move
beneath a stationary pointer.
Spinners rendered near each other (like a sidebar full of running
threads) each start rotating from the moment their element first
renders, so they spin out of phase and the group looks jittery.
This adds `Animation::repeat_synced()`, which derives the phase from a
clock shared by the whole app instead of the element's mount time, and
switches `with_rotate_animation` over to it, so every spinner with the
same period now renders the same frame at the same time. The epoch is
read off the scheduler clock at app creation, so the phase stays
deterministic under the test scheduler.
Release Notes:
- Improved loading spinners to rotate in phase with one another
Currently, GPUI on web calls `requestAnimationFrame` every frame, which
causes it to do meaningful GPU work every frame, even if it was
identical.
This PR makes GPUI only call `requestAnimationFrame` when it has new
content to display.
---
Release Notes:
- N/A or Added/Fixed/Improved ...
The markdown preview used `vertical_scrollbar_for()` which always sets
the scrollbar to auto-hide mode, ignoring the user's `scrollbar.show`
setting.
This fix uses
`Scrollbars::for_settings::<EditorSettingsScrollbarProxy>()` so the
markdown preview respects the same editor scrollbar visibility setting
as regular editor panes (always, auto, system, never).
Changes:
- Replaced `vertical_scrollbar_for()` with `custom_scrollbars()` +
`Scrollbars::for_settings::<EditorSettingsScrollbarProxy>()` in the
markdown preview render method
Fixes#60380
Release Notes:
- Fixed `scrollbar.show` setting not being respected in Markdown
previews
---------
Co-authored-by: Akshit Jain <akshitj11@users.noreply.github.com>
Co-authored-by: MrSubidubi <finn@zed.dev>
# Objective
- Fixes#61925.
- GPUI already carries AccessKit author IDs through its platform
adapters, but applications cannot set one on an ordinary element.
## Solution
- Add `accessibility_id(...)` beside the other semantic builders.
- Store the value separately from GPUI's element ID and write it to
`Node::set_author_id`.
- Document that applications should keep the value stable and unique
within the accessibility tree.
- Document the platform mapping accurately: UIA `AutomationId` on
Windows, `AXIdentifier` on macOS, and AT-SPI `AccessibleId` on Linux
stacks whose deployed adapter exposes it.
## Testing
Exact candidate `d099c529`:
- `cargo fmt --all -- --check`
- `git diff --check`
- `cargo test -p gpui test_accessibility_id_builder_writes_author_id
--offline`: 1 passed, 218 filtered out
The test exercises the public builder and verifies that the author ID
reaches the AccessKit node. Validation is unit-level; this branch has
not run live platform UIA, AX, or AT-SPI end-to-end tests.
## Self-Review Checklist:
- [ ] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments ; no unsafe block
added
- [x] The content adheres to Zed's UI standards ; no visual change
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
---------
Co-authored-by: Friday <260232009+buildfriday@users.noreply.github.com>
Label | Description
-- | --
area:integrations/git/panel | Feedback for the Git panel UI and
behavior.
area:gpui/graphics/wgpu | Feedback for GPUI's WGPU graphics backend,
including initialization and rendering.
area:breadcrumbs | Feedback for editor path and symbol breadcrumbs.
area:title bar | Issues suitable for title bar.
area:ai/agent thread/checkpoints | Feedback for Agent checkpoint
creation, comparison, restoration, and related Git behavior.
area:ai/agent thread/tools | Feedback for built-in Agent tools,
including execution, permissions, inputs, and outputs.
Release Notes:
- N/A
While building Zed with nightly rustc I've noticed it doesn't compile
because of good old pathfinder_simd. It also emits a bunch of warnings
about use of f64 literals where f32 is expected, so I've fixed them - it
should make future upgrades more straightforward.
# Objective
Prevent the thread from automatically scrolling to the end when
expanding a "Context Compacted" message at the end of the thread, as we
suspect the user would likely be trying to read it from top to bottom.
## Solution
Update how the `ThreadView` behaves when expanding a "Context Compacted"
message, namely by updating `ThreadView::toggle_compaction_expansion` in
order to anchor the scroll position, which disables the tail following
behavior, ensuring that the scroll offset is kept.
In order to better support this, a new method is introduced to
`gpui::elements::list::ListState`, `anchor_scroll_position`, which takes
the current scroll offset and scrolls to it which, in turns, disables
the following behavior.
Another option would be to simply introduce
`gpui::elements::list::ListState::stop_following` but I'm not sure
whether we'd want to expose that implementation detail, even though we
already have `gpui::elements::list::ListState::is_following_tail` .
## Testing
Tested both manually as well as introduced a new test for
`ListState::anchor_scroll_position`.
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] 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>Before</summary>
https://github.com/user-attachments/assets/cf8ee10f-9c74-429d-afed-7a39ccd71c67
</details>
<details>
<summary>After</summary>
https://github.com/user-attachments/assets/78edfca9-099a-4fdb-9c4e-75f790096957
</details>
---
Release Notes:
- Improved expanding "Context Compacted" messages in the Agent Panel to
ensure that the scroll position is preserved, instead of automatically
scrolling to the end of the thread.
---------
Co-authored-by: Joseph T. Lyons <JosephTLyons@gmail.com>
Auto-hiding scrollbars currently reveal whenever their prepaint geometry
changes. That matches browser behavior, but it causes continuously
updating views to restart the visibility timer on every content change
even when the user has not scrolled.
Add a per-instance `ScrollbarRevealPolicy`. The default
`ScrollOrContentChange` policy preserves the existing behavior for all
current callers. Views with continuously growing content can opt into
`ScrollOnly`, which reveals only when the offset changes independently
of content size, including when a view remains anchored to the bottom.
Tests pin the default behavior, the opt-in behavior, ordinary scrolling,
stationary content growth, bottom-anchored growth, and scrolling while
content is growing.
Release Notes:
- N/A
# Objective
Fixes FR-149
- Make word movement and selection predictable around punctuation.
- Prior art: [#58882](https://github.com/zed-industries/zed/pull/58882),
[#61916](https://github.com/zed-industries/zed/pull/61916), and their
revert [#62213](https://github.com/zed-industries/zed/pull/62213).
## Solution
- Treat words and punctuation runs as separate movement units in both
directions.
- This adds a stop between leading punctuation and its following word,
such as `.▏foo`.
## Testing
- Added table-driven coverage for reported examples, delimiters,
operators, punctuation runs, and Unicode punctuation.
- Tested editor movement, selection, and deletion behavior.
## 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 word movement and selection stopping on the wrong side of
punctuation.
In the current Python Tree-sitter `highlights.scm`, dunder variables
(e.g., `__name__`, `__file__`) are not highlighted.
This PR adds a regex `#match?` so all dunder variables are highlighted
under `@attribute.special`.
An alternative solution would be to use `#any-of?` and list all dunder
variables.
| Before | After |
|
:---------------------------------------------------------------------------------------------------------------------------------:
|
:--------------------------------------------------------------------------------------------------------------------------------:
|
|<img width="623" height="895" alt="image"
src="https://github.com/user-attachments/assets/ad7b67ba-541c-40ac-a38a-cc863e417fcc"
/> | <img width="612" height="903" alt="image"
src="https://github.com/user-attachments/assets/a91f5efb-230a-4214-b16b-04278b3ef9ee"
/>|
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 Python dunder variables highlighting via `attribute.special` in
themes.
## Objective
Add functional horizontal scrollbars to wide Markdown tables, matching
the existing code-block scrollbar pattern.
Fixes#61437
PR was talked about in https://github.com/zed-industries/zed/pull/61698
## Implementation:
- Added a `BTreeMap<usize, ScrollHandle>` to `Markdown` for table scroll
handles, keyed by source-range start.
- During `MarkdownElement` layout, each table container is connected to
a `Scrollbars` widget configured for the horizontal axis, using a stable
ID derived from `("markdown-table-scrollbar", range.start)`.
- The inner table div uses `overflow_x_scroll()` + `track_scroll()` with
`restrict_scroll_to_axis`.
- Handles for removed tables are discarded after re-rendering.
- No public API, setting, schema, or migration changes required.
## Recording
https://github.com/user-attachments/assets/cd0f635b-a485-4de8-9059-40a05f256fb1
## Release Notes:
- Improved navigation of wide Markdown tables with horizontal
scrollbars.
---------
Co-authored-by: MrSubidubi <finn@zed.dev>
# Objective
Zed's `wgpu` backend currently allocates memory for fonts, even if they
are statically available in memory. Zed embeds 8 fonts, which accounts
for about 1.6 megabytes of memory. This change should reduce memory
usage by that amount on the `wgpu` backend. (Linux and Web)
For more context, this is the function signature for `load_font_data`:
```rust
/// Loads a font data into the `Database`.
///
/// Will load all font faces in case of a font collection.
pub fn load_font_data(&mut self, data: Vec<u8>) {
self.load_font_source(Source::Binary(alloc::sync::Arc::new(data)));
}
```
## Solution
Instead of calling `fontdb::Database::load_font_data`, which needs an
owned `Vec`, use `load_font_source`, which allows us to create an `Arc`
ourselves, which doesn't require ownership of the underlying data.
## Testing
All tests pass
## 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:
- Slightly improved memory usage on Linux
# Objective
This PR aims to fix these related deficiencies with the terminal tool's
working directory path resolution:
- Fix#60014
- Fix#60040
- Fix#60043
## Solution
- Use `project.path_style(cx).is_absolute(dir)` instead of
`Path::is_absolute`. The latter follows the path semantics of the host
which fails to recognize `/home/...` etc as an absolute path on Windows,
we want to follow the path semantics of the *project*.
- Splits out path resolution into a separate pure function
`resolve_cd_in_worktrees` to enable comprehensive cross-PathStyle
testing
- The function unifies path prefix checking across both absolute and
relative modes, using the `path_style.strip_prefix` (which uses the
RelPath util internally) which fails when subdirs try to escape with
`..`.
- Add comprehensive tests for absolute/relative modes, path styles, and
potential `..` escapes
- Enables targeting subdirectories with both absolute and relative path
modes (separate commit)
- Also makes both path modes use `project.worktrees`. Before, the
relative path mode used `project.visible_worktrees`.
## Testing
Here's how I tested these changes:
- Added a new test: `test_resolve_cd_uses_project_path_style` with a
comprehensive collection of assertions for `..` edge cases
- Run `cargo test -p agent` and `./script/clippy -p agent` on:
- Linux
- Windows in Ubuntu WSL
- Windows native
- Build and run Zed on:
- Linux
- Windows
- Verify that the three issues are fixed:
- `cd` param path traversal escapes are blocked
- Linux local project
- Windows local project
- Windows remote WSL project
- Allows absolute paths when running on Windows in a WSL project
- `cd` param may target subdirectories in both absolute and relative
path modes
- Linux local project
- Windows local project
- Windows WSL project
- Check that different models find the updated tool descriptions to be
understandable and usable the first time. Used the prompt below to get
the following models to test path resolution on each of: Windows local,
Windows WSL, Linux. All models except GPT-5-nano one-shot the below
prompt.
- Claude Sonnet 4.6
- Claude Opus 4.8
- Claude Haiku 4.5
- GPT-5.5 pro
- GPT-5-nano - got there eventually but is confused by the design of the
cd param, it expects that if you set cd to `my-project` that it will
target the directory `my-project/my-project`.
- Gemini 3.1 Pro
- Gemini 3.5 Flash
- Grok 4.3
- Grok 0.1 build
<details>
<summary>Agent test prompt</summary>
<blockquote>
List the current directory contents and pick one subdir.
Then use that information and the project path details you were provided
to execute `pwd` with the terminal tool's cd parameter set to the
following values:
- current project absolute path
- current project name
- current project absolute path + an existing subdir
- current project name + an existing subdir
- absolute path to user's .ssh dir
- current project absolute path + whatever necessary path traversal .. +
.ssh segments to target the user's .ssh dir
Then tell me what happened.
Then stop.
</blockquote>
</details>
## 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 terminal tool targeting absolute directories on Windows host
connected to a remote SSH / WSL project
- Fixed terminal tool not blocking path traversal escapes
- Improved terminal tool targeting project subdirectories
---------
Co-authored-by: Richard Feldman <richard@zed.dev>
Co-authored-by: Richard Feldman <oss@rtfeldman.com>
# Objective
Fix several Git panel focus issues:
- Directional navigation could not move focus into the History tab.
- History focus state was not updated when the panel received focus.
- Switching back to Changes could leave focus on the panel instead of
the commit editor.
Fixes#62211
## Solution
- Use the Git panel root as the activation focus target when History is
active.
- Reuse the panel's focus handle for focus events.
- Use the appropriate activation target when switching tabs.
## Testing
- Add a regression test
`test_history_tab_pane_navigation_focuses_rendered_panel` for navigating
between the editor and History.
## 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
after fix:
[2026-08-05
22-45-38.webm](https://github.com/user-attachments/assets/fdb3f87a-f1af-4ae1-95f7-0d61acfb3095)
---
Release Notes:
- Fixed directional focus navigation into the Git panel's History tab.
The renderer benchmarks drain the main queue to quiescence before each
measured frame, so a task that yields and re-queues itself (an idle
sweep, a poller) runs to completion inside a single measured frame — or
keeps the benchmark spinning forever. Real platforms don't work that
way: macOS's main-queue drain only runs the items present when the drain
starts, Linux runs one runnable per calloop idle callback, and Windows
drains under a 10ms budget before servicing paint messages — frames
always get a chance to preempt. So `run_ready_main_tasks` now only runs
the tasks that were queued when servicing began, letting self-re-queuing
work advance one batch per frame like it would under a real run loop,
and `BenchAppContext` grows a `run_until` (wrapping the dispatcher
primitive task benchmarks already use) so setup code can pump the app
until a condition holds without settling to idle first.
Release Notes:
- N/A
# Objective
Document how to use Poolside in Zed through the ACP Registry, Poolside
Agent CLI, manual Custom Agent configuration, and Terminal Threads.
## Solution
- Add Poolside paths to the AI by Company guide.
- Document ACP Registry installation and in-thread login.
- Document CLI-assisted and manual Custom Agent configuration.
- Explain the settings-path and PATH requirements.
- Link to the public Poolside Agent CLI repository and Poolside’s Zed
documentation.
## Testing
- Ran `./script/prettier`.
- Ran `git diff --check`.
- Verified Poolside’s live ACP Registry entry.
- Verified the commands, configuration, and authentication behavior
against the Poolside and Zed implementations.
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks are not applicable
- [x] The content follows Zed’s documentation and UI conventions
- [x] Code tests are not applicable to this documentation-only change
- [x] Performance impact is not applicable
---
Release Notes:
- N/A
# Objective
Prevent auto-indent from using stale syntax when text changes during a
background parse.
## Solution
Keep auto-indent pending and parsing active until the current parse
completes.
## 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:
- Editor: Fixed auto-indent occasionally using stale syntax after rapid
edits.
Enables zooming of mermaid diagrams by supporting horizontal scroll
---
Release Notes:
- improved: Mermaid diagrams can now be zoomed and horizontally
scrolled, in both the markdown preview and the agent panel
Resolves#61888.
Multi-modifier gestures could leave GPUI’s standalone-modifier state
armed after one modifier was released. For example, releasing `Alt`
before `Shift` during an `Alt+Shift` gesture caused the final `Shift`
release to be synthesized as a standalone shift keystroke.
This diff invalidates standalone-modifier synthesis whenever multiple
modifiers are active, while preserving genuine modifier-only key
bindings.
Release Notes:
- Fixed Alt+Shift gestures potentially triggering standalone Shift key
bindings.
`ThreadedDispatcher::run_until` - the completion mechanism under
`BenchAppContext` async task benchmarks (`bench_task` /
`bench_batched_task`, added in #62180) - drained the entire main queue
before checking its readiness predicate. Main-thread work that re-queues
itself (an idle-time sweep, a polling loop) keeps the queue non-empty
until it finishes every iteration, so a task benchmark's measured
interval silently extended past the awaited task's completion until all
such deferred work settled. Benchmarks of UI workloads that schedule
follow-up idle work could report several times their true completion
latency.
This changes `run_until` to step main-thread runnables one at a time and
check readiness before each, so it returns at the completion it awaits
rather than at queue quiescence, making async task benchmarks more
accurate. The regression test spawns a task that re-queues itself 10,000
times plus a one-shot completion task, and asserts `run_until` returns
without draining the re-queued work; it fails against the previous
drain-first implementation.
Release Notes:
- N/A
Removes an unnecessary dependency on settings as
`settings::OpenAiReasoningEffort` just points to
`language_model::ReasoningEffort`
Release Notes:
- N/A