This makes this take the LSP adapter delegate instead of the binary
itself.
Despite us passing `LanguageServerBinaryOptions` with `allow_download:
false`, extensions would still try to download the binary because it was
never implemented for these to respect that. This would cause us to try
to download all langauge servers provided by extensions when opening a
settings file and/or requesting the JSON schema for that.
This PR fixes this by passing the LSP adapter delegate instead, so the
few language servers which actually want to have the binary for
resolving the initialization options can decide on this by themselves.
With that, we no longer download all language servers for the schema
request
Release Notes:
- N/A
Updates the community champions list to the latest state, adding some of
our active extension contributors, and sorts the list/removes
duplicates.
Release Notes:
- N/A
This PR reworks the (still feature-gated) side-by-side diff view to use
a different approach to representing the multibuffers on the left- and
right-hand sides.
Previously, these two multibuffers used identical sets of buffers and
excerpts, and were made to behave differently by adding a new knob to
the multibuffer controlling how diffs are displayed. Specifically, the
left-hand side multibuffer would filter out the added range of each hunk
from the excerpts using a new `FilteredInsertedHunk` diff transform, and
the right-hand side would simply not show the deleted sides of expanded
hunks. This approach has some problems:
- Line numbers, and actions that navigate by line number, behaved
incorrectly for the left-hand side.
- Syntax highlighting and other features that use the buffer syntax tree
also behaved incorrectly for the left-hand side.
In this PR, we've switched to using independent buffers to build the
left-hand side. These buffers are constructed using the base texts for
the corresponding diffs, and their lifecycle is managed by `BufferDiff`.
The red "deleted" regions on the left-hand side are represented by
`BufferContent` diff transforms, not `DeletedHunk` transforms. This
means each excerpt on the left represents a contiguous slice of a single
buffer, which fixes the above issues by construction.
The tradeoff with this new approach is that we now have to manually
synchronize excerpt ranges from the right side to the left, which we do
using `BufferDiffSnapshot::row_to_base_text_row`.
Release Notes:
- N/A
---------
Co-authored-by: cameron <cameron.studdstreet@gmail.com>
Co-authored-by: HactarCE <6060305+HactarCE@users.noreply.github.com>
Co-authored-by: Miguel Raz Guzmán Macedo <miguel@zed.dev>
Co-authored-by: Anthony <anthony@zed.dev>
Co-authored-by: Cameron <cameron@zed.dev>
Closes#45211
This ensures that all sub-processes that were launched by the ACP server
are terminated. One scenario where this is easily reproducible:
- Start a new Claude Code ACP session
- Submit a prompt
- While Claude-code is still responding, start a new session
- The `claude-code` subprocess is leaked from the previous session (The
Claude-code SDK runs the Claude-code binary in a sub process)
This PR fixes this by using process groups on Unix.
It does not fix the process leaks on Windows yet (will follow up with
another PR)
Release Notes:
- Fixed an issue where subprocesses of ACP servers could be leaked after
starting a new session
Now that the edit mode in number fields is finally working well, we can
make the UX of editing font sizes much nicer because you can now type
inside the number field :)
https://github.com/user-attachments/assets/8df7c6ee-e82b-4e10-a175-e0ca5f1bab1f
Release Notes:
- settings UI: Improved the UX of editing font size fields as you can
now type the desired value as opposed to just using the
decrement/increment buttons.
Follow up to https://github.com/zed-industries/zed/pull/45447 and in
preparation to enable the edit mode in number field instances within the
settings UI. This PR fixes the editor in the number field capturing
focus automatically (unnecessary), tab index in the buttons and editor,
and other things.
Release Notes:
- N/A
This has been something we've wanted to do for a long time since docs
aside thus far have been hard-anchored either at the top or bottom of
the container that their trigger is sitting in. This PR introduces the
change so that they're centered with their trigger, regardless of
whether it's on a context menu or picker, by including a canvas element
in both the container and the trigger to calculate where the docs aside
should precisely sit on. Here's the result:
https://github.com/user-attachments/assets/8147ad05-1927-4353-991d-405631de67d0
Note that at the moment, docs aside are only visible through _hovering_,
and ideally, they should be available on both hover and selection
(keyboard nav). But I'll leave that for later.
Release Notes:
- N/A
I changed the runner sizes to a smaller but more recent image yesterday
and broke the version bumping in the process. This PR fixes this by
force installing the needed package.
Release Notes:
- N/A
- **search: Make search cancellation more responsive (again)**
- **Fix project benchmarks build**
- **Less scoping and lifetimes for workers**
Related to #45300
Release Notes:
- Project search will consume less resources immediately after
cancellation.
---------
Co-authored-by: Max Brunsfeld <max@zed.dev>
Closes https://github.com/zed-industries/zed/issues/45630
Remote host location alone is not enough to distinguish between remote
worktrees: different remote projects open in different windows will have
the same remote host location and _will_ have the same `WorktreeId`.
Thus, require an associated `WorktreeStore` with all
`WorktreeId`-related trust questions, and store those IDs based on the
store key.
Release Notes:
- Fixed worktree trust handling of multiple projects on the same remote
host
There were several places adding a copy icon button, so thought of
encapsulating the logic to copy a given string into the clipboard (and
other small details like swapping the icon and tooltip if copied) into a
component, making it easier to introduce this sort of functionality in
the future, with fewer lines of code.
All it takes (for the simplest case) is:
```rs
CopyButton::new(your_message)
```
<img width="600" height="714" alt="Screenshot 2025-12-29 at 10 50@2x"
src="https://github.com/user-attachments/assets/e6949863-a056-4855-82d8-e4ffb5d62c90"
/>
Release Notes:
- N/A
GitHub flags these as security vulnerabilities. Hence, this PR specifies
the needed permissions for the workflows used in the `zed-extensions`
organization.
Release Notes:
- N/A
Fixes#43306
Long error messages from LLM providers in the Agent Panel were not
scrollable, making it impossible to read the full error content.
Changes:
- Add max_h_48() and overflow_y_scroll() to description containers
- Add element IDs required for scroll functionality
- Add min_h_0() and overflow_hidden() to parent flex container
- Add component preview example demonstrating scrollable content
Release Notes:
- Fixed long error messages in Agent Panel being unreadable by making
them scrollable
([#43306](https://github.com/zed-industries/zed/issues/43306)).
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Thanks for the cool project and making it open source! Started using Zed
recently and I really enjoy it.
Made a tiny addition to devcontainer docs to specify the version. Wasn't
able to get it to work as shown in the
[docs](https://zed.dev/docs/dev-containers) (should "just work"). The
feature was introduced recently on [PR
44442](https://github.com/zed-industries/zed/pull/44442) and is only
available as of v0.218 (currently still in preview), while I was still
on the latest stable version.
So I thought of opening a small PR 😊
Thanks again for the awesome project!
Release Notes:
- N/A
---------
Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
This PR introduces the `MentionCrease` component, aimed at solving two
issues with mention creases in the agent panel:
- Previously, the mention crease was using a button with a regular size,
which is bigger than the default buffer font line height. That made the
crease look clipped and also overlapping with one another when in a
multiple line scenario where the creases would be on top of each other.
`MentionCrease` uses the window line height value to set the button
height, with a small one pixel vertical padding just for a bit of
spacing.
- Previously, given the crease used a `Label`, its font size wouldn't
scale if you changed the `agent_buffer_font_size` setting. Now,
`MentionCrease` uses that font size value, which makes regular text and
its text grow together as you'd expect.
Release Notes:
- agent: Fix a bug where mention creases didn't scale with
`agent_buffer_font_size` and got clipped/jumbled when rendered one above
the other.
Follow-up to https://github.com/zed-industries/zed/pull/45164 which
caused the active line number to always be `0` instead of the actual
current line number. No release notes since its only on nightly
Release Notes:
- N/A
Closes https://github.com/zed-industries/zed/issues/42845
Repro steps:
https://github.com/zed-industries/zed/issues/42845#issuecomment-3687413958
Initial investigation and Zed memory trace:
https://github.com/zed-industries/zed/issues/42845#issuecomment-3687877977
The PR consists of 2 commits:
*
[first](732d308c8d)
adds cosmetic fixes to remove backtraces from logs yet again and print
paths in quotes, as file descriptors may return empty paths.
It also stubs the cause if OOM in project panel: that one traversed all
worktrees in `for worktree_snapshot in visible_worktrees` and "accepted"
the one with empty paths + never called `entry_iter.advance();` in "no
file name found for the worktree" case, thus looping endlessly and
bloating the memory quite fast.
*
[second](7ebfe5da2f)
adds something that resembles a fix: `fn current_path` on macOS used the
file handler to re-fetch the worktree root file path on worktree root
canonicalization failure.
What's odd, is that `libc::fcntl` returns `0` in the case when external
volume is not mounted, thus resulting in the `""` path string that is
propagated all the way up.
*
[third](1a7560cef3)
moves the fix down to the platform-related FS implementations
The "fix" now checks the only usage of this method inside `async fn
process_events` for an empty path and bails if that is the case.
I am not sure what is a better fix, but this stops any memory leaks and
given how bad the situation now, seems ok to merge for now with the
`TODO` comment for more clever people to fix properly later.
----------------
Now, when I disconnect the SMB share and reconnect it again, Zed stops
displaying any files in the project tree but the ones opened as editors.
As before, at first, when the share is unmounted, Zed fails to save any
changes because of the timeouts.
Later, when the share is re-connected, macOS Finder hangs still but Zed
starts to react on saves yet still only shows the files that are open as
editors.
The files can be edited and saved from now on.
Later, when Finder finally stops hanging and indicates that the share is
mounted fully, the rest of the file structure reappear in the project
panel, and all file saves are propagated, hence can be observed in the
share in Finder.
It feels that one good improvement to add on top is some "disconnected"
indicator that clearly shows that the file is not properly handles in
the OS.
This requires much more changes and thinking as nothing like that exists
in Zed yet, hence not done.
Release Notes:
- Fixed Zed OOM-ing when macOS file descriptors become invalid
Follow up to https://github.com/zed-industries/zed/pull/45311. Instead
of searching for the string in the find pasteboard as soon as the pane
is focused, we will now wait until the search bar is either deployed or
`Select{Next|Prev}Match` is triggered.
Release Notes:
- N/A
This brings the terminal element's viewport culling in line with the
editor optimization in PR #44995 and the fix in PR #45077.
## Problem
When a terminal is inside a scrollable container (e.g., the Agent Panel
thread view), it would render ALL cells during prepaint, even when the
terminal was entirely outside the viewport. This caused unnecessary CPU
usage when multiple terminal tool outputs existed in the Agent Panel.
## Solution
Calculate the intersection of the terminal's bounds with the current
content_mask (the visible viewport after all parent clipping). If the
intersection has zero area, skip all cell processing entirely.
### Three code paths
1. **Offscreen** (`intersection.size <= 0`): Early exit, process 0 cells
2. **Fully visible** (`intersection == bounds`): Fast path, stream cells
directly (no allocation)
3. **Partially clipped**: Group cells by line, skip/take visible rows
only
### Key insight: filter by screen position, not buffer coordinates
The previous approach tried to filter cells by `cell.point.line`
(terminal buffer coordinates), which breaks in Scrollable mode where
cells can have negative line numbers for scrollback history.
The new approach filters by **screen position** using
`chunk_by(line).skip(N).take(M)`, which works regardless of the actual
line numbers because we're filtering on enumerated line group index.
## Testing
Added comprehensive unit tests for:
- Screen-position filtering with positive lines (Inline mode)
- Screen-position filtering with negative lines (Scrollable mode with
scrollback)
- Edge cases (skip all, positioning math)
- Unified filtering works for both modes
Manually verified:
- Terminal fully visible (no clipping) ✓
- Terminal clipped from top/bottom ✓
- Terminal completely outside viewport ✓
- Scrollable terminals with scrollback history ✓
- Selection/interaction still works ✓
Release Notes:
- Improved Agent Panel performance when terminals are scrolled
offscreen.
/cc @as-cii
There are some too long lines which make `rustfmt` unable to format the
file, which in turn makes editing and working with this file rather
hard. This PR fixes this.
Release Notes:
- N/A
We adjusted the labels some time ago, but never took care of the `good
first issue` notifier that posts the good first issues to discord.
Adjusting the label accordingly so that it notifies people again.
Release Notes:
- N/A
Release Notes:
- git: Added the ability to copy a commit's SHA in the commit view.
---------
Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
The documentation referenced a “Curated board of issues” GitHub Project
that no longer exists.
The linked project returns a 404, and only three public projects are
currently available under
zed-industries.
This PR removes the outdated reference. Documentation-only change.
Release Notes:
- N/A
Closes#23158
Release Notes:
- Added a right-click context menu for the thread view in the agent
panel.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
In https://github.com/zed-industries/zed/pull/45440, we're implementing
the ability to right-click in the agent panel and copy the rendered
markdown. However, that presented itself as not as straightforward as
just making the menu item fire the `CopyAsMarkdown` action because any
selection in markdown is cleared after a new mouse click, and for the
right-click copy menu item to work, we need to persist that selection
even after the menu itself is opened and the "Copy" menu item is
clicked.
This all demanded a bit of work in the markdown file itself, and given
we may want to use this functionality for other non-agent thread view
markdown use cases in the future, I felt like it'd be better breaking it
down into a separate PR that we can more easily track in the future.
The context menu still needs to be built in the place where the markdown
is created and rendered, though. This PR only adds the infrastructure
needed so that this menu can simply fire the `CopyAsMarkdown` and make
the copying work.
Release Notes:
- N/A
`2x4` is not nearly enough for some of the grammars in use, hence change
this to a larger runner.
Also, reduce the size for the Rust runners a bit, as they don't need to
be quite as large for the amount of Rust code we have in extensions.
Release Notes:
- N/A
This PR improves the `edit prediction: Capture Example` in several ways:
* fixed bugs in how the uncommitted diff was calculated
* added a `edit_predictions.examples_dir` setting that can be set in
order to have the action automatically save examples into the given
folder
* moved the action into the `edit_predictions` crate, in preparation for
collecting this data passively from end users, when they have opted in
to data sharing, similar to what we did for Zeta 1
Release Notes:
- N/A
This PR adds the ability to favorite models for external agents—writing
to the settings in the `agent_servers` key—as well as a handful of other
improvements:
- Make the cycling keybinding `alt-enter` work for the inline assistant
as well as previous user messages
- Better organized the keybinding files removing some outdated
agent-related keybinding definitions
- Renamed the inline assistant key context to "InlineAssistant" as
"PromptEditor" is old and confusing
- Made the keybindings to rate an inline assistant response visible in
the thumbs up/down button's tooltip
- Created a unified component for the model selector tooltip given we
had 3 different places creating the same element
- Make the "Cycle Favorited Models" row in the tooltip visible only if
there is more than one favorite models
Release Notes:
- agent: External agents also now support the favoriting model feature,
which comes with a handy keybinding to cycle through the favorite list.
## Documentation Update Summary
### Changes Made
| File | Change | Related Code |
| --- | --- | --- |
| `docs/src/ai/edit-prediction.md` | Updated Codestral setup
instructions to use Settings Editor path instead of outdated
`agent::OpenSettings` action reference | Settings Editor provider
configuration flow |
### Rationale
The primary documentation update addresses outdated instructions in the
Codestral setup section. The original text referenced an
`agent::OpenSettings` action that directed users to an "Agent Panel
settings view" which no longer reflects the current UI flow. The updated
instructions now guide users through the Settings Editor with
platform-specific keyboard shortcuts and provide an alternative status
bar path.
### Review Notes
- **Codestral instructions**: Reviewers should verify the Settings
Editor navigation path (`Cmd+,` → search "Edit Predictions" →
**Configure Providers**) matches the current Zed UI
- **Status bar alternative**: The alternative path via "edit prediction
icon in the status bar" should be confirmed as accurate
---
## Update from 2025-12-21 20:25
---
**Source**: [#44914](https://github.com/zed-industries/zed/pull/44914) -
settings_ui: Add Edit keybindings button
**Author**: @probably-neb
Now I have all the context needed to create a comprehensive
documentation update summary.
## Documentation Update Summary
### Changes Made
| File | Change | Related Code |
| --- | --- | --- |
| docs/src/ai/agent-panel.md | Added documentation for `agent::PasteRaw`
action, explaining automatic @mention formatting for pasted code and how
to bypass it | PR #45254 |
### Rationale
PR #45254 ("agent_ui: Improve UX when pasting code into message editor")
introduced the `agent::PasteRaw` action, which allows users to paste
clipboard content without automatic formatting. When users copy
multi-line code from an editor buffer and paste it into the Agent panel,
Zed now automatically formats it as an @mention with file context. The
`PasteRaw` action provides a way to bypass this behavior when raw text
is preferred.
This documentation update ensures users can discover both:
1. The new automatic @mention formatting behavior
2. The keybinding to bypass it when needed
### Review Notes
- The new paragraph was placed in the "Adding Context" section,
immediately after the existing note about image pasting support—this
maintains logical flow since both relate to pasting behavior
- Uses the standard `{#kb agent::PasteRaw}` syntax for keybinding
references, consistent with other keybinding documentation in the file
- The documentation passed Prettier formatting validation without
modifications
---
### Condensed Version (for commit message)
```
docs(agent-panel): Document PasteRaw action for bypassing auto @mention formatting
Added explanation that multi-line code pasted from editor buffers is
automatically formatted as @mentions, with keybinding to paste raw text.
Related: PR #45254
```
Release Notes:
- N/A
---------
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Closes#44720
Release Notes:
- Fixed dock panel button tooltips not being dismissed when toggling
panels via keyboard shortcut
**Problem:** When hovering over a dock panel button and using a keyboard
shortcut to toggle the panel, the tooltip remains visible with stale
content. This is inconsistent with mouse click behavior, where the
tooltip is dismissed on mouse down.
**Solution:** Include the panel's active state in the button's element
ID. When the state changes, the element ID changes (e.g., `"DebugPanel"`
→ `"DebugPanel-active"`), which causes GPUI to discard the old element
state including the cached tooltip.
**Testing:** Manually verified:
1. Hover over a dock panel button, wait for tooltip
2. Press keyboard shortcut to toggle the panel
3. Tooltip is now dismissed (consistent with mouse click behavior)
https://github.com/user-attachments/assets/ed92fb6c-6c22-44e2-87e3-5461d35f7106
---------
Co-authored-by: MrSubidubi <finn@zed.dev>
Draft as a base for continuing the discussion in #8008 : adds a
`SplitOperation` enum to support bindings like `["pane::SplitLeft",
{"operation": "Clear"}]`
To be discussed @MrSubidubi and others:
- Naming: Generally not happy with names yet and specifically `Empty` is
unclear, e.g., what does this mean for terminal panes? Added placeholder
code to split without cloning, but unsure what users would expect in
this case.
- ~~I removed `SplitAndMoveXyz` actions but I guess we should keep them
for backwards compatibility?~~
- May have missed details in the move implementation. Will check the
code again for opportunities to refactor more code after we agree on the
approach.
- ~~Tests should go to `crates/collab/src/tests/integration_tests.rs`?~~
Closes#8008
Release Notes:
- Add `pane::Split` mode (`{ClonePane,EmptyPane,MovePane}`) to allow
creating an empty buffer.
---------
Co-authored-by: Finn Evers <finn.evers@outlook.de>
Co-authored-by: MrSubidubi <finn@zed.dev>
* Abs path trust should transitively trust all single file worktrees on
the same host
* Init worktree trust on the client side even when devcontainers are
run: remote host unconditionally checks trust, hence the client has to
keep track of it and respond with approves/declines.
Do trust all devcontainers' remote worktrees, as containers are isolated
and "safe".
Release Notes:
- N/A
The function returns the previous focus handle, which may be null if
there is no previous focus. Unfortunately that also overlaps with the
error return value, so winapi will hand us a error 0 back in those cases
which we log ...
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Closes#18287
Release Notes:
- Added autocomplete for lsp initialization_options
## Description
This MR adds the following code-changes:
- `initialization_options_schema` to the `LspAdapter` to get JSON
Schema's from the language server
- Adds a post-processing step to inject schema request paths into the
settings schema in `SettingsStore::json_schema`
- Adds an implementation for fetching the schema for rust-analyzer which
fetches it from the binary it is provided with
- Similarly for ruff
<img width="857" height="836" alt="image"
src="https://github.com/user-attachments/assets/3cc10883-364f-4f04-b3b9-3c3881f64252"
/>
## Open Questions(Would be nice to get some advice here)
- Binary Fetching:
- I'm pretty sure the binary fetching is suboptimal. The main problem
here was getting access to the delegate but i figured that out
eventually in a way that i _hope_ should be fine.
- The toolchain and binary options can differ from what the user has
configured potentially leading to mismatches in the autocomplete values
returned(these are probably rarely changed though). I could not really
find a way to fetch these in this context so the provided ones are for
now just `default` values.
- For the trait API it is just provided a binary, since i wanted to use
the potentially cached binary from the CachedLspAdapter. Is that fine
our should the arguments be passed to the LspAdapter such that it can
potentially download the LSP?
- As for those LSPs with JSON schema files in their repositories i can
add the files to zed manually e.g. in
languages/language/initialization_options_schema.json, which could cause
mismatches with the actual binary. Is there a preferred approach for Zed
here also with regards to updating them?
Continuing of #44334
I removed disabling of vsync which was causing jitter on some external
displays
cc: @maxbrunsfeld @Anthony-Eid
Release Notes:
- Mark metal layers opaque for non-transparent windows to allow
direct-to-display when supported
Signed-off-by: Marco Mihai Condrache <52580954+marcocondrache@users.noreply.github.com>
Release Notes:
- Fixed spurious "no checkpoint" error in agent panel
---
## Summary
`update_last_checkpoint` would call `last_user_message()` twice - once
at the start to capture the checkpoint, and again in an async closure
after the checkpoint comparison completed. If a new user message without
a checkpoint was added between these two calls, the second call would
find the new message and fail with "no checkpoint".
## Fix
Capture the user message ID at the start and use `user_message_mut(&id)`
in the async closure to find the specific message.
cc @mikayla-maki
This PR fixes two issues with regards to markdown codeblocks rendered in
tool call input and output content display:
- the JSON code snippets weren't properly indented
- codeblocks weren't being rendered in unique containers; e.g., if you
hovered one scrollbar, all of them would also be hovered, even though
horizontal scrolling itself worked properly
Here's the end result:
https://github.com/user-attachments/assets/3d6daf64-0f88-4a16-a5a0-94998c1ba7e2
Release Notes:
- agent: Fix scrollbar and JSON indentation for tool call input/output
content's markdown codeblocks.
- Make the buttons capable of changing the editor's content
(incrementing or decrementing the value)
- Make arrow key up and down increment and decrement the editor value
- Tried to apply a bit of DRY here by creating some functions that can
be reused across the buttons and editor given they all essentially do
the same thing (change the value)
- Fixed an issue where the editor would not allow focus to move
elsewhere, making it impossible to open a dropdown, for example, if your
focus was on the number field's editor
Release Notes:
- N/A
Closes https://github.com/zed-industries/zed/issues/43208
This PR essentially unblocks the editable number field. The function
that shapes editor lines was hard-coding text alignment to the left,
meaning that whatever different alignment we'd pass through
`EditorStyles`would be ignored. To solve this, I just added a text align
and align width fields to the line paint function and updated all call
sites keeping the default configuration. Had to also add an
`alignment_offset()` helper to make sure the cursor positioning, the
selection background element, and the click-to-focus functionality were
kept in-sync with the non-left aligned editor.
Then... the big star of the show here is being able to add the `mode`
method to the number field, which uses `TextAlign::Center`, thus making
it work as we designed it to work.
https://github.com/user-attachments/assets/3539c976-d7bf-4d94-8188-a14328f94fbf
Next up, is turning the number filed to edit mode where applicable.
Release Notes:
- Fixed a bug where different text alignment configurations (i.e.,
center and right-aligned) wouldn't take effect in editors.
Currently on x11, gpui PopUp windows only rely on the "notification"
type in order to indicate that they should spawn as floating window.
Several window managers (leftwm in my case, but it also seems to be the
case for dwm and ratpoison) do not this property into account thus not
spawning them as float. On the other hand, using Floating instead of
PopUp do make those windows spawn as floating, as these window manager
do take into account the (older) "dialog" type.
The [freedekstop
documentation](https://specifications.freedesktop.org/wm/1.5/ar01s05.html#id-1.6.7)
does seem to suggest that these windows should also have the override
redirect property :
> This property is typically used on override-redirect windows.
Note that this also disables pretty much all interactions with the
window manager (such as moving the window, resizing etc...)
Release Notes:
- Fix popup windows not spawning floating sometime on x11
This fixes an X11 scrolling issue where Zed may jump by a large amount
due to the scroll valuator state not being reset when the window loses
focus. If you Alt-Tab away from Zed, scroll in another application, then
return, the first scroll event in Zed applies the entire accumulated
delta instead of a single step.
The missing FocusOut reset was originally identified in issue #34901.
Resetting scroll positions on FocusOut matches the behavior already
implemented in the XinputLeave handler and prevents this jump.
Closes#34901Closes#40538
Release Notes:
- Fixed an X11 issue where Alt-Tabbing to another application,
scrolling, and returning to Zed could cause the next scroll event to
jump by a large amount.
I've just enriched the existing tab_stop.rs example for GPUI with a
demonstration of tab_group. I don't think tab groups existed when the
original example was written.
(I didn't understand the behaviour for tab_group from the doccomments
and the example was missing, so I think this is a productive PR)
Release Notes:
- N/A
The failure would happen if the current version of the file was open as
an editor. This happened because the git blob and current version of the
buffer would have the same `ProjectPath`.
The fix was adding a new `DiskState::Historic` variant to represent
buffers that are past versions of a file (usually a snapshot from
version control). Historic buffers don't return a `ProjectPath` because
the file isn't real, thus there isn't and shouldn't be a `ProjectPath`
to it. (At least with the current way we represent a project path)
I also change the display name to use the local OS's path style instead
of being hardcoded to Posix, and cleaned up some code too.
Release Notes:
- N/A
---------
Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: cameron <cameron.studdstreet@gmail.com>
Co-authored-by: xipengjin <jinxp18@gmail.com>
Reverts zed-industries/zed#44334
From my testing, this PR introduced screen tearing, or some kind of
strange visual artifact, when scrolling at medium speed on a large
display.
Release notes:
- N/A
#40291 made floating windows always stay on top, which made the settings
ui window always on top of Zed. To maintain the old behavior, this PR
changes the setting window to be a normal window.
Release Notes:
- N/A
Stashes local changes before branch checkout in droid auto docs CLI
Release Notes:
- N/A
---------
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
## Problem
When users paste or drag large images into the agent panel, the encoded
payload can exceed upstream provider limits (e.g., Anthropic's 5MB
per-image limit), causing API errors.
## Solution
Enforce a default 5MB limit on encoded PNG bytes in
`LanguageModelImage::from_image`:
1. Apply existing Anthropic dimension limits first (1568px max in either
dimension)
2. Iteratively downscale by ~15% per pass until the encoded PNG is under
5MB
3. Return `None` if the image can't be shrunk within 8 passes
(fail-safe)
The limit is enforced at the `LanguageModelImage` conversion layer,
which is the choke point for all image ingestion paths (agent panel
paste/drag, file mentions, text threads, etc.).
## Future Work
The 5MB limit is a conservative default. Provider-specific limits can be
introduced later by adding a `from_image_with_constraints` API.
## Testing
Added a regression test that:
1. Generates a noisy 4096x4096 PNG (guaranteed >5MB)
2. Converts it via `LanguageModelImage::from_image`
3. Asserts the result is ≤5MB and was actually downscaled
---
**Note:** This PR builds on #45312 (prompt store fail-open fix). Please
merge that first.
cc @rtfeldman
---------
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Droid needs a specific model with a date
Release Notes:
- N/A
---------
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
In the case of large vertical_scroll_margin, we could scroll up such
that the assistant was out of view. Now, keep it no lower than the
center of the editor.
Closes#18058
Release Notes:
- N/A
This commit fixes an issue where saving UTF-16 files resulted in UTF-8
bytes due to `encoding_rs` default behavior. It also introduces a
heuristic to detect BOM-less UTF-16 and binary files.
Changes:
- Manually implement UTF-16LE/BE encoding during file save to avoid
implicit UTF-8 conversion.
- Add `analyze_byte_content` to guess UTF-16LE/BE or Binary based on
null byte distribution.
- Prevent loading binary files as text by returning an error when binary
content is detected.
Special thanks to @CrazyboyQCD for pointing out the `encoding_rs`
behavior and providing the fix, and to @ConradIrwin for the suggestion
on the detection heuristic.
Closes#14654
Release Notes:
- (nightly only) Fixed an issue where saving files with UTF-16 encoding
incorrectly wrote them as UTF-8. Also improved detection for binary
files and BOM-less UTF-16.
Change from cli.factory.ai/install.sh to app.factory.ai/cli per official
Factory documentation.
Release Notes:
- N/A
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Closes#42586
This includes a rewrite of `calculate_relative_line_numbers()`. Now it's
linear-time with respect to the number of rows displayed, instead of
linear time with respect to the number of rows displayed _plus_ the
distance to the base row.
Release Notes:
- Improved performance when using relative line numbers in large files
- Fixed relative line numbers not appearing in sticky headers
Adds a multi-step agentic loop to github actions for opening a
once-daily documentation PR that can be merged only be a Zedi
Release Notes:
- N/A
---------
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Closes#17467
Release Notes:
- On macOS, buffer search now syncs with the system find pasteboard,
allowing <kbd>⌘E</kbd> and <kbd>⌘G</kbd> to work seamlessly across Zed
and other apps.
Closes #ISSUE
Release Notes:
- Fixed an issue where the `pane: close all items` action would give up
if you hit "Cancel" on the prompt for what to do with a dirty buffer
It's been a little that we've noticed some flickering and other weird
resizing behavior with text truncation in Zed:
https://github.com/user-attachments/assets/4d5691a3-cd3d-45e0-8b96-74a4e0e273d2https://github.com/user-attachments/assets/d1d0e587-7676-4da0-8818-f4e50f0e294e
Initially, we suspected this could be due to how we calculate the length
of a line to insert truncation, which is based first on the length of
each individual character, and then second goes through a pass
calculating the line length as a whole. This could cause mismatch and
culminate in our bug.
However, even though that felt like a reasonable suspicion, I realized
something rather simple at some point: the `truncate` and
`truncate_start` methods in the `Label` didn't use `whitespace_nowrap`.
If you take Tailwind as an example, their `truncate` utility class takes
`overflow: hidden; text-overflow: ellipsis; white-space: nowrap;`. This
pointed out to a potential bug with `whitespace_nowrap` where that was
blocking truncation entirely, even though that's technically part of
what's necessary to truncate as you don't want text that will be
truncated to wrap.
Ultimately, what was happening was that the text element was caching its
layout based on its `wrap_width` but not considering its
`truncate_width`. The truncate width is essentially the new definitive
width of the text based on the available space, which was never being
computed. So the fix here was to add `truncate_width.is_none()` to the
cache validation check, so that it only uses the cached text element
size _if the truncation width is untouched_. But if that changes, we
need to account for the new width. Then, in the Label component, we
added `min_w_0` to allow the label div to shrink below its original
size, and finally, we added `whitespace_nowrap()` as the cache check
fundamentally fixed that method's problem.
In a future PR, we can basically remove the `single_line()` label method
because: 1) whenever you want a single label, you most likely want it to
truncate, and 2) most instances of `truncate` are already followed by
`single_line` in Zed today, so we can cut that part.
Result is no flickering with truncated labels!
https://github.com/user-attachments/assets/ae17cbde-0de7-42ca-98a4-22fcb452016b
Release Notes:
- Fixed a bug in GPUI where truncated text would flicker as you resized
the container in which the text was in.
Co-authored-by: Lukas Wirth <me@lukaswirth.dev>
Closes#5089
Release notes:
- Markdown lists now continue automatically when you press Enter
(unordered, ordered, and task lists). This can be configured with
`extend_list_on_newline` (default: true).
- You can now indent list markers with Tab to quickly create nested
lists. This can be configured with `indent_list_on_tab` (default: true).
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
From Zed's title bar, you can click on buttons to open three modal
pickers: remote projects, projects, and branches. All of these pickers
use the modal layer, which by default, renders them centered on the UI.
However, a UX issue we've been bothered by is that when you _click_ to
open them, they show up just way too far from where your mouse likely is
(nearby the trigger you just clicked). So, this PR introduces a
`ModalPlacement` enum to the modal layer, so that we can pick between
the "centered" and "anchored" options to render the picker. This way, we
can make the pickers use anchored positioning when triggered through a
mouse click and use the default centered positioning when triggered
through the keybinding.
One thing to note is that the anchored positioning here is not as
polished as regular popovers/dropdowns, because it simply uses the x and
y coordinates of the click to place the picker as opposed to using
GPUI's `Corner` enum, thus making them more connected to their triggers.
I chose to do it this way for now because it's a simpler and more
contained change, given it wouldn't require a tighter connection at the
code level between trigger and picker. But maybe we will want to do that
in the near future because we can bake in some other related behaviors
like automatically hiding the button trigger tooltip if the picker is
open and changing its text color to communicate which button triggered
the open picker.
https://github.com/user-attachments/assets/30d9c26a-24de-4702-8b7d-018b397f77e1
Release Notes:
- Improved the UX of title bar modal pickers (remote projects, projects,
and branches) by making them open closer to the trigger when triggering
them with the mouse.
This adds the following Vim commands:
- `:r[ead] [name]`
- `:{range}r[ead] [name]`
The most important parts of this feature are outlined
[here](https://vimhelp.org/insert.txt.html#%3Ar).
The only intentional difference between this and Vim is that Vim only
allows `:read` (no filename) for buffers with a file attached. I am
allowing it for all buffers because I think that could be useful.
Release Notes:
- vim: Added the [`:r[ead] [name]` Vim
command](https://vimhelp.org/insert.txt.html#:read)
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
Fixes#29073
This PR reduces unnecessary GPU usage by being more selective about when
we present frames to prevent display underclocking (VRR optimization).
## Problem
Previously, we would keep presenting frames for 1 second after *any*
input event, regardless of whether it triggered a re-render. This caused
unnecessary GPU work when the user was idle or during low-frequency
interactions.
## Solution
1. **Only track input that triggers re-renders**: We now only record
input timestamps when the input actually causes the window to become
dirty, rather than on every input event.
2. **Rate-based activation**: The VRR optimization now only activates
when input arrives at a high rate (≥ 60fps over the last 100ms). This
means casual mouse movements or occasional keystrokes won't trigger
continuous frame presentation.
3. **Sustained optimization**: Once high-rate input is detected (e.g.,
during scrolling or dragging), we sustain frame presentation for 1
second to prevent display underclocking, even if input briefly pauses.
## Implementation
Added `InputRateTracker` which:
- Tracks input timestamps in a 100ms sliding window
- Activates when the window contains ≥ 6 events (60fps × 0.1s)
- Extends a `sustain_until` timestamp by 1 second each time high rate is
detected
Release Notes:
- Reduced GPU usage when idle by only presenting frames during bursts of
high-frequency input.
This fixes a number of issues where zed depends on the order of polling which changed when switching scheduler. We have adjusted the algorithm so it matches the previous order while keeping the prioritization feature.
Release Notes:
- N/A
This PR is an additive change introducing the `truncate_start` method to
labels, which gives us the ability to add an ellipsis at the beginning
of the text as opposed to the regular `truncate`. This will be generally
used for truncating file paths, where the end is typically more relevant
than the beginning, but given it's a general method, there's the
possibility to be used anywhere else, too.
<img width="500" height="690" alt="Screenshot 2025-12-17 at 12 35@2x"
src="https://github.com/user-attachments/assets/f853f5a3-60b3-4380-a11c-bb47868a4470"
/>
Release Notes:
- N/A
---------
Co-authored-by: Lukas Wirth <lukas@zed.dev>
Closes#42268
We've migrated user selections when a given workspace has a single
worktree (as then we could determine what the target worktree is).
Release Notes:
- python: Fixed selected virtual environments not being
persisted/deserialized correctly within long-running Zed sessions (where
multiple different projects might've been opened). This is a breaking
change for users of multi-worktree projects - your selected toolchain
for those projects will be reset.
Co-authored-by: Dino <dino@zed.dev>
- adjust wording for the upcoming simplified process
- upgrade to the github action version that has a fix for configuring issue types the bot should look at
- add two inputs for the manual runs of stalebot that help testing it in a safe and controlled manner
Release Notes:
- N/A
Closes#23367
**Summary**
- Prevents inline diagnostics, code actions, blame annotations, and
hover popovers from overlapping with the right-click context menu by
checking for `mouse_context_menu` presence before rendering these UI
elements.
PS: Same behaviour is present in other editors like VS Code.
**Screen recording**
https://github.com/user-attachments/assets/8290412b-0f86-4985-8c70-13440686e530
Release Notes:
- N/A *or* Added/Fixed/Improved ...
## Summary
Fixes arithmetic underflow panics in `terminal_scrollbar.rs` by
converting unsafe subtractions to `saturating_sub`.
Closes#45281
## Problem
Two locations perform raw subtraction on `usize` values that panic when
underflow occurs:
- `offset()`: `state.total_lines - state.viewport_lines -
state.display_offset`
- `set_offset()`: `state.total_lines - state.viewport_lines`
This happens when `total_lines < viewport_lines + display_offset`, which
can occur during terminal creation, with small window sizes, or when
display state becomes stale.
## Solution
Replace the two unsafe subtractions with `saturating_sub`, which returns
0 on underflow instead of panicking.
Also standardizes the existing `checked_sub().unwrap_or(0)` in
`max_offset()` to `saturating_sub` for consistency across the file.
## Changes
- N/A
Closes #ISSUE
Uses the existing `--dump-all-actions` arg on the Zed binary to generate
an asset of all of our actions so that the `docs_preprocessor` can
injest it, rather than depending on the Zed crate itself to collect all
action names
Release Notes:
- N/A *or* Added/Fixed/Improved ...
---------
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
- Both the mode, profile, and model selectors have the option to cycle
through its options with a keybinding. In the tooltip that shows it, in
some of them the "Cycle Through..." label was at the top, and in others
at the bottom. Now it's all at the bottom.
- We used different language in different places for "going to a file".
The tool call edit card's header said "_Jump_ to File" while the edit
files list said "_Go_ to File". Now it's both "Go to File".
Release Notes:
- N/A
I wanted a way to make it easy to figure out which version of a language
server Zed is running. Now, you get a tooltip when hovering on a
language server in the Language Servers popover.
<img width="498" height="168" alt="SCR-20251218-ovln"
src="https://github.com/user-attachments/assets/1ced4214-b868-4405-8881-eb7c0b75a53e"
/>
This PR also fixes a bug. We had existing code to open a tooltip on
these language server entrees and display the language server message,
which was never fully wired up for `CustomEntry`s. Now, in this PR, we
will show show either version, message, or both, in the documentation
aside, depending on what the server has given us.
Mostly done with Droid (using GPT-5.2), with manual review and multiple
follow ups to guide it into using existing patterns in the codebase,
when it did something abnormal.
Release Notes:
- Added language server version in a tooltip on language server hover
---------
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This PR simplifies how we display thread timestamps in the agent panel's
history view. For threads that are older-than-yesterday, we just show
how many days ago that thread was had in. Hovering over the thread item
shows you both the title and the full date, if needed (time and date).
<img width="450" height="786" alt="Screenshot 2025-12-18 at 5 24@2x"
src="https://github.com/user-attachments/assets/11416e9b-f1b0-4307-9db0-988a95a316a1"
/>
Release Notes:
- N/A
Closes#37902
Release Notes:
- Enable LSP Message action items for more language servers. These are interactive prompts, often for things like downloading build inputs for a project.
Closes#43355
Fixes the issue were code actions with long labels would get cut off
without being able to see the full description. We now properly truncate
those labels with an ellipsis and show the full description in an aside.
Release Notes:
- Added ellipsis to truncated code actions and an aside showing the full
action description.
Closes#13304
Release Notes:
- Add global `git status` and `git diff` on/off in one place instead of
control everywhere
We can first review to ensure this change meets both `Zed` and user
requirements, as well as code rules. Currently, we only support
user-level settings. We can wait for this PR:
https://github.com/zed-industries/zed/pull/43173 to be merged, then
modify it to support both user and project levels.
When profiling Zed with Instruments, a warning appears indicating that
surfaces cannot be pushed directly to the display as they are
non-opaque. This happens because the metal layer is currently marked as
non-opaque by default, even though the window itself is not transparent.
<img width="590" height="55" alt="image"
src="https://github.com/user-attachments/assets/2647733e-c75b-4aec-aa19-e8b2ffd6194b"
/>
Metal on macOS can bypass compositing and present frames directly to the
display when several conditions are met. One of those conditions is that
the backing layer must be declared opaque. Apple’s documentation notes
that marking layers as opaque allows the system to avoid unnecessary
compositing work, reducing GPU load and improving frame pacing
Ref:
https://developer.apple.com/documentation/metal/managing-your-game-window-for-metal-in-macos
This PR updates the Metal renderer to mark the layer as opaque whenever
the window does not use transparency. This makes Zed eligible for
macOS’s direct-to-display optimization in scenarios where the system can
apply it.
Release Notes:
- gpui: Mark metal layers opaque for non-transparent windows to allow
direct-to-display when supported
---------
Signed-off-by: Marco Mihai Condrache <52580954+marcocondrache@users.noreply.github.com>
Closes #ISSUE
Removes a few eager container clones and iterations.
Added a todo to `get_prev_tab_group_window` and
`get_next_tab_group_window`. They seem to use `HashMap::keys()` for
choosing the previous tab group, however `.keys()` returns an arbitrary
order, so I'm not sure if previous actually means anything here. Conrad
seems to have worked on this part previously, maybe he has some
insights. That can possibly be a follow-up PR, but I'd be willing to
work on it here as well since the other changes are so simple.
Release Notes:
- N/A
Follow up to a regression that happened when we introduced agent servers
that made everywhere displaying agent names use the extension name
instead of the display name. This has been since fixed in other places
and this PR now updates the agent panel's message editor, too:
| Before | After |
|--------|--------|
| <img width="1154" height="254" alt="Screenshot 2025-12-18 at 12 54
2@2x"
src="https://github.com/user-attachments/assets/5f3de9f9-4e11-42f6-90c2-56fc8cdff32e"
/> | <img width="1154" height="254" alt="Screenshot 2025-12-18 at 12
54@2x"
src="https://github.com/user-attachments/assets/46ed5c45-7e1d-4cc6-b219-b6cc19206d1b"
/> |
Release Notes:
- N/A
Closes#42934
Release Notes:
- Fix toggling adjacent git-diff hunks based on the reported behaviour
in #42934
---------
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
Closes #ISSUE
A [modal dialog](https://en.wikipedia.org/wiki/Modal_window) window is a
window that demands the user's immediate attention and blocks
interaction with other parts of the application until it's closed.
- On Windows this is done by disabling the parent window when the dialog
window is created and re-enabling the parent window when closed.
- On Wayland this is done using the
[`XdgDialog`](https://wayland.app/protocols/xdg-dialog-v1) protocol,
which hints to the compositor that the dialog should be modal. While
compositors like GNOME and KDE block parent interaction automatically,
the XDG specification does not guarantee this behavior, compositors may
deliver events to the parent window unfiltered. Since the specification
explicitly requires clients to implement event filtering logic
themselves, this PR implements client-side blocking in GPUI to ensure
consistent modal behavior across all Wayland compositors, including
those like Hyprland that don't block parent interaction.
- On X11 this is done by enabling the application window property
[`_NET_WM_STATE_MODAL`](https://specifications.freedesktop.org/wm/latest/ar01s05.html#id-1.6.8)
state.
I'm unable to implement this on MacOS as I lack the experience and the
hardware to test it. If anyone is interested on implementing this let me
know.
|Window|Linux (wayland)| Linux (x11) |MacOS|
|-|-|-|-|
|<video
src="https://github.com/user-attachments/assets/bfd0733a-445d-4b63-ac6b-ebe098a7dc74"></video>|<video
src="https://github.com/user-attachments/assets/024cd6ec-ff81-4250-a5be-5d207a023f8c"></video>|
N/A | <video
src="https://github.com/user-attachments/assets/656e60a5-26b2-4ee2-8368-1fbbe872453c"></video>|
TODO:
- [x] Block parent interaction client-side on X11
Release Notes:
- Added modal dialog window kind on GPUI
---------
Co-authored-by: Jason Lee <huacnlee@gmail.com>
Co-authored-by: Anthony Eid <anthony@zed.dev>
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Follow up to #42982
Release Notes:
- agent: Allow pasting code without formatting via ctrl/cmd-shift-v.
- agent: Fixed an issue where pasting a single line of code would always
insert an @mention
## Summary
Fix panic "cannot update workspace::pane::Pane while it is already being
updated" when dragging terminal tabs to split the pane.
## Problem
When dragging a terminal tab to create a split, the app panics due to
re-entrancy: the drop handler calls `terminal_panel.center.split()`
synchronously, which invokes `mark_positions()` that tries to update all
panes in the group. When the pane being updated is part of the terminal
panel's center group, this causes a re-entrancy panic.
## Solution
Defer the split operation using `cx.spawn_in()`, similar to how
`move_item` was already deferred in the same handler. This ensures the
split (and subsequent `mark_positions()` call) runs after the current
pane update completes.
## Test plan
- Open terminal panel
- Create a terminal tab
- Drag the terminal tab to split the pane
- Verify no panic occurs and split works correctly
Closes#44717
Sometimes, we show the user the agent's auth methods because we got an
AuthRequired error.
However, there are also several ways a user can choose to re-enter the
authentication flow even though they are still logged in.
This has caused some confusion with several users, where after logging
in, they type /login again to see if anything changed, and they saw an
"Authentication Required" warning.
So, I made a distinction in the UI if we go to this flow from a concrete
error, or if not, made the language less error-like to help avoid
confusion.
| Before | After |
|--------|--------|
| <img width="1154" height="446" alt="Screenshot 2025-12-18 at 10
54@2x"
src="https://github.com/user-attachments/assets/9df0d59a-2d45-4bfc-ba85-359dd1a4c8ae"
/> | <img width="1154" height="446" alt="Screenshot 2025-12-18 at 10
53@2x"
src="https://github.com/user-attachments/assets/73a9fb45-4e6f-4594-8795-aaade35b2a72"
/> |
Release Notes:
- N/A
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-authored-by: Miguel Raz Guzmán Macedo <miguel@zed.dev>
They count the requested max_output_tokens against the prompt total.
Seems like a bug on their end as most other providers don't do this, but
now we just default to None for the main models and let the API use its
default behavior which works just fine.
Closes: #45134
Release Notes:
- deepseek: Fix issue with Deepseek API that was causing the token limit
to be reached sooner than necessary
Closes#45179
## Summary
Fixes the focus behavior when creating terminals with
`RevealStrategy::NoFocus` or `RevealStrategy::Never`. Previously,
terminals would still receive focus if the terminal pane already had
focus, contradicting the documented behavior.
## Changes
- **`add_terminal_task()`**: Changed focus logic to only focus when
`RevealStrategy::Always`
- **`add_terminal_shell()`**: Same fix
The fix changes:
```rust
// Before
let focus = pane.has_focus(window, cx)
|| matches!(reveal_strategy, RevealStrategy::Always);
// After
let focus = matches!(reveal_strategy, RevealStrategy::Always);
```
## Impact
This affects:
- Vim users running `:!command` (uses `NoFocus`)
- Debugger terminal spawning (uses `NoFocus`)
- Any programmatic terminal creation requesting background behavior
Release Notes:
- Fixed terminal focus behavior to respect `RevealStrategy::NoFocus` and
`RevealStrategy::Never` settings when the terminal pane already has
focus.
It seems we unintentionally changed the default behavior of if we use
the gemini on the path in #40663
Changing this back so by default we use a managed version of the CLI so
we can better control min versions and the like, but still allow people
to override if they need to.
Release Notes:
- N/A
Previously, when opening a new project (one that was never opened
before), the window bounds restoration logic would fall through to
GPUI's default window sizing instead of using the last known window
bounds.
This change consolidates the window bounds restoration logic so that
both empty workspaces and new projects use the stored default window
bounds, making the behavior consistent: any new window will use the last
resized window's size and position.
Closes#45092
Release Notes:
- Fixed new files and projects opening with default window size instead
of the last used window size.
Follow up to https://github.com/zed-industries/zed/pull/44297.
Initial implementation in ce884443f1 used
`Arc` to store the reference to the hash map inside the iterator while
keeping the lifetime static. The code was later simplified in
5151b22e2e to build the list eagerly but
the Arc was forgotten, although it became unnecessary.
cc @bennetbo
Release Notes:
- N/A
This is already noted in our `default-macos.json`, but was never
surfaced in our docs for some reason. A user noted their LSP completions
were not working because they were not aware of the conflicting global
shortcut.
Ref:
https://github.com/zed-industries/zed/issues/44970#issuecomment-3664118523
Release Notes:
- N/A
The change simplifies the `max_token_count` and `max_output_tokens`
methods by grouping Gemini models with identical token limits.
Release Notes:
- N/A
Currently, extensions cannot have tests that call methods like
`label_for_symbol` and `label_for_completion`, because those methods
take a `LanguageServerId`, and that type is opaque, and cannot be
constructed outside of the `zed_extension_api` crate.
This PR makes it possible to construct those types from strings, so that
it's more straightforward to write unit tests for these LSP adapter
methods.
Release Notes:
- N/A
When running Codex CLI, Claude Code, or other TUI agents in Zed’s
terminal, pasting images wasn’t supported — Zed
treated all clipboard content as plain text and simply pushed it into
the PTY, so the agent never saw the image data.
This change makes terminal pastes behave like they do in a native
terminal: if the clipboard contains an image, Zed now emits a raw Ctrl+V
to the PTY so the agent can read the system clipboard itself.
Release Notes:
- Fixed terminal-launched Codex/Claude sessions by forwarding Ctrl+V for
clipboard images so agents can attach them
Generated by AI.
`DocumentTypes.plist` declares `CFBundleTypeIconFile` as `Document` for
Zed’s document types, but the macOS bundle did not include
`Contents/Resources/Document.icns`, causing Finder to fall back to
generic icons.
This PR:
- Adds `crates/zed/resources/Document.icns` as a placeholder document
icon (currently derived from the app icon).
- Updates `script/bundle-mac` to copy it into the `.app` at
`Contents/Resources/Document.icns` during bundling.
- Adds `script/verify-macos-document-icon` for one-command validation.
## How to test (CLI)
1. Build a debug bundle:
- `./script/bundle-mac -d aarch64-apple-darwin`
2. Verify the bundle contains the referenced icon:
- `./script/verify-macos-document-icon
"target/aarch64-apple-darwin/debug/bundle/osx/Zed Dev.app"`
## Optional visual validation in Finder
- Pick a file (e.g. `.rs`), Get Info → Open with: Zed Dev → Change
All...
- Restart Finder: `killall Finder` (or log out/in)
@JosephTLyons — would you mind running the steps above and confirming
Finder shows Zed’s icon for source files after "Change All" + Finder
restart?
@danilo-leal — this PR ships a placeholder `Document.icns`. When the
real document icon is ready, replace
`crates/zed/resources/Document.icns` and the bundling script will
include it automatically.
Closes#44403.
Release Notes:
- TODO
---------
Co-authored-by: Matt Miller <mattrx@gmail.com>
Closes#28732
Release Notes:
- Opening the command palette or other modals no longer triggers
auto-save with the `{ "autosave": "on_focus_change" }` setting. This
reduces the chance of unwanted format changes when executing actions,
and fixes a race condition with `:w` in Vim mode
I think we're not triggering the after-release workflow because of
github's loop detection when you use the default GITHUB_TOKEN
Closes #ISSUE
Release Notes:
- N/A
Closes#26424
Supersedes #35328
Originally, `git::blame` uses its own `ParsedCommitMessage` as the
source for the commit information, including the PR section. This
changes unifies this with `git::repository` and `git_ui::git_panel` by
moving this and some other commit-related structs to `git::commit`
instead, and making both `git_ui::blame_ui` and `git_ui::git_panel` pull
their information from these structs.
Release notes :
- (Let's Git Together) Fixed the commit tooltip in the git panel not
showing information like avatars.
---------
Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
This PR ensures truncation works for the file paths, which should set up
the stage for when the new GPUI `truncation_start` method lands
(https://github.com/zed-industries/zed/pull/45122) so that we can use
for them. In the process of doing so and figuring it out why it wasn't
working as well before, I noticed some opportunities to clean up some UI
code: removing unnecessary styles, making the file easier to navigate
given all of the different UI conditions, etc.
Note: You might notice a subtle label flashing that comes with the label
truncation and that's a standalone GPUI bug that's also visible in other
surface areas of the app. I don't think it should block these changes
here as it's something we should fix on its own...
Release Notes:
- N/A
Otherwise, all *.json files under `zed` directory will be matched as
JSONC, e.g `zed/crates/vim/test_data/test_a.json` which is not right.
On top, `globset` considers that `zed/crates/vim/test_data/test_a.json`
matches `**/zed/*.json` glob (!).
Release Notes:
- N/A
Also adjust the code for streaming tool use to always use a
rewrite_section; remove insert_here entirely.
Release Notes:
- N/A
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
Related to
- #44407
This PR further improves performance for regex hyperlink finding by
eliminating unnecessary regex matching. Currently, we repeatedly search
for matches from the start of the line until the match contains the
hovered point. This is only required to support custom regexes which
match strings containing spaces, with multiple matches on a single line.
This isn't actually a useful scenario, and is no longer supported. This
PR changes to only search twice, the first match starting from the start
of the line, and the hovered word (space-delimited). The most dramatic
improvement is for long lines with many words.
In addition to the above changes, this PR:
- Adds test for the scenarios from #44407 and #44510
- Simplifies the logic added in #44407
Performance measurements
For the scenario from #44407, this improves the perf test's iteration
time from 1.22ms to 0.47ms.
main:
| Branch | Command | Iter/sec | Mean [ms] | SD [ms] | Iterations |
Importance (weight) |
|:---|:---|---:|---:|---:|---:|---:|
| main |
terminal_hyperlinks::tests::path::perf::pr_44407_hyperlink_benchmark |
819.64 | 937.60 | 2.20 | 768 | average (50) |
| this PR |
terminal_hyperlinks::tests::path::perf::pr_44407_hyperlink_benchmark |
2099.79 | 1463.20 | 7.20 | 3072 | average (50) |
Release Notes:
- terminal: Improve path hyperlink performance for long lines
This PR introduces support for Next Edit Suggestions while doing away
with calling legacy endpoints. In the process we've also removed support
for cycling completions, as NES will give us a single prediction, for
the most part.
Closes#30124
Release Notes:
- Zed now supports Copilot's [Next Edit
Suggestions](https://code.visualstudio.com/blogs/2025/02/12/next-edit-suggestions).
## Summary
Addresses #16965
This PR adds support for **opening and saving** files with legacy
encodings (non-UTF-8).
Previously, Zed failed to open files encoded in Shift-JIS, EUC-JP, Big5,
etc., displaying a "Could not open file" error screen. This PR
implements automatic encoding detection upon opening and ensures the
original encoding is preserved when saving.
## Implementation Details
1. **Worktree (Loading)**:
* Updated `load_file` to use `chardetng` for automatic encoding
detection.
* Files are decoded to UTF-8 internal strings for editing, while
preserving the detected `Encoding` metadata.
2. **Language / Buffer**:
* Added an `encoding` field to the `Buffer` struct to store the detected
encoding.
3. **Worktree (Saving)**:
* Updated `write_file` to accept the stored encoding.
* **Performance Optimization**:
* **UTF-8 Path**: Uses the existing optimized `fs.save` (streaming
chunks directly from Rope), ensuring no performance regression for the
vast majority of files.
* **Legacy Encoding Path**: Implemented a fallback that converts the
Rope to a contiguous `String/Bytes` in memory, re-encodes it to the
target format (e.g., Shift-JIS), and writes it to disk.
* *Note*: This fallback involves memory allocation, but it is necessary
to support legacy encodings without refactoring the `fs` crate's
streaming interfaces.
## Changes
- `crates/worktree`:
- Add dependencies: `encoding_rs`, `chardetng`.
- Update `load_file` to detect encoding and decode content.
- Update `write_file` to handle re-encoding on save.
- `crates/language`: Add `encoding` field and accessors to `Buffer`.
- `crates/project`: Pass encoding information between Worktree and
Buffer.
- `crates/vim`: Update `:w` command to use the new `write_file`
signature.
## Verification
I validated this manually using a Rust script to generate test files
with various encodings.
**Results:**
* ✅ **Success (Opened & Saved correctly):**
* **Japanese:** `Shift-JIS` (CP932), `EUC-JP`, `ISO-2022-JP`
* **Chinese:** `Big5` (Traditional), `GBK/GB2312` (Simplified)
* **Western/Unicode:** `Windows-1252` (CP1252), `UTF-16LE`, `UTF-16BE`
* ⚠️ **limitations (Detection accuracy):**
* Some specific encodings like `KOI8-R` or generic `Latin1` (ISO-8859-1)
may partially display replacement characters (`?`) depending on the file
content length. This is a known limitation of the heuristic detection
library (`chardetng`) rather than the saving logic.
Release Notes:
- Added support for opening and saving files with legacy encodings
(Shift-JIS, Big5, etc.)
---------
Co-authored-by: CrazyboyQCD <53971641+CrazyboyQCD@users.noreply.github.com>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
I could not find any related issue, but at least I want to use the git
panel like this :)
Being used to `lazygit`, this PR makes navigation of the git panel more
similar to the CLI tool.
Instead of selecting -> enter'ing for skimming each file, I just want to
move between the files in the git panel and have the diff multibuffer
advance to the appropriate file. This also adheres to the behavior of
the outline panel, which I like better.
If the multibuffer is not active, it behaves same as before (just
selecting the file in the panel, nothing else).
I did not modify existing `menu::Select*` actions in case anybody still
prefers previous behavior.
https://github.com/user-attachments/assets/2d1303d4-50c8-4500-ab3b-302eb7d4afda
Release Notes:
- Improved navigation of the git panel, by advancing the "Uncommitted
Changes" multibuffer to the current selected file. To restore the old
behavior, you can bind `up` and `down` to `menu::SelectPrevious` and
`menu::SelectNext` under the `GitPanel` context in your keymap.
Co-authored-by: Cole Miller <cole@zed.dev>
Fix broken LICENSE-GPL symlink that was pointing to itself instead of
the LICENSE-GPL file in the root of the repo.
It caused jujutsu to freak out and made it impossible to work with the
repo using it without switching to raw git:
```
Internal error: Failed to check out commit 22d04a82b119882e7aed88fb422430367c4df5f9
Caused by:
1: Failed to validate path /Users/aqrln/git/zed/crates/agent_ui_v2/LICENSE-GPL
2: Too many levels of symbolic links (os error 62)
```
Release Notes:
- N/A
The below memory leaks were caused by failing to release reference
counted resources. I confirmed using instruments that my changes stopped
the leaks from occurring.
- System prompts
- Screen capturing
- loading font families
There were also two memory leaks I found from some of our dependencies
that I made PRs to fix
- https://github.com/RustAudio/coreaudio-rs/pull/147
- https://github.com/servo/core-foundation-rs/pull/746
Release Notes:
- N/A
Follow-up of https://github.com/zed-industries/zed/pull/44887
Trims the worktree trust mechanism to the actual `worktree`s, so now
"global", workspace-level things like `prettier`, `NodeRuntime`,
`copilot` and global MCP servers are considered as "trusted" a priori.
In the future, a separate mechanism for those will be considered and
added.
Release Notes:
- N/A
Closes #ISSUE
Problem:
- The status bar’s pending keystroke indicator (shown next to --NORMAL--
in Vim mode) didn’t clear when focus moved to another context, e.g.
hitting g in the editor then clicking the Git panel. The keymap state
correctly canceled the prefix, but observers that render the indicator
never received a “pending input changed” notification, so the UI kept
showing stale prefixes until a new keystroke occurred.
Fix:
- The change introduces a `pending_input_changed_queued` flag and a new
helper `notify_pending_input_if_needed` which will flushes the queued
notification as soon as we have an App context. The
`pending_input_changed` now resets the flag after notifying subscribers.
Before:
https://github.com/user-attachments/assets/7bec4c34-acbf-42bd-b0d1-88df5ff099aa
After:
https://github.com/user-attachments/assets/2264dc93-3405-4d63-ad8f-50ada6733ae7
Release Notes:
- Fixed: pending keybinding prefixes on the status bar now clear
immediately when focus moves to another panel or UI context.
---------
Co-authored-by: Nathan Sobo <nathan@zed.dev>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Fixes#42668
When clicking 'Configure' to enter a settings subpage, focus was being
lost because push_sub_page only called cx.notify() without managing
focus. Similarly, pop_sub_page had the same issue when navigating back.
This fix:
- Adds window parameter to push_sub_page and pop_sub_page
- Focuses the content area when entering/leaving subpages
- Resets scroll position when entering a subpage
Release Notes:
- Fixed a bug that prevented keyboard navigation in the settings window.
Release Notes:
- Improved display map rendering performance with many lines in the the multi-buffer.
---------
Co-authored-by: cameron <cameron.studdstreet@gmail.com>
Co-authored-by: Cole Miller <cole@zed.dev>
We recently added this `InlineCode` component but I'd forgotten that
many months ago I also introduced an `inline_code` method to the Label
component which does the same thing. That means we don't need a
standalone component at all!
Release Notes:
- N/A
Some refactoring I ran into while working on automatic Markdown list
continuation on newline.
This PR:
- Moves `comment_delimiter` and `documentation_delimiter` computation
outside of newline method.
- Adds `NewlineFormatting`, which holds info about how newlines affect
indentation and other formatting we need.
- Moves newline-specific methods into the new `NewlineFormatting`
struct.
Release Notes:
- N/A
Add support for `zed://git/commit/<path-to-repo>#<sha>` (**EDIT:** now
changed to `zed://git/commit/<sha>?repo=<path>`) URI scheme to access
the git commit view
implement parsing and handling of git commit URIs to navigate directly
to commit views from external links. the main use case for me is to use
OSC8 hyperlinks to link from a git sha into zed. this allows me e.g. to
easily navigate from a terminal into zed
**questions**
- is this URI scheme appropriate? it was the first one i thought of, but
wondering if `?ref=<some sha>` might make more sense – the git/commit
namespace was also an equally arbitrary choice
<details>
<summary>video demo showing navigation from zed's built in
terminal</summary>
https://github.com/user-attachments/assets/18ad7e64-6b39-44b2-a440-1a9eb71cd212
</details>
<details>
<summary>video demo showing navigation from ghostty to zed's commit
view</summary>
https://github.com/user-attachments/assets/1825e753-523f-4f98-b59c-7188ae2f5f19
</details>
Release Notes:
- Added support for `zed://git/commit/<sha>?repo=<path>` URI scheme to
access the git commit view
---------
Co-authored-by: Agus Zubiaga <agus@zed.dev>
Previously, the list of edit files had a double axis scroll issue
because the list itself scrolled vertically and each file row would
scroll horizontally, causing a bad UX. The horizontal scroll intention
was so that you could see the whole path, but I've included it in the
tooltip in case it becomes obscured due to a small panel width.
<img width="500" height="666" alt="Screenshot 2025-12-17 at 11 24@2x"
src="https://github.com/user-attachments/assets/ea87236d-f5c6-475a-bf66-1afae7a6ca05"
/>
Release Notes:
- agent: N/A
Fixes an issue where we would update the imports after a file rename in
TypeScript, but those changes wouldn't surface anywhere until those
buffers were manually opened
(https://github.com/zed-industries/zed/issues/35930#issuecomment-3366852945).
In https://github.com/zed-industries/zed/pull/36681 we already added
support for opening a multibuffer with edits, but vtsls has a different
flow for renames.
Release Notes:
- Files with updated imports now open in a multibuffer when renaming or
moving TypeScript or JavaScript files
Closes#35930
When a TypeScript file is renamed or moved, vtsls can automatically
update the imports in other files. It pops up a message with the option
to always automatically update imports. This choice would previously
only be remembered for the current session and would pop up again after
a restart.
Now we persist that choice to the vtsls LSP settings in Zed, so that it
remembers across editor sessions.
Release Notes:
- When renaming a TypeScript or JavaScript file, the selected option to
automatically update imports will now be remembered across editor
sessions.
Addresses some tasks in #43969. Namely adding TailwindCSS documentation
for the following languages: HTML, JavaScript and Typescript.
**Some Notes**
- Maybe the additional information in the HTML section is unnecessary,
unsure open to suggestions.
- I tried utilizing capturing groups with alternatives like
`\\.(add|remove|toggle|contains)` but this didn't seem to work, so I was
forced to use multiple lines.
Release Notes:
- N/A
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Relevant for Nightly Users only, follow up to #45004.
In case you use nightly this will break preview/stable since
deserialisation will fail. Shipping this to Nightly so that staff does
not run into this issue. We can revert this PR in the following days.
I'll make a follow up PR which only stores the prompt in the database in
case you customise it.
Release Notes:
- N/A
Reverts https://github.com/zed-industries/zed/pull/44933.
It turns out that if you're copying agent responses to paste it anywhere
else that isn't the message editor (e.g., for a follow up prompt),
getting Markdown formatting is helpful. However, with the revert, the
underlying issue in https://github.com/zed-industries/zed/issues/42958
remains, so I'll reopen that issue, unfortunately.
Release Notes:
- N/A
Closes#33018
### Problem
When opening a `PopoverMenu` or `RightClickMenu`, the pane's tab bar
buttons would flicker (disappear for a couple frames then reappear).
This happened because:
1. The menu is created and `window.focus()` was called immediately
2. However, menus are rendered using `deferred()`, so their focus
handles aren't connected in the dispatch tree until after the deferred
draw callback runs
3. When the pane checks `has_focus()`, it calls `contains_focused()`
which walks up the focus hierarchy — but the menu's focus handle isn't
linked yet
4. `has_focus()` returns false → tab bar buttons disappear
5. Next frame, the menu is rendered and linked → `has_focus()` returns
true → buttons reappear
### Solution
Delay the focus transfer by 2 frames using nested `on_next_frame()`
calls before focusing the menu.
**Why 2 frames instead of 1?**
The frame lifecycle in GPUI runs `next_frame_callbacks` BEFORE `draw()`:
```
on_request_frame:
1. Run next_frame_callbacks
2. window.draw() ← menu rendered here via deferred()
3. Present
```
So:
- **Frame 1**: First `on_next_frame` callback runs, queues second
callback. Then `draw()` renders the menu and connects its focus handle
to the dispatch tree.
- **Frame 2**: Second `on_next_frame` callback runs and focuses the
menu. Now the focus handle is connected (from Frame 1's draw), so
`contains_focused()` returns true.
With only 1 frame, the focus would happen BEFORE `draw()`, when the
menu's focus handle isn't connected yet.
This follows the same pattern established in b709996ec6 which fixed the
identical issue for the editor's `MouseContextMenu`.
Closes #ISSUE
This PR is rather a nice to have change than anything critical, so
review priority should remain low.
Switch to using `semver::Version` for representing node binary and npm
package versions. This is in an effort to root out implicit behavior and
improve type safety when interacting with the `node_runtime` crate by
catching invalid versions where they appear. Currently Zed may
implicitly assume the current version is correct, or always install the
newest version when a invalid version is passed. `semver::Version` also
doesn't require the heap, which is probably more of a fun fact than
anything useful.
`npm_install_packages` still takes versions as a `&str`, because
`latest` can be used to fetch the latest version on npm. This could
likely be made into an enum as well, but would make the PR even larger.
I tested changes with some node based language servers and external
agents, which all worked fine. It would be nice to have some e2e tests
for node. To be safe I'd put it on nightly after a Wednesday release.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Closes#44624
Before this change, white space would be trimmed from word diff ranges.
Users found this behavior confusing, so we're changing it to be more
inline with how GitHub treats whitespace in their word diffs.
Release Notes:
- git: Word diffs won't filter out pure whitespace diffs now
Both `test_miniquotes_object` and `test_minibrackets_object` rely on
tree-sitter parsing for `MultiBufferSnapshot.bracket_ranges` to find
quote/bracket pairs. The `VimTestContext.set_state` call eventually
triggers async tree-sitter parsing, but `run_until_parked` doesn't
guarantee parsing completion.
We suspect this is what might be causing the flakiness on Windows, as
the syntax might not yet be parsed when the
`VimTestContext.simulate_keystrokes` call is made, so there's no bracket
pairs returned.
This commit adds an explicit await call on `Bufffer.parsing_idle` after
each `VimTestContext.set_state` call, to ensure tree-sitter parsing
completes before simulating keystrokes.
Release Notes:
- N/A
Obviously this doesn't do too much without having an actual windows
server binary for the remote side, but it does at least improve the
error message as right now we will complain about `uname` not being a
valid powershell command.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Closes#45033
This bug happened because the deletion icon would use the selected entry
index to choose what branch to delete. This works for all cases except
when hovering on an entry, so the fix was passing in the entry index to
the deletion button on_click handler.
I also disabled the deletion button from working if a branch is HEAD,
because it's an illegal operation to delete a branch a user is currently
on.
Finally, I made WeakEntity<Workspace> a non-optional field on
`BranchList` because a workspace should always be present, and it's used
to show toast notifications when a git operation fails. The popover view
wouldn't have a workspace before, so users wouldn't get error messages
when a git operation failed in that view.
Release Notes:
- git: Fix bug where branch list deletion button would delete the wrong
branch
Closes#43722
Release Notes:
- Fixed an issue where auto-indentation didn’t work correctly for Python
code blocks in Markdown.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Fixes the hang introduced in #44995 (which was reverted in #45011) and
re-enables the optimization.
## Background
PR #44995 introduced an optimization to skip rendering lines that are
clipped by parent containers (e.g., when a large AutoHeight editor is
inside a scrollable List). This significantly improved performance for
large diffs in the Agent Panel.
However, #45011 reverted this change because it caused the main thread
to hang for 100+ seconds in certain scenarios, requiring a force quit to
recover.
## Root Cause
The original analysis in #45011 suggested that visible_bounds wasn’t
being intersected properly, but that was incorrect—the intersection via
with_content_mask works correctly. The actual bug: when an editor is
positioned above the visible viewport (e.g., scrolled past in a List),
the clipping calculation produces a start_row that exceeds max_row:
1. Editor’s bounds.origin.y becomes very negative (e.g., -10000px)
2. After intersection, visible_bounds.origin.y is at the viewport top
(e.g., 0)
3. clipped_top_in_lines = (0 - (-10000)) / line_height = huge number
4. start_row = huge number, but end_row is clamped to max_row
5. This creates an invalid range where start_row > end_row
This caused two different failures depending on build mode:
- Debug mode: Panic from subtraction overflow in
Range<DisplayRow>::len()
- Release mode: Integer wraparound causing blocks_in_range to enter an
infinite loop (the 100+ second hang)
## Fix
Simply clamp start_row to max_row, ensuring the row range is always
valid:
```rs
let start_row = cmp::min(
DisplayRow((scroll_position.y + clipped_top_in_lines).floor() as u32),
max_row,
);
```
## Testing
Added a regression test that draws an editor at y=-10000 to simulate an
editor that’s been scrolled past in a List. This would panic in debug
mode (and hang in release mode) before the fix.
Release Notes:
- Improved agent panel performance when rendering large diffs.
0.0.2 is not a pre-release artifact unlike the previous one, so our
version fetch ignored it.
Fixes https://github.com/zed-industries/zed/issues/45061
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Closes #ISSUE
Remove some intermediate allocations when reconstructing text or wrapped
text from a `TextLayout`. Currently creates a intermediate `Vec<String>`
which gets joined, when you could join an `impl Iterator<Item = &str>`
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Closes#20613
Release Notes:
- Fixed: New windows no longer flicker between "Open a file or project
to get started" and an empty editor.
---
When opening a new window (`cmd-shift-n`), the window rendered showing
the empty state message before the editor was created, causing a visible
flicker.
**Changes:**
- Modified `Workspace::new_local` to accept an optional `init` callback
that executes inside the window build closure
- The init callback runs within `cx.new` (the `build_root_view`
closure), before `window.draw()` is called for the first render
- Changed the NewWindow action handler to use
`Project::create_local_buffer()` (synchronous) instead of
`Editor::new_file()` (asynchronous)
- Updated `open_new` to pass the editor creation callback to `new_local`
- All other `new_local` call sites pass `None` to maintain existing
behavior
**Key Technical Detail:**
The window creation sequence in `cx.open_window()` is:
1. `build_root_view` closure is called (creates workspace via `cx.new`)
2. `window.draw(cx)` is called (first render)
3. `open_window` returns
The fix uses `Project::create_local_buffer()` which creates a buffer
**synchronously** (returns `Entity<Buffer>` directly), rather than
`Editor::new_file()` which is asynchronous (calls
`project.create_buffer()` which returns a `Task`). The editor is created
from this buffer inside the `cx.new` closure (step 1), ensuring it
exists before step 2 renders the first frame.
**Before:**
```rust
let task = Workspace::new_local(Vec::new(), app_state, None, env, cx);
cx.spawn(async move |cx| {
let (workspace, _) = task.await?; // Window already drawn
workspace.update(cx, |workspace, window, cx| {
Editor::new_file(workspace, ...) // Async - editor not present for first render
})?;
})
```
**After:**
```rust
cx.open_window(options, {
move |window, cx| {
cx.new(|cx| {
let mut workspace = Workspace::new(...);
// Create buffer synchronously, then create editor
if let Some(init) = init {
init(&mut workspace, window, cx); // Uses create_local_buffer (sync)
}
workspace
})
}
})?
```
The editor is now part of the workspace before the window's first frame
is rendered, eliminating the flicker.
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>Opening a new window flickers before opening an empty
buffer</issue_title>
> <issue_description>### Check for existing issues
>
> - [x] Completed
>
> ### Describe the bug / provide steps to reproduce it
>
> Opening a new window, with e.g. `cmd-shift-n`, flickers for a fraction
of a second. The new window first shows the startup page, "Open a file
or project to get started.". Then, a frame or two later, a new empty
buffer opens.
>
> Not sure if I'm sensitive or something but these kinds of flashes can
knock me out of focus/flow pretty easily.
>
> It'd be great to either have the empty buffer open from the first
frame, or to have an option to simply not open that empty buffer when a
new window is opened.
>
> ### Zed Version and System Specs
>
> Zed: v0.170.4 (Zed)
> OS: macOS 14.6.1
> Memory: 36 GiB
> Architecture: aarch64
>
> ### If applicable, add screenshots or screencasts of the incorrect
state / behavior
>
>
https://github.com/user-attachments/assets/6d9ba791-8a02-4e13-857c-66a33eb0905b
>
> ### If applicable, attach your Zed.log file to this issue.
>
> N/A</issue_description>
>
> <agent_instructions>We should make sure that the window is created in
the correct state, and not have an intermediate render before the editor
opens.</agent_instructions>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> <comment_new><author>@ConradIrwin</author><body>
> Ugh, no. I don't believe I never noticed this before, but now I can't
unsee it :s
>
> If you'd like to pair on this: https://cal.com/conradirwin/pairing,
otherwise I'll see if I get around to it.</body></comment_new>
> <comment_new><author>@ConradIrwin</author><body>
> Yeah... I wonder if that can be a preview tab or something. It's nice
when you want it, but not so nice when you don't.
>
> Fixing this will also make zed-industries/zed#33334 feel much
smoother.</body></comment_new>
> <comment_new><author>@zelenenka</author><body>
> @robinplace do you maybe have an opportunity to test it with the
latest stable version, 0.213.3?</body></comment_new>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixeszed-industries/zed#23742
<!-- START COPILOT CODING AGENT TIPS -->
---
💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ConradIrwin <94272+ConradIrwin@users.noreply.github.com>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Split running `cargo clippy` out of the job that has access to ZIPPY
secrets as
a precaution against accidentally leaking the secrets through build.rs
or
something...
Release Notes:
- N/A
Follow-up of https://github.com/zed-industries/zed/pull/44887
This fixes remote server builds.
Additionally:
* slightly rewords workspace trust text in the security modal
* eagerly ask for worktree trust on open
Release Notes:
- N/A
This PR fixes the warning from entering the nix development shell:
```
evaluation warning: 'hostPlatform' has been renamed to/replaced by 'stdenv.hostPlatform'
```
Decided to go with `zed-editor = mkZed pkgs;` instead of `zed-editor =
packages.${pkgs.stdenv.hostPlatform.system}.default;`, because it is
simpler and with my understanding it is logically equivalent (i.e. we
are getting `packages.<system>.default` which we can see in the
definition of packages is equal to `mkZed pkgs;`).
Release Notes:
- N/A
Just touching up the tooltip casing, colors, and a bit of spacing. Also
added the keybiniding to close the assistant. Maybe it was obvious
already but I don't think it hurts.
Release Notes:
- N/A
## Summary
This PR adds support for the MCP (Model Context Protocol)
`notifications/tools/list_changed` notification, enabling dynamic tool
discovery when MCP servers add, remove, or modify their available tools
at runtime.
## Release Notes:
- Improved: MCP tools are now automatically reloaded when a context
server sends a `tools/list_changed` notification, eliminating the need
to restart the server to discover new tools.
## Changes
- Register a notification handler for `notifications/tools/list_changed`
in `ContextServerRegistry`
- Automatically reload tools when the notification is received
- Handler is registered both on initial server startup and when a server
transitions to `Running` status
## Motivation
The MCP specification includes a `notifications/tools/list_changed`
notification to inform clients when the list of available tools has
changed. Previously, Zed's agent would only load tools once when a
context server started. This meant that:
1. If an MCP server dynamically registered new tools after
initialization, they would not be available to the agent
2. The only way to refresh tools was to restart the entire context
server
3. Tools that were removed or modified would remain in the old state
until restart
## Implementation Details
The implementation follows these steps:
1. When a context server transitions to `Running` status, register a
notification handler for `notifications/tools/list_changed`
2. The handler captures a weak reference to the `ContextServerRegistry`
entity
3. When the notification is received, spawn a task that calls
`reload_tools_for_server` with the server ID
4. The existing `reload_tools_for_server` method handles fetching the
updated tool list and notifying observers
This approach is minimal and reuses existing tool-loading
infrastructure.
## Testing
- [x] Code compiles with `./script/clippy -p agent`
- The notification handler infrastructure already exists and is tested
in the codebase
- The `reload_tools_for_server` method is already tested and working
## Benefits
- Improves developer experience by enabling hot-reloading of MCP tools
- Aligns with the MCP specification's capability negotiation system
- No breaking changes to existing functionality
- Enables more flexible and dynamic MCP server implementations
## Related Issues
This implements part of the MCP specification that was already defined
in the type system but not wired up to actually handle the
notifications.
---------
Co-authored-by: Agus Zubiaga <agus@zed.dev>
Similar to how you can use `shift-tab` to cycle through profiles/modes,
you can now use `alt-tab` to cycle through the language models you have
favorited.
<img width="500" height="312" alt="Screenshot 2025-12-16 at 5 23@2x"
src="https://github.com/user-attachments/assets/006d417d-5da1-48f9-82cc-ea06e28adb30"
/>
Release Notes:
- agent: Added the ability to cycle through favorited models using the
`alt-tab` keybinding.
We need to prevent this, since commit message generation did not count
as a prompt in the old billing model.
If users of Legacy Zed Pro customise the prompt, it will count as an
actual prompt since our matching algorithm will fail.
We can remove this once we stop supporting Legacy Zed Pro on 17 January.
Release Notes:
- N/A
This PR solves my main pain point with Zed agent: I have a long list of
available models from different providers, and I switch between a few of
them depending on the context and the project. In particular, I use the
same models from different providers depending on whether I'm working on
a personal project or at my day job. Since I only care about a few
models (none of which are in "recommended") that are scattered all over
the list, switching between them is bothersome, even using search.
This change adds a new option in `settings.json`
(`agent.favorite_models`) and the UI to manipulate it directly from the
list of available models. When any models are marked as favorites, they
appear in a dedicated section at the very top of the list. Each model
has a small icon button that appears on hover and allows to toggle
whether it's marked as favorite.
I implemented this on the UI level (i.e. there's no first-party
knowledge about favorite models in the agent itself; in theory it could
return favorite models as a group but it would make it harder to
implement bespoke UI for the favorite models section and it also
wouldn't work for text threads which don't use the ACP infrastructure).
The feature is only enabled for the native agent but disabled for
external agents because we can't easily map their model IDs to settings
and there could be weird collisions between them.
https://github.com/user-attachments/assets/cf23afe4-3883-45cb-9906-f55de3ea2a97
Closes https://github.com/zed-industries/zed/issues/31507
Release Notes:
- Added the ability to mark language models as favorites and pin them to
the top of the list. This feature is available in the native Zed agent
(including text threads and the inline assistant), but not in external
agents via ACP.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
`cargo-about` got pinned to 0.8.2 in
https://github.com/zed-industries/zed/pull/44012, but this isn't exactly
"easy" to accomplish in nix. The version of nixpkgs in the flake inputs
uses the proper version, but if you override the nixpkgs input or use
the provided overlay, you might end up trying to build with a bad
version of `cargo-about`.
Since nixpkgs is versioned as a whole, your options are (in rough order
of desirability):
1. Hope that nixpkgs simply includes multiple versions of the same
package (common for things with stable major versions/breaking changes)
1. Use either `override` or `overrideAttrs` to provide different
version/source attributes
1. Depend on multiple versions of nixpkgs to get the specific versions
of the packages you want
1. Vendor the whole package build from a specific point in its history
Option 1 is out - there's only one version of cargo-about in nixpkgs.
Option 2 doesn't seem to work due to the way that `buildRustPackage`
wraps the base `mkDerivation` which provides the `override` extension
functions. There *might* be a way to make this work, but I haven't dug
into the `buildRustPackage` internals enough to say for sure. Edit: I
apparently can't read and the problems with this option were already
solved for `cargo-bundle`, so this is the final approach!
Option 3 always just feels a bit icky and opaque to me.
Leaving Option 4. I usually find this approach to be "fine" for small
package definitions that aren't actually much bigger than the overridden
attributes would have be with the Option 2 approach. ~~Since the
`cargo-about` definition is nice and small, this is the approach I
chose.~~
~~Since this has the potential to require a build of `cargo-about`, I'm
only actually invoking its build if the provided version is wrong - more
or less the same thing that's happening in the `generate-licenses`
script, but nix-y.~~
Edit: Shouldn't ever cause a rebuild since there's only one 0.8.2 input
source/vendored deps, so anything that was already using it will already
be cached.
I'm also updating nixpkgs to the latest unstable which currently has
`cargo-about 0.8.4` to prove that this works.
Unrelatedly, I also ran `nix fmt` as a drive-by change. `nix/build.nix`
was a bit out of spec.
Release Notes:
- N/A
Closes#32951
## Summary
When an agent notification was shown and the `AcpThreadView` was dropped
(e.g., by closing the project window or navigating to a new thread), the
notification would become orphaned and undismissable because the
subscriptions handling dismiss events were dropped along with the thread
view.
## Fix
Added an `on_release` callback that closes all notification windows when
the thread view is dropped. This ensures notifications are always
cleaned up properly.
## Testing
Added `test_notification_closed_when_thread_view_dropped` to verify
notifications are closed when the thread view is dropped.
Release Notes:
- Fixed agent notification getting stuck and becoming undismissable when
the project window is closed or when navigating to a new thread
Closes https://github.com/zed-industries/zed/issues/12589
Forces Zed to require user permissions before running any basic
potentially dangerous actions: parsing and synchronizing
`.zed/settings.json`, downloading and spawning any language and MCP
servers (includes `prettier` and `copilot` instances) and all
`NodeRuntime` interactions.
There are more we can add later, among the ideas: DAP downloads on
debugger start, Python virtual environment, etc.
By default, Zed starts in restricted mode and shows a `! Restricted
Mode` in the title bar, no aforementioned actions are executed.
Clicking it or calling `workspace::ToggleWorktreeSecurity` command will
bring a modal to trust worktrees or dismiss the modal:
<img width="1341" height="475" alt="1"
src="https://github.com/user-attachments/assets/4fabe63a-6494-42c7-b0ea-606abb1c0c20"
/>
Agent Panel shows a message too:
<img width="644" height="106" alt="2"
src="https://github.com/user-attachments/assets/0a4554bc-1f1e-455b-b97d-244d7d6a3259"
/>
This works on local, SSH and WSL remote projects, trusted worktrees are
persisted between Zed restarts.
There's a way to clear all persisted trust with
`workspace::ClearTrustedWorktrees`, this will restart Zed.
This mechanism can be turned off with settings:
```jsonc
"session": {
"trust_all_worktrees": true
}
```
in this mode, all worktrees will be trusted by default, allowing all
actions, but no auto trust will be persisted: hence, when the setting is
changed back, auto trusted worktrees will require another trust
confirmation.
This settings switch was added to the onboarding view also.
Release Notes:
- Introduced worktree trust mechanism, can be turned off with
`"session": { "trust_all_worktrees": true }`
---------
Co-authored-by: Matt Miller <mattrx@gmail.com>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-authored-by: John D. Swanson <swanson.john.d@gmail.com>
Fixes#43165
## Problem
MCP prompts were only available in text threads, not agent threads.
Users with MCP servers that expose prompts couldn't use them in the main
agent panel.
## Solution
Added MCP prompt support to agent threads by:
- Creating `ContextServerPromptRegistry` to track MCP prompts from
context servers
- Subscribing to context server events to reload prompts when MCP
servers start/stop
- Converting MCP prompts to available commands that appear in the slash
command menu
- Integrating prompt expansion into the agent message flow
## Testing
Tested with a custom MCP server exposing `explain-code` and
`write-tests` prompts. Prompts now appear in the `/` slash command menu
in agent threads.
Release Notes:
- Added MCP prompt support to agent threads. Prompts from MCP servers
now appear in the slash command menu when typing `/` in agent threads.
---------
Co-authored-by: Agus Zubiaga <agus@zed.dev>
Closes#26823
Release Notes:
- Added support for customising the prompt used for generating commit
message in the rules library
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
This reverts commit 914b0117fb (#44995).
The optimization introduced a regression that causes the main thread to
hang for **100+ seconds** in certain scenarios, requiring a force quit
to recover.
## Analysis from spindump
When a large `AutoHeight` editor is displayed inside a `List` (e.g.,
Agent Panel thread view), the clipping calculation can produce invalid
row ranges:
1. `visible_bounds` from `window.content_mask().bounds` represents the
window's content mask, not the intersection with the editor
2. When the editor is partially scrolled out of view,
`clipped_top_in_lines` becomes extremely large
3. This causes `start_row` to be computed as an astronomically high
value
4. `blocks_in_range(start_row..end_row)` then spends excessive time in
`Cursor::search_forward` iterating through the block tree
The spindump showed **~46% of samples** (459/1001 over 10+ seconds)
stuck in `BlockSnapshot::blocks_in_range()`, specifically in cursor
iteration.
### Heaviest stack trace
```
EditorElement::prepaint
└─ blocks_in_range + 236
└─ Cursor::search_forward (459 samples)
```
## Symptoms
- Main thread unresponsive for 33-113 seconds before sampling even began
- UI completely frozen
- High CPU usage on main thread (10+ seconds of CPU time in the sample)
- Force quit required to recover
## Path forward
The original optimization goal (reducing line layout work for clipped
editors) is valid, but the implementation needs to:
1. Correctly calculate the **intersection** of editor bounds with the
visible viewport
2. Ensure row calculations stay within valid ranges (clamped to
`max_row`)
3. Handle edge cases where the editor is completely outside the visible
bounds
Release Notes:
- Fixed a hang that could occur when viewing large diffs in the Agent
Panel
This PR adds support for collapsing/expanding Git entries with your
keyboard like you can inside the project panel and variable list.
I noticed there is a bug that selecting the next entry when you are on
the directory level will select a non-visible entry. Will fix that in
another PR, as it is not related to this feature implementation.
**Result**:
https://github.com/user-attachments/assets/912cc146-1e1c-485f-9b60-5ddc0a124696
Release Notes:
- Git panel: Add support for collapsing/expanding entries with your
keyboard.
Until now, Helix-mode users would have to rely on Vim's `d *` behaviour
which cannot be reliably replicated with Helix's default delete
behaviour and so I believe that remapping this functionality to Helix's
goto mode is a better fit.
Release Notes:
- Added custom mappings for Zed specific diff and git-related actions to
Helix's goto mode:
* `g o` - toggle selected diff hunks
* `g O` - toggle staged
* `g R` - restore change
* `g u` - stage and goto next diff hunk
* `g U` - unstage and goto next diff hunk
This re-introduces the `save_file` and `restore_file_from_disk` agent
tools that were reverted in #44949.
I pushed that original PR without trying it just to get the build off my
machine, but I had missed a step: the tools weren't added to the default
profile settings in `default.json`, so they were never enabled even
though the code was present.
## Changes
- Add `save_file` and `restore_file_from_disk` to the "write" profile in
`default.json`
- Add `Thread::has_tool()` method to check tool availability at runtime
- Make `edit_file_tool`'s dirty buffer error message conditional on
whether `save_file`/`restore_file_from_disk` tools are available (so the
agent gets appropriate guidance based on what tools it actually has)
- Update test to match new conditional error message behavior
Release Notes:
- Added `save_file` and `restore_file_from_disk` agent tools to handle
dirty buffers when editing files
Fixes#44997
## Summary
Optimizes editor rendering when an editor is partially clipped by a
parent container (e.g., a `List`). The editor now only lays out and
renders lines that are actually visible within the viewport, rather than
all lines in the document.
## Problem
When an `AutoHeight` editor with thousands of lines is placed inside a
scrollable `List` (such as in the Agent Panel thread view), the editor
would lay out **all** lines during prepaint, even though only a small
portion was visible. Profiling showed that ~50% of frame time was spent
in `EditorElement::prepaint` → `LineWithInvisibles::from_chunks`,
processing thousands of invisible lines.
## Solution
Calculate the intersection of the editor's bounds with the current
content mask (which represents the visible viewport after all parent
clipping). Use this to determine:
1. `clipped_top_in_lines` - how many lines are clipped above the
viewport
2. `visible_height_in_lines` - how many lines are actually visible
Then adjust `start_row` and `end_row` to only include visible lines. The
parent container handles positioning, so `scroll_position` remains
unchanged for paint calculations.
## Example
For a 3000-line editor where only 50 lines are visible:
- **Before**: Lay out and render 3000 lines
- **After**: Lay out and render ~50 lines
## Testing
Verified the following scenarios work correctly:
- Editor fully visible (no clipping)
- Editor clipped from top
- Editor clipped from bottom
- Editor completely outside viewport (renders nothing)
- Fractional line clipping at boundaries
- Scrollable editors with internal scroll state inside a clipped
container
Release Notes:
- Improved agent panel performance when rendering large diffs.
Release Notes:
- Added project settings schema to the schema_generator CLI. This allows
for exporting the project settings schema as JSON for use in other
tools.
Closes#41994
This PR introduces Element-bounded drag tolerance for Ctrl/Cmd+click in
terminal.
Previously, Ctrl/Cmd+click on terminal links required pixel-perfect
accuracy. Any mouse movement during the click would cancel the
navigation, making it frustrating to click on links, especially on
high-DPI displays or with sensitive mice.
Users can now click anywhere within a clickable element (file path, URL,
hyperlink), drag the cursor anywhere within that same element's
boundaries and release to trigger navigation
Implementation:
- Stores detected element metadata (`text` and `grid_range`) on
Ctrl/Cmd+mouse-down
- Tracks cursor position during drag, preserving click state while
within element bounds
- Verifies element match on mouse-up before triggering navigation
- Uses existing `find_from_grid_point()` for element detection
Before:
[before.webm](https://github.com/user-attachments/assets/ee80de66-998e-4d8e-94d0-f5e65eb06d22)
After:
[after.webm](https://github.com/user-attachments/assets/7c9ddd9e-cfc1-4c79-b62c-78e9d909e6f4)
Release Notes:
- terminal: Fixed an issue where `ctrl|cmd+click` on links was very
sensitive to mouse movement. Clicking links now tolerates mouse movement
within the same clickable element, making link navigation more reliable
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
Release Notes:
- Fixed double slash in commit URLs
The github_url variable was generating URLs with an extra slash like
"https://github.com//user/repo/commit/xxxx" due to manual string
formatting
of the base_url() result.
Fixed by replacing manual URL construction with the proper
build_commit_permalink() method that uses Url::join() for correct
path handling, consistent with how other Git hosting providers
construct URLs.
Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
Closes#40678
The python file below simulates the macros at various timings and can be
run by running:
1. `sudo python3 -m pip install evdev --break-system-packages`
2. `sudo python3 zed_shift_brace_replayer.py`
Checked timings for hold=0.1, =0.01 and =0.001 with the latter two no
longer causing incorrect inputs.
[zed_shift_brace_replayer.py](https://github.com/user-attachments/files/23560570/zed_shift_brace_replayer.py)
Release Notes:
- linux: fixed a race condition where the macros containing modifier +
key would sometimes be processed without the modifier
Related to:
- #44510
- #44407
Previously we were searching for hyperlinks on every scroll, even if Cmd
was not held. With this PR,
- We only search for hyperlinks on scroll if Cmd is held
- We now clear `last_hovered_word` in all cases where Cmd is not held
- Renamed `word_from_position` -> `schedule_find_hyperlink`
- Simplified logic in `schedule_find_hyperlink`
Performance measurements
The test scrolls up and down 20,000x in a loop. However, since this PR
is just removing a code path that was very dependent on the length of
the line in terminal, it's not super meaningful as a comparison. The
test uses a line length of "long line ".repeat(1000), and in main the
performance is directly proportional to the line length, so for
benchmarking it in main it only scrolls up and down 20x. I think all
that is really useful to say is that currently scrolling is slow, and
proportional to the line length, and with this PR it is buttery-smooth
and unaffected by line length. I've included a few data points below
anyway. At least the test can help catch future regressions.
| Branch | Command | Scrolls | Iter/sec | Mean [ms] | SD [ms] |
Iterations | Importance (weight) |
|:---|:---|---:|---:|---:|---:|---:|---:|
| main | tests::perf::scroll_long_line_benchmark | 40 | 16.85 | 712.00 |
2.80 | 12 | average (50) |
| this PR | tests::perf::scroll_long_line_benchmark | 40 | 116.22 |
413.60 | 0.50 | 48 | average (50) |
| this PR | tests::perf::scroll_long_line_benchmark | 40,000 | 9.19 |
1306.40 | 7.00 | 12 | average (50) |
| only overhead | tests::perf::scroll_long_line_benchmark | 0 | 114.29 |
420.90 | 2.00 | 48 | average (50) |
Release Notes:
- terminal: Improved scroll performance
Closes#44825
Release Notes:
- Fixed a case where an incorrect match could be generated in
label_for_completion
---------
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
This PR introduces a few components for the model selector pickers.
Given we're still maintaining two flavors of it due to one of them being
wired through ACP and the other through the language model registry,
having one source of truth for the UI should help with maintenance
moving forward, considering that despite the internal differences, they
look and behave the same from the standpoint of the UI.
Release Notes:
- N/A
## Summary
This fixes a minor bug I found #44981
- Fix percent-encoded filenames appearing in agent mentions after
message submission.
- Decode file:// paths in MentionUri::parse using the existing
urlencoding crate (already used elsewhere in the codebase).
- Add tests for non-ASCII file URIs.
## Screenshots
<img width="409" height="116" alt="image"
src="https://github.com/user-attachments/assets/32ef033b-6232-47c5-80c7-d5247d5dae88"
/>
## Summary
The diagnostics panel was ignoring the user's `toolbar.breadcrumbs`
setting and always showing breadcrumbs. This makes both
`BufferDiagnosticsEditor` and `ProjectDiagnosticsEditor` check the
`EditorSettings` to determine whether to display breadcrumbs.
## Changes
- `buffer_diagnostics.rs`: Updated `breadcrumb_location` to check
`EditorSettings::get_global(cx).toolbar.breadcrumbs`
- `diagnostics.rs`: Updated `breadcrumb_location` to check
`EditorSettings::get_global(cx).toolbar.breadcrumbs`
This follows the same pattern used by the regular `Editor` in
`items.rs`.
## Test plan
1. Set `toolbar.breadcrumbs` to `false` in settings.json
2. Open a file with diagnostics
3. Run `diagnostics: deploy current file`
4. Verify that breadcrumbs are hidden in the diagnostics panel
Fixes#43020
I had previously added `flex_none` to the Divider and that caused it to
grow beyond the container's width in some cases (project panel, agent
panel's restore to check point button, etc.).
Release Notes:
- N/A
We were previously matching the search on both model name and provider
ID. In most cases, this would yield an okay result, but if you search
for "Opus", for example, you'd see the Sonnet models in the search
result, which was very confusing. This was because we were matching to
both provider ID and model name. "Sonnet" and "Opus" share the same
provider ID, so they both contain "Anthropic" as a prefix. Then, "Opus"
contains the letter P, as well as Anthropic, thus the match.
Now, we're only matching by model name, which I think most of the time
will yield more accurate results.
Release Notes:
- agent: Improved the model search quality in the model picker.
Closes#44306
This PR makes two changes:
- Uses the new `grid_cols_min_content` API. See more here:
https://github.com/zed-industries/zed/pull/44973.
- Changes Markdown table rendering to use a single grid instead of
creating a new grid per row, so column widths stay consistent across
rows.
Release Notes:
- Fixed an issue where Markdown tables wouldn't render in the hover
popover.
Similar to the mode selector in external agents, it will now be possible
to use `shift-tab` to cycle through profiles.
<img width="500" height="384" alt="Screenshot 2025-12-16 at 9 04@2x"
src="https://github.com/user-attachments/assets/11e8824e-9fad-4aab-9e19-53878096db52"
/>
Release Notes:
- Added the ability to use `shift-tab` to cycle through profiles for the
built-in Zed agent.
It was only possible to delete profiles through the `settings.json`, but
now you can do it through the UI:
<img width="500" height="1954" alt="Screenshot 2025-12-16 at 8 42@2x"
src="https://github.com/user-attachments/assets/077ecdf5-1e80-4b70-86c9-177cc3741e77"
/>
Release Notes:
- agent: Added the ability to delete a profile through the "Manage
Profiles" modal.
Required for https://github.com/zed-industries/zed/pull/44712
We started using `grid` for Markdown tables instead of flex. This
resulted in tables having a width of 0 inside popovers, since popovers
are laid out using `AvailableSpace::MinContent`.
One way to fix this is to lay out popovers using `MaxContent` instead.
But that would affect all Markdown rendered in popovers and could change
how popovers look, or regress things.
The other option is to fix it where the problem actually is:
`repeat(count, vec![minmax(length(0.0), fr(1.0))])`. Since the minimum
width here is `0`, laying things out with `MinContent` causes the
Markdown table to shrink completely. What we want instead is for the
minimum width to be the min-content size, but only for Markdown rendered
inside popovers.
This PR does exactly that, without interfering with the `grid_cols` API,
which intentionally follows a TailwindCSS-like convention. See
https://github.com/zed-industries/zed/pull/44368 for context.
Release Notes:
- N/A
### Problem
PR #44411 replaced the `editor::AcceptPartialEditPrediction` action with
`editor::AcceptNextLineEditPrediction` and
`editor::AcceptNextWordEditPrediction`. However, the Linux cursor keymap
wasn't updated to reflect this change, causing a panic on startup for
Linux users.
### Solution
Updated the Linux keymap configuration to reference the new actions
Release Notes:
- N/A
Copying rendered markdown doesn't reliably do anything sensible. If we
copy text from the middle of a bold section, no formatting is copied. If
we copy text at the end, the trailing bold delimiters are copied,
resulting in gibberish markdown. Thus even fixing the associated issue
(so that leading delimeters are reliably copied) won't consistently
produce good results.
Also, as the user messages in the agent panel don't render markdown
anyway, it seems the most likely use case for copying markdown is
inapplicable.
Closes#42958
Release Notes:
- N/A
Hi,
This PR fixes nothing. I just miss the option to open recent projects
quickly upon opening Zed, so I made this. Hope I can see it soon in
Preview channel.
If there is any suggestion, just comment. I will take it seriously.
Thank you!
|ui|before|after|
|-|-|-|
|empty pane|<img width="1571" height="941" alt="Screenshot 2025-12-03 at
12 39 25"
src="https://github.com/user-attachments/assets/753cbbc5-ddca-4143-aed8-0832ca59b8e7"
/>|<img width="1604" height="952" alt="Screenshot 2025-12-03 at 12 34
03"
src="https://github.com/user-attachments/assets/2f591d48-ef86-4886-a220-0f78a0bcad92"
/>|
|new window|<img width="1571" height="941" alt="Screenshot 2025-12-03 at
12 39 21"
src="https://github.com/user-attachments/assets/a3a1b110-a278-4f8b-980e-75f5bc96b609"
/>|<img width="1604" height="952" alt="Screenshot 2025-12-04 at 10 43
17"
src="https://github.com/user-attachments/assets/74a00d91-50da-41a2-8fc2-24511d548063"
/>|
---
Release Notes:
- Added a new value to the `restore_on_startup` setting called
`launchpad`. This value makes Zed open with a variant of the welcome
screen ("the launchpad") upon startup. Additionally, this same page
variant is now also what is displayed if you close all tabs in an
existing window that doesn't contain any folders open. The launchpad
page shows you up to 5 recent projects, making it easy to open something
you were working recently.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Use the url crate to extract the domain from the verification URI and
construct the appropriate Copilot sign-up URL for GitHub or GitHub
Enterprise.
Release Notes:
- Improved github enterprise (ghe) copilot sign in
Simple documentation PR.
Added information for installing on Windows via winget. Added links from
the main README to relevant sections for both macOS and Windows
Release Notes:
- N/A
First up: I'm sorry if this is a low quality PR, or if this feature
isn't wanted. I implemented this because I'd like to have this
behaviour. If you don't think that this is useful, feel free to close
the PR without comment. :)
My idea is this: I love to pull random models with Ollama to try them.
At the same time, not all of them are useful for coding, or some won't
work out of the box with the context_length set. So, I'd like to change
Zed's behaviour to not show me all models Ollama has, but to limit it to
the ones that I configure manually.
What I did is add an `auto_discover` field to the settings. The idea is
that you can write a config like this:
```json
"language_models": {
"ollama": {
"api_url": "http://localhost:11434",
"auto_discover": false,
"available_models": [
{
"name": "qwen3:4b",
"display_name": "Qwen3 4B 32K",
"max_tokens": 32768,
"supports_tools": true,
"supports_thinking": true,
"supports_images": true
}
]
}
}
```
The `auto_discover: false` means that Zed won't pick up or show the
language models that Ollama knows about, and will only show me the one I
manually configured in `available_models`. That way, I can pull random
models with Ollama, but in Zed I can only see the ones that I know work
(because I've configured them).
The default for `auto_discover` (when it is not explicitly set) is
`true`, meaning that the existing behaviour is preserved, and this is
not a breaking change for configurations.
Release Notes:
- ollama: Added `auto_discover` setting to optionally limit visible
models to only those manually configured in `available_models`
Since the rule is no longer a `style` lint as of
[mid-August](https://github.com/rust-lang/rust-clippy/pull/15454), the
comment mentioning it not being one is outdated and should be removed.
> [!NOTE]
> I kept the severity at `error` for now to avoid rustling feathers.
> If `warn` is preferred, feel free to change it yourself or ask me to
do it - it's only 1 line of code, after all.
Release Notes:
- N/A
- **Fix editor::OpenUrl on zed links**
- **Fix cmd-clicking links too**
Closes#44293Closes#43833
Release Notes:
- The `editor::OpenUrl` action now works for links to https://zed.dev
- Clicking on a link to a Zed channel or channel-note within the editor
no-longer redirects you via the web.
---------
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Fixes#23347
Release Notes:
- Implemented the `zed --wait` flag so that it works when opening a
directory. The command will block until the window is closed.
Previously we were only awaiting on up to 4 of the blame futures at a
time, but we would still call `Project::blame_buffer` eagerly for every
buffer in the multibuffer. Since that returns a `Task`, all the blame
invocations were still launched concurrently.
Release Notes:
- N/A
Updates #44089
- Restores the ability to have a partially staged/`Indeterminate` status
for the git panel checkboxes
- Removes the `optimistic_staging` logic, since its stated purpose is
served by the `PendingOps` system in the `GitStore` (which may have
bugs, but we should fix them in the git store rather than adding another
layer)
Release Notes:
- Fixed partially-staged files not being represented accurately in the
git panel.
---------
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
One of the major annoyances with writing code with claude is that its
poorly indented; instead of requiring manual intervention, let's just
fix that in CI.
Similar to https://autofix.ci, but as we already have a github app,
we can do it without relying on a 3rd party.
This PR doesn't trigger the workflow (we need a separate change in Zippy
to do
that) but will let me test it manually.
Release Notes:
- N/A
Release Notes:
- Added `save_file` and `restore_file_from_disk` tools to the agent,
allowing it to resolve dirty buffer conflicts when editing files. When
the agent encounters a file with unsaved changes, it will now ask
whether you want to keep or discard those changes before proceeding.
Closes#14472
Introduces `workspace::ZoomIn` and `workspace::ZoomOut` actions that
complement the existing `workspace::ToggleZoom` action. ZoomIn only
zooms if not already zoomed, and ZoomOut only zooms out if currently
zoomed. This enables composing zoom actions with
`workspace::SendKeystrokes` for workflows like "focus terminal then zoom
in".
<details><summary>Example usage</summary>
<p>
Example keybindings:
```json
[
{
"bindings": {
"ctrl-cmd-,": "terminal_panel::ToggleFocus",
"ctrl-cmd-.": "workspace::ZoomIn",
}
},
{
"context": "Terminal",
"bindings": {
"cmd-.": "terminal_panel::ToggleFocus"
}
},
{
"context": "!Terminal",
"bindings": {
"cmd-.": ["workspace::SendKeystrokes", "ctrl-cmd-, ctrl-cmd-."]
}
},
]
```
Demo:
https://github.com/user-attachments/assets/1b1deda9-7775-4d78-a281-dc9622032ead
</p>
</details>
Release Notes:
- Added the actions: `workspace::ZoomIn` and `workspace::ZoomOut` that
complement the existing `workspace::ToggleZoom` action
Closes#18228
We parse local clickable links by looking for start/end based on
whitespace. However, this means that we don't catch links which are
embedded in parenthesis, such as in markdown syntax:
`[here's my link text](./path/to/file.txt)`
Parsing strictly against parenthesis can be problematic, because
strictly-speaking, files can have parenthesis. This is a valid file name
in at least MacOS:
`thisfilehas)parens.txt`
Therefore, this change adds a small regex layer on top of the filename
finding logic, which parses out text within parenthesis. If any are
found, they are checked for being a valid filepath. The original
filename string is also checked in order to preserve behavior.
Before:
https://github.com/user-attachments/assets/37f60335-e947-4879-9ca2-88a33f5781f5
After:
https://github.com/user-attachments/assets/bd10649e-ad74-43da-80f4-3e7fd56abd86
Release Notes:
- Improved link parsing for cases when a link is embedded in
parenthesis, e.g. markdown
Closes#43354
Overview:
In a diagnostic panel (and all Markdown derived panels, including
function hint popovers and the like), the expected behavior is that when
a user double clicks a word, the whole word is highlighted. If they
double click and hold, then drag, the text selection proceeds word by
word. There is similar behavior for triple click which goes line by
line, and quadruple click which selects all text.
Before this fix, the DiagnosticPopover allowed the user to click and
drag, but double click and drag reverts to selecting text character by
character. The same wrong behavior is shown for triple click (line).
Quadruple click (all text) was not previously implemented in
MarkdownElement.
Quick example of wrong behavior, showing single click and drag, double
click and drag, triple click and drag, then quadruple click (fails).
https://github.com/user-attachments/assets/1184e64d-5467-4504-bbb6-404546eab90a
Quick example showing the correct behavior fixed in this PR:
https://github.com/user-attachments/assets/06bf5398-d6d6-496c-8fe9-705031207f05
Nota bene:
I'm not a rust dev, so a lot of this relied on my C/C++ experience,
cribbing from elsewhere in the repo, and help from Claude. If that's not
ok for this project, I totally understand.
Much of this was informed by editor.rs, using a similar pattern to
SelectMode in there (see lines 450, and begin_selection and
extend_selection). It didn't seem appropriate to import SelectMode from
there (also Markdown range and Anchor range seemed different enough),
nor did it seem appropriate to move SelectMode to markdown.rs.
The tests are non-ui based, instead testing the relevant functions. Not
sure if that's what's expected.
Release Notes:
- Double- and triple-click selection now correctly expands by word and
by line within Markdown elements (diagnostics, agent panel, etc.).
In a previous Pull Request, a new field was added to `editor::Editor`,
namely `cursor_offset_on_selection`, in order to control whether the
cursor representing the head of a selection should be positioned in the
last selected character, as we have on Vim mode, or after, like we have
when Vim mode is disabled.
This field would then be set by the `vim` crate, depending on the
current vim mode. However, it was noted that
`vim_mode_setting::VimModeSetting` already exsits and allows other
crates to determine whether Vim mode is enabled or not. Since we're
already checking `!range.is_empty()` in
`editor::element::SelectionLayout::new` we can then rely on simply
determining whether Vim mode is enabled to decide whether tho shift the
cursor one position to the left when making a selection.
As such, this commit removes the `cursor_offset_on_selection` field, as
well as any related methods in favor of a new `Editor.vim_mode_enabled`
method, which can be used to achieve the same behavior.
Relates to #42837
Release Notes:
- N/A
Adds an optional `timeout_ms` parameter to the terminal tool that allows
bounding the runtime of shell commands. When the timeout expires, the
running terminal task is killed and the tool returns with the partial
output captured so far.
## Summary
This PR adds the ability for the agent to specify a maximum runtime when
invoking the terminal tool. This helps prevent indefinite hangs when
running commands that might wait for network, user prompts, or long
builds/tests.
## Changes
- Add `timeout_ms` field to `TerminalToolInput` schema
- Extend `TerminalHandle` trait with `kill()` method
- Implement `kill()` for `AcpTerminalHandle` and `EvalTerminalHandle`
- Race terminal exit against timeout, killing on expiry
- Update system prompt to recommend using timeouts for long-running
commands
- Add test for timeout behavior
- Update `.rules` to document GPUI executor timers for tests
## Testing
- Added `test_terminal_tool_timeout_kills_handle` which verifies that
when a timeout is specified and expires, the terminal handle is killed
and the tool returns with partial output.
- All existing agent tests pass.
Release Notes:
- agent: Added optional `timeout_ms` parameter to the terminal tool,
allowing the agent to bound command runtime and prevent indefinite hangs
Enables using Zeta edit predictions with a custom
`ZED_PREDICT_EDITS_URL` without requiring authentication to Zed servers.
This is useful for:
- Development and testing workflows
- Self-hosted Zeta instances
- Custom AI model endpoints
Prior context on this usage of `ZED_PREDICT_EDITS_URL`:
https://github.com/zed-industries/zed/pull/30418
Release Notes:
- Improved self-hosted zeta UX. Users no longer have to log into Zed to
use custom or self-hosted zeta backends.
---------
Co-authored-by: Agus Zubiaga <agus@zed.dev>
## Summary
This PR updates the vitest test runner integration to use the modern
`--no-file-parallelism` flag instead of the deprecated
`--poolOptions.forks.minForks=0` and `--poolOptions.forks.maxForks=1`
flags.
## Changes
- Replaced verbose pool options with `--no-file-parallelism` flag in
both file-level and symbol-level vitest test tasks
- This change works with vitest v4 while maintaining backwards
compatibility with earlier versions (or 3 at least!)
## Testing
- Added test `test_vitest_uses_no_file_parallelism_flag` that verifies:
- The `--no-file-parallelism` flag is present in generated test tasks
- The deprecated `poolOptions` flags are not present
- Manually tested with both vitest v4 and older versions to confirm
backwards compatibility
- All existing tests pass
## Impact
This allows Zed users to run and debug vitest tests in projects using
vitest v4 while maintaining support for earlier versions.
Release Notes:
- Fixed vitest test running and debugging for projects using vitest v4
---------
Co-authored-by: Cole Miller <cole@zed.dev>
Closes #ISSUE
Post #43854, we are advertising trailing comma support for our asset
`jsonc` files to the JSON LSP. This results in it adding trailing commas
on format of these files. This PR batch updates the formatting for these
files, so they are not spuriously added as part of other PRs that happen
to modify these files
Release Notes:
- N/A *or* Added/Fixed/Improved ...
This PR allows for a handle to an existing Tokio runtime to be passed to
gpui_tokio's initialization function, which means that Tokio runtimes
created externally can be used.
Mikayla suggested that the function simply take the runtime from
whatever context the initialization function is called from but I think
there could reasonably be situations where that isn't the case and this
shouldn't have a meaningful impact to code complexity. If you want to
use the current context's runtime you can just do
`gpui_tokio::init_from_handle(cx, Handle::current());`.
This doesn't have an impact on the current users of the crate - the
existing `init()` function is functionally unchanged.
Release Notes:
- N/A
Closes#4644
Release Notes:
- Adds `MousePressureEvent`, an event that is sent anytime the touchpad
pressure changes, into `gpui`. MacOS only.
- Triggers go-to-defintion on force clicks in the editor.
This is my first contribution, let me know if I've missed something
here.
---------
Co-authored-by: Anthony Eid <anthony@zed.dev>
Co-authored-by: Antonio Scandurra <me@as-cii.com>
We called out to `request_on_type_formatting` only in handle_input
function, but newlines are actually handled by editor::Newline action.
Closes#12383
Release Notes:
- Added support for on-type formatting with newlines.
## Motivating problem
The gpui API currently has this counter intuitive behaviour
```rust
div()
.id("hallo")
.cursor_pointer()
.text_color(white())
.font_weight(FontWeight::SEMIBOLD)
.text_size(px(20.0))
.child("hallo")
.active(|this| this.text_color(red()))
```
By changing the text_color when the div is active, the current behaviour
is to overwrite all of the text styling rather than do a proper
refinement of the existing text styling leading to this odd result:
The button being active inadvertently changes the font size.
https://github.com/user-attachments/assets/1ff51169-0d76-4ee5-bbb0-004eb9ffdf2c
## Solution
Previously refining a Style would not recursively refine the TextStyle
inside of it, leading to this behaviour:
```rust
let mut style = Style::default();
style.refine(&StyleRefinement::default().text_size(px(20.0)));
style.refine(&StyleRefinement::default().font_weight(FontWeight::SEMIBOLD));
assert!(style.text_style().unwrap().font_size.is_none());
//assertion passes
```
(As best as I can tell) Style deliberately has `pub text:
TextStyleRefinement` storing the `TextStyleRefinement` rather than the
absolute `TextStyle` so that these refinements can be elsewhere used in
cascading text styles down to element's children. But a consequence of
that is that the refine macro was not properly recursively refining the
`text` field as it ought to.
I've modified the refine macro so that the `#[refineable]` attribute
works with `TextStyleRefinement` as well as the usual `TextStyle`.
(Perhaps a little bit haphazardly by simply checking whether the name
ends in Refinement - there may be a better solution there).
This PR resolves the motivating problem and triggers the assertion in
the above code as you'd expect. I've compiled zed under these changes
and all seems to be in order there.
Release Notes:
- N/A
---------
Co-authored-by: Antonio Scandurra <me@as-cii.com>
Vim visual mode and Helix selection mode both require the cursor to be
on the last character of the selection. Until now, this was implemented
by offsetting the cursor one character to the left whenever a block
cursor is used. (Since the visual modes use a block cursor.)
However, this oversees the problem that **some users might want to use
the block cursor without being in visual mode**. Meaning that the cursor
is offset by one character to the left even though Vim/Helix mode isn't
even activated.
Since the Vim mode implementation is separate from the `editor` crate
the solution is not as straightforward as just checking the current vim
mode. Therefore this PR introduces a new `Editor` struct field called
`cursor_offset_on_selection`. This field replaces the previous check
condition and is set to `true` whenever the Vim mode is changed to a
visual mode, and `false` otherwise.
Closes#36677 and #20121
Release Notes:
- Fixes block and hollow cursor being offset when selecting text
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
Closes#44417
Release Notes:
- Added a setting `show_user_menu` (defaulting to true) which shows or
hides the user menu (the one with the user avatar) in title bar.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Release Notes:
- Make Helix keybinds use visual line movement for `j`, `Down`, `k` and `Up`, and textual line movement for `g j`, `g Down`, `g k` and `g Up`.
For folders and files basically any selected item in the git panel we
draw a border around it. The issue is that the right side of this border
wasn't ever visible.
In the project_panel.rs file I've saw that the decision was to make the
right side border 2 pixels. And this panel doesn't have this issue, no
matter which side of the dock is selected. So it was a very easy `look
at how we did x do y`.
Before:

After:

I don't think it warrants a release note.
Release Notes:
- N/A
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
The issue is that we aren't consistent in using the same
`panel_focus_border` color across zed.
Might completely fix my issue: #44750
For focused items in:
- outline panel
- git panel
While these:
- project panel
- keymap editor tab
Are actually using the panel_focused_border option.
Not sure if this warrants a release note, feel free to adapt.
Release Notes:
- N/A
- Set PAGER='' and GIT_PAGER=cat for agent/terminal commands so pager
configs (e.g. delta) don't hang tool output\n\nFixes #42943
Release Notes:
- Prevent git pager configs from hanging agent/terminal git commands by
forcing PAGER and GIT_PAGER off.
Closes#43784Closes#44375Closes#21057
This PR updates the Proto extension to include support for two new
language servers as well as an updated grammar for better highlighting.
Release Notes:
- Improved Proto support to work better out of the box.
🔜
TODO:
- [x] Add a utility pane to the left and right edges of the workspace
- [x] Add a maximize button to the left and right side of the pane
- [x] Add a new agents pane
- [x] Add a feature flag turning these off
POV: You're working agentically
<img width="354" height="606" alt="Screenshot 2025-12-13 at 11 50 14 PM"
src="https://github.com/user-attachments/assets/ce5469f9-adc2-47f5-a978-a48bf992f5f7"
/>
Release Notes:
- N/A
---------
Co-authored-by: Nathan Sobo <nathan@zed.dev>
Co-authored-by: Zed <zed@zed.dev>
In helix, `space /` activates a global search picker, so I think that it
should be the same in zed's helix mode.
Release Notes:
- Added helix's `space /` keybinding to open a global search menu to
zed's helix mode
Tighten up evals, make assistant less talkative, get them passing a bit
more, improve telemetry, stream in failure messages, and turn it on for
staff.
Release Notes:
- N/A
This PR makes zed terminal gruvbox theme consistent with other terminals
themes.
Current ansi colors is broken, by not only not using colors from
original palette, but also by inverting of bright/normal colors...
Currently I took colors from Ghostty (Iterm2 themes), making sure that
they are consistent with palette.
For dim colors I darken them by decreasing "Value" from HSV
representation of colors by 30%.
I am open to discussion and willing to implement those changes for light
theme after receiving feedback.
Examples below:
| Before | After |
| - | - |
| <img width="489" height="472" alt="image"
src="https://github.com/user-attachments/assets/599dd162-6666-4705-adb7-1b62a7800f70"
/> | <img width="490" height="470" alt="image"
src="https://github.com/user-attachments/assets/fee02cc5-6ca8-4daa-88f1-7f37f27f2ce4"
/> |
Script to reproduce:
```bash
#!/bin/bash
echo "Normal ANSI Colors:"
for i in {30..37}; do
printf "\e[${i}m Text \e[0m"
done
echo ""
echo "Bright ANSI Colors (Foreground):"
for i in {90..97}; do
printf "\e[${i}m Text \e[0m"
done
echo ""
echo "Bright ANSI Colors (Background):"
for i in {100..107}; do
printf "\e[${i}m Text \e[0m"
done
echo ""
echo "Foreground and Background Combinations:"
for fg in {30..37}; do
for bg in {40..47}; do
printf "\e[${fg};${bg}m FB \e[0m"
done
echo ""
done
echo "Bright Foreground and Background Combinations:"
for fg in {90..97}; do
for bg in {100..107}; do
printf "\e[${fg};${bg}m FB \e[0m"
done
echo ""
done
```
Release Notes:
- Fixed ANSI colors definitions in the Gruvbox theme (thanks @dangooddd)
---------
Co-authored-by: Oleksiy Syvokon <oleksiy@zed.dev>
I have noticed you care about `SumTree` (and `Rope`) construction
performance, hence using rayon for parallelism and careful `Chunk`
splitting to avoid reallocation in `Rope::push`. It seemed strange to me
that using multi-threading is that beneficial there, so I tried to
investigate why the serial version (`SumTree::from_iter`) is slow in the
first place.
From my analysis I believe there are two main factors here:
1. `SumTree::from_iter` stores temporary `Node<T>` values in a vector
instead of heap-allocating them immediately and storing `SumTree<T>`
directly, as `SumTree::from_par_iter` does.
2. `Chunk::new` is quite slow: for some reason the compiler does not
vectorize it and seems to struggle to optimize u128 shifts (at least on
x86_64).
For (1) the solution is simple: allocate `Node<T>` immediately after
construction, just like `SumTree::from_par_iter`.
For (2) I was able to get better codegen by rewriting it into a simpler
per-byte loop and splitting computation into smaller chunks to avoid
slow u128 shifts.
There was a similar effort recently in #43193 using portable_simd
(currently nightly only) to optimize `Chunk::push_str`. From what I
understand from that discussion, you seem okay with hand-rolled SIMD for
specific architectures. If so, then I also provide sse2 implementation
for x86_64. Feel free to remove it if you think this is unnecessary.
To test performance I used a big CSV file (~1GB, mostly ASCII) and
measured `Rope::from` with this program:
```rust
fn main() {
let text = std::fs::read_to_string("big.csv").unwrap();
let start = std::time::Instant::now();
let rope = rope::Rope::from(text);
println!("{}ms, {}", start.elapsed().as_millis(), rope.len());
}
```
Here are results on my machine (Ryzen 7 4800H)
| | Parallel | Serial |
| ------------ | -------- | ------ |
| Before | 1123ms | 9154ms |
| After | 497ms | 2081ms |
| After (sse2) | 480ms | 1454ms |
Since serial performance is now much closer to parallel, I also
increased `PARALLEL_THRESHOLD` to 1000. In my tests the parallel version
starts to beat serial at around 150 KB strings. This constant might
require more tweaking and testing though, especially on ARM64.
<details>
<summary>cargo bench (SSE2 vs before)</summary>
```
Running benches\rope_benchmark.rs (D:\zed\target\release\deps\rope_benchmark-3f8476f7dfb79154.exe)
Gnuplot not found, using plotters backend
push/4096 time: [43.592 µs 43.658 µs 43.733 µs]
thrpt: [89.320 MiB/s 89.473 MiB/s 89.610 MiB/s]
change:
time: [-78.523% -78.222% -77.854%] (p = 0.00 < 0.05)
thrpt: [+351.56% +359.19% +365.61%]
Performance has improved.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severe
push/65536 time: [632.36 µs 634.03 µs 635.76 µs]
thrpt: [98.308 MiB/s 98.576 MiB/s 98.836 MiB/s]
change:
time: [-51.521% -50.850% -50.325%] (p = 0.00 < 0.05)
thrpt: [+101.31% +103.46% +106.28%]
Performance has improved.
Found 18 outliers among 100 measurements (18.00%)
11 (11.00%) low mild
6 (6.00%) high mild
1 (1.00%) high severe
append/4096 time: [11.635 µs 11.664 µs 11.698 µs]
thrpt: [333.92 MiB/s 334.89 MiB/s 335.72 MiB/s]
change:
time: [-24.543% -23.925% -22.660%] (p = 0.00 < 0.05)
thrpt: [+29.298% +31.450% +32.525%]
Performance has improved.
Found 12 outliers among 100 measurements (12.00%)
2 (2.00%) low mild
2 (2.00%) high mild
8 (8.00%) high severe
append/65536 time: [1.1287 µs 1.1324 µs 1.1360 µs]
thrpt: [53.727 GiB/s 53.900 GiB/s 54.075 GiB/s]
change:
time: [-44.153% -37.614% -29.834%] (p = 0.00 < 0.05)
thrpt: [+42.518% +60.292% +79.061%]
Performance has improved.
slice/4096 time: [28.340 µs 28.372 µs 28.406 µs]
thrpt: [137.52 MiB/s 137.68 MiB/s 137.83 MiB/s]
change:
time: [-8.0798% -6.3955% -4.4109%] (p = 0.00 < 0.05)
thrpt: [+4.6145% +6.8325% +8.7900%]
Performance has improved.
Found 3 outliers among 100 measurements (3.00%)
1 (1.00%) low mild
1 (1.00%) high mild
1 (1.00%) high severe
slice/65536 time: [527.51 µs 528.17 µs 528.90 µs]
thrpt: [118.17 MiB/s 118.33 MiB/s 118.48 MiB/s]
change:
time: [-53.819% -45.431% -34.578%] (p = 0.00 < 0.05)
thrpt: [+52.853% +83.256% +116.54%]
Performance has improved.
Found 5 outliers among 100 measurements (5.00%)
1 (1.00%) low severe
3 (3.00%) low mild
1 (1.00%) high mild
bytes_in_range/4096 time: [3.2545 µs 3.2646 µs 3.2797 µs]
thrpt: [1.1631 GiB/s 1.1685 GiB/s 1.1721 GiB/s]
change:
time: [-3.4829% -2.4391% -1.7166%] (p = 0.00 < 0.05)
thrpt: [+1.7466% +2.5001% +3.6085%]
Performance has improved.
Found 8 outliers among 100 measurements (8.00%)
6 (6.00%) high mild
2 (2.00%) high severe
bytes_in_range/65536 time: [80.770 µs 80.832 µs 80.904 µs]
thrpt: [772.52 MiB/s 773.21 MiB/s 773.80 MiB/s]
change:
time: [-1.8710% -1.3843% -0.9044%] (p = 0.00 < 0.05)
thrpt: [+0.9126% +1.4037% +1.9067%]
Change within noise threshold.
Found 8 outliers among 100 measurements (8.00%)
5 (5.00%) high mild
3 (3.00%) high severe
chars/4096 time: [790.50 ns 791.10 ns 791.88 ns]
thrpt: [4.8173 GiB/s 4.8220 GiB/s 4.8257 GiB/s]
change:
time: [+0.4318% +1.4558% +2.0256%] (p = 0.00 < 0.05)
thrpt: [-1.9854% -1.4349% -0.4299%]
Change within noise threshold.
Found 6 outliers among 100 measurements (6.00%)
1 (1.00%) low severe
1 (1.00%) low mild
2 (2.00%) high mild
2 (2.00%) high severe
chars/65536 time: [12.672 µs 12.688 µs 12.703 µs]
thrpt: [4.8046 GiB/s 4.8106 GiB/s 4.8164 GiB/s]
change:
time: [-2.7794% -1.2987% -0.2020%] (p = 0.04 < 0.05)
thrpt: [+0.2025% +1.3158% +2.8588%]
Change within noise threshold.
Found 15 outliers among 100 measurements (15.00%)
1 (1.00%) low mild
12 (12.00%) high mild
2 (2.00%) high severe
clip_point/4096 time: [63.009 µs 63.126 µs 63.225 µs]
thrpt: [61.783 MiB/s 61.880 MiB/s 61.995 MiB/s]
change:
time: [+2.0484% +3.2218% +5.2181%] (p = 0.00 < 0.05)
thrpt: [-4.9593% -3.1213% -2.0073%]
Performance has regressed.
Found 13 outliers among 100 measurements (13.00%)
12 (12.00%) low mild
1 (1.00%) high severe
Benchmarking clip_point/65536: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 7.7s, enable flat sampling, or reduce sample count to 50.
clip_point/65536 time: [1.2420 ms 1.2430 ms 1.2439 ms]
thrpt: [50.246 MiB/s 50.283 MiB/s 50.322 MiB/s]
change:
time: [-0.3495% -0.0401% +0.1990%] (p = 0.80 > 0.05)
thrpt: [-0.1986% +0.0401% +0.3507%]
No change in performance detected.
Found 7 outliers among 100 measurements (7.00%)
6 (6.00%) high mild
1 (1.00%) high severe
point_to_offset/4096 time: [16.104 µs 16.119 µs 16.134 µs]
thrpt: [242.11 MiB/s 242.33 MiB/s 242.56 MiB/s]
change:
time: [-1.3816% -0.2497% +2.2181%] (p = 0.84 > 0.05)
thrpt: [-2.1699% +0.2503% +1.4009%]
No change in performance detected.
Found 6 outliers among 100 measurements (6.00%)
3 (3.00%) low mild
1 (1.00%) high mild
2 (2.00%) high severe
point_to_offset/65536 time: [356.28 µs 356.57 µs 356.86 µs]
thrpt: [175.14 MiB/s 175.28 MiB/s 175.42 MiB/s]
change:
time: [-3.7072% -2.3338% -1.4742%] (p = 0.00 < 0.05)
thrpt: [+1.4962% +2.3896% +3.8499%]
Performance has improved.
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) low mild
cursor/4096 time: [18.893 µs 18.934 µs 18.974 µs]
thrpt: [205.87 MiB/s 206.31 MiB/s 206.76 MiB/s]
change:
time: [-2.3645% -2.0729% -1.7931%] (p = 0.00 < 0.05)
thrpt: [+1.8259% +2.1168% +2.4218%]
Performance has improved.
Found 12 outliers among 100 measurements (12.00%)
12 (12.00%) high mild
cursor/65536 time: [459.97 µs 460.40 µs 461.04 µs]
thrpt: [135.56 MiB/s 135.75 MiB/s 135.88 MiB/s]
change:
time: [-5.7445% -4.2758% -3.1344%] (p = 0.00 < 0.05)
thrpt: [+3.2358% +4.4668% +6.0946%]
Performance has improved.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severe
append many/small to large
time: [38.364 ms 38.620 ms 38.907 ms]
thrpt: [313.75 MiB/s 316.08 MiB/s 318.19 MiB/s]
change:
time: [-0.2042% +1.0954% +2.3334%] (p = 0.10 > 0.05)
thrpt: [-2.2802% -1.0836% +0.2046%]
No change in performance detected.
Found 21 outliers among 100 measurements (21.00%)
9 (9.00%) high mild
12 (12.00%) high severe
append many/large to small
time: [48.045 ms 48.322 ms 48.648 ms]
thrpt: [250.92 MiB/s 252.62 MiB/s 254.07 MiB/s]
change:
time: [-6.5298% -5.6919% -4.8532%] (p = 0.00 < 0.05)
thrpt: [+5.1007% +6.0354% +6.9859%]
Performance has improved.
Found 11 outliers among 100 measurements (11.00%)
2 (2.00%) high mild
9 (9.00%) high severe
```
</details>
Release Notes:
- N/A *or* Added/Fixed/Improved ...
## Fix incorrect directory path folding in slash command file collection
**Description:**
This PR fixes a bug in the `collect_files` function where the directory
folding logic (used to compact chains like `.github/workflows`) failed
to reset its state when traversing out of a folded branch.
**The Issue:**
The `folded_directory_names` accumulator was persisting across loop
iterations. If the traversal moved from a folded directory (e.g.,
`.github/workflows`) to a sibling directory (e.g., `.zed`), the sibling
would incorrectly inherit the prefix of the previously folded path,
resulting in incorrect paths like `.github/.zed`.
**The Fix:**
* Introduced `folded_directory_path` to track the specific path
currently being folded.
* Added a check to reset `folded_directory_names` whenever the traversal
encounters an entry that is not a child of the currently folded path.
* Ensured state is cleared immediately after a folded directory is
rendered.
**Release Notes:**
- Fixed an issue where using slash commands to collect files would
sometimes display incorrect directory paths (e.g., showing
`.github/.zed` instead of `.zed`) when adjacent directories were
automatically folded.
---------
Co-authored-by: Lukas Wirth <lukas@zed.dev>
### Summary:
- Ensure the external agents with ACP servers start via non-interactive
shells to prevent shell startup noise from corrupting JSON-RPC.
- Apply the same tweak to MCP stdio transports so remote context servers
aren’t affected by prompts or greetings.
### Description:
Switch both ACP and MCP stdio launch paths to call
`ShellBuilder::non_interactive()` before building the command. This
removes `-i` on POSIX shells, suppressing prompt/title sequences that
previously prefixed the first JSON line and caused `serde_json` parse
failures. No functional regressions are expected: both code paths only
need a shell for Windows/npm script compatibility, not for
interactivity.
Release Notes:
- Fixed external agents that hung on “Loading…” when shell startup
output broke JSON-RPC initialization.
Zed currently doesn’t support all protocol extensions implemented by
`clangd`, but it does support two:
- `textDocument/inactiveRegion`
- `textDocument/switchSourceHeader`
Release Notes:
- N/A
---------
Co-authored-by: Kunall Banerjee <hey@kimchiii.space>
Fixes#33958
## Problem
When opening a terminal in Zed, `SHLVL` incorrectly starts at 2 instead
of 1. On `workspace: reload`, it increases by 2 instead of 1.
## Root Cause
1. Zed's `shell_env::capture()` spawns a login shell (`-l -i -c`) to
capture the user's environment, which increments `SHLVL`
2. The captured `SHLVL` is passed through to the PTY options
3. When alacritty_terminal spawns the user's shell, it increments
`SHLVL` again
Result: `SHLVL` = captured value + 1 = 2 (when launched from Finder)
## Solution
Remove `SHLVL` from the environment in `TerminalBuilder::new()` before
passing it to alacritty_terminal. This allows the spawned shell to
initialize `SHLVL` to 1 on its own, matching the behavior of standalone
terminal emulators like iTerm2, Kitty, and Alacritty.
## Testing
- Launch Zed from Finder → open terminal → `echo $SHLVL` → should output
`1`
- Launch Zed from shell → open terminal → `echo $SHLVL` → should output
`1`
- `workspace: reload` → open terminal → `echo $SHLVL` → should remain
`1`
- Tested with bash, zsh, fish
Release Notes:
- Fixed terminal `$SHLVL` starting at 2 instead of 1
([#33958](https://github.com/zed-industries/zed/issues/33958))
This PR adds a staff-only button to the edit prediction menu for
capturing your current editing session as edit prediction example file.
When you click that button, it opens a markdown tab with the example. By
default, the most recent change that you've made is used as the expected
patch, and all of the previous events are used as the editing history.
<img width="303" height="123" alt="Screenshot 2025-12-14 at 6 58 33 PM"
src="https://github.com/user-attachments/assets/600c7bf2-7cf4-4d27-8cd4-8bb70d0b20b0"
/>
Release Notes:
- N/A
Imitating the approach of #41829. Prevents e.g. reverting a hunk and
having that excerpt yanked out from under the cursor.
Release Notes:
- git: Improved stability of excerpts when editing in the project diff.
The test `test_collaborating_with_completion` has a latent race
condition that hasn't manifested on CI yet but could cause hangs with
certain task orderings.
## The Bug
Commit `fd1494c31a` set up LSP request handlers AFTER typing the trigger
character:
```rust
// Type trigger first - spawns async tasks to send completion request
editor_b.update_in(cx_b, |editor, window, cx| {
editor.handle_input(".", window, cx);
});
// THEN set up handlers (race condition!)
fake_language_server
.set_request_handler::<lsp::request::Completion, _, _>(...)
.next().await.unwrap(); // Waits for handler to receive a request
```
Whether this works depends on task scheduling order, which varies by
seed. If the completion request is processed before the handler is
registered, the request goes to `on_unhandled_notification` which claims
to handle it but sends no response, causing a hang.
## Changes
- Move handler setup BEFORE typing the trigger character
- Make `TestDispatcher::spawn_realtime` panic to prevent future
non-determinism from real OS threads
- Add `execution_hash()` and `execution_count()` to TestDispatcher for
debugging
- Add `DEBUG_SCHEDULER=1` logging for task execution tracing
- Document the investigation in `situation.md`
cc @localcc @SomeoneToIgnore (authors of related commits)
Release Notes:
- N/A
---------
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
This adds implementations of `std::iter::Sum` for `Pixels`, allowing the
use of `.sum()` on iterators of `Pixels` values.
### Changes
- Implement `Sum<Pixels>` for `Pixels` (owned values)
- Implement `Sum<&Pixels>` for `Pixels` (references)
This enables ergonomic patterns like:
```rust
let total: Pixels = pixel_values.iter().sum();
```
This change matches how normal hovers are handled (which early return
with `None` in this branch)
Release Notes:
- Fixed hover boxes for inlays blinking in and out without movement when
cursor blinking was enabled
When an external agent doesn't provide an icon, we were using different
fallback icons in all the places we display icons (settings view, thread
new menu, and the thread view toolbar itself).
Release Notes:
- N/A
Fix a bug where the branch picker would be dismissed before completing
the add remote flow, thus making Zed unable to add remote repositories
through the branch picker.
This bug was caused by the picker always being dismissed on the confirm
action, so the fix was stopping the branch modal from being dismissed
too early.
I also cleaned up the UI a bit and code.
1. Removed the loading field from the Branch delegate because it was
never used and the activity indicator will show remote add command if it
takes a while.
2. I replaced some async task spawning with the use of `cx.defer`.
3. Added a `add remote name` fake entry when the picker is in the name
remote state. I did this so the UI would be consistent with the other
states.
4. Added two regression tests.
4.1 One to prevent this bug from occurring again:
https://github.com/zed-industries/zed/pull/44742
4.2 Another to prevent the early dismissal bug from occurring
5. Made `init_branch_list_test` param order consistent with Zed's code
base
###### Updated UI
<img width="1150" height="298" alt="image"
src="https://github.com/user-attachments/assets/edead508-381c-4bd8-8a41-394dd5b7b781"
/>
Release Notes:
- N/A
Add the repository name when:
- there's more than one repository, and
- the name of the active repository doesn't match the name of the
project (to avoid stuttering with the adjacent project switcher button)
Release Notes:
- The branch name in the title bar now includes the name of the current
repository when needed to disambiguate.
- Edit prediction providers can now be configured through the settings
UI
- Cleaned up the status bar menu to only show _configured_ providers
- Added to the status bar icon button tooltip the name of the active
provider
- Only display the data collection functionality under "Privacy" for the
Zed models
- Moved the Codestral edit prediction provider out of the Mistral
section in the agent panel into the settings UI
- Refined and improved UI and states for configuring GitHub Copilot as
both an agent and edit prediction provider
#### Todos before merge:
- [x] UI: Unify with settings UI style and tidy it all up
- [x] Unify Copilot modal `impl`s to use separate window
- [x] Remove stop light icons from GitHub modal
- [x] Make dismiss events work on GitHub modal
- [ ] Investigate workarounds to tell if Copilot authenticated even when
LSP not running
Release Notes:
- settings_ui: Added a section for configuring edit prediction providers
under AI > Edit Predictions, including Codestral and GitHub Copilot.
Once you've updated you can use the following link to open it:
zed://settings/edit_predictions.providers
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
This fixes an issue where a user could get confused by the branch picker
because it would only show the 10 most recent branches, instead of all
branches.
Release Notes:
- git: Show all branches in branch picker when search field is empty
We were panicking whenever something went wrong with an example in the
CLI. This can be very disruptive when running many examples, and e.g a
single request fails. Instead, if running more than one example, errors
will now be logged alongside instructions to explore and re-run the
example by itself.
<img width="1454" height="744" alt="CleanShot 2025-12-12 at 13 32 04@2x"
src="https://github.com/user-attachments/assets/87c59e64-08b9-4461-af5b-03af5de94152"></img>
You can still opt in to stop as soon as en error occurs with the new
`--failfast` argument.
Release Notes:
- N/A
Improves the scheduler by allowing tasks to have a set priority which
will significantly improve responsiveness.
Release notes:
- N/A
---------
Co-authored-by: Yara <git@yara.blue>
Co-authored-by: dvdsk <noreply@davidsk.dev>
- Limit status lines to 10 in case `max_parallelism` is specified with a
grater value
- Handle logging gracefully rather than writing over it when clearing
status lines
Release Notes:
- N/A
Currently we have a single cache for this data shared between all
snapshots which is incorrect, as we might update the cache to a new
version while having old snapshots around which then may try to access
new data with old offsets/rows.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Update the issue template used for "Report a bug" to include a field
specifically for the user's keymap file, as we've seen multiple cases
where we end up asking the users for their custom keymap, to ensure that
they're not overriding existing defaults.
Release Notes:
- N/A
- Fix missing font features in
`git_ui::blame_ui::GitBlameRenderer.render_blame_entry`
- Fix missing buffer font features in
`markdown_preview::markdown_renderer`
- Update the way that the markdown style is built for hover popovers so
that, for code blocks, the buffer font features are used.
- Introduce `gpui::Styled.font_features` to allow callers to also set
the font's features, similar to how `gpui::Styled.font_family` already
exists.
Relates to #44209
Release Notes:
- Fixed wrong font features in Blame UI, Hover Popover and Markdown
Preview
Closes#41567
We were using the git panel editor to check the focus where the commit
modal has its only editor.
Release Notes:
- Fixed an issue where commit and amend actions wouldn’t trigger when
using keybinds in the commit modal.
Update the behavior of `git::Amend` to ensure that the latest head
commit message, if available, is always loaded into the commit message
editor, regardless of its state. The previous text, if any, is now also
restored after the amend is finished.
- Update `FakeGitRepository.show` to include a message in the returned
`CommitDetails` so we can assert that this specific commit message is
set in the commit message editor.
- Add default implementation for `FakeGitRepository.commit` and
`FakeGitRepository.run_hook` to ensure that tests are able to run and
don't panic on `unimplemented!()`
- Refactor `GitPanel.load_last_commit_message_if_empty` to
`GitPanel.load_last_commit_message`, ensuring that the head commit
message is always loaded, regardless of whether the commit message
editor is empty.
- Update `GitPanel.commit_changes` to ensure that the pending amend
state is only updated if the editor managed to actually commit the
changes. This also ensures that we don't restore the commit message
editor's contents when amending a commit, before the amend is actually
processed.
- Update `CommitModal.amend`, removing the call to
`GitPanel.set_amend_pending` as that is now handled by the background
task created in `GitPanel.commit_changes`.
- Split the `commit` and `amend` methods from the event handlers so that
the methods can be called directly, as is now being done by
`CommitModal.on_commit` and `CommitModal.on_amend`.
Release Notes:
- Updated the `git: amend` command to always load the latest head
commit message, and to restore any previously entered text in the commit
message editor after the amend completes
This also applies to `cargo clean` one.
Closes#20873
Release Notes:
- rust: Changed cwd of tasks that spawn a binary target to the root of a
current package (which used to be a directory of the current source
file).
Closes#21324
Adds four new commands:
- `markdown::MoveUp`, `markdown::MoveDown` - these scroll up and down in
markdown preview mode, by no more than the height of a large headline.
- `markdown::MoveUpByItem`, and `markdown::MoveDownByItem` - these
scroll up and down by the height of the item at the top of the markdown
preview window. So headlines and large codeblocks, for instance, scroll
further than individual paragraph lines.
Also attempts to create sensible defaults:
`down` -> `markdown::ScrollDown`
`up` -> `markdown::ScrollUp`
`alt-down` -> `markdown::ScrollDownByItem`
`alt-up` -> `markdown::ScrollUpByItem`
And in Vim:
`ctrl-u` -> `markdown::ScrollPageUp`
`ctrl-d` -> `markdown::ScrollPageDown`
`ctrl-e` -> `markdown::ScrollDown`
`ctrl-y` -> `markdown::ScrollUp`
Release Notes:
- Added commands `markdown::ScrollUp`, `markdown::ScrollDown`,
`markdown::ScrollUpByItem`, and `markdown::ScrollDownByItem`
- Changed commands `markdown::MovePageUp` to `markdown::ScrollPageUp`
and `markdown::MovePageDown` to `markdown::ScrollPageDown`
Tiny thing I noticed; the image metadata showing on the status bar was
previously a button, but given that nothing happens when you click it,
it doesn't need to be one. Having hover, active, and all other states
was confusing.
Release Notes:
- N/A
Closes https://github.com/zed-industries/zed/issues/39056
Leverages a new `await_on_background` API that spawns the future on the
background but blocks the current task, allowing to borrow from the
surrounding scope.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Addressing #22546, we want git permalinks to be aware of the current
changes within the buffer.
This change calculates how many lines have been added/deleted between
the start and end of the selection and uses those values to offset the
selection.
This is done within `Editor::get_permalink_to_line` so that it can be
passed to any git_store.
Example:
<img width="284" height="316" alt="image"
src="https://github.com/user-attachments/assets/268043a0-2fc8-41c1-b094-d650fd4e0ae0"
/>
Where this selections permalink would previously return L3-L9, it now
returns L2-L7.
Release Notes:
- git: make permalinks aware of current diffs
Closes#22546
---
This is my first PR into the zed repository so very happy for any
feedback on how I've implemented this. Thanks!
Builds on https://github.com/zed-industries/zed/pull/40794 and
https://github.com/zed-industries/zed/pull/44381
- Fixes the case where creating a new line inside a nested list puts the
cursor correctly under that nested list item.
- Fixes the case where typing a new list item at the expected indent no
longer auto-indents or outdents incorrectly.
Release Notes:
- Fixed an issue in Markdown where new list items weren’t respecting the
expected indentation on type.
Improves the scheduler by allowing tasks to have a set priority which
will significantly improve responsiveness.
Release notes:
- N/A
---------
Co-authored-by: Yara <git@yara.blue>
Release Notes:
- Fixed new windows underflowing the taskbar on windows
- Improved new windows spawned from maximized or fullscreened windows by
copying the maximized and fullscreened states
Fix git hook hang when using with `prek`. Can see
[comments](https://github.com/zed-industries/zed/issues/44057#issuecomment-3606837089),
this is easy test, should using release build, debug build sometimes not
hang.
The issue existing long time, see issue #37293 , and then in commit
#42239 this issue had fixed. but in commit #43285 broken again. So I
reference the implementation in #42239, then this code work.
I MUST CLAIM, I really don't known what happend, and why this code work.
But it worked.
Release Notes:
- N/A
---------
Co-authored-by: Cole Miller <cole@zed.dev>
This PR restructures the commands of the Edit Prediction CLI (now called
`ep`), to support some flows that are important for the training
process:
* generating zeta2 prompt and expected output, without running
predictions
* scoring outputs that are generated by a system other than the
production code (to evaluate the model during training)
To achieve this, we've restructured the CLI commands so that they all
take as input, and produce as output, a consistent, uniform data format:
a set of one or more `Example` structs, expressible either as the
original markdown format, or as a JSON lines. The `Example` struct
starts with the basic fields that are in human-readable eval format, but
contain a number of optional fields that are filled in by different
steps in the processing pipeline (`context`, `predict`, `format-prompt`,
and `score`).
### To do
* [x] Adjust the teacher model output parsing to use the full buffer
contents
* [x] Move udiff to cli
* [x] Align `format-prompt` with Zeta2's production code
* [x] Change score output to assume same provider
* [x] Move pretty reporting to `eval` command
* [x] Store cursor point in addition to cursor offset
* [x] Rename `edit_prediction_cli2` -> `edit_prediction_cli` (nuke the
old one)
Release Notes:
- N/A
---------
Co-authored-by: Oleksiy Syvokon <oleksiy@zed.dev>
Co-authored-by: Agus Zubiaga <agus@zed.dev>
Co-authored-by: Ben Kunkle <ben@zed.dev>
Closes#35803
This PR adds tree view support to the git panel UI as an additional
setting and moves git entry checkboxes to the right. Tree view only
supports sorting by paths behavior since sorting by status can become
noisy, due to having to duplicate directories that have entries with
different statuses.
### Tree vs Flat View
<img width="358" height="250" alt="image"
src="https://github.com/user-attachments/assets/c6b95d57-12fc-4c5e-8537-ee129963e50c"
/>
<img width="362" height="152" alt="image"
src="https://github.com/user-attachments/assets/0a69e00f-3878-4807-ae45-65e2d54174fc"
/>
#### Architecture changes
Before this PR, `GitPanel::entries` represented all entries and all
visible entries because both sets were equal to one another. However,
this equality isn't true for tree view, because entries can be
collapsed. To fix this, `TreeState` was added as a logical indices field
that is used to filter out non-visible entries. A benefit of this field
is that it could be used in the future to implement searching in the
GitPanel.
Another significant thing this PR changed was adding a HashMap field
`entries_by_indices` on `GitPanel`. We did this because `entry_by_path`
used binary search, which becomes overly complicated to implement for
tree view. The performance of this function matters because it's a hot
code path, so a linear search wasn't ideal either. The solution was
using a hash map to improve time complexity from O(log n) to O(1), where
n is the count of entries.
#### Follow-ups
In the future, we could use `ui::ListItem` to render entries in the tree
view to improve UI consistency.
Release Notes:
- Added tree view for Git panel. Users are able to switch between Flat
and Tree view in Git panel.
---------
Co-authored-by: Anthony Eid <anthony@zed.dev>
Co-authored-by: Remco Smits <djsmits12@gmail.com>
Partially addresses #11473
MVP of dev containers with the following capabilities:
- If in a project with `.devcontainer/devcontainer.json`, a pop-up
notification will ask if you want to open the project in a dev
container. This can be dismissed:
<img width="1478" height="1191" alt="Screenshot 2025-12-08 at 3 15
23 PM"
src="https://github.com/user-attachments/assets/ec2e20d6-28ec-4495-8f23-4c1d48a9ce78"
/>
- Similarly, if a `devcontainer.json` file is in the project, you can
open a devcontainer (or go the devcontainer.json file for further
editing) via the `open remote` modal:
https://github.com/user-attachments/assets/61f2fdaa-2808-4efc-994c-7b444a92c0b1
*Limitations*
This is a first release, and comes with some limitations:
- Zed extensions are not managed in `devcontainer.json` yet. They will
need to be installed either on host or in the container. Host +
Container sync their extensions, so there is not currently a concept of
what is installed in the container vs what is installed on host: they
come from the same list of manifests
- This implementation uses the [devcontainer
CLI](https://github.com/devcontainers/cli) for its control plane. Hence,
it does not yet support the `forwardPorts` directive. A single port can
be opened with `appPort`. See reference in docs
[here](https://github.com/devcontainers/cli/tree/main/example-usage#how-the-tool-examples-work)
- Editing devcontainer.json does not automatically cause the dev
container to be rebuilt. So if you add features, change images, etc, you
will need to `docker kill` the existing dev container before proceeding.
- Currently takes a hard dependency on `docker` being available in the
user's `PATH`.
Release Notes:
- Added ability to Open a project in a DevContainer, provided a
`.devcontainer/devcontainer.json` is present
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
Buttons and menu items should preferably always start with an infinitive
verb that describes what will happen when you trigger them. Instead of
just "File History", we should say "_View_ File History".
Release Notes:
- N/A
Closes #ISSUE
It seems that `ctrl-6` is used exclusively as an alias, as can be seen
in the [linked section of the vim
docs](https://vimhelp.org/editing.txt.html#CTRL-%5E) from the initial PR
that added it. This however conflicts with the `ctrl-{n}` bindings for
`pane::ActivateItem` on macOS, leading to confusing file selection when
`ctrl-6` is pressed.
Release Notes:
- vim(BREAKING): Removed a keybinding conflict between the default macOS
bindings for `pane::ActivateItem` and the `ctrl-6` alias
for`pane::AlternateFile` which is primarily bound to `ctrl-^`. `ctrl-6`
is no longer treated as an alias for `ctrl-^` in vim mode. If you'd like
to restore `ctrl-6` as a binding for `pane::AlternateFile`, paste the
following into your `keymap.json` file:
```
{
"context": "VimControl && !menu",
"bindings": {
"ctrl-6": "pane::AlternateFile"
}
}
```
We were defining these in multiple places and also weren't leveraging
the ids the agents were already providing.
This should make sure we use them consistently and avoid issues in the
future.
Release Notes:
- N/A
The problem with inserting the absolute paths is that the agent will try
to read them. However, we don't allow the agent to read files outside
the current project. For now, we will only insert the crease in case the
code that is getting pasted is from the same project
Release Notes:
- Fixed an issue where pasting code into the agent panel from another
window would show an error
In preparation for https://github.com/zed-extensions/csharp/pull/11. Do
not merge before that PR is published.
Release Notes:
- Added support for Roslyn in C# files. Roslyn will now be the default
language server for C#
Fixes a few cases where the commit view would layout shift as the diff
loaded. This was caused by:
- Adding the commit message buffer after all the diff files
- Using the gutter dimensions from the last frame for the avatar spacing
Release Notes:
- commit view: Fix layout shift while loading commit
---------
Co-authored-by: MrSubidubi <dev@bahn.sh>
Only by reusing the previous scroll handle, we can ensure that both the
scrollbar remains usable and also that the scrollbar does not flicker.
Previously, the scrollbar would hold the reference to an outdated
handle.
I tried invalidating the handle the scrollbar uses, but that leads to
flickering, which is worse. Hence, let's just reuse the scrollbar here.
Release Notes:
- Fixed an issue where the scrollbar would become stale in the code
completions menu after the items were updated.
For qualified identifiers we end up requesting both the definition of
the module and the item within it, but we only want the latter. At the
moment, we can't skip the request altogether, because we can't tell them
apart from the highlights query. However, we can tell from the target
range length, because it should be small for individual definitions as
it only covers their name, not the whole body.
Release Notes:
- N/A
We reallocate quite a bunch in this codepath even though we don't need
to, we already roughly know what number of elements we are working with
so we can reduce the required allocations to some degree. This also
reduces the amount of anchor comparisons required.
Came up in profiling for
https://github.com/zed-industries/zed/issues/44503
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Release Notes:
- Fixed an issue where creating a file through the project panel with a
trailing dot in its name would duplicate the entries with and without
the dot
Co-authored by: Smit Barmase <smit@zed.dev>
Co-Authored-By: Claude <ai+claude@zed.dev>
Closes #ISSUE
Release Notes:
- Added history to the command palette (`up` will now show recently
executed
commands). This is particularly helpful in vim mode when you may mistype
a
complicated command and want to re-run a slightly different version
thereof.
---------
Co-authored-by: Claude <ai+claude@zed.dev>
Closes#40067
Release Notes:
- The `--user-data-dir` flag now works on Windows and Linux, as well as
macOS if you pass `--foreground`.
---------
Co-authored-by: Lukas Wirth <me@lukaswirth.dev>
Fixes a bug that led to us unnecessarily restarting a language server
when we were looking at a single file of a given language.
Release Notes:
- Fixed a bug that led to Zed sometimes starting an excessive amount of
language servers
## Closes#43887
## Release Notes:
### Problem
DeepSeek's reasoning mode API requires `reasoning_content` to be
included in assistant messages that precede tool calls. Without it, the
API returns a 400 error:
```
Missing `reasoning_content` field in the assistant message at message index 2
```
### Added/Fixed/Improved
- Add `reasoning_content` field to `RequestMessage::Assistant` in
`crates/deepseek/src/deepseek.rs`
- Accumulate thinking content from `MessageContent::Thinking` and attach
it to the next assistant/tool-call message
- Wire reasoning content through the language model provider in
`crates/language_models/src/provider/deepseek.rs`
### Testing
- Verified with DeepSeek Reasoner model using tool calls
- Confirmed reasoning content is properly included in API requests
Fixes tool-call errors when using DeepSeek's reasoning mode.
---------
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
This was pulling in tokio which is pretty unfortunate. The solution is
to do the `reqwest::Form` to `http::Reqwest` conversion in the
reliability crate instead of our http client wrapper.
Release Notes:
- N/A
While this fixes the link in the Readme it breaks the one in the docs
which is the more important one (we should probably just duplicate the
readme and not include it into gpui.rs but that is annoying).
Reverts zed-industries/zed#43437
Internally we noticed some regression related to removed query for
PascalCase identifiers. Reverting now to prevent this from going to
preview, still planning to land this with the necessary fixes later.
Introduces RotateSelectionsForward and RotateSelectionsBackward actions
that rotate content in a circular fashion across multiple cursors.
Behavior based on context:
- With selections: rotates the selected text at each cursor position
(e.g., x=1, y=2, z=3 becomes x=3, y=1, z=2)
- With just cursors: rotates entire lines at cursor positions (e.g.,
three lines cycle to line3, line1, line2)
Selections are preserved after rotation, allowing repeated cycling.
Useful for quickly rearranging values, lines, or arguments.
For more examples and use cases, please refer to #5315.
I'm eager to read your thoughts and make any adjustments or improvements
to any aspect of this change.
Closes#5315
Release Notes:
- Added `RotateSelectionsForward` and `RotateSelectionsBackward` actions
that rotate content in a circular fashion across multiple cursors
Hopefully addresses #43575. cc @cole-miller
Release Notes:
- GPU initialization errors are more reliably reported
---------
Co-authored-by: Cole Miller <cole@zed.dev>
Since [this
PR](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1014),
the `tailwindCSS.userLanguages` option has been deprecated, and it is
recommended to use `tailwindCSS.includeLanguages` instead. Using
`tailwindCSS.userLanguages` triggers the warning shown below in the
`tailwindcss-language-server` logs.
<img width="634" height="259" alt="tailwindcss-language-server (kron)
Server Logs v"
src="https://github.com/user-attachments/assets/763551ad-f41a-4756-9d7d-dfb7df45cc5c"
/>
Release Notes:
- Fixed a warning indicating the deprecation of
`tailwindCSS.userLanguages` by initializing the options with
`tailwindCSS.includeLanguages`.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
This PR removes the database schema migrations from the repo, as these
are now managed by Cloud.
There's a new `20251208000000_test_schema.sql` "migration" that we use
to create the database schema for the tests, similar to what we use for
SQLite.
Release Notes:
- N/A
This PR removes the actions `collab::ToggleScreenSharing`,
`collab::ToggleMute`, and `collab::ToggleDeafen`. They weren't actually
registered to any behavior, so while it was possible to create a keybind
bound to them, they never actually trigger. I spent ~30 minutes trying
to figure out why I was getting this result for my `"f13":
"collab::ToggleMute"` keybind in the keybind context menu:
<img width="485" height="174" alt="image"
src="https://github.com/user-attachments/assets/23064c8f-fe8d-42e5-b94f-bd4b8a0cb3b5"
/>
(This really threw me for a loop because I was trying to use this as a
known good case to compare against a _different_ action that wasn't
working because I forgot to register it.)
As a side benefit, this enables telemetry for toggling mic mute via
keybind.
Release Notes:
- Fixed telemetry for `collab::Mute`
- Removed unregistered actions `collab::ToggleMute`,
`collab::ToggleDeafen`, and `collab::ToggleScreenshare`
- The correctly-functioning actions `collab::Mute`, `collab::Deafen`,
and `collab::ScreenShare` are recommended instead
Closes#43155
Adds a missing check to also update packages when the
`typescript-language-server` package is outdated.
I created a new `SERVER_PACKAGE_NAME ` constant so that the package name
isn't coupled to the language server name inside of Zed.
Release Notes:
- Fixed the typescript language server falling out of date
This fixes an issue where the snippet file location would not be the
proper one for compiled extensions because it would be populated with an
absolute path instead of a relative one in relation to the extension
output directory. This caused the copy operation downstream to not do
anything, because it copied the file to the location it already was
(which was not the output directory for that extension).
Also adds some tests and pulls in the `Fs` so we do not have such issues
with snippets a third time hopefully.
Release Notes:
- N/A
Problem statement: When given a line that contained a lot of matches of
your hyperlink regex of choice (thanks to #40305), we would look for
matches
that intersected with currently hovered point. This is *hella*
expensive, because we would re-walk the whole alacritty grid for each
match. With the repro that Joseph shared, we had to go through 4000 such
matches on each frame render.
Problem solution: We now convert the hovered point into a range within
the line (byte-wise) in order to throw away matches that do not
intersect the
hovered range. This lets us avoid performing the unnecessary conversion
when we know it's never going to yield a match range that intersects the
hovered point.
Release Notes:
- terminal: Fixed performance regression when handling long lines.
---------
Co-authored-by: Dave Waggoner <waggoner.dave@gmail.com>
Implements a specialized constructor `LanguageName::new_static` for
`&'static str` which reduces allocations.
`LanguageName::new` always backs the underlying `SharedString` with an
owned `Arc<str>` even when a `&'static str` is passed. This makes us
allocate each time we create a new `LanguageName` no matter what.
Creating a specialized constructor for `&'static str` allows us to
essentially construct them for free.
Additional change:
Encourages using explicit constructors to avoid needless allocations.
Currently there were no instances of this trait being called where the
lifetime was not `'static` saving another 48 locations of allocation.
```rust
impl<'a> From<&'a str> for LanguageName {
fn from(str: &'a str) -> Self {
Self(SharedString::new(str))
}
}
// to
impl From<&'static str> for LanguageName {
fn from(str: &'static str) -> Self {
Self(SharedString::new_static(str))
}
}
```
Release Notes:
- N/A
Closes#44324
Release Notes:
- Uses the lowercase representation of the query for the matrix length
calculation to match the bounds size expected in `recursive_score_match`
This PR includes several minor modifications and improvements related to
Git hosting providers, covering the following areas:
1. Bitbucket Owner Parsing Fix: Remove the common `scm` prefix from the
remote URL of self-hosted Bitbucket instances to prevent incorrect owner
parsing.
[Reference](a6e3c6fbb2/src/git/remotes/bitbucket-server.ts (L72-L74))
2. Bitbucket Avatars in Blame: Add support for displaying Bitbucket
avatars in the Git blame view.
<img width="2750" height="1994" alt="CleanShot 2025-11-10 at 20 34
40@2x"
src="https://github.com/user-attachments/assets/9e26abdf-7880-4085-b636-a1f99ebeeb97"
/>
3. Self-hosted SourceHut Support: Add support for self-hosted SourceHut
instances.
4. Configuration: Add recently introduced self-hosted Git providers
(Gitea, Forgejo, and SourceHut) to the `git_hosting_providers` setting
option.
<img width="2750" height="1994" alt="CleanShot 2025-11-10 at 20 33
48@2x"
src="https://github.com/user-attachments/assets/44ffc799-182d-4145-9b89-e509bbc08843"
/>
Closes#11043
Release Notes:
- Improved self-hosted git provider support and Bitbucket integration
When using the latest version of `GPUI`, I found some grid layout
issues. I discovered #43555 modified the default behavior of grid
template columns. I checked the implementation at
https://tailwindcss.com/docs/grid-template-columns, and it seems our
previous implementation was correct.
If a grid layout is placed inside a flexbox, the layout becomes
unpredictable.
```rust
impl Render for HelloWorld {
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
div()
.flex()
.size(px(500.0))
.bg(rgb(0x505050))
.text_xl()
.text_color(rgb(0xffffff))
.child(
div()
.size_full()
.gap_1()
.grid()
.grid_cols(2)
.border_1()
.border_color(gpui::red())
.children((0..10).map(|ix| {
div()
.w_full()
.border_1()
.border_color(gpui::green())
.child(ix.to_string())
})),
)
}
}
```
| Before | After |
| - | - |
| <img width="612" height="644" alt="After1"
src="https://github.com/user-attachments/assets/64eaf949-0f38-4f0b-aae7-6637f8f40038"
/> | <img width="612" height="644" alt="Before1"
src="https://github.com/user-attachments/assets/561a508d-29ea-4fd2-bd1e-909ad14b9ee3"
/> |
I also placed the grid layout example inside a flexbox too.
| Before | After |
| - | - |
| <img width="612" height="644" alt="After"
src="https://github.com/user-attachments/assets/fa6f4a2d-21d8-413e-8b66-7bd073e05f87"
/> | <img width="612" height="644" alt="Before"
src="https://github.com/user-attachments/assets/9e0783d1-18e9-470d-b913-0dbe4ba88835"
/> |
I tested the changes from the previous PR, and it seems that setting the
table's parent to `v_flex` is sufficient to achieve a non-full table
width without modifying the grid layout. This was already done in the
previous PR.
I reverted the grid changes, the blue border represents the table width.
cc @RemcoSmitsDev
<img width="1107" height="1000" alt="table"
src="https://github.com/user-attachments/assets/4b7ba2a2-a66a-444d-ad42-d80bc9057cce"
/>
So, I believe we should revert to this implementation to align with
tailwindcss behavior and avoid potential future problems, especially
since the cause of this issue is difficult to pinpoint.
Release Notes:
- N/A
Release Notes:
- Added support for Grok 4.1 Fast (reasoning and non-reasoning) models
in the xAI provider, with 2M token context windows and full vision
capabilities.
- Extended 2M token context to existing Grok 4 Fast variants (from 128K)
for consistency with xAI updates.
- Enabled image/vision support for all Grok 4 family models.
Doc:
https://docs.x.ai/docs/models/grok-4-1-fast-reasoninghttps://docs.x.ai/docs/models/grok-4-1-fast-non-reasoning
**Problem addressed:**
Cannot distinguish an identical path on multiple remote hosts in the
"Recent Projects" picker.
**Related work:**
- Issue #40358 (already closed) identified the issue in the "Expected
Behavior" section for both WSL and SSH remotes.
- PR #40375 implemented WSL distro labels.
**Screenshots:**
Before:
<img width="485" height="98" alt="screenshot-sample-project-before"
src="https://github.com/user-attachments/assets/182d907a-6f11-44aa-8ca5-8114f5551c93"
/>
After:
<img width="481" height="94" alt="screenshot-sample-project-after"
src="https://github.com/user-attachments/assets/5f87ff12-6577-404e-9319-717f84b7d2e7"
/>
**Implementation notes:**
RemoteConnectionOptions::display_name() will be subject to
exhaustiveness checking on RemoteConnectionOption variants.
Keeps the same UI approach as the WSL distro variants.
Release Notes:
- Improved Recent Projects picker: now displays SSH hostname with
remotes.
When installing local "dev" extensions that provide tree-sitter
grammars, compiling the parser can be quite intensive[^anecdote]. This
PR changes the logic to only compile the parser if the WASM object
doesn't exist or the source files are newer than the object (just like
`make(1)` would do).
[^anecdote]: The tree-sitter parser for LLVM IR takes >10 minutes to
compile and uses 20 GB of memory on my laptop.
Release Notes:
- N/A
---------
Co-authored-by: Finn Evers <finn.evers@outlook.de>
This mostly affects Channel Notes, but due to a change in
https://github.com/zed-industries/zed/pull/43921 we were
short-circuiting before opening links.
I moved the workspace checks back to right before we need them so that
we still follow the same control flow as usual for these editors.
Closes#44207
Release Notes:
- N/A
Closes#26949
## Summary
1. Split editor references to avoid borrow conflicts in event handlers
2. Check
[has_mouse_context_menu()](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html)
state directly in tooltip conditional instead of caching stale value
3. Restructured context menu deployment to ensure proper sequencing:
hide popover → build menu → deploy menu → notify for re-render
**Screen recording**
https://github.com/user-attachments/assets/8a00f882-1c54-47b0-9211-4f28f8deb867
Release Notes:
- Fixed an issue where the context menu in the Git Blame view would be
frequently overlapped by the commit information tooltip.
---------
Co-authored-by: Finn Evers <finn.evers@outlook.de>
This ensures that the casing of this entry aligns with other entries in
the app popover Menus.
Release Notes:
- N/A
---------
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
This PR removes the default, error, warning, and success color variants
from the `SwitchColor` enum. In the most YAGNI spirit, I think we'll
probably never want to use these colors for the switch, so there's no
reason to support them. And if we ever want to do it, we can re-add
them.
I also took the opportunity to change the default color to be "accent",
which is _already_ what we use for all instances of this component, so
there's no need to have to define it every time. This effectively makes
the enum support only "accent" and "custom", which I think is okay for
now if we ever need an escape hatch before committing to supporting new
values.
Release Notes:
- N/A
This PR partially implements a knowledge distillation data pipeline.
`zeta distill` gets a dataset of chronologically ordered commits and
generates synthetic predictions with a teacher model (one-shot Claude
Sonnet).
`zeta distill --batches cache.db` will enable Message Batches API. Under
the first run, this command will collect all LLM requests and upload a
batch of them to Anthropic. On subsequent runs, it will check the batch
status. If ready, it will download the result and put them into the
local cache.
Release Notes:
- N/A
---------
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
Co-authored-by: Ben Kunkle <ben@zed.dev>
This pull request enhances syntax highlighting for JavaScript,
TypeScript, TSX, and JSDoc by adding more precise rules for parameters,
types, and punctuation.
- Added queries for highlighting parameters (`@variable.parameter`)
- Expanded highlighting for type identifiers, type aliases, interfaces,
classes
- Extended/implemented types to improve distinction between different
type constructs (`@type`, `@type.class`)
- Added highlighting for punctuation in type parameters, unions,
intersections, annotations, index signatures, optional fields, and
predicates (`@punctuation.special`, `@punctuation.bracket`)
- Added highlighting for identifiers in JSDoc comments
(`@variable.jsdoc`)
Release Notes:
- Refined syntax highlighting in JavaScript and TypeScript for better
visual distinction of
types, parameters, and JSDoc elements
## Summary
Follow-up to #40716. This applies the same `reset_exception_ports()` fix
to `set_pre_exec_to_start_new_session()`, which is used by shell
environment capture, terminal spawning, and DAP transport.
### Root Cause
After more debugging, I finally figured out what was causing the issue
on my machine. Here's what was happening:
1. Zed spawns a login shell (zsh) to capture environment variables
2. A pipe is created: reader in Zed, writer mapped to fd 0 in zsh
3. zsh sources `.zshrc` → loads oh-my-zsh → runs poetry plugin
4. Poetry plugin runs `poetry completions zsh &|` in background
5. Poetry inherits fd 0 (the pipe's write end) from zsh
6. zsh finishes `zed --printenv` and exits
7. Poetry still holds fd 0 open
8. Zed's `reader.read_to_end()` blocks waiting for all writers to close
9. Poetry hangs (likely due to inherited crash handler exception ports
interfering with its normal operation)
10. Pipe stays open → Zed stuck → no more processes spawn (including
LSPs)
I confirmed this by killing the hanging `poetry` process, which
immediately unblocked Zed and allowed LSPs to start. However, this
workaround was needed every time I started Zed.
While poetry was the culprit in my case, this can affect any shell
configuration that spawns background processes during initialization
(oh-my-zsh plugins, direnv, asdf, nvm, etc.).
Fixes#36754
## Test plan
- [x] Build with `ZED_GENERATE_MINIDUMPS=true` to force crash handler
initialization
- [x] Verify crash handler logs appear ("spawning crash handler
process", "crash handler registered")
- [x] Confirm LSPs start correctly with shell plugins that spawn
background processes
Release Notes:
- Fixed an issue on macOS where LSPs could fail to start when shell
plugins spawn background processes during environment capture.
This bug was caused by using two separate keys for writing/reading from
the KVP database. The bug didn't show up in my debug build because there
was an old entry of a valid key.
I added an integration test for this feature to prevent future
regressions as well.
Release Notes:
- debugger: Fix a bug where the stack frame filter state wouldn't
persist between sessions
This PR fixes that the `Current State` option inside the history
dropdown does not updating the UI. This was because we didn't send the
`SessionEvent::HistoricSnapshotSelected` event in the reset case. This
was just a mistake.
**After**
https://github.com/user-attachments/assets/6df5f990-fd66-4c6b-9633-f85b422fb95a
cc @Anthony-Eid
Release Notes:
- N/A
This allows users to select any snapshot in the debugger history feature
and go back to the active session snapshot.
We also change variable names to use hsitoric snapshot instead of
history and move the snapshot icon to the back of the debugger top
control strip.
https://github.com/user-attachments/assets/805de8d0-30c1-4719-8af7-2d47e1df1da4
Release Notes:
- N/A
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
This PR adds the basic logic for a feature that allows you to visit any
stopped information back in time. We will follow up with PRs to improve
this and actually add UI for it so the UX is better.
https://github.com/user-attachments/assets/42d8a5b3-8ab8-471a-bdd0-f579662eadd6
Edit Anthony:
We feature flagged this so external users won't be able to access this
until the feature is polished
Release Notes:
- N/A
---------
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Even if `workspace_diagnostics_refresh_tasks` is empty, registrations
which didn't advertise support for workspace diagnostics may still
exist.
Release Notes:
- N/A
Closes https://github.com/zed-industries/zed/issues/43292
We were seeing clicks on the "View Panel" and "Dismiss" buttons
sometimes not being triggered. I believe this was happening because the
overall parent also had an on_click, which due to this being a popup
window, was causing conflicts with the buttons' on click handlers. This
should hopefully fix that issue.
Release Notes:
- agent: Fixed an issue where clicking on the agent notification buttons
would sometimes not trigger their actions.
It's just distracting having excerpts for all the successfully merged
hunks.
Release Notes:
- git: The project diff now focuses on merge conflicts for files that
have them.
Make gpui's `rems()`, `phi()`, `auto()` length related helpers into
const functions.
I can't see why these functions aren't already const except that it
must've been overlooked when they were written?
In my project I had need for rems() to be const, and I thought I'd do
phi() and auto() whilst I was in the neighbourhood
Release Notes:
- N/A
We were just deleting them before
Co-Authored-By: Matthew Chisolm <mchisolm0@gmail.com>
Closes #ISSUE
Release Notes:
- Fixed restoring window location for single-file worktrees
Co-authored-by: Matthew Chisolm <mchisolm0@gmail.com>
Instead of allocating a one-element vec on the heap, we can just use an
array here (since `Editor::edit` accepts anything that implements
`IntoIterator`).
I haven't checked if there are more instances that can be simplified,
just accidentally stumbled upon this when working on something else in
the markdown preview crate.
Release Notes:
- N/A
Follow-up of https://github.com/zed-industries/zed/pull/43854
Closes https://github.com/zed-industries/zed/issues/40970
Seems that json language server does not distinguish between JSONC and
JSON files in runtime, but there is a static schema, which accepts globs
in its `fileMatch` fields.
Use all glob overrides and file suffixes for JSONC inside those match
fields, and provide a grammar for such matches, which accepts trailing
commas.
Release Notes:
- Improved JSONC trailing comma handling
Follow up to https://github.com/zed-industries/zed/pull/42819 and
https://github.com/zed-industries/zed/pull/44206.
- Make this picker feel more consistent with other similar pickers
(namely, the project picker)
- Move actions to the footer and toggle them conditionally
- Only show the "Create" and "Create New From: {default}" when we're
selecting the "Create" list item _or_ when that item is the only
visible. This means I'm changing here the state transition to only
change to `NewBranch/NewRemote` if we only have those items available.
- Reuse more UI code and use components when available (e.g.,
`ListHeader`)
- Remove secondary actions from the list item
Next step (in another PR), will be refine the same picker in the
smaller, panel version.
https://github.com/user-attachments/assets/fe72ac06-c1df-4829-a8a4-df8a9222672f
Release Notes:
- N/A
There's still a weird problem happening where the labels (and the label
on the tab, too, for what is worth) flicker as the file history view
gets smaller. I suspect that problem is related to something
else—potentially the truncation algorithm or focus management—so I'm not
solving it here.
<img width="500" height="1948" alt="Screenshot 2025-12-05 at 11 24@2x"
src="https://github.com/user-attachments/assets/25715725-e2cb-475a-bdab-f506bb75475f"
/>
Release Notes:
- N/A
Tracing code is not included in normal release builds
Documents how to use them in our performance docs
Only the maps and cursors are instrumented atm
# Compile times:
current main: fresh release build (cargo clean then build --release)
377.34 secs
current main: fresh debug build (cargo clean then build )
89.31 secs
tracing tracy: fresh release build (cargo clean then build --release)
374.84 secs
tracing tracy: fresh debug build (cargo clean then build )
88.95 secs
tracing tracy: fresh release build with timings (cargo clean then build
--release --features tracing)
375.77 secs
tracing tracy: fresh debug build with timings (cargo clean then build
--features tracing)
90.03 secs
Release Notes:
- N/A
---------
Co-authored-by: localcc <work@localcc.cc>
Addresses a regression introduced by
https://github.com/zed-industries/zed/pull/44021 that caused @mentions
and slash commands to stop working if you set
`show_completions_on_input: false` in your settings.
In this case, we should always show these menus, otherwise the features
won't work at all.
Release Notes:
- N/A
- Replace `gpui::styled::Styled.font_family()` calls with
`gpui::styled::Styled.font()` when laying out inline diagnostics and
inline blame, to ensure that the font's features are also used, and
not just the font feature.
- Update both `editor::hover_popover::hover_markdown_style` and
`editor::hover_popover::diagnostics_markdown_style` to ensure that
both the UI and Buffer font features are used in both markdown and
diagnostics popover.
Closes#44209
Release Notes:
- Fixed font feature application for inline git blame, inline
diagnostics, markdown popovers and diagnostics popovers
Sometimes machines are configured to drop outbound packets (rather than
reject connections). In these cases, curl/wget just hang causing our
download step to never complete. This PR adds a timeout of 10s for the
connection (not the whole download), so that in situations like this we
can fallback to our client-side download eventually.
Related to but doesn't fully fix:
https://github.com/zed-industries/zed/issues/43694 and
https://github.com/zed-industries/zed/issues/43718
Release Notes:
- remote: Add 10s connect timeout for server download
We have seen cases (see
https://github.com/zed-industries/zed/issues/43694) where the user's
shell initialization script includes text that ends up in the output of
the commands we use to detect the platform and shell of the remote. This
solution isn't perfect, but it should address the issue in most
situations since both commands should only output one line.
Release Notes:
- remote: Improve resiliency when initialization scripts output text
The bug was introduced in this recent PR:
https://github.com/zed-industries/zed/pull/42819. Since it's still in
nightly, there is no need for release notes.
I also polished the feature a bit by:
- Ensuring branch names are always a single line so the branch picker's
uniform list uses the correct element height.
- Adding tooltip text for the filter remotes button.
- Fixing the create branch from default icon showing up for non-new
branch entries.
Release Notes:
- N/A
Evaluate selection now acts as if the text was typed verbatim into the
console.
Closes ##33526
Release Notes:
- debugger: Fixed "evaluate selection" not behaving as if the
highlighted text was not typed verbatim into the console.
To do
* [x] Default to no context retrieval. Allow opting in to LSP-based
retrieval via a setting (for users in `zeta2` feature flag)
* [x] Feed this context to models when enabled
* [x] Make the zeta2 context view work well with LSP retrieval
* [x] Add a UI for the setting (for feature-flagged users)
* [x] Ensure Zeta CLI `context` command is usable
---
* [ ] Filter out LSP definitions that are too large / entire files (e.g.
modules)
* [ ] Introduce timeouts
* [ ] Test with other LSPs
* [ ] Figure out hangs
Release Notes:
- N/A
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
Co-authored-by: Agus Zubiaga <agus@zed.dev>
The JSON language server looks for a top-level `allowTrailingCommas`
flag to decide whether it should warn for trailing commas. Since the
JSONC parser for these builtin files can handles trailing commas, adding
this flag to the schema also prevents a warning for those commas.
I don't think there's an issue that is only for this specific issue, but
it relates to *many* existing / older issues:
- #18509
- #17487
- #40970
- #18509
- #21303
Release Notes:
- Suppress warning for trailing commas in builtin JSON files
(`settings.json`, `keymap.json`, etc.)
Just recently realized we don't need this custom component for it given
we now have `Tooltip::element`. UI result is exactly the same; nothing
changes.
Release Notes:
- N/A
Follow up to https://github.com/zed-industries/zed/pull/44162 where my
strategy for not displaying the indent guides only in the commit message
was wrong given I ended up... disabling indent guides for all the
buffers. This PR adds a new method to the editor where we can disable it
for a specific buffer ID following the pattern of
`disable_header_for_buffer`.
Release Notes:
- N/A
Closes#40757
## Summary
This PR addresses an issue where Zed incorrectly adjusts the indentation
of Markdown lists when inserting text using multiple cursors. Currently:
- Editing individual lines with a single cursor behaves correctly (no
unwanted indentation changes).
- Using multiple cursors, Zed automatically adjusts the indentation,
unlike VS Code, which preserves the existing formatting.
## Tasks
- [x] Implement a new test to verify correct Markdown indentation
behavior with multiple cursors.
- [x] Apply the fix to prevent Zed from adjusting indentation when
inserting text on multiple cursors.
------------------------
Release Notes:
- Fixed an issue where inserting text with multiple cursors inside a
nested Markdown list would cause it to lose its indentation.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
We already store the remote URLs for `origin` and `upstream` in the
`RepositorySnapshot`, so just use that data. Follow-up to #44092.
Release Notes:
- N/A
Reformat document structure like other language docs, improve
information flow, add missing requirements, and fix typos.
Release Notes:
- N/A
---------
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
One half of https://github.com/zed-industries/zed/issues/42861
This basically reduces the main thread work for large enough json (and
other) files from multiple milliseconds (15ms was observed in that test
case) down to microseconds (100ms here).
Release Notes:
- Improved cursor movement performance when edit predictions are enabled
Closes#41521
Release Notes:
- Fixed codex web login not working on wsl remotes if no browser is
installed
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
Fixes a deadlock in the background scanner that occurs on single-core
Linux devices. This happens because the background scanner would `block`
on a background thread waiting for a future, but on single-core Linux
devices there would be no other thread to pick it up. This mostly
affects SSH remoting use cases where it's common for servers to have 1
vCPU.
Closes#43884Closes#43809
Release Notes:
- Fix SSH remoting hang when connecting to 1 vCPU servers
Closes#44148
the existing rate == 0 check inside the timer callback already handles
disabling repeat - it just drops the timer immediately. So the fix
prevents the crash while preserving correct behavior.
Release Notes:
- Linux (Wayland): Fixed a crash that could occur when
`characters_per_second` was zero
Closes#44090
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Release Notes:
- python: Improved sorting order of toolchains in monorepos with
multiple local virtual environments.
- python: Fixed toolchain selector not having an active toolchain
selected on open.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Co-authored-by: Smit <smit@zed.dev>
Set `prettier_parser` explicitly if the file extension for the buffer
does not match a known one for the current language
Release Notes:
- N/A
---------
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
In project search UI code we were seeing an issue where "Go to next
match" would act up and behave weirdly. It would not wrap at times.
Stuff would be weird, yo. It turned out that match ranges reported by
core project search were sometimes out of sync with the state of the
multi-buffer. As in, the sort order of
`search::ProjectSearch::match_ranges` would not match up with
multi-buffer's sort order. This is ~because multi-buffers maintain their
own sort order.
What happened within project search is that we were skipping straight
from stage 1 (filtering paths) to stage 3 via an internal channel and in
the process we've dropped the channel used to maintain result sorting.
This made is so that, given 2 files to scan:
- project/file1.rs <- not open, has to go through stage2 (FS scan)
- project/file2.rs <- open, goes straight from stage1 (path filtering)
to stage3 (finding all matches) We would report matches for
project/file2.rs first, because we would notice that there's an
existing language::Buffer for it. However, we should wait for
project/file1.rs status to be reported first before we kick off
project/file2.rs
The fix is to use the sorting channel instead of an internal one, as
that keeps the sorting worker "in the loop" about the state of the
world.
Closes#43672
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Release Notes:
- Fixed "Select next match" in project search results misbehaving when
some of the buffers within the search results were open before search
was ran.
- Fixed project search results being scrolled to the last file active
prior to running the search.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Co-authored-by: Smit <smit@zed.dev>
Closes#43598
Release Notes:
- bedrock: Added opt-in `allow_global` which enables global endpoints
- bedrock: Updated cross-region-inference endpoint and model list
- bedrock: Fixed Opus 4.5 access on Bedrock, now only accessible through the `allow_global` setting
Related to https://github.com/zed-industries/zed/pull/44109,
https://github.com/zed-industries/zed/issues/43884,
https://github.com/zed-industries/zed/issues/43809.
In the Linux dispatcher, we create one background thread per CPU, but
when a single core is available, having a single background thread
significantly hinders the perceived performance of Zed. This is
particularly helpful when SSH remoting to low-resource servers.
We may want to bump this to more than two threads actually, but I wanted
to be conservative, and this seems to make a big difference already.
Release Notes:
- N/A
Adds `com.apple.security.files.user-selected.read-write` and
`com.apple.security.files.downloads.read-write` to zed.entitlements.
This resolves an issue where the integrated terminal could not access
external drives or user-selected files on macOS, even when "Full Disk
Access" was granted. These entitlements are required for the application
to properly inherit file access permissions.
Release Notes:
- Resolves an issue where the integrated terminal could not access
external drives or user-selected files on macOS.
`WorkItemPriority::High` will enqueue the work items to threads with
higher-than-normal priority. If the work items are very intensive, this
can cause the system to become unresponsive. It's not clear what this
gets us, so let's avoid the responsiveness issue by deleting this.
Release Notes:
- N/A
Fancy regex has a max backtracking limit which defaults to 1,000,000
backtracks. This avoids spinning the CPU forever in the case that a
match is taking a long time (though does mean that some matches may be
missed).
Unfortunately the verison we depended on causes an infinite loop when
the backtracking limit is hit
(https://github.com/fancy-regex/fancy-regex/issues/137), so we got the
worse of both worlds: matches were missed *and* we spun the CPU forever.
Updating fixes this.
Excitingly regex may gain support for lookarounds
(https://github.com/rust-lang/regex/pull/1315), which will make
fancy-regex much less load bearing.
Closes#43821
Release Notes:
- Fix a bug where search regexes with look-around or backreferences
could hang
the CPU. They will now abort after a certain number of match attempts.
When adding the File History option here, I used the pattern to hide the
option, since that's what another option was already doing here, but I
see other menus in the git panel (`...`) that use disabling over hiding,
which is what I think is a nicer experience (allows you to learn of
actions, the full range of actions is always visible, don't have to
worry about how multiple hidden items might interact in various
configurations, etc).
<img width="336" height="241" alt="SCR-20251203-pnpy"
src="https://github.com/user-attachments/assets/0da90b9a-c230-4ce3-87b9-553ffb83604f"
/>
<img width="332" height="265" alt="SCR-20251203-pobg"
src="https://github.com/user-attachments/assets/5da95c7d-faa9-4f0f-a069-f1d099f952b9"
/>
In general, I think it would be good to move to being more consistent
with disabling over hiding - there are other places in the app that are
hiding - some might be valid, but others might just choices made on a
whim.
Release Notes:
- N/A
Closes#43171
Previously the tab switcher only subscribed to events from a single pane
so closing tabs in other panes wouldn't cause the tab switcher to
update. This PR changes that so the tab switcher subscribes to the whole
workspace and thus updates when tabs in other panes are closed.
It also modifies the work in #44006 to sync selected index across the
whole workspace instead of just the original pane in the case of the
all-panes tab switcher.
Release Notes:
- Fixed all-panes tab switcher not updating in response to changes in
other panes
Closes https://github.com/zed-industries/zed/issues/41935
The registration ID responsible for generating each diagnostic is now
tracked. This allows us to replace only the diagnostics from the same
registration ID when a pull diagnostics report is applied.
Additionally, various deficiencies in our support for pull diagnostics
have been fixed:
- Document pulls are issued for all open buffers, not just the edited
one. A shorter debounce is used for the edited buffer. Workspace
diagnostics are also now ignored for open buffers.
- Tracking of `lastResultId` is improved.
- Stored pull diagnostics are discarded when the corresponding buffer is
closed.
Release Notes:
- Improved compatibility with language servers that use the "pull
diagnostics" feature of Language Server Protocol.
---------
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
This reverts commit 05764e8af7.
Internally we've seen a much higher incidence of macOS code-signing
failing on
the download rust analyzer than we did before this change.
It's unclear why this would be a problem, but we want to try reverting
to see if that fixes it.
Release Notes:
- Reverted a change that seemed to cause problems with code-signing on
rust-analyzer
Whenever an item is removed using the Tab Switcher, the list of matches
is automatically updated, which can lead to the order of the elements
being updated and changing in comparison to what the user was previously
seeing. Unfortunately this can lead to a situation where the selected
index, since it wasn't being updated, would end up in a different item
than the one that was actually active in the pane.
This Pull Request updates the handling of the `PaneEvent::RemovedItem`
event so that the `TabSwitcherDelegate.selected_index` field is
automatically updated to match the pane's new active item.
Seeing as this is being updated, the
`test_close_preserves_selected_position` test is also removed, as it no
longer makes sense with the current implementation. I believe a better
user experience would be to actually not update the order of the
matches, simply removing the ones that no longer exist, and keep the
selected index position, but will tackle that in a different Pull
Request.
Closes#44005
Release Notes:
- Fixed a bug with the tab switcher where, after closing a tab, the
selected entry would not match the pane's active item
Use `MotionKind::LineWise` in both
`vim::normal::change::Vim.change_object` and
`vim::normal::yank::Vim.yank_object` when dealing with objects that
target `Mode::VisualLine`, for example, paragraphs. This fixes an issue
where yanking and changing paragraphs would not include the trailing
newline character.
Closes#28804
Release Notes:
- Fixed linewise text object operations (`yap`, `cap`, etc.) omitting
trailing blank line in vim mode
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
Closes#40851
Release Notes:
- Fixed: Commit diff multibuffers now open real project files whenever
possible, restoring navigation and annotations inside those excerpts.
---------
Co-authored-by: Anthony Eid <anthony@zed.dev>
Closes#39152
This PR fixes an issue where we would render Markdown tables full width
based on their container size. We now render tables based on their
content min size, meaning you are still allowed to make the table render
as it was before by making the columns `w_full`.
I had to change the `div()` to `v_flex().items_start()` because this
introduced a weird displaying behavior of the outside table border,
because the grid container was not shrinking due to It was always taking
up the full width of their container.
**Before**
<img width="1273" height="800" alt="Screenshot 2025-11-26 at 14 37 19"
src="https://github.com/user-attachments/assets/2e152021-8679-48c2-b7bd-1c02768c0253"
/>
**After**
<img width="1273" height="797" alt="Screenshot 2025-11-26 at 14 56 12"
src="https://github.com/user-attachments/assets/4459d20e-8c3b-487b-a215-c95ee5c1fc8e"
/>
**Code example**
```markdown
| Name | Age | Occupation |
|:--------:|:-------:|:--------------:|
| Alice | 28 | Engineer |
| Bob | 34 | Designer |
| Carol | 25 | Developer |
| Syntax | Description |
| ----------- | ----------- |
| Header | Title |
| Paragraph | Text |
| City | Population (approx.) | Known For |
|----------------|----------------------|------------------------------------|
| New York | 8,500,000 | Statue of Liberty, Wall Street |
| Los Angeles | 4,000,000 | Hollywood, film industry |
| Chicago | 2,700,000 | Architecture, deep-dish pizza |
| Houston | 2,300,000 | NASA, energy industry |
| Miami | 470,000 | Beaches, Latin culture |
| San Francisco | 800,000 | Golden Gate Bridge, Silicon Valley |
| Las Vegas | 650,000 | Casinos, nightlife |
<table>
<caption>Table Caption</caption>
<thead>
<tr>
<th>ID asjkfjaslkf jalksjflksajflka jlksdla k</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Chris</td>
</tr>
<tr>
<td>2</td>
<td>Dennis</td>
</tr>
<tr>
<td>3</td>
<td>Sarah</td>
</tr>
<tr>
<td>4</td>
<td>Karen</td>
</tr>
</tbody>
</table>
```
cc @bennetbo
Release Notes:
- Markdown Preview: Markdown tables scale now based on their content
size
This seems sensible to do - it already was the case prior but
indirectly, lets rather be explicit about this.
Release Notes:
- N/A
Co-authored-by: Agus Zubiaga <agus@zed.dev>
Uses the latest version of the SDK + schema crate. A bit painful because
we needed to move to `#[non_exhaustive]` on all of these structs/enums,
but will be much easier going forward.
Also, since we depend on unstable features, I am pinning the version so
we don't accidentally introduce compilation errors from other update
cycles.
Release Notes:
- N/A
Add informational banners for extensions that have been integrated into
Zed core:
- Basedpyright (Python language server)
- Ruff (Python linter)
- Ty (Python language server)
These banners appear when users search for these extensions, informing
them that the functionality is now built-in and linking to relevant
documentation.
The banners trigger when:
- Users search by extension ID (e.g., 'id:ruff')
- Users search using relevant keywords (e.g., 'basedpyright', 'pyright',
'ruff', 'ty')
Supersedes #43844Closes#43837
Release Notes:
- Added banners to the extensions page when searching for Basedpyright,
Ruff, or Ty, indicating that these features are now built-in.
---------
Co-authored-by: Marshall Bowers <git@maxdeviant.com>
#42441 moved the commit message out of the multi-buffer editor into its
own header element which looks nicer, but unfortunately can make the
view become unusable when the commit message is too long since it
doesn't scroll with the diff.
This PR maintains the metadata in its own element, but moves the commit
message back to the editor so the user can scroll past it. This does
mean that we lose markdown rendering for now, but we think this is a
good solution for the moment.
https://github.com/user-attachments/assets/d67cf22e-1a79-451a-932a-cdc8a65e43de
Release Notes:
- N/A
---------
Co-authored-by: cameron <cameron.studdstreet@gmail.com>
With the merging and publishing of
https://github.com/tree-sitter/tree-sitter-bash/pull/311 , we can now go
ahead and update the version of `tree-sitter-bash` that Zed relies on to
the latest version.
Closes#42091
Release Notes:
- Improved grammar for "Shell Script"
This PR forks a new version of the `zed_extension_api` in preparation
for new changes.
We're jumping from v0.6.0 to v0.8.0 for the WIT because we released
v0.7.0 of the `zed_extension_api` without any WIT changes (it probably
should have been v0.6.1, instead).
Release Notes:
- N/A
Closes#43408
Previously, we checked the setting inside `is_completion_trigger()`,
which only affects LSP completions. This was ok because user-defined
snippets were tacked onto LSP completions. Then #42122 and #42398 made
snippet completions their own thing, similar to word completions,
surfacing #43408. This PR moves the settings check into
`open_or_update_completions_menu()` so it applies to all completions.
Release Notes:
- Fixed setting `show_completions_on_input: false` so that it affects
word and user-defined snippet completions as well as LSP completions
Closes#41582
Release Notes:
- Improves the '%' vim motion for html by moving the cursor to the
opening tag when its positioned on the `/` ( slash ) of the closing tag
Hello, this is my first time contributing here! The issue creation
button noted that "feature request"-esque items should go to
discussions, so with this PR, I'm closing that discussion and not an
issue. I hope that's ok :)
---
Closes https://github.com/zed-industries/zed/discussions/43769
Preview:
<img width="500" alt="image"
src="https://github.com/user-attachments/assets/00b8d475-d452-42e9-934b-ee5dbe48586e"
/><p/>
Release Notes:
- Added JavaScript highlighting via YAML `injections.scm` for script
blocks of `actions/github-script`
We currently attempt to flush all rejected predictions at once even if
we have accumulated more than
`MAX_EDIT_PREDICTION_REJECTIONS_PER_REQUEST`. Instead, we will now flush
as many as possible, and then keep the rest for the next batch.
Release Notes:
- N/A
Windows applications tend to be fairly re-entrant which does not work
well with our current top-level `RefCell` approach. We have worked
around a bunch of panics in the past due to this, but ultimately this
will re-occur (and still does according to sentry) in the future. So
this PR moves all interior mutability down to the fields.
Fixes ZED-1HM
Fixes ZED-3SH
Fixes ZED-1YV
Fixes ZED-29S
Fixes ZED-29X
Fixes ZED-369
Fixes ZED-20W
Release Notes:
- Fixed panics on windows caused by unexpected re-entrancy for interior
mutability
Closes https://github.com/zed-industries/zed/issues/43328
Instead of trying to guess whether we can `--exec`, this now
restructures things to only attempt to use that flag where its
necessary. We only need to `--exec` when we are interested in the shell
output after all.
Release Notes:
- Fixed wsl remoting not working with some nixOS setups
Currently, Zed does not provide suggestions and validations for Gleam,
as it is only available for languages specified in `tailwind.rs`. This
pull-request adds Gleam to that list of languages.
After this, if Tailwind is configured to work with Gleam, suggestions
and validation appear correctly.
Even after this change, Tailwind will not be able to detect and give
suggestions in Gleam directly. Below is the config required for Tailwind
classes to be detected in all Gleam strings.
<details><summary>Zed Config for Tailwind detection in Gleam</summary>
<p>
```
{
"languages": {
"Gleam": {
"language_servers": [
"gleam",
"tailwindcss-language-server"
]
}
},
"lsp": {
"tailwindcss-language-server": {
"settings": {
"experimental": {
"classRegex": [
"\"([^\"]*)\""
]
}
}
}
}
}
```
The `classRegex` will match all Gleam strings, making it work seamlessly
with Lustre templates and plain string literals.
</p>
</details>
Release Notes:
- Added support for Tailwind suggestions and validations for the [Gleam
programming language](https://gleam.run/).
Release Notes:
- pane::ActivatePreviousItem and pane::ActivateNextItem now toggle the
most recent pane when called from a dock panel
a couple months ago i posted a work around that used `SendKeystrokes` to
cycle through pane items when focused on a dock.
#35253
this pr would add this functionality to the these actions by default.
i implemented this by adding an action listener to the workspace level.
------
if the current context is a dock that does not hold a pane
it retrieves the most recent pane from `activation_history` and
activates the next item on that pane instead.
- `"Pane > Editor"`
cycles through the current pane like normal
- `"Dock > Pane > Terminal"`
also cycles through the pane items like normal
- `"Dock > (Any Child that is not a child of Pane)"`
cycles through the items of the most recent pane.
this is the standard behavior in VS Code i believe.
in the video below you can see the actions cycling through the editor
like normal when focus is on the editor.
then you can see the editor continue to cycle when the focus is on the
project panel.
and that the focus stays on the project panel.
and you can see the action cycle the terminal items when the focus is
moved to the terminal
https://github.com/user-attachments/assets/999ab740-d2fa-4d00-9e53-f7605217e6ac
the only thing i noticed is that for this to work the keybindings must
be set above `Pane`
so they have to be set globally or on workspace. otherwise they do not
match in the context
Tracking Issue (does not close):
https://github.com/zed-industries/zed/issues/35552
This is somewhat of a blocker for
https://github.com/zed-industries/zed/pull/40035 (but also the current
behavior doesn't really make sense).
The current behavior of `ThemeSelectorDelegate::set_theme` (the theme
selector menu) is to simply set the in-memory settings to `Static`,
regardless of if it is currently `Dynamic`. The reason this doesn't
matter now is that the `theme::set_theme` function that updates the
user's settings file _will_ make this check, so dynamic settings stay
dynamic in `settings.json`, but not in memory.
But this is also sort of strange, because `theme::set_theme` will set
the setting of whatever the old appearance was to the new theme name. In
other words, if I am currently on a light mode theme and I change my
theme to a dark mode theme using the theme selector, the `light` field
of `theme` in `settings.json` is set to a dark mode theme!
_I think this is because displaying the new theme in the theme selector
does not update the global context, so
`ThemeSettings::get_global(cx).theme.name(appearance).0` returns the
original theme appearance, not the new one._
---
This PR makes `ThemeSelectorDelegate::set_theme` keep the current
`ThemeSelection`, as well as changes the behavior of the
`theme::set_theme` call to always choose the correct setting to update.
One edge case that might be slightly strange now is that if the user has
specified the mode as `System`, this will now override that with the
appearance of the new theme. I think this is fine, as otherwise a user
might set a dark theme and nothing will change because the
`ThemeAppearanceMode` is set to `light` or `system` (where `system` is
also light).
I also have an `unreachable!` in there that I'm pretty sure is true but
I don't really know how to formally prove that...
Release Notes:
- N/A *or* Added/Fixed/Improved ...
---------
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
This PR adds word/character diff for expanded diff hunks that have both
a deleted and added section, as well as a setting `word_diff_enabled` to
enable/disable word diffs per language.
- `word_diff_enabled`: Defaults to true. Whether or not expanded diff
hunks will show word diff highlights when they're able to.
### Preview
<img width="1502" height="430" alt="image"
src="https://github.com/user-attachments/assets/1a8d5b71-449e-44cd-bc87-d6b65bfca545"
/>
### Architecture
I had three architecture goals I wanted to have when adding word diff
support:
- Caching: We should only calculate word diffs once and save the result.
This is because calculating word diffs can be expensive, and Zed should
always be responsive.
- Don't block the main thread: Word diffs should be computed in the
background to prevent hanging Zed.
- Lazy calculation: We should calculate word diffs for buffers that are
not visible to a user.
To accomplish the three goals, word diffs are computed as a part of
`BufferDiff` diff hunk processing because it happens on a background
thread, is cached until the file is edited, and is only refreshed for
open buffers.
My original implementation calculated word diffs every frame in the
Editor element. This had the benefit of lazy evaluation because it only
calculated visible frames, but it didn't have caching for the
calculations, and the code wasn't organized. Because the hunk
calculations would happen in two separate places instead of just
`BufferDiff`. Finally, it always happened on the main thread because it
was during the `EditorElement` layout phase.
I used Zed's
[`diff_internal`](02b2aa6c50/crates/language/src/text_diff.rs (L230-L267))
as a starting place for word diff calculations because it uses
`Imara_diff` behind the scenes and already has language-specific
support.
#### Future Improvements
In the future, we could add `AST` based word diff highlights, e.g.
https://github.com/zed-industries/zed/pull/43691.
Release Notes:
- git: Show word diff highlight in expanded diff hunks with less than 5
lines.
- git: Add `word_diff_enabled` as a language setting that defaults to
true.
---------
Co-authored-by: David Kleingeld <davidsk@zed.dev>
Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: cameron <cameron.studdstreet@gmail.com>
Co-authored-by: Lukas Wirth <lukas@zed.dev>
Follow-up to #43586--when the diff is not split, just render the primary
editor. Otherwise the child `Pane` intercepts `CloseActiveItem`. (This
is still a bug for the actual split diff, but just fixing the
user-visible regression for now.)
Release Notes:
- N/A
Related: #42574
If an integration test is annotated with the ignore attribute, allow the
"debug: Test" option of the debug scenario or Code Action to run with
the "--include-ignored" and "--exact" arguments. Inclusion of "--exact"
covers the case where more that one test shares a base name. For
example, consider two tests named "test_no_ace_in_middle_of_straight"
and "test_no_ace_in_middle_of_straight_flush." Without the "--exact"
argument both tests would run if a user attempts to debug
"test_no_ace_in_middle_of_straight".
Release Notes:
- Improved "debug test" experience in Rust with ignored tests.
This makes rolling this out across extensions a far bit easier and also
safer, because we don't have to manually set `run_tests` for every
extension (and never have to consider this when updating these).
Release Notes:
- N/A
We were allowing the client to build up to
`MAX_EDIT_PREDICTION_REJECTIONS_PER_REQUEST`. We'll now attempt to flush
the rejections when we reach half max.
Release Notes:
- N/A
Mostly cleaning up the UI code. The UI looks fairly the same just a bit
more polished, with proper colors and spacing. Also added a scrollbar in
there. Next step would be to make it keyboard navigable.
<img width="500" height="1948" alt="Screenshot 2025-12-01 at 5 38@2x"
src="https://github.com/user-attachments/assets/c266b97c-4a79-4a0e-8e78-2f1ed1ba495f"
/>
Release Notes:
- N/A
While this does work for PRs and such, it does not work with main...
Hence, moving the token a few chars to the right to fix this issue.
Release Notes:
- N/A
- Updates tone to match bug template
- Removes the "current vs expected" behavior section
- It doesn't feel very useful. Users expect Zed to not crash, regardless
of what they are doing.
Release Notes:
- N/A
This PR adds workflows to be used for CD in extension reposiories in the
`zed-extensions` organization and updates some of the existing ones with
minor improvemts.
Release Notes:
- N/A
For now, just using Sonnet 4.5 and Opus 4.5 - I'll make a separate PR
for non-Anthropic models, in case they introduce new failures.
Release Notes:
- N/A
Release Notes:
- Fixed the behavior of the attach to process feature for the Golang
debugger.
**Step to reprorduce:**
1. Build and run golang binary
2. In Zed open debugger
3. Go to Attach tab
4. Select the binary you just built from the list
**Actual result:**
```
Tried to launch debugger with: {
"request": "attach",
"mode": "debug",
"processId": 74702,
"stopOnEntry": false,
"cwd": "/path/to/the/current/working/directory"
}
error: Failed to attach: invalid debug configuration - unsupported 'mode' attribute "debug"
```
**Expected result:** The debugger can attach to the process.
According to the [Delve
documentation](https://github.com/go-delve/delve/tree/master/Documentation/api/dap#launch-and-attach-configurations)
`attach` request supports `local` and `remote` values only
At some point, rust-analyzer started including the snippet expression
for some completions in the description field, but that can look like a
bug:
<img width="1570" height="578" alt="CleanShot 2025-11-27 at 20 39 49@2x"
src="https://github.com/user-attachments/assets/5a87c9fe-c0a8-472f-8d83-3bc9e9e00bbc"></img>
In these cases, we will now inline the tab stops as an ellipsis
character:
<img width="1544" height="428" alt="CleanShot 2025-12-01 at 10 01 18@2x"
src="https://github.com/user-attachments/assets/4c550891-4545-47cd-a295-a5eb07e78e92"></img>
You may also notice that we now syntax highlight the pattern closer to
what it looks like after accepted.
Alternatively, when the tab stop isn't just one position, it gets
highlighted as a selection since that's what it would do when accepted:
<img width="1558" height="314" alt="CleanShot 2025-12-01 at 10 04 37@2x"
src="https://github.com/user-attachments/assets/ce630ab2-da22-4072-a996-7b71ba21637d"
/>
Release Notes:
- rust: Display completion tab stops inline rather than as a raw LSP
snippet expression
Gist is we only need to block the foreground thread for reparsing if
immediate language changes are useful to the user. That is usually only
the case when they edit the buffer
Release Notes:
- Improved performance of large project searches and project diffs
Co-authored by: David Kleingeld <david@zed.dev>
Generalizes the digest verification logic from `rust-analyzer` and
`clangd` into a reusable helper function in
`http_client::github_download`.
This removes ~100 lines of duplicated code across the two language
adapters and makes it easier for other language servers to adopt digest
verification in the future.
Closes#35201
Release Notes:
- N/A
Relates to #35759, but maybe doesn't entirely fix it? I think it will
improve the situation, at least.
Also provides a workaround for the issue described in
https://github.com/zed-industries/zed/issues/40094#issuecomment-3559808526
for users of WSL + `nix-direnv`.
Rationale: there are cases where automatic direnv integration is not
always desirable, but Zed currently has no way of opting out of this
integration besides `direnv revoke` (which is often not desirable).
This PR provides such an opt-out for users who run into problems with
the existing direnv integration methods. Some reasons why disabling
might be useful:
- Security concerns about auto-loading `.envrc` (arguably, `direnv
revoke` should cover this most of the time)
- As in #35759, for users who use different shells/envs for
interactive/non-interactive cases and want to manually control the
environment Zed uses
- As in #40094, to workaround OS limits on environment variable /
command-line parameter size
Release Notes:
- Added the ability to disable direnv integration entirely
After #39928, if a font's weight changes between text runs without other
decoration changing, the earlier weight continues to be used for the
subsequent run(s).
PR #40840 fixes this in shape_text, but similar code exists also in
layout_text. The latter is used for text in the editor view itself, so
the issue continues to appear when using a highlighting theme with
varied font weights.
Fix the issue by applying the same fix in layout_text.
Closes#42297
Release Notes:
- Fixed incorrect font weights in editor view when using a highlighting
theme with varying font weights
We were previously always highlighting the last header in the table of
contents as active even if you were at the top of the page. This is now
fixed, where upon loading the page, no header is highlighted, and as you
scroll, we highlight the top-most heading one by one.
Release Notes:
- N/A
Summary
Fixed the thread deletion issue by:
1. Click handler conflict between the trash icon and the main ListItem
2. Added `cx.stop_propagation()` to prevent the click event from
bubbling up to the parent ListItem's click handler
3. Followed the established `cx.stop_propagation()` pattern used
throughout the codebase
Now when you click the trash icon to delete a thread:
- ✅ The thread deletion happens immediately on the first click
- ✅ No race condition between deletion and activation
- ✅ No double-clicking required
The fix is minimal, follows established patterns, and addresses the
exact root cause of the issue.
- Stop event propagation in thread removal handler
Release Notes:
- agent: Improved delete thread action in the history view by preventing
it from also triggering the thread activation.
Closes https://github.com/zed-industries/zed/issues/43721
This PR makes the loading state clearer by disabling the message editor
while the agent is loading as well as pulsating the icon.
Release Notes:
- agent: Made the thread loading state clearer in the agent panel.
Follow up to https://github.com/zed-industries/zed/pull/43758.
This PR uses view transition animations to reduce the page flickering
when navigating between one and the other. Pretty cool CSS-only
solution.
Release Notes:
- N/A
Closes https://github.com/zed-industries/zed/issues/43726
Note that the truncation strategy on the file path is not yet perfect.
I'm just applying the regular method from the label component, but we
should wrap path text from the start rather than from the end. Some time
in the future!
<img width="500" height="712" alt="Screenshot 2025-11-28 at 7 17@2x"
src="https://github.com/user-attachments/assets/6ebc618a-4b4a-42fd-b5b7-39fec3ae5335"
/>
Release Notes:
- Fixed a bug where the "Open File" button would overflow in the
multibuffer header if the file path was too long.
Closes https://github.com/zed-industries/zed/issues/43728
Release Notes:
- agent: Fixed a bug where the plan and edit files list would consume
the whole space of the thread if they were too long. They're now capped
by a max-height and scrollable.
This is still not perfect, but it reduces the shift that happens when
navigating between pages that have and don't have the table of contents.
It also tries to reduce the theme flicker that happens by moving its
loading to an earlier moment.
Release Notes:
- N/A
Adds clarifying examples and information about the `include_pattern`
parameter for the grep tool, analogous to the `path` parameter of the
read and list tools and others.
The lack of clarity led to unexpected agent behavior described in
#41189. This change is confirmed to improve the precision of Claude
Sonnet 4.5 when searching for code in an empty conversation (without it,
it leaves out the root directory in the query).
Closes#41189.
```
Release Notes:
- Clarify grep tool description to improve agent precision when using it with the `include_pattern` parameter
```
Closes#43040
Release Notes:
- Remove the end-of-support Gemini 1.5 model from the options.
- Remove the older Gemini 2.0 model from the options.
- Please let me know if you think it's better to keep it, as it is still
a usable model.
- Update the incorrect amounts for some input/output tokens.
- Update the default model to Gemini 2.5 Flash-Lite.
- Rename variant `Gemini3ProPreview` to `Gemini3Pro`
When this PR is merged, users will be able to select the following
Gemini models.
- 2.5 Flash
- 2.5 Flash-Lite
- 2.5 Pro
- 3 Pro
This PR adds the ability to collapse section in the docs sidebar (which
are persistent until you close the tab), and some design facelift to the
docs, which makes its design close to the site as well as polishing up
many elements and interactions (like moving the search to a modal and
making the table of content visible in smaller breakpoints).
<img width="600" height="2270" alt="Screenshot 2025-11-28 at 5 26@2x"
src="https://github.com/user-attachments/assets/3a8606c6-f74f-4bd2-84c8-d7a67ff97564"
/>
Release Notes:
- N/A
Release Notes:
- Added a keybinding to open the `settings.json` file when the Settings
UI is in focus: `cmd-,` (macOS) / `ctrl-,` (Windows / Linux).
- A tooltip was added to the `Edit in settings.json` button to show this
keybinding.
- shorten some phrases to (hopefully) retain attention better
- move the required field up to not bore people with scrolling
- call it a bug and not an issue to further emphasize we want feature
requests in Discussions where the product managers are
- remove the default from the WSL question since not everyone does
WSL or even Windows
Release Notes:
- N/A
---------
Co-authored-by: Miguel Raz Guzmán Macedo <miguel@zed.dev>
Co-authored-by: Kunall Banerjee <hey@kimchiii.space>
Closes#9648#9755
Release Notes:
- Added way to configure ESLint's working directories in settings. For
example:
`{"lsp":{"eslint":{"settings":{"workingDirectories":["./client","./server"]}}}}`
---------
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
Closes#26649
Release Notes:
- Improved git support for remotes handling. Git will now check pushRemote and pushDefault configurations before
falling back to branch remote.
---------
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
There is still room for improvement here as `anchor(s)_in_excerpt` is
generally a bad API here due to it reseeking the entire excerpt tree
from the start on every call which we don't really need. But this at
least cuts the seeks down by a factor of 4 for now.
Release Notes:
- Improved performance of bracket colorization in large multibuffers
Introduces new "mapping point cursors" for the different display map
layers allowing one to map multiple points in increasing order more
efficiently than using the one shot operations.
This is used in the `BlockMap::sync` for `header_and_footer_blocks`
which spends a significant time in sumtree traversal due to repeatedly
transforming points between the different layers. This effectively turns
the complexity of those operations from quadratic in the number of
excerpts to linear, as we only go through the respective sumtrees once
instead of restarting from the start over and over again.
Release Notes:
- Improved performance for editors of large multibuffers with many
different files
These are long running foreground tasks that tend to not have pending
await points, meaning once we start executing them they will never
reschedule themselves, starving the foreground thread.
Release Notes:
- Improved git project diff responsiveness
Replace single quotes with double quotes when referencing the askpass
script name in the helper command. The Windows command processor
(cmd.exe) requires double quotes for proper string handling, as single
quotes are treated as literal characters.
Error I get when trying to open remote project:
<img width="396" height="390" alt="image"
src="https://github.com/user-attachments/assets/1538ee10-8efc-4f80-a867-b367908091b6"
/>
```
Zed Nightly 0.216.0
c2281779af
0.216.0+nightly.1965.c2281779af56bd52c829ccd31aae4eb82b682ebc
```
Release Notes:
- N/A
Without this new flag, the Sweep API will actually produce a combination
of UTF-16 and char indices, leading to incorrect edit positions.
Release Notes:
- N/A
We restructured `struct Repository` a bit so that it now stores a shared
task of `enum RepositoryState`. This way, we can now re-use it outside
of the git job queue when spawning a git job a standalone bg task. An
example here would be `git-blame` that does not require any file locks
and is not susceptible to git job ordering.
As a result of this change, loading (and modifying) a file that contains
a huge git history will no longer block other git operations on the repo
such as staging/unstaging/committing.
Release Notes:
- Improved overall git experience when loading buffers with massive git
history where they would block other git jobs from running (such as
staging/unstaging/commiting). Now, git-blame will run separately from
the git job queue on the side and the buffer with blame hints when
finished thus unblocking other git operations.
Co-authored-by: Cole Miller <cole@zed.dev>
This reduces hangs on windows when we have many tasks queued up on the
main thread that yield a lot.
Release Notes:
- Reduced hangs on windows in some situations
Introducing this little popover here that's aimed at better
communicating what Zed's built-in edit prediction feature is and how
much people can get of it for free by purely just signing in.
<img width="600" height="1914" alt="Screenshot 2025-11-27 at 9 50@2x"
src="https://github.com/user-attachments/assets/a7013292-f662-4cae-9a6f-0e69a4a4fa1d"
/>
Release Notes:
- N/A
- **release_channel: Do not use prerelease channel for build id**
Prerelease channel specifiers always compare as less than to
non-prerelease, which led to 2 auto-update bugs fixed in
https://github.com/zed-industries/zed/pull/43595 and
https://github.com/zed-industries/zed/pull/43611.
We'll use a dot-delimited build specifiers in form:
release-channel.build_number.sha1 instead
- **auto_update: Do not display full build metadata in update
notification**
Release Notes:
- N/A
Sometimes we are unable to receive messages at all from an agent. This
puts on upper bound on the `initialize` call so we can at least give a
message to the user that something is wrong here.
30s might feel like too long, but I wanted to avoid some false positives
in case there was something an agent needed to do at startup. This will
still communicate to the user at some point that something is wrong,
rather than leave them waiting forever with no signal that something is
going wrong.
Release Notes:
- agent: Show an error message to the user if we are unable to
initialize an ACP agent in a reasonable amount of time.
Update the way that both
`search::buffer_search::BufferSearchBar.replace_next` and
`search::buffer_search::BufferSearchBar.replace_all` are registered as
listeners, so that we don't require the replacement editor to be focused
in order for these listeners to be active, only requiring the
replacement mode to be active in the buffer search bar.
This means that, even if the user is focused on the buffer editor, if
the "Replace Next Match" or "Replace All Matches" buttons are clicked,
the replacement will be performed.
Closes#42471
Release Notes:
- Fixed issue with buffer search bar where the replacement buttons
("Replace Next Match" & "Replace All Matches") wouldn't work if search
bar was not focused
Fixes ZED-3P9
We only clamped the end which for a completely wrong input could cause
us to construct a reversed range which will end up underflowing later
on.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Zeta evals now include a character n-gram metric adapted for multi-edit diffs (“delta chrF”). It works as follows:
1. Reconstruct the original, golden (expected), and actual texts from unified diffs.
- "original": the text before any edits
- "golden": the text after applying the expected edits
- "actual": the text after applying the actual edits
2. Compute n-gram count deltas between original→golden and original→actual.
- n-grams are computed as in chrF (max n=6, whitespace ignored).
3. Compare these deltas to assess how well the actual edits match the expected edits.
- As in standard chrF, classify n-grams as true positives, false positives, and false negatives, and report the F-beta score with beta=2.
Release Notes:
- N/A
Current approach is to colorize brackets based on their depth, which was
broken for markdown:
<img width="388" height="50" alt="image"
src="https://github.com/user-attachments/assets/bd8b6c2f-5a26-4d6b-a301-88675bf05920"
/>
Markdown grammar, for bracket queries
00e93bfa11/crates/languages/src/markdown/brackets.scm (L1-L8)
and markdown document `[LLM-powered features](./ai/overview.md), [bring
and configure your own API
keys](./ai/llm-providers.md#use-your-own-keys)`, matches first bracket
(offset 0) with two different ones:
* `[LLM-powered features]`
* `[LLM-powered features](./ai/overview.md), [bring and configure your
own API keys]`
which mix and add different color markers.
Now, in case multiple pairs exist for the same first bracket, Zed will
only colorize the shortest one:
<img width="373" height="33" alt="image"
src="https://github.com/user-attachments/assets/04b3f7af-8927-4a8b-8f52-de8b5bb063ac"
/>
Release Notes:
- Fixed bracket colorization mixing colors in markdown files
There are 3 factors:
1. The Preview channel endpoint does not propagate versions with build
identifier (which we oh-so-conveniently store in pre-release field of
semver).
2. Preview build, once fetched, sees it's version *with* build
identifier (as that's baked into the binary).
3. Auto update logic treats versions with pre-release version as less
than versions without pre-release version.
This in turn makes any Preview client see itself as versioned like
0.214.4-123-asdf1234455311, whereas the latest version on the endpoint
is 0.214.4. Thus, the endpoint version is always more recent than the
client version, causing an update loop.
The fix is to ignore build identifier when comparing versions of
non-nightly channels. This should still let us introduce changes to
auto-update behavior in minor releases in the future.
Closes#43584
Release Notes:
- (Preview only): Fixed an update loop with latest Preview update.
CLOSES #39042
This is a reopening of #34985+.
_Original descrioption_:
In Wayland, the client implement key repeat themself. In Zed this is
ultimately handled by the gpui crate by inserting a timer source into
the event loop which repeat itself if the key is still held down [1].
But it seems the processing of the repeated key event happen
synchronously inside the timer source handler, meaning the effective
rate become slightly lower (since the repeated timer is scheduled using
the 1/rate as delay).
I measured the event processing time on my laptop and it's typically
around 3ms, but sometimes spiking at 10ms. At low key repeat rates this
is probably not _very_ noticeable. I see the default in Zed is set to a
(measly) 16/s, but I assume most systems will use something closer to
25, which is a 40ms delay. So ~3ms is around 7.5% of the delay. At
higher rate the discrepancy become worse of course.
I can visible notice the spikes, and doing some crude stopwatch
measurements using gedit as a reference I can reproduce around 5-10%
slower rates in Zed.
IMO this is significant enough to warrant improving, especially since
some people can get quite used the repeat rate and might feel something
being "off" in Zed.
~~The suggested fix simply subtract the processing time from the next
delay timer.~~
[1] 32df726f3b/crates/gpui/src/platform/linux/wayland/client.rs (L1355)
Release Notes:
- Improved Wayland (Linux) key repeat rate precision
Adds a `trigger` field to the zeta1/zeta2 prediction requests so that we
can distinguish between editor, diagnostic, and zeta-cli requests.
Release Notes:
- N/A
Many prediction requests end up being rejected early without ever being
set as the current prediction. Before this change, those cases weren’t
reported as rejections because the `request_prediction_with_*` functions
simply returned `Ok(None)`.
With this update, whenever we get a successful response from the
provider, we will return at least the `id`, allowing it to be properly
reported. The request now also includes a “reject reason,” since the
different variants carry distinct implications for prediction quality.
All of these scenarios are now covered by tests. While adding them, I
also found and fixed a bug where some cancelled predictions were
incorrectly being set as the current one.
Release Notes:
- N/A
---------
Co-authored-by: MrSubidubi <dev@bahn.sh>
Update the `fs::RenameOptions` used by
`project::lsp_store::LocalLspStore.deserialize_workspace_edit` in order
to always set `create_parents` to `true`. Doing this ensures that we'll
always create the folders for the new file path provided by the language
server instead of failing to handle the request in case the parent
- Introduce `create_parents` field to `fs::RenameOptions`
- Update `fs::RealFs.rename` to ensure that the `create_parents` option
is respected
Closes#41820
Release Notes:
- Fixed a bug where using language server's file renaming actions could
fail if the parent directory of the new file did not exist
We were using `std::path::Path::strip_prefix` to determine which
repository an absolute path belongs to, which doesn't work when the
paths are Windows-style but the code is running on unix. Replace it with
a platform-agnostic implementation of `strip_prefix`.
Release Notes:
- Fixed git features not working when a Windows host collaborates with a
unix guest
This adds an intial workflow file that can be pulled in to create a bump
commit for an extension version in an extension repository.
Release Notes:
- N/A
Follow-up to https://github.com/zed-industries/zed/pull/39367
Release Notes:
- Fixed a small issue where a scrollbar would sometimes show in the
editor although the content fix exactly on screen.
While logically not really correct, its better than tearing down the
application until we figure out the root cause here
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Closes#28667
Release Notes:
- Fixed git not preserving file mode when committing. Now if an input file is executable it will be preserved when committed with Zed.
---------
Signed-off-by: 11happy <soni5happy@gmail.com>
Signed-off-by: 11happy <bhuminjaysoni@gmail.com>
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
I have git installed via [scoop](https://scoop.sh). The current
implementation finds `git.exe` in scoop's shims folder and then tries to
find `bash.exe` relative to it.
For example, `git.exe` (shim) is located at:
```
C:\Users\<username>\scoop\shims\git.exe
```
And the code tries to find `bash.exe` at:
```
C:\Users\<username>\scoop\shims\..\bin\bash.exe
```
which doesn't exist.
This PR changes the logic to first check if `bash.exe` is available in
PATH (using `which::which`), and only falls back to the git-relative
path if that fails.
The fix for this is emitting a wake-up event to tell the terminal to
recalculate its search highlights on resize.
Release Notes:
- terminal: Fix bug where search match highlights wouldn't update their
position when resizing the terminal.
Clang-Format uses uses a YAML config file format.
Use YAML language by default for `.clang-format` and `_clang-format`
filenames.
([source](https://clang.llvm.org/docs/ClangFormatStyleOptions.html))
Add `#yaml-language-server: $schema` to `.clang-format` example in C
language docs.
Release Notes:
- Added support for identifying. `.clang-format` files as YAML by
default
Most of the features for collab were previously listed in the section
that was written for private calls. Most of this PR is moving that
content over to the channel documentation and adapting it slightly.
Private calls have similar collaboration, so we can just point back to
the channels doc in that section and keep it pretty thin / DRY.
Release Notes:
- N/A
Fixes an issue where the terminal cursor wouldn't always be displayed in
the default `blink: "terminal_controlled"` mode unless the terminal
requested cursor blinking.
Release Notes:
- N/A
Closes#41723
This PR fixes an issue with accepting partial semver completions by
including `.` in the completion query. This makes the editor treat the
entire version string as the query, instead of breaking segment at last
`.` .
This PR also adds a test for sorting semver completions. The actual
sorting fix is handled in the `package-version-server` by having it
provide `sort_text`. More:
https://github.com/zed-industries/package-version-server/pull/10
<img width="600" alt="image"
src="https://github.com/user-attachments/assets/7657912f-c6da-4e05-956b-1c044918304f"
/>
Release Notes:
- Fixed an issue where accepting a completion for a semver version in
package.json would append the suggestion to the existing text instead of
replacing it.
- Improved the sorting of semver completions in package.json so the
latest versions appear at the top.
It is easy for us to get the two fields out of sync causing weird
problems, there is no reason to have both here so.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Co-authored by: Antonio Scandurra <antonio@zed.dev>
Follow up to #39021.
<img width="576" height="141" alt="image"
src="https://github.com/user-attachments/assets/c89885a4-e664-4614-9bb0-86442dff34ee"
/>
- Add migration to remove `source` tag because `ContextServerSettings`
is now untagged
- Fix typos in context server modal
- PR seems to have removed the `test_action_namespaces` test, which I
brought back in this PR
Release Notes:
- Fixed an issue where the `source` property of MCP settings would show
up as unrecognised
Overview
- Channels
- Private calls
---
Up next would be to
- [ ] Update any zed.dev links to point to items in this structure
- [ ] Update content in these docs (would prefer to do that in a
separate PR from this one)
Release Notes:
- N/A
This reverts #39643, effectively
For the record, @SomeoneToIgnore found it quite cumbersome to scroll
through logs just to see which tests have failed. I kinda see the
argument. At the same time, I wish nextest could do both: it could
aggregate logs of failed tests and then print out the summary.
Release Notes:
- N/A
Closes#43209Closes#38121
Starting on the first character.
Running `v e` before changes:
<img width="410" height="162" alt="image"
src="https://github.com/user-attachments/assets/ee13fa29-826c-45c0-9ea0-a598cc8e781a"
/>
Running `v e` after changes:
<img width="483" height="166" alt="image"
src="https://github.com/user-attachments/assets/24791a07-97df-47cd-9ef2-171522adb796"
/>
Change Notes:
- Added helix selection sanitation code that directly mirrors the code
in the Vim
[`visual_motion`](b6728c080c/crates/vim/src/visual.rs (L237))
method. I kept the comments from the Vim section that explains its
purpose.
- The above change converted the problem from fixing `v e` to fixing `v
w`. Since `w` is treated differently in Helix than in Vim (i.e. `w` in
Vim goes to the first character of a word and `w` in Helix goes to the
character before a word. Commented
[here](b6728c080c/crates/vim/src/helix.rs (L132))),
the code treats `w` in `HelixSelect` as a motion that differs from the
Vim motion in the same way that the function
[`helix_move_cursor`](b6728c080c/crates/vim/src/helix.rs (L353))
separates these behaviors.
- Added a regression test
Release Notes:
- Fixes bug where `Vim::NextWordEnd` in `HelixSelect` would not select
whole word.
The bug is easily verified by:
1. open any multi-buffer
2. place the cursor at the beginning of an excerpt
3. run the editor::ExpandExcerpts / editor: expand excerpts action
4. The excerpt is not expanded
Since the `buffer_ids_for_range` function basically did the same and had
even been changed the same way earlier I DRYed these functions as well.
Note: I'm a rust novice, so keep an extra eye on rust technicalities
when reviewing :)
---
Release Notes:
- Fix editor: expand excerpts failing when cursor is at excerpt start
---------
Co-authored-by: Lukas Wirth <me@lukaswirth.dev>
We've realized that a lot of the logic within an
`EditPredictionProvider` is not specific to a particular edit prediction
model / service. Rather, it is just the generic state management
required to perform edit predictions at all in Zed. We want to move to a
setup where there's one "built-in" edit prediction provider in Zed,
which can be pointed at different edit prediction models. The only logic
that is different for different models is how we construct the prompt,
send the request, and parse the output.
This PR also changes the behavior of the staff-only `zeta2` feature flag
so that in only gates your *ability* to use Zeta2, but you can still use
your local settings file to choose between different edit prediction
models/services: zeta1, zeta2, and sweep.
This PR also makes zeta1's outcome reporting and prediction-rating
features work with all prediction models, not just zeta1.
To do:
* [x] remove duplicated logic around sending cloud requests between
zeta1 and zeta2
* [x] port the outcome reporting logic from zeta to zeta2.
* [x] get the "rate completions" modal working with all EP models
* [x] display edit prediction diff
* [x] show edit history events
* [x] remove the original `zeta` crate.
Release Notes:
- N/A
---------
Co-authored-by: Agus Zubiaga <agus@zed.dev>
Co-authored-by: Ben Kunkle <ben@zed.dev>
9a119b18ee/extension.toml
provides 3 language servers for `php`, so `...` will always include all
3 if those are not excluded or included explicitly.
Change the configs and docs so, that only one php language server is
used.
Release Notes:
- N/A
This fixes running `zed <path>` inside nixos wsl instances. We're
copying the approach used elsewhere which is to try using `--exec`
first, and if that fails use an actual shell which should cover the
nixos case because it only puts binaries on your PATH inside the
`/etc/profile` script which is sourced on shell startup.
Release Notes:
- N/A
---------
Co-authored-by: John Tur <john-tur@outlook.com>
Update the `Vim.deactivate` method to ensure that the cursor shape is
reset to the one available in the user's settings, in the `cursor_shape`
setting, instead of simply defaulting to `CursorShape::Bar`.
In order to test this behavior, the `Editor.cursor_shape` method was
also introduced.
Release Notes:
- Fixed the cursor shape reset in vim mode deactivation, ensuring that
the user's `cursor_shape` setting is used
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
Adds support for Opus 4.5
- [x] BYOK
- [x] Amazon Bedrock
Release Notes:
- Added support for Opus 4.5
Co-authored-by: Richard Feldman <oss@rtfeldman.com>
Path canonicalization on windows will now favor keeping the drive letter
intact when canonicalizing paths. This helps some lsps with mapped
network drive compatibility.
Closes#41336
Release Notes:
- N/A
We’re reworking our triage process and in doing so, reworking our issue
templates is worth looking into. We have multiple issue templates, for
arbitrary categories, and not enough enforcement. The plan is to
consolidate the issue templates (maybe all into one) and drop the
others.
Release Notes:
- N/A
Closes#39448Closes#37866
This PR expands the env-clearing fix from #42587 to include the
SystemNodeRuntime, which covers Node.js installations managed by Mise.
When running under the system runtime, npm subcommands were still
launched with a cleared environment, preventing variables such as
MISE_DATA_DIR from reaching the shim or the mise binary itself. As a
result, Mise finds the npm binary in the default MISE_DATA_DIR,
consistent with the behavior described in
https://github.com/zed-industries/zed/issues/39448#issuecomment-3433644569.
This change ensures that environment variables are passed through for
npm subcommands when using the system Node runtime, restoring expected
behavior for Mise-managed Node installations. This also fixes cases
where envs are used by npm itself.
Release Notes:
- Enable environment passthrough for npm subcommands
We'll now add panels to the workspace as soon as they're ready rather
than waiting for all the rest to complete. We should strive to make all
panels fast, but given that their load tasks are fallible and do IO,
this approach seems more resilient.
Additionally, we'll now start loading the agent panel at the same time
as the rest.
Release Notes:
- workspace: Add panels as soon as they are ready
This bug seems to be caused by pushing an operator (i.e. `d`) followed
by a repeat (i.e. `.`) so the recording includes the push operator and
the repeat. When this is repeated (i.e. `.`) it causes an infinite loop.
This change fixes this bug by pushing a ClearOperator action if there is
an ongoing recording when repeat is called.
Release Notes:
- Fixed bug where pressing `d . .` in Vim mode would freeze the editor.
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
Closes#41550
Release Notes:
- Fixed `<g-l>` behavior in helix mode which will now correctly go to the last charactor of the line.
- Fixed not switching to helix normal mode when in default vim context and pressing escape.
---------
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
1. Introduce a common `PromptFormatter` trait
2. Let models define their generation params.
3. Add support for the experimental 1120-seedcoder prompt format
Release Notes:
- N/A
This PR adds a button to close the panel when it is docked to the
bottom. Effectively, the button triggers the same `ToggleBottomDock`
action that clicking on the button that opened the panel triggers, but I
think having it there just makes it extra obvious how to close it, which
is beneficial.
As a bonus, also fixed the panel controls container height when it is
docked to the sides, so it perfectly aligns with the panel tabbar
height.
| Perfectly Aligned Header | Close Button |
|--------|--------|
| <img width="2620" height="2010" alt="Screenshot 2025-11-24 at 12 01
2@2x"
src="https://github.com/user-attachments/assets/08a50858-1b50-4ebd-af7a-c5dae32cf4f6"
/> | <img width="2620" height="2010" alt="Screenshot 2025-11-24 at 12
01@2x"
src="https://github.com/user-attachments/assets/17a6eee0-9934-4949-8741-fffd5b106e95"
/> |
Release Notes:
- N/A
Closes https://github.com/zed-industries/zed/issues/42753
Consider the following flow: you submit prompt A. Prompt A generates
some edits. You don't click on either "reject" or "keep"; they stay in a
pending state. You then submit prompt B, but before the agent outputs
any response, you click to edit prompt B, thus submitting a
regeneration.
Before this PR, the above flow would make the edits originated from
prompt A to be auto-rejected. This feels very incorrect and can surprise
users when they see that the edits that were pending got rejected. It
feels more correct to only auto-reject changes if you're regenerating
the prompt that directly generated those edits in the first place. Then,
it also feels more correct to assume that if there was a follow-up
prompt after some edits were made, those edits were passively
"accepted".
So, this is what this PR is doing. Consider the following flow to get a
picture of the behavior change:
- You submit prompt A.
- Prompt A generates some edits.
- You don't click on either "reject" or "keep"; they're pending.
- You then submit prompt B, but before the agents outputs anything, you
click to edit prompt B, submitting a regeneration.
- Now, edits from prompt A will be auto-kept.
Release Notes:
- agent: Improved the "reject"/"keep" behavior when regenerating older
prompts by auto-keeping pending edits that don't originate from the
prompt to-be-regenerated.
The `SumTree::append` method is slow when appending large trees to small
trees. The reason is this code here:
f57f4cd360/crates/sum_tree/src/sum_tree.rs (L628-L630)
`append` is called recursively until `self` and `other` have the same
height, effectively making this code `O(log^2 n)` in the number of
leaves of `other` tree in the worst case.
There are no algorithmic reasons why appending large trees must be this
much slower.
This PR proves it by providing implementation of `append` that works in
logarithmic time regardless if `self` is smaller or larger than `other`.
The helper method `append_large` has the symmetric logic to
`push_tree_recursive` but moves the (unlikely) case of merging
underflowing node in a separate helper function to reduce stack usage. I
am a bit unsure about some implementation choices made in
`push_tree_recursive` and would like to discuss some of these later, but
at the moment I didn't change anything there and tried to follow the
same logic in `append_large`.
We might also consider adding `push_front`/`prepend` methods to
`SumTree`.
I did not find a good benchmark that covers this case so I added a new
one to rope benchmarks.
<details>
<summary>cargo bench (compared to current main)</summary>
```
Running benches\rope_benchmark.rs (D:\zed\target\release\deps\rope_benchmark-59c669d2895cd2c4.exe)
Gnuplot not found, using plotters backend
push/4096 time: [195.67 µs 195.75 µs 195.86 µs]
thrpt: [19.944 MiB/s 19.955 MiB/s 19.964 MiB/s]
change:
time: [+0.2162% +0.3040% +0.4057%] (p = 0.00 < 0.05)
thrpt: [-0.4040% -0.3030% -0.2157%]
Change within noise threshold.
Found 14 outliers among 100 measurements (14.00%)
2 (2.00%) low mild
6 (6.00%) high mild
6 (6.00%) high severe
Benchmarking push/65536: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 7.8s, enable flat sampling, or reduce sample count to 50.
push/65536 time: [1.4431 ms 1.4485 ms 1.4546 ms]
thrpt: [42.966 MiB/s 43.147 MiB/s 43.310 MiB/s]
change:
time: [-3.2257% -1.2013% +0.6431%] (p = 0.27 > 0.05)
thrpt: [-0.6390% +1.2159% +3.3332%]
No change in performance detected.
Found 11 outliers among 100 measurements (11.00%)
1 (1.00%) low mild
5 (5.00%) high mild
5 (5.00%) high severe
append/4096 time: [15.107 µs 15.128 µs 15.149 µs]
thrpt: [257.86 MiB/s 258.22 MiB/s 258.58 MiB/s]
change:
time: [+0.9650% +1.5256% +1.9057%] (p = 0.00 < 0.05)
thrpt: [-1.8701% -1.5026% -0.9557%]
Change within noise threshold.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) low mild
1 (1.00%) high severe
append/65536 time: [1.2870 µs 1.4496 µs 1.6484 µs]
thrpt: [37.028 GiB/s 42.106 GiB/s 47.425 GiB/s]
change:
time: [-28.699% -16.073% -0.3133%] (p = 0.04 < 0.05)
thrpt: [+0.3142% +19.151% +40.250%]
Change within noise threshold.
Found 17 outliers among 100 measurements (17.00%)
1 (1.00%) high mild
16 (16.00%) high severe
slice/4096 time: [30.580 µs 30.611 µs 30.639 µs]
thrpt: [127.49 MiB/s 127.61 MiB/s 127.74 MiB/s]
change:
time: [-2.2958% -0.9674% -0.1835%] (p = 0.08 > 0.05)
thrpt: [+0.1838% +0.9769% +2.3498%]
No change in performance detected.
slice/65536 time: [614.86 µs 795.04 µs 1.0293 ms]
thrpt: [60.723 MiB/s 78.613 MiB/s 101.65 MiB/s]
change:
time: [-12.714% +7.2092% +30.676%] (p = 0.52 > 0.05)
thrpt: [-23.475% -6.7244% +14.566%]
No change in performance detected.
Found 14 outliers among 100 measurements (14.00%)
14 (14.00%) high severe
bytes_in_range/4096 time: [3.3298 µs 3.3416 µs 3.3563 µs]
thrpt: [1.1366 GiB/s 1.1416 GiB/s 1.1456 GiB/s]
change:
time: [+2.0652% +3.0667% +4.3765%] (p = 0.00 < 0.05)
thrpt: [-4.1930% -2.9754% -2.0234%]
Performance has regressed.
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high severe
bytes_in_range/65536 time: [80.640 µs 80.825 µs 81.024 µs]
thrpt: [771.38 MiB/s 773.28 MiB/s 775.05 MiB/s]
change:
time: [-0.6566% +1.0994% +2.9691%] (p = 0.27 > 0.05)
thrpt: [-2.8835% -1.0875% +0.6609%]
No change in performance detected.
Found 10 outliers among 100 measurements (10.00%)
2 (2.00%) high mild
8 (8.00%) high severe
chars/4096 time: [763.17 ns 763.68 ns 764.36 ns]
thrpt: [4.9907 GiB/s 4.9952 GiB/s 4.9985 GiB/s]
change:
time: [-2.1138% -0.7973% +0.1096%] (p = 0.18 > 0.05)
thrpt: [-0.1095% +0.8037% +2.1595%]
No change in performance detected.
Found 10 outliers among 100 measurements (10.00%)
1 (1.00%) low severe
6 (6.00%) low mild
3 (3.00%) high severe
chars/65536 time: [12.479 µs 12.503 µs 12.529 µs]
thrpt: [4.8714 GiB/s 4.8817 GiB/s 4.8910 GiB/s]
change:
time: [-2.4451% -1.0638% +0.6633%] (p = 0.16 > 0.05)
thrpt: [-0.6589% +1.0753% +2.5063%]
No change in performance detected.
Found 11 outliers among 100 measurements (11.00%)
4 (4.00%) high mild
7 (7.00%) high severe
clip_point/4096 time: [63.148 µs 63.182 µs 63.229 µs]
thrpt: [61.779 MiB/s 61.825 MiB/s 61.859 MiB/s]
change:
time: [+1.0107% +2.1329% +4.2849%] (p = 0.02 < 0.05)
thrpt: [-4.1088% -2.0883% -1.0006%]
Performance has regressed.
Found 5 outliers among 100 measurements (5.00%)
4 (4.00%) high mild
1 (1.00%) high severe
Benchmarking clip_point/65536: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 7.8s, enable flat sampling, or reduce sample count to 50.
clip_point/65536 time: [1.2578 ms 1.2593 ms 1.2608 ms]
thrpt: [49.573 MiB/s 49.631 MiB/s 49.690 MiB/s]
change:
time: [+0.4881% +0.8942% +1.3488%] (p = 0.00 < 0.05)
thrpt: [-1.3308% -0.8863% -0.4857%]
Change within noise threshold.
Found 15 outliers among 100 measurements (15.00%)
1 (1.00%) high mild
14 (14.00%) high severe
point_to_offset/4096 time: [16.211 µs 16.235 µs 16.257 µs]
thrpt: [240.28 MiB/s 240.61 MiB/s 240.97 MiB/s]
change:
time: [-1.4913% +0.1685% +2.2662%] (p = 0.89 > 0.05)
thrpt: [-2.2159% -0.1682% +1.5139%]
No change in performance detected.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severe
point_to_offset/65536 time: [360.06 µs 360.58 µs 361.16 µs]
thrpt: [173.05 MiB/s 173.33 MiB/s 173.58 MiB/s]
change:
time: [+0.0939% +0.8792% +1.8751%] (p = 0.06 > 0.05)
thrpt: [-1.8406% -0.8715% -0.0938%]
No change in performance detected.
Found 10 outliers among 100 measurements (10.00%)
3 (3.00%) high mild
7 (7.00%) high severe
cursor/4096 time: [19.266 µs 19.282 µs 19.302 µs]
thrpt: [202.38 MiB/s 202.58 MiB/s 202.75 MiB/s]
change:
time: [+1.2457% +2.2477% +2.8702%] (p = 0.00 < 0.05)
thrpt: [-2.7901% -2.1983% -1.2304%]
Performance has regressed.
Found 4 outliers among 100 measurements (4.00%)
2 (2.00%) high mild
2 (2.00%) high severe
cursor/65536 time: [467.63 µs 468.36 µs 469.14 µs]
thrpt: [133.22 MiB/s 133.44 MiB/s 133.65 MiB/s]
change:
time: [-0.2019% +1.3419% +2.8915%] (p = 0.10 > 0.05)
thrpt: [-2.8103% -1.3241% +0.2023%]
No change in performance detected.
Found 12 outliers among 100 measurements (12.00%)
3 (3.00%) high mild
9 (9.00%) high severe
append many/small to large
time: [37.419 ms 37.656 ms 37.929 ms]
thrpt: [321.84 MiB/s 324.17 MiB/s 326.22 MiB/s]
change:
time: [+0.8113% +1.7361% +2.6538%] (p = 0.00 < 0.05)
thrpt: [-2.5852% -1.7065% -0.8047%]
Change within noise threshold.
Found 9 outliers among 100 measurements (9.00%)
9 (9.00%) high severe
append many/large to small
time: [51.289 ms 51.437 ms 51.614 ms]
thrpt: [236.50 MiB/s 237.32 MiB/s 238.00 MiB/s]
change:
time: [-87.518% -87.479% -87.438%] (p = 0.00 < 0.05)
thrpt: [+696.08% +698.66% +701.13%]
Performance has improved.
Found 13 outliers among 100 measurements (13.00%)
4 (4.00%) high mild
9 (9.00%) high severe
```
</details>
Release Notes:
- sum_tree: Make SumTree::append run in logarithmic time
Closes#33903
Release Notes:
- Ensured Zed reuses `GITHUB_TOKEN` env variable when querying GitHub
---
Before fixing:
- The `crates-lsp` extension request captured:
```
curl 'https://api.github.com/repos/MathiasPius/crates-lsp/releases' \
-H 'accept: */*' \
-H 'user-agent: Zed/0.212.3 (macos; aarch64)' \
-H 'host: api.github.com' \
```
- `crates-lsp` extension error:
```
Language server crates-lsp:
from extension "Crates LSP" version 0.2.0: status error 403, response: "{\"message\":\"API rate limit exceeded for x.x.x.x. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)\",\"documentation_url\":\"https://docs.github.com/rest/overview/resources-in-the-rest-api#rate-limiting\"}\n"
```
After fixing:
```
export GITHUB_TOKEN=$(gh auth token)
cargo run
```
- The `crates-lsp` extension request captured:
```
curl 'https://api.github.com/repos/MathiasPius/crates-lsp/releases' \
-H 'authorization: Bearer gho_Nt*****************2KXLw2' \
-H 'accept: */*' \
-H 'user-agent: Zed/0.214.0 (macos; aarch64)' \
-H 'host: api.github.com' \
```
The API rate limitation is resolved.
---
This isn't a perfect solution, but it enables users to avoid the noise.
Closes#38433
Document how to register self-hosted GitHub/GitLab/Bitbucket instances
via git_hosting_providers setting so permalinks and issue links resolve.
Release Notes:
- Added documentation on how to register self-hosted
GitHub/GitLab/Bitbucket instances via the `git_hosting_providers`
setting. This ensures permalinks and issue links can be resolved for
these instances.
### Description
The `installing-extensions.md` guide was missing the directory path for
the Windows platform. It currently only lists the paths for macOS and
Linux. This PR adds the correct path for Windows users
(`%LOCALAPPDATA%\zed\extensions`).
Release Notes:
- N/A
---------
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
Changes are made to `parse_path_with_position`:
we try to get the canonical, existing parts of
a path, then append the non-existing parts.
Closes#4441
Release Notes:
- Added the possibility to open a non-existing path using `zed` CLI
```
zed path/to/non/existing/file.txt
```
Co-authored-by: Syed Sadiq Ali <sadiqonemail@gmail.com>
This PR makes the thread markdown editable. This refers to the "open
thread as markdown" feature, where you previously could only read. One
benefit of this move is that it makes a bit more obvious that you can
`cmd-s` to save the markdown, allowing you to store the content of a
given thread. You could already do this before, but due to it being
editable now, you see the tab with a dirty indicator, which communicates
that better.
Release Notes:
- agent: Made the thread markdown editable.
This PR improves the edit prediction page particularly by adding
information about pricing and plans, which wasn't at all mentioned here
before, _and_ by including a section with a keybinding example
demonstrating how to always use just `tab` to always accept edit
predictions.
Release Notes:
- N/A
Fixes a panic that was introduced in #42633. Repro steps:
1. Open the inline assistant and mention a file in the prompt
2. Run the inline assistant
3. Remove the mention and insert a different one
4. 💥
This would happen because the mention set still had a reference to the
old editor, because we create a new one in `PromptEditor::unlink`.
Also removes the unused
`crates/agent_ui/src/context_picker/completion_provider.rs` file, which
was not removed by mistake in the previous PR.
Release Notes:
- N/A
This PR adds back the footer with the "Configure" button in the model
selector but only when the seeing it from the Zed agent (or inline
assistant/text threads). I had removed it a while back because seeing
the "Configure" button, which takes you to the agent panel settings
view, when clicking from an external agent didn't make much sense, given
there's nothing model-wise you can configure from Zed (at least yet) for
an external agent.
This also makes the button in the footer a bit nicer by making it full
screen and displaying a keybinding, so that you can easily do the whole
"trigger model selector → go to settings view" all with the keyboard.
<img width="400" height="870" alt="Screenshot 2025-11-21 at 10 38@2x"
src="https://github.com/user-attachments/assets/c14f2acf-b793-4bc1-ac53-8a8a53b219e6"
/>
Release Notes:
- N/A
- In the launch tab of the new session mode, I've switched it to use the
`InputField` component instead given that had all that we needed
already. Allows for removing a good chunk of editor-related code
- Also in the launch tab, added support for keyboard navigation between
all of the elements there (dropdown, inputs, and switch component)
- Added some simple an empty state treatment for the breakpoint column
when there are none set
https://github.com/user-attachments/assets/a441aa8a-360b-4e38-839f-786315a8a235
Release Notes:
- debugger: Made the input elements within the launch tab in the new
session modal keyboard navigable˙.
This PR finally removes the `CheckboxWithLabel` component, which is not
fully needed given the `Checkbox` can take a `label` method. Then, took
advantage of the opportunity to add more methods with regards to label
customization (position, size, and color) in both the `Checkbox` and
`Switch` components.
Release Notes:
- N/A
We now run git pre-commit hooks before we commit. This ensures we don't
run into timeout issues with askpass delegate and report invalid error
to the user.
Closes#43157
Release Notes:
- Fixed long running pre-commit hooks causing committing from Zed to
fail.
Co-authored-by: Cole Miller <cole@zed.dev>
Previously, this was controllable via the undocumented
ZED_WINDOW_DECORATIONS environment variable (added in #13866). Using an
environment variable for this is inconvenient because it requires users
to set that environment variable somehow before starting Zed, such as in
the .desktop file or persistently in their shell. Controlling this via a
Zed setting is more convenient.
This does not modify the design of the titlebar in any way. It only
moves the existing option from an environment variable to a Zed setting.
Fixes#14165
Client-side decorations (default):
<img width="3840" height="2160" alt="image"
src="https://github.com/user-attachments/assets/525feb92-2f60-47d3-b0ca-47c98770fa8c"
/>
Server-side decorations in KDE Plasma:
<img width="3840" height="2160" alt="image"
src="https://github.com/user-attachments/assets/7379c7c8-e5e3-47ba-a3ea-4191fec9434d"
/>
Release Notes:
- Changed option for Wayland server-side decorations from an environment
variable to settings.json field
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
It is optional for Wayland servers to support server-side decorations.
In particular, GNOME chooses to not implement SSD
(https://gitlab.gnome.org/GNOME/mutter/-/issues/217). So, even if the
application requests SSD, it must draw client-side decorations unless
the application receives a response from the server confirming the
request for SSD.
Before, when the user requested SSD for Zed, but the Wayland server did
not support it, there were no server-side decorations (window titlebar)
drawn, but Zed did not draw the window minimize, maximize, and close
buttons either. This fixes Zed so it always draws the window control
buttons if the Wayland server does not support SSD.
Before on GNOME Wayland with SSD requested:
<img width="3840" height="2160" alt="image"
src="https://github.com/user-attachments/assets/68a6d853-623d-401f-8e7f-21d4dea00543"
/>
After on GNOME Wayland with SSD requested:
<img width="3840" height="2160" alt="image"
src="https://github.com/user-attachments/assets/b258ae8b-fe0e-4ba2-a541-ef6f2c38f788"
/>
Release Notes:
- Fixed window control buttons not showing in GNOME Wayland when SSD
requested
Closes:
- #12338
- #40202
1. Adds two new settings which allow customizing the set of regexes used
to identify path hyperlinks in terminal
1. Fixes path hyperlinks for paths containing unicode emoji and
punctuation, for example, `mojo.🔥`
1. Fixes path hyperlinks for Windows verbatim paths, for example,
`\\?\C:\Over\here.rs`.
1. Improves path hyperlink performance, especially for terminals with a
lot of content
1. Replaces existing custom hard-coded default path hyperlink parsing
logic with a set of customizable default regexes
## New settings
(from default.json)
### terminal.path_hyperlink_regexes
Regexes used to identify paths for hyperlink navigation. Supports
optional named capture
groups `path`, `line`, `column`, and `link`. If none of these are
present, the entire match
is the hyperlink target. If `path` is present, it is the hyperlink
target, along with `line`
and `column` if present. `link` may be used to customize what text in
terminal is part of the
hyperlink. If `link` is not present, the text of the entire match is
used. If `line` and
`column` are not present, the default built-in line and column suffix
processing is used
which parses `line:column` and `(line,column)` variants. The default
value handles Python
diagnostics and common path, line, column syntaxes. This can be extended
or replaced to
handle specific scenarios. For example, to enable support for
hyperlinking paths which
contain spaces in rust output,
```
[
"\\s+(-->|:::|at) (?<link>(?<path>.+?))(:$|$)",
"\\s+(Compiling|Checking|Documenting) [^(]+\\((?<link>(?<path>.+))\\)"
],
```
could be used. Processing stops at the first regex with a match, even if
no link is
produced which is the case when the cursor is not over the hyperlinked
text. For best
performance it is recommended to order regexes from most common to least
common. For
readability and documentation, each regex may be an array of strings
which are collected
into one multi-line regex string for use in terminal path hyperlink
detection.
### terminal.path_hyperlink_timeout_ms
Timeout for hover and Cmd-click path hyperlink discovery in
milliseconds. Specifying a
timeout of `0` will disable path hyperlinking in terminal.
## Performance
This PR fixes terminal to only search the hovered line for hyperlinks
and adds a benchmark. Before this fix, hyperlink detection grows
linearly with terminal content, with this fix it is proportional only to
the hovered line. The gains come from replacing
`visible_regex_match_iter`, which searched all visible lines, with code
that only searches the line hovered on (including if the line is
wrapped).
Local benchmark timings (terminal with 500 lines of content):
||main|this PR|Δ|
|-|-|-:|-|
| cargo_hyperlink_benchmark | 1.4 ms | 13 µs | -99.0% |
| rust_hyperlink_benchmark | 1.2 ms | 11 µs | -99.1% |
| ls_hyperlink_benchmark | 1.3 ms | 7 µs | -99.5% |
Release Notes:
- terminal: New settings to allow customizing the set of regexes used to
identify path hyperlinks in terminal
- terminal: Fixed terminal path hyperlinks for paths containing unicode
punctuation and emoji, e.g. mojo.🔥
- terminal: Fixed path hyperlinks for Windows verbatim paths, for
example, `\\?\C:\Over\here.rs`
- terminal: Improved terminal hyperlink performance, especially for
terminals with a lot of content visible
When no predictions are available for the current buffer, we will now
attempt to predict at the closest diagnostic from the cursor location
that wasn't included in the last prediction request. This enables a
commonly desired kind of far-away jump without requiring explicit model
support.
Release Notes:
- N/A
Reverts zed-industries/zed#36848
Turns out this broke copying a screenshot from apps like CleanShot X and
then pasting it over. We should land this again after taking a look at
those cases. Pasting screenshots from the native macOS screenshot
functionality works though.
cc @seantimm
Release Notes:
- Fixed issue where copying a screenshot from apps like CleanShot X into
Agent Panel didn't work as expected.
Also tidies up error notifications so that in the case of syntax errors
we don't see noise about the migration failing as well.
Release Notes:
- Invalid values in settings files will no longer prevent the rest of
the file from being parsed.
We were just missing adding keybindings for these.
Release Notes:
- onboarding: The onboarding pages can now be zoomed in/out with the
same keybindings you'd use to zoom in/out a regular buffer.
While zed itself is not a heavy user of rayon, wasmtime is, especially
for compilation. This change is similar to the rayon default but we
halve the number of threads still so we don't spawn too many threads
overall.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Closes https://github.com/zed-industries/zed/issues/14639
## Release Notes:
Various improvements to the Jetbrains keymap. Added various missing
keyboard shortcuts that I use on a daily basis in Jetbrains, and changed
a few which were present in the keymap but mapped to the wrong behavior.
### Added:
- Added various missing keybindings for Jetbrains keymap
- `ctrl-n` → `project_symbols::Toggle`
- `ctrl-alt-n` → `file_finder::Toggle` (open project files)
- `ctrl-~` → `git::Branch`
- `ctrl-\` → `assistant::InlineAssist`
- `ctrl-space` → `editor::ShowCompletions`
- `ctrl-q` → `editor::Hover`
- `ctrl-p` → `editor::ShowSignatureHelp`
- `ctrl-f5` → `task::Rerun`
- `shift-f9` → `debugger::Start`
- `shift-f10` → `task::Spawn`
- Added macOS equivalents for all of the above, however I only have a
Linux machine so I have not tested the mac bindings. The binding are
generally the same except `ctrl → cmd` with few exceptions.
- `cmd-j` → `editor::Hover`
### Fixed:
- Several incorrectly mapped keybindings for the Jetbrains keymap
- `ctrl-alt-s` → `editor::OpenSettings` (was `editor::OpenSettingsFile`)
- `ctrl-alt-b` → `editor::GoToImplementation` (was
`editor::GoToDefinitionSplit`)
- `alt-left` → `pane::ActivatePreviousItem`
- `alt-right` → `pane::ActivateNextItem`
- `ctrl-k` now opens the Git panel. I believe this was commented out
because of a bug where focus is not given to the commit message text
box, but imo the current behavior of not doing anything at all feels
more confusing/frustrating to a Jetbrains user (projecting a little
here, happy to revert).
Closes#42727
Unfortunately we can only support IPv4 addresses right now because
`TcpArguments` only supports an IPv4 address. I'm not sure how difficult
it would be to lift this limitation.
Release Notes:
- Fixed `connect.host` setting being ignored by debugpy
Co-authored-by: Cole Miller <cole@zed.dev>
Closes https://github.com/zed-industries/zed/issues/42360
If updating a language server takes longer than 10 seconds, we now fall
back to launching the currently installed version (if exists) and
continue downloading the update in the background.
Release Notes:
- Improved language server updates for slow connection, now Zed launches
existing server if the update is taking too long.
---------
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
Problem: Some macOS environments report no devices via
MTLCopyAllDevices, causing startup failure with “unable to access a
compatible graphics device,” especially on Apple Silicon.
Change: Prefer MTLCreateSystemDefaultDevice
(metal::Device::system_default()) first. If None, enumerate devices and
select a non‑removable, low‑power device by preference.
Why this works: On Apple Silicon the system default is the unified GPU;
on Intel, the fallback keeps a stable policy and avoids accidentally
picking removable/high‑power devices.
Impact: Fixes startup on affected ASi systems; improves selection
consistency on Intel multi‑GPU. Behavior unchanged where
system_default() succeeds.
Risk: Low. Aligns with Apple’s recommended selection path. Still fails
early with a clearer message if no Metal devices exist.
Closes#37689.
Release Notes:
- Fixed: Startup failure on some Apple Silicon machines when Metal
device enumeration returned no devices by falling back to the system
default device.
---------
Co-authored-by: 张小白 <364772080@qq.com>
Co-authored-by: Kate <work@localcc.cc>
Part One for Resolving #10910
### Summary
Typing prefix (partial keybinding) will behave like Vim. No timeout
until you either finish the sequence or hit Escape, while ambiguous
sequences still auto-resolve after 1s.
### Description
This follow-up tweaks the which-key system first part groundwork so our
timeout behavior matches Vim’s expectations. Then we can implement the
UI part in the next step (reference latest comments in
https://github.com/zed-industries/zed/pull/34798)
- `DispatchResult` now reports when the current keystrokes are already a
complete binding in the active context stack (`pending_has_binding`). We
only start the 1s flush timer in that case. Pure prefixes or sequences
that only match in other contexts—stay pending indefinitely, so
leader-style combos like `space f g` no longer evaporate after a second.
- `Window::dispatch_key_event` cancels any prior timer before scheduling
a new one and only spawns the background flush task when
`pending_has_binding` is true. If there’s no matching binding, we keep
the pending keystrokes and rely on an explicit Escape or more typing to
resolve them.
Release Notes:
- Fixed multi-stroke keybindings so only ambiguous prefixes auto-trigger
after 1 s; unmatched prefixes now stay pending until canceled, matching
Vim-style leader behavior.
This PR fixes the casing of the operating system names in the
language-specific sections of `default.json`.
This files serves as documentation for users (since it can be viewed
through `zed: open default settings`), so we should make sure it is
tidy.
Release Notes:
- N/A
This PR simplifies error and event handling by removing the
`Ok(LanguageModelCompletionEvent::Status(CompletionRequestStatus::Failed)))`
state from the stream returned by `LanguageModel::stream_completion()`,
by changing it into an `Err(LanguageModelCompletionError)`. This was
done by collapsing the valid `CompletionRequestStatus` values into
`LanguageModelCompletionEvent`.
Release Notes:
- N/A
---------
Co-authored-by: Michael Benfield <mbenfield@zed.dev>
This mostly affects the collab and outline panels for now. It has always
been a bit weird that the search field was at the bottom of the panel,
even more so because in both cases, you can _arrow down_ to start
navigating the list with your keyboard. So, with the search at the
bottom, you'd arrow down and get to the top of the list, which was very
strange. Now, with it at the top, it not only looks better but it is
also more generally consistent with other surfaces in the app, like
pickers, the settings UI, rules library, etc. Most search fields are
always at the top.
<img width="800" height="1830" alt="image"
src="https://github.com/user-attachments/assets/3e2c3b8f-5907-4d83-8804-b3fc77342103"
/>
Release Notes:
- N/A
The WM_DPICHANGED suggested RECT is calculated for non-maximized
windows. When a maximized window's DPI changes, we now query the
monitor's work area directly to ensure the window correctly fills the
entire screen.
For non-maximized windows, the original behavior using the
system-suggested RECT is preserved.
Release Notes:
- windows: Fixed maximized window size when DPI scale changes
Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
These appear in a lot of stacktraces (especially on windows) despite
them being plain forwarding calls.
Also removes some intermediate calls within gpui that will only turn
into more unnecessary compiler work.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Deals with https://github.com/zed-industries/zed/issues/5259
Highlights brackets with different colors based on their depth.
Uses existing tree-sitter queries from brackets.scm to find brackets,
uses theme's accents to color them.
https://github.com/user-attachments/assets/cc5f3aba-22fa-446d-9af7-ba6e772029da
1. Adds `colorize_brackets` language setting that allows, per language
or globally for all languages, to configure whether Zed should color the
brackets for a particular language.
Disabled for all languages by default.
2. Any given language can opt-out a certain bracket pair by amending the
brackets.scm like `("\"" @open "\"" @close) ` -> `(("\"" @open "\""
@close) (#set! rainbow.exclude))`
3. Brackets are using colors from theme accents, which can be overridden
as
```jsonc
"theme_overrides": {
"One Dark": {
"accents": ["#ff69b4", "#7fff00", "#ff1493", "#00ffff", "#ff8c00", "#9400d3"]
}
},
```
Release Notes:
- Added bracket colorization (rainbow brackets) support. Use
`colorize_brackets` language setting to enable.
---------
Co-authored-by: MrSubidubi <dev@bahn.sh>
Co-authored-by: Lukas Wirth <lukas@zed.dev>
Co-authored-by: MrSubidubi <finn@zed.dev>
Co-authored-by: Lukas Wirth <me@lukaswirth.dev>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Before we were simply not rendering anything which could lead to some
very surprising situations when joining channels ...
Now it will look like so
<img width="147" height="50" alt="image"
src="https://github.com/user-attachments/assets/13069de8-3dc0-45e1-b562-3fe81507dd87"
/>
Release Notes:
- Improved rendering of avatars that failed to load by rendering a
fallback icon
Closes#39088
Release Notes:
- Fixed AI assistant edits being scrambled when file was modified while
it was open
--
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This allows you to specify default_model and default_mode for ACP
extensions, e.g.
```
"auggie": {
"default_model": "gpt-5",
"default_mode": "default",
"type": "extension"
},
```
Release Notes:
- Added support for specifying settings for ACP extensions
(`default_mode`, `default_model`)
While investigating a bug report that, in Helix mode, pressing the
`escape` key would only hide the signature help popup and not the
completions menu, when `auto_signature_help` was enabled, it was noted
that the `editor::Editor.dismiss_menus_and_popups` method was not
dismissing all possible menus and popups and was, instead, stopping as
soon as a single menu or popup was dismissed.
From the name of the method it appears that we actually want to dismiss
all so this commit updates it as such, ensuring that the bug reported is
also fixed.
Closes#42499
Release Notes:
- Fixed issue with popups and menus not being dismissed while using
`auto_signature_help` in Helix Mode
We're not using it anywhere anymore, so I think we can clean it up now.
This was a somewhat specific component we did for the sake of
Onboarding, but it ended up being removed.
Release Notes:
- N/A
Closes#33286
This PR adds support for Zed's `$ZED_PICK_PID` command in debug
configurations, which allows users to select a process to attach to at
debug time. When this variable is present in a debug configuration, Zed
automatically opens a process picker modal.
Follow up for this will be integrating this variable in the task system
instead of just the debug configuration system.
Release Notes:
- Added `$ZED_PICK_PID` variable for debug configurations, allowing
users to select which process to attach the debugger to at runtime
---------
Co-authored-by: Remco Smits <djsmits12@gmail.com>
Something else is broken in Zed (exclude crashing).
type:"Bug"
name:Report a bug
description:Report a problem with Zed.
type:Bug
labels:"state:needs triage"
body:
- type:markdown
attributes:
value:|
Is this bug already reported? Upvote to get it noticed faster. [Here's the search](https://github.com/zed-industries/zed/issues). Upvote means giving it a :+1: reaction.
Feature request? Please open in [discussions](https://github.com/zed-industries/zed/discussions/new/choose) instead.
Just have a question or need support? Welcome to [Discord Support Forums](https://discord.com/invite/zedindustries).
- type:textarea
attributes:
label:Summary
description:Provide a one sentence summary and detailed reproduction steps
value:|
<!-- Begin your issue with a one sentence summary -->
SUMMARY_SENTENCE_HERE
### Description
<!-- Describe with sufficient detail to reproduce from a clean Zed install.
- Any code must be sufficient to reproduce (include context!)
- Include code as text, not just as a screenshot.
- Issues with insufficient detail may be summarily closed.
-->
DESCRIPTION_HERE
Steps to reproduce:
1.
2.
3.
4.
**Expected Behavior**:
**Actual Behavior**:
<!-- Before Submitting, did you:
1. Include settings.json, keymap.json, .editorconfig if relevant?
2. Check your Zed.log for relevant errors? (please include!)
3. Click Preview to ensure everything looks right?
4. Hide videos, large images and logs in ``` inside collapsible blocks:
<details><summary>click to expand</summary>
```json
```
</details>
-->
label:Reproduction steps
description:A step-by-step description of how to reproduce the bug from a **clean Zed install**. The more context you provide, the easier it is to find and fix the problem fast.
placeholder:|
1. Start Zed
2. Click X
validations:
required:true
- type:textarea
attributes:
label:Current vs. Expected behavior
description:|
Current behavior (screenshots, videos, etc. are appreciated), vs. what you expected the behavior to be.
placeholder:|
Current behavior: <screenshot with an arrow> The icon is blue. Expected behavior: The icon should be red because this is what the setting is documented to do.
validations:
required:true
- type:textarea
id:environment
attributes:
label:Zed Version and System Specs
label:Zed version and system specs
description:|
Open Zed, from the command palette select "zed: copy system specs into clipboard"
Open the command palette in Zed, then type “zed: copy system specs into clipboard”.
label:If applicable, attach your `Zed.log` file to this issue.
label:Attach Zedlog file
description:|
From the command palette, run `zed: open log` to see the last 1000 lines.
Or run `zed: reveal log in file manager` to reveal the log file itself.
Open the command palette in Zed, then type `zed: open log` to see the last 1000 lines. Or type `zed: reveal log in file manager` in the command palette to reveal the log file itself.
value:|
<details><summary>Zed.log</summary>
@@ -73,3 +59,57 @@ body:
</details>
validations:
required:false
- type:textarea
attributes:
label:Relevant Zed settings
description:|
Open the command palette in Zed, then type “zed: open settings file” and copy/paste any relevant (e.g., LSP-specific) settings.
value:|
<details><summary>settings.json</summary>
<!-- Paste your settings inside the code block. -->
```json
```
</details>
validations:
required:false
- type:textarea
attributes:
label:Relevant Keymap
description:|
Open the command palette in Zed, then type “zed: open keymap file” and copy/paste the file's contents.
value:|
<details><summary>keymap.json</summary>
<!-- Paste your keymap file inside the code block. -->
```json
```
</details>
validations:
required:false
- type:textarea
attributes:
label:(for AI issues) Model provider details
placeholder:|
- Provider: (Anthropic via ZedPro, Anthropic via API key, Copilot Chat, Mistral, OpenAI, etc.)
- Model Name: (Claude Sonnet 4.5, Gemini 3 Pro, GPT-5)
- Mode: (Agent Panel, Inline Assistant, Terminal Assistant or Text Threads)
- Other details (ACPs, MCPs, other settings, etc.):
validations:
required:false
- type:dropdown
attributes:
label:If you are using WSL on Windows, what flavor of Linux are you using?
description:Zed is crashing or freezing or hanging.
type:Crash
labels:"state:needs triage"
body:
- type:textarea
attributes:
label:Summary
description:Summarize the issue with detailed reproduction steps
value:|
<!-- Begin your issue with a one sentence summary -->
SUMMARY_SENTENCE_HERE
### Description
<!-- Include all steps necessary to reproduce from a clean Zed installation. Be verbose -->
Steps to trigger the problem:
1.
2.
3.
Actual Behavior:
Expected Behavior:
validations:
required:true
- type:textarea
id:environment
attributes:
label:Zed Version and System Specs
description:'Open Zed, and in the command palette select "zed: copy system specs into clipboard"'
label:Reproduction steps
description:A step-by-step description of how to reproduce the crash from a **clean Zed install**. The more context you provide, the easier it is to find and fix the problem fast.
placeholder:|
Output of "zed: copy system specs into clipboard"
1. Start Zed
2. Perform an action
3. Zed crashes
validations:
required:true
- type:textarea
attributes:
label:If applicable, attach your `Zed.log` file to this issue.
label:Zed version and system specs
description:|
From the command palette, run `zed: open log` to see the last 1000 lines.
Or run `zed: reveal log in file manager` to reveal the log file itself.
Open the command palette in Zed, then type “zed: copy system specs into clipboard”.
Open the command palette in Zed, then type `zed: open log` to see the last 1000 lines. Or type `zed: reveal log in file manager` in the command palette to reveal the log file itself.
We're working to clean up our issue tracker by closing older bugs that might not be relevant anymore. If you are able to reproduce this issue in the latest version of Zed, please let us know by commenting on this issue, and it will be kept open. If you can't reproduce it, feel free to close the issue yourself. Otherwise, it will close automatically in 14 days.
Hi there!
Zed development moves fast and a significant number of bugs become outdated.
If you can reproduce this bug on the latest stable Zed, please let us know by leaving a comment with the Zed version.
If the bug doesn't appear for you anymore, feel free to close the issue yourself; otherwise, the bot will close it in a couple of weeks.
Thanks for your help!
close-issue-message:"This issue was closed due to inactivity. If you're still experiencing this problem, please open a new issue with a link to this issue."
close-issue-message:"This issue was closed due to inactivity. If you're still experiencing this problem, please leave a comment with your Zed version so that we can reopen the issue."
* In GPUI tests, prefer GPUI executor timers over `smol::Timer::after(...)` when you need timeouts, delays, or to drive `run_until_parked()`:
- Use `cx.background_executor().timer(duration).await` (or `cx.background_executor.timer(duration).await` in `TestAppContext`) so the work is scheduled on GPUI's dispatcher.
- Avoid `smol::Timer::after(...)` for test timeouts when you rely on `run_until_parked()`, because it may not be tracked by GPUI's scheduler and can lead to "nothing left to run" when pumping.
# GPUI
GPUI is a UI framework which also provides primitives for state and concurrency management.
@@ -15,15 +15,16 @@ with the community to improve the product in ways we haven't thought of (or had
In particular we love PRs that are:
- Fixes to existing bugs and issues.
-Small enhancements to existing features, particularly to make them work for more people.
- Fixing or extending the docs.
-Fixing bugs.
- Small enhancements to existing features to make them work for more people (making things work on more platforms/modes/whatever).
- Small extra features, like keybindings or actions you miss from other editors or extensions.
-Work towards shipping larger features on our roadmap.
-Part of a Community Program like [Let's Git Together](https://github.com/zed-industries/zed/issues/41541).
If you're looking for concrete ideas:
-Our [top-ranking issues](https://github.com/zed-industries/zed/issues/5393) based on votes by the community.
-Our [public roadmap](https://zed.dev/roadmap) contains a rough outline of our near-term priorities for Zed.
-[Triaged bugs with confirmed steps to reproduce](https://github.com/zed-industries/zed/issues?q=is%3Aissue%20state%3Aopen%20type%3ABug%20label%3Astate%3Areproducible).
-[Area labels](https://github.com/zed-industries/zed/labels?q=area%3A*) to browse bugs in a specific part of the product you care about (after clicking on an area label, add type:Bug to the search).
## Sending changes
@@ -37,9 +38,17 @@ like, sorry).
Although we will take a look, we tend to only merge about half the PRs that are
submitted. If you'd like your PR to have the best chance of being merged:
-Include a clear description of what you're solving, and why it's important to you.
- Include tests.
- If it changes the UI, attach screenshots or screen recordings.
-Make sure the change is **desired**: we're always happy to accept bugfixes,
but features should be confirmed with us first if you aim to avoid wasted
effort. If there isn't already a GitHub issue for your feature with staff
confirmation that we want it, start with a GitHub discussion rather than a PR.
- Include a clear description of **what you're solving**, and why it's important.
- Include **tests**.
- If it changes the UI, attach **screenshots** or screen recordings.
- Make the PR about **one thing only**, e.g. if it's a bugfix, don't add two
features and a refactoring on top of that.
- Keep AI assistance under your judgement and responsibility: it's unlikely
we'll merge a vibe-coded PR that the author doesn't understand.
The internal advice for reviewers is as follows:
@@ -50,10 +59,9 @@ The internal advice for reviewers is as follows:
If you need more feedback from us: the best way is to be responsive to
Github comments, or to offer up time to pair with us.
If you are making a larger change, or need advice on how to finish the change
you're making, please open the PR early. We would love to help you get
things right, and it's often easier to see how to solve a problem before the
diff gets too big.
If you need help deciding how to fix a bug, or finish implementing a feature
that we've agreed we want, please open a PR early so we can discuss how to make
the change with code in hand.
## Things we will (probably) not merge
@@ -61,11 +69,11 @@ Although there are few hard and fast rules, typically we don't merge:
- Anything that can be provided by an extension. For example a new language, or theme. For adding themes or support for a new language to Zed, check out our [docs on developing extensions](https://zed.dev/docs/extensions/developing-extensions).
- New file icons. Zed's default icon theme consists of icons that are hand-designed to fit together in a cohesive manner, please don't submit PRs with off-the-shelf SVGs.
- Features where (in our subjective opinion) the extra complexity isn't worth it for the number of people who will benefit.
- Giant refactorings.
- Non-trivial changes with no tests.
- Stylistic code changes that do not alter any app logic. Reducing allocations, removing `.unwrap()`s, fixing typos is great; making code "more readable" — maybe not so much.
-Features where (in our subjective opinion) the extra complexity isn't worth it for the number of people who will benefit.
- Anything that seems completely AI generated.
-Anything that seems AI-generated without understanding the output.
@@ -9,7 +9,7 @@ Welcome to Zed, a high-performance, multiplayer code editor from the creators of
### Installation
On macOS, Linux, and Windows you can [download Zed directly](https://zed.dev/download) or [install Zed via your local package manager](https://zed.dev/docs/linux#installing-via-a-package-manager).
On macOS, Linux, and Windows you can [download Zed directly](https://zed.dev/download) or install Zed via your local package manager ([macOS](https://zed.dev/docs/installation#macos)/[Linux](https://zed.dev/docs/linux#installing-via-a-package-manager)/[Windows](https://zed.dev/docs/windows#package-managers)).
Other platforms are not yet available:
@@ -20,7 +20,6 @@ Other platforms are not yet available:
- [Building Zed for macOS](./docs/src/development/macos.md)
- [Building Zed for Linux](./docs/src/development/linux.md)
- [Building Zed for Windows](./docs/src/development/windows.md)
Here's a file of {{language_name}} that the user is going to ask you to make an edit to.
{{else}}
Here's a file of text that the user is going to ask you to make an edit to.
{{/if}}
The section you'll need to rewrite is marked with <rewrite_this></rewrite_this> tags.
<document>
{{{document_content}}}
</document>
{{#ifis_truncated}}
The context around the relevant section has been truncated (possibly in the middle of a line) for brevity.
{{/if}}
And here's the section to rewrite based on that prompt again for reference:
<rewrite_this>
{{{rewrite_section}}}
</rewrite_this>
{{#ifdiagnostic_errors}}
Below are the diagnostic errors visible to the user. If the user requests problems to be fixed, use this information, but do not try to fix these errors if the user hasn't asked you to.
{{#eachdiagnostic_errors}}
<diagnostic_error>
<line_number>{{line_number}}</line_number>
<error_message>{{error_message}}</error_message>
<code_content>{{code_content}}</code_content>
</diagnostic_error>
{{/each}}
{{/if}}
Only make changes that are necessary to fulfill the prompt, leave everything else as-is. All surrounding {{content_type}} will be preserved.
Start at the indentation level in the original file in the rewritten {{content_type}}.
IMPORTANT: You MUST use one of the provided tools to make the rewrite or to provide an explanation as to why the user's request cannot be fulfilled. You MUST NOT send back unstructured text. If you need to make a statement or ask a question you MUST use one of the tools to do so.
It is an error if you try to make a change that cannot be made simply by editing the rewrite_section.
{path="std::process::Command::stderr",reason="`smol::process::Command::from()` does not preserve stdio configuration",replacement="smol::process::Command::stderr"},
{path="serde_json::from_reader",reason="Parsing from a buffer is much slower than first reading the buffer into a Vec/String, see https://github.com/serde-rs/json/issues/160#issuecomment-253446892. Use `serde_json::from_slice` instead."},
{path="serde_json_lenient::from_reader",reason="Parsing from a buffer is much slower than first reading the buffer into a Vec/String, see https://github.com/serde-rs/json/issues/160#issuecomment-253446892, Use `serde_json_lenient::from_slice` instead."},
{path="cocoa::foundation::NSString::alloc",reason="NSString must be autoreleased to avoid memory leaks. Use `ns_string()` helper instead."},
message(User,[text("Create a second empty todo file ")]),
message(
Assistant,
[
text(formatdoc!{"
I'll help you create a second empty todo file.
First, let me examine the project structure to see if there's already a todo file, which will help me determine the appropriate name and location for the second one.
"}),
I'll help you create a second empty todo file.
First, let me examine the project structure to see if there's already a todo file, which will help me determine the appropriate name and location for the second one.
- Like Aider/Claude Code you take the user's initial prompt and then call the LLM and perform tool calls in a loop until the ultimate goal is achieved.
- Unlike Aider or Claude code, it's not intended to be interactive. Once the initial prompt is passed in, there will be no further input from the user.
- The system you will build must reach the stated goal just by performing too calls and calling the LLM
- The system you will build must reach the stated goal just by performing tool calls and calling the LLM
- I want you to build this in python. Use the anthropic python sdk and the model context protocol sdk. Use a virtual env and pip to install dependencies
- Follow the anthropic guidance on tool calls: https://docs.anthropic.com/en/docs/build-with-claude/tool-use/overview
- Use this Anthropic model: `claude-3-7-sonnet-20250219`
- Use this Anthropic API Key: `sk-ant-api03-qweeryiofdjsncmxquywefidopsugus`
- One of the most important pieces to this is having good too calls. We will be using the tools provided by the Claude MCP server. You can start this server using `claude mcp serve` and then you will need to write code that acts as an MCP **client** to connect to this mcp server via MCP. Likely you want to start this using a subprocess. The JSON schema showing the tools available via this sdk are available below. Via this MCP server you have access to all the tools that zode needs: Bash, GlobTool, GrepTool, LS, View, Edit, Replace, WebFetchTool
- One of the most important pieces to this is having good tool calls. We will be using the tools provided by the Claude MCP server. You can start this server using `claude mcp serve` and then you will need to write code that acts as an MCP **client** to connect to this mcp server via MCP. Likely you want to start this using a subprocess. The JSON schema showing the tools available via this sdk are available below. Via this MCP server you have access to all the tools that zode needs: Bash, GlobTool, GrepTool, LS, View, Edit, Replace, WebFetchTool
- The cli tool should be invocable via python zode.py file.md where file.md is any possible file that contains the users prompt. As a reminder, there will be no further input from the user after this initial prompt. Zode must take it from there and call the LLM and tools until the user goal is accomplished
- Try and keep all code in zode.py and make heavy use of the asks I mentioned
- Once you’ve implemented this, you must run python zode.py eval/instructions.md to see how well our new agent tool does!
@@ -16,7 +16,7 @@ You are a highly skilled software engineer with extensive knowledge in many prog
3. DO NOT use tools to access items that are already available in the context section.
4. Use only the tools that are currently available.
5. DO NOT use a tool that is not available just because it appears in the conversation. This means the user turned it off.
6. NEVER run commands that don't terminate on their own such as web servers (like `npm run start`, `npm run dev`, `python -m http.server`, etc) or file watchers.
6. When running commands that may run indefinitely or for a long time (such as build scripts, tests, servers, or file watchers), specify `timeout_ms` to bound runtime. If the command times out, the user can always ask you to run it again with a longer timeout or no timeout if they're willing to wait or cancel manually.
7. Avoid HTML entity escaping - use plain characters instead.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.