## Goal
This PR creates the initial settings ui structure with the primary goal
of making a settings UI that is
- Comprehensive: All settings are available through the UI
- Correct: Easy to understand the underlying JSON file from the UI
- Intuitive
- Easy to implement per setting so that UI is not a hindrance to future
settings changes
### Structure
The overall structure is settings layer -> data layer -> ui layer.
The settings layer is the pre-existing settings definitions, that
implement the `Settings` trait. The data layer is constructed from
settings primarily through the `SettingsUi` trait, and it's associated
derive macro. The data layer tracks the grouping of the settings, the
json path of the settings, and a data representation of how to render
the controls for the setting in the UI, that is either a marker value
for the component to use (avoiding a dependency on the `ui` crate) or a
custom render function.
Abstracting the data layer from the ui layer allows crates depending on
`settings` to implement their own UI without having to add additional UI
dependencies, thus avoiding circular dependencies. In cases where custom
UI is desired, and a creating a custom render function in the same crate
is infeasible due to circular dependencies, the current solution is to
implement a marker for the component in the `settings` crate, and then
handle the rendering of that component in `settings_ui`.
### Foundation
This PR creates a macro and a trait both called `SettingsUi`. The
`SettingsUi` trait is added as a new trait bound on the `Settings`
trait, this allows the type system to guarantee that all settings
implement UI functionality. The macro is used to derived the trait for
most types, and can be modified through attributes for unique cases as
well.
A derive-macro is used to generate the settings UI trait impl, allowing
it the UI generation to be generated from the static information in our
code base (`default.json`, Struct/Enum names, field names, `serde`
attributes, etc). This allows the UI to be auto-generated for the most
part, and ensures consistency across the UI.
#### Immediate Follow ups
- Add a new `SettingsPath` trait that will be a trait bound on
`SettingsUi` and `Settings`
- This trait will replace the `Settings::key` value to enable
`SettingsUi` to infer the json path of it's derived type
- Figure out how to render `Option<T> where T: SettingsUi` correctly
- Handle `serde` attributes in the `SettingsUi` proc macro to correctly
get json path from a type's field and identity
Release Notes:
- N/A
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
Add support for scrolling the contents rendered aside an
`editor::code_context_menus::CodeContextMenu` by introducing the
`scroll_aside` method.
For now this method is only implemented for the
`CodeContextMenu::Completions` variant, which will scroll the aside
contents for an `editor::code_context_menus::CompletionsMenu` element,
as a `ScrollHandle` is added to the aside content that is rendered.
In order to be possible to trigger this via keybindings, a new editor
action is introduced, `ContextMenuScrollAside`, which accepts a number
of lines or pages to scroll the content by.
Lastly, the default keymaps for both MacOS and Linux, as well as for
Zed's vim mode, are updated to ensure that the following keybindings are
supported when a completion menu is open and the completion item's
documentation is rendered aside:
- `ctrl-e`
- `ctrl-y`
- `ctrl-d`
- `ctrl-u`
### Recording
https://github.com/user-attachments/assets/02043763-87ea-46f5-9768-00e907127b69
---
Closes#13194
Release Notes:
- Added support for scrolling the documentation panel shown alongside
the completion menu in the editor with `cltr-d`, `ctrl-u`, `ctrl-e` and
`ctrl-y`
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Co-authored-by: MrSubidubi <finn@zed.dev>
Closes#36981
- Add completion text and position caching to reduce redundant API calls
- Only trigger new completion requests on text changes, not cursor
movement
- Validate cursor position to ensure completions show at correct
location
- Improve end-of-line range calculation for more accurate deletions
- Extract reset_completion_cache helper for cleaner code organization
- Update completion diff algorithm documentation for clarity
Edit: Sorry this is the 2nd PR, I forgot that the forks history was
messy; I cherrypicked and cleaned it properly with this PR
Release Notes:
- supermaven: Improved caching of predictions
- supermaven: Fixed an issue where changing cursor position would
incorrectly trigger new completions
In the case where we fail to create an ACP connection to Gemini, only
report the "unsupported version" error if the version for the found
binary is at least our minimum version. That means we'll surface the
real error in this situation.
This also fixes incorrect sorting of downloaded Gemini versions--as @kpe
pointed out we were effectively using the version string as a key. Now
we'll correctly use the parsed semver::Version instead.
Release Notes:
- N/A
Closes https://github.com/zed-industries/zed/issues/36383
The project symbols modal didn't use the buffer font and highlighted
matches through modifying the font weight, which is inconsistent with
the outline picker, which presents code in list items in a similar way,
as well as project _and_ buffer search highlighting design.
Release Notes:
- N/A
Closes#35787Closes#17890Closes#28789Closes#36495
How it works:
For highlights (and selections) within the visible rows of the editor,
we split them row by row. This is efficient since the number of visible
rows is constant. For each row, all highlights and selections, which may
overlap, are flattened using a line sweep. This produces non-overlapping
consecutive segments for each row, each with a blended background color.
Next, for each row, we split text runs into smaller runs to adjust its
color using APCA contrast. Since both text runs and segment are
non-overlapping and consecutive, we can use two-pointer on them to do
this.
For example, a text run for the variable red might be split into two
runs if a highlight partially covers it. As a result, one part may
appear as red, while the other appears as a lighter red, depending on
the background behind it.
Result:
<img width="1458" height="949" alt="image"
src="https://github.com/user-attachments/assets/4814c93d-12e7-4b4d-8542-d912acccfb8e"
/>
<img width="1459" height="952" alt="image"
src="https://github.com/user-attachments/assets/9e497b6c-3e66-43e8-8e5b-f634dd5ee8d3"
/>
<img width="1457" height="621" alt="image"
src="https://github.com/user-attachments/assets/8dfa6ce5-f46b-45b9-8008-66169d5aecd4"
/>
Release Notes:
- Improved text contrast when selected or highlighted in the editor.
Follow-up of https://github.com/zed-industries/zed/pull/36764
* Fix `anyhow!({e})` conversion lossing Collab error codes context when
opening a buffer remotely
* Use this context to only allow opening files that had not specific
Collab error code
Release Notes:
- N/A
Follow-up https://github.com/zed-industries/zed/pull/37083
Noisy RPC LSP logs were functioning this way already, but to keep Collab
loaded even less, do not send any kind of logs to the client if the
client has a corresponding log tab not opened.
This change is pretty raw and does not fully cover scenarious with
multiple clients: if one client has a log tab open and another opens tab
with another kind of log, the 2nd kind of logs will be streamed only.
Also, it should be possible to forward the host logs to the client on
enabling — that is not done to keep the change smaller.
Release Notes:
- N/A
To show these notifications, Zeta was being initialized with the initial
workspace it's used on - which may not even still exist! This removes a
confusing/misleading workspace field from Zeta.
Release Notes:
- N/A
We have a bug in our ACP implementation where sometimes the
Accept/Reject buttons are disabled (and stay disabled even after the
thread has finished). I haven't found a complete fix for this yet, so in
the meantime I'm putting out the fire by making it so those buttons are
always enabled. That way you're never blocked, and the only consequence
of the bug is that sometimes they should be disabled but are enabled
instead.
Release Notes:
- N/A
@JosephTLyons pointed out that it's a bit weird that we only show a
preview for items selected after the initial one, so this does it for
that too.
It makes tab switching feel even faster!
Release Notes:
- N/A
Co-authored-by: David Kleingeld <davidsk@zed.dev>
Closes: https://github.com/zed-industries/zed/issues/37089
Instead of looking for the gemini command on `$PATH`, by default we'll
install our own copy on demand under our data dir, as we already do for
language servers and debug adapters. This also means we can handle
keeping the binary up to date instead of prompting the user to upgrade.
Notes:
- The download is only triggered if you open a new Gemini thread
- Custom commands from `agent_servers.gemini` in settings are respected
as before
- A new `agent_servers.gemini.ignore_system_version` setting is added,
similar to the existing settings for language servers. It's `true` by
default, and setting it to `false` disables the automatic download and
makes Zed search `$PATH` as before.
- If `agent_servers.gemini.ignore_system_version` is `false` and no
binary is found on `$PATH`, we'll fall back to automatic installation.
If it's `false` and a binary is found, but the version is older than
v0.2.1, we'll show an error.
Release Notes:
- acp: By default, Zed will now download and use a private copy of the
Gemini CLI binary, instead of searching your `$PATH`. To make Zed search
your `$PATH` for Gemini CLI before attempting to download it, use the
following setting:
```
{
"agent_servers": {
"gemini": {
"ignore_system_version": false
}
}
}
```
This PR makes it so the channel list will still be shown while
reconnecting to Collab instead of showing the signed-out state.
In order to model the transitional states that occur while reconnecting,
we needed to introduce a new `Status::Reauthenticated` state that we go
through when signing in as part of a reconnect. This is because we
cannot tell from `Status::Authenticated` alone if we're authenticating
for the first time or reauthenticating.
Release Notes:
- N/A
Closes#36420
## Synopsis
The issue in #36420 is caused by #7276, which bound the appropriate
tree-sitter queries to the `@variable.member` color. However, I have
found neither this color's declaration nor its other usages in the
codebase (neither on the latest `main` nor on
79c1003b34).
Other languages use for such situations the `@property` color.
## Solution
Just change the used `@variable.member` color to the `@property` one.
Seems fully inline with the changes illustrated in #7276.
## Screenshots
<img width="856" height="465" alt="Screenshot 2025-08-28 at 13 18 38"
src="https://github.com/user-attachments/assets/9d1f3542-8749-421f-864f-959c1242cc64"
/>
<img width="837" height="462" alt="Screenshot 2025-08-28 at 13 20 08"
src="https://github.com/user-attachments/assets/36a80c22-9de9-46b1-87e3-7fdeaa62978f"
/>
## Changelog
Release Notes:
- go: Fixed highlighting of fields.
Use the latest Copilot Chat model schema, matching what is used in
VSCode, to get more data about available models than was previously
accessible. Replace hardcoded default model (gpt-4.1) with the default
model included in JSON. Other data like premium request multipliers
could be used in the future if Zed implements a way for models to
display additional details about themselves, such as with tooltips on
hover.
Release Notes:
- N/A
---------
Co-authored-by: Peter Tripp <peter@zed.dev>
Closes#37022Closes#36994
This update ensures all Grok models use the JsonSchemaSubset format for
tool schemas.
A previous fix for this issue was too specific, only targeting grok-4
models. This caused other variants, like grok-code-fast-1, to be missed.
We've now broadened the logic to correctly apply the setting to the
entire Grok model family.
Release Notes:
- Fix tool calling for `x-ai/grok-code-fast-1` model via OpenRouter.
Instead of manually constructing the venv we now ask the python
toolchain for the relevant information, unifying the approach of vent
inspection
Fixes https://github.com/zed-industries/zed/issues/27350
Release Notes:
- Improved the detection of python virtual environments for terminals
and tasks in remote projects.
Closes#37043
Previously claude sonnet 4 was missing from copilot as it was colliding
with zed's claude-sonnet-4 model id. Now we do deduplication based upon
model and provider id both.
| Before | After |
|--------|--------|
| <img width="784" height="950" alt="CleanShot 2025-08-28 at 18 31
28@2x"
src="https://github.com/user-attachments/assets/d49d5a17-7271-417d-bb5e-bc380071e810"
/> | <img width="720" height="876" alt="CleanShot 2025-08-28 at 18 31
42@2x"
src="https://github.com/user-attachments/assets/a5100c05-994e-4e19-ab20-34c0258b977c"
/> |
Release Notes:
- Fixed an issue where models with the same ID from different providers
(such as Claude Sonnet 4 from both Zed and Copilot) were incorrectly
deduplicated in the model selector—now all variants are shown.
Take 2: https://github.com/zed-industries/zed/pull/36709 but without the
very bad `cfg`-based approach for storing the RPC logs.
--------------
Enables LSP log tracing in both remote collab and remote ssh
environments.
Server logs and server RPC traces can now be viewed remotely, and the
LSP button is now shown in such projects too.
Closes https://github.com/zed-industries/zed/issues/28557
Co-Authored-By: Kirill <kirill@zed.dev>
Co-Authored-By: Lukas <lukas@zed.dev>
Release Notes:
- Enabled LSP log tracing in both remote collab and remote ssh
environments
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
Co-authored-by: Lukas Wirth <lukas@zed.dev>
This prevents the common footgun of copy/pasting an API key
starting/ending with extra newlines, which would lead to a "bad request"
error.
Closes#37038
Release Notes:
- agent: Support pasting language model API keys that contain newlines.
Release Notes:
- agent: Fixed a bug that canceled editing when scrolling the user
message out of view.
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
This pull request refactors the `KeybindingKeystroke` struct and related
code to improve platform abstraction. The changes centralize
platform-specific logic within `KeybindingKeystroke` and update its
usage throughout the codebase, making the API more consistent and less
error-prone.
Release Notes:
- N/A
This PR adds a toggleable filter to the stack frame list that filters
out entries that don't exist within a user's project (visible work
trees). This works by keeping a vector of entry indices that exist
within a user's project and updates the list state based on these
entries when filtering the list.
I went with this approach so the stack frame list wouldn't have to
rebuild itself whenever the filter is toggled and it could persist its
state across toggles (uncollapsing a collapse list). It was also easier
to keep track of selected entries on toggle using the vector as well.
### Preview
https://github.com/user-attachments/assets/d86c7485-c885-4bbb-bebb-2f6385674925
Release Notes:
- debugger: Add option to only show stack frames from user's project in
stack frame list
This PR fixes two bugs and also changes one behavior in the **Keymap
Editor**.
As shown in the video, when I press `ctrl-shift-2` in the Keymap Editor,
the first keystroke is displayed as `ctrl-shift-@`, which is incorrect.
On macOS and Linux, it should be `ctrl-@`.
https://github.com/user-attachments/assets/69cfcfa0-b422-45d6-8e69-80f8608180fd
Also, after pressing `ctrl-shift-2` and then releasing `2` and `ctrl`, a
`shift` keystroke was incorrectly added.
https://github.com/user-attachments/assets/892124fd-847d-4fde-9b20-a27ba49ac934
Now, when you enter a sequence like `+ctrl+alt-alt+f` in the Keymap
Editor, it will output `ctrl-f` instead of `ctrl-alt-f`, matching VS
Code’s behavior.
Release Notes:
- Fixed incorrect keystroke reporting in the Keymap Editor.
This Pull Request introduces support for pattern items in the buffer
search. It does so by splitting the `query` methods into two new
methods:
- `BufferSearchBar.raw_query` – returns the text from the search query
editor
- `BufferSearchBar.query` - returns the search query with pattern items
removed
Whenever the search query is updated, processing of the
`EditorEvent::Edited` event ends up calling the
`BufferSearchBar.apply_pattern_items` method, which parses the pattern
items from the raw query, and updates the buffer search bar's search
options accordingly. This `apply_pattern_items` function avoids updating
the `BufferSearchBar.default_options` field in order to be able to reset
the search options when a pattern items is removed. Lastly, new pattern
items can easily be added by updating the `PATTERN_ITEMS` array.
### Screen Capture
https://github.com/user-attachments/assets/ebd83c38-e480-4c24-9b8c-6edde69cf392
---
Closes#32390
Release Notes:
- Added support for the `\c` and `\C` query pattern items to control
case-sensitivity in buffer search
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Closes#32020
Release Notes:
- Helix: Improve `x` behaviour. Will respect modifiers (`5 x`). Pressing
`x` on a empty line, will select current+next line, because helix
considers current line to be already selected without the need of
pressing `x`.
The scanner is restarted after loading initial settings, and there was
an optimization to not re-discover and re-watch git repositories if they
already exist in the snapshot. #35865 added cleanup of watches that
occurred when the scanner restarts, and so in some cases repos were no
longer watched.
Release Notes:
- Linux: Fixed a case where Git repositories might not be watched for
changes, causing branch switching to not update the UI.
Co-authored-by: Julia <julia@zed.dev>
This makes sure we do not apply the highlights for snake case
identifiers as well as paths for attributes too broadly to all types of
macros, which should make macros much more readable overall whilst
keeping the highlighting for the attribute items.
| Before | After |
| --- | --- |
| <img width="1414" height="958" alt="Bildschirmfoto 2025-08-28 um 00 37
58"
src="https://github.com/user-attachments/assets/1254b9a2-d07a-4be4-9b4f-555a7c640302"
/> | <img width="1414" height="958" alt="Bildschirmfoto 2025-08-28 um 00
37 38"
src="https://github.com/user-attachments/assets/5f6dd66c-5469-4f27-9f1d-0a6e6e8d8085"
/> |
Release Notes:
- rust: Improved highlighting within macros.
Closes#36931 and #21956
Preserves `SearchOptions` across dismisses of the buffer search bar.
This behavior is consistent with VSCode, which seems reasonable. The
`configured_options` field is then no longer being used. The
configuration is still read during initialization of the
`BufferSearchBar`, but not after.
Something to consider is that there are other elements in the search bar
which are not kept across dismisses such as replace status. However
these are visually separated in the UI, leading me to believe this is a
okay change to make.
Release Notes:
- Preserve search options between buffer search dismisses
This PR adds the ability for a user to select one or more blocks of text
and wrap each selection in an HTML tag — which works by placing multiple
cursors inside the open and close tags so the appropriate element name
can be typed in to all places simultaneously.
This is similar to the emmet "Wrap with Abbreviation" functionality
discussed in #15588 but is a simpler version that does not rely on
Emmet's language server.
Here's a preview of the feature in action:
https://github.com/user-attachments/assets/1931e717-136c-4766-a585-e4ba939d9adf
Some notes and questions:
- The current implementation is a hardcoded with regards to supported
languages. I'd love some direction on how much of this information to
push into the relevant language structs.
- I can see this feature as something that languages added by an
extension would want to enable support for — is this something you'd
want?
- The syntax is hardcoded to support HTML/XML/JSX-like languages. I
don't suppose this is a problem but figured I'd point it out anyway.
- I called it "Wrap in tag" but open to whatever naming you feel is
appropriate.
- The implementation doesn't use `manipulate_lines` — I wasn't sure how
make use of that without extra overhead / bookkeeping — does this seem
fine?
- I could also investigate adding wrap in abbreviation support by
communicating with the Emmet language server but I think I'll need some
direction on how to handle Emmet's custom LSP message. I could do this
either in addition to or instead of this feature — though imo this
feature is a nice "shortcut" regardless.
Release Notes:
- Added a new "Wrap Selections in Tag" action that lets you wrap one or
more selections in tags based on language. Works in HTML, JSX, and
similar languages, and places cursors inside both opening and closing
tags so you can type the tag name once and apply it everywhere.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
cc @michael-ud - if you can build Zed, I'd appreciate it if you could
give this a go with your project. Otherwise I can provide a link to
download of current nightly via an e-mail for you to try out (if you
want).
This change will land in Preview (if merged) on next Wednesday and then
it'll be in Stable a week after that.
Related to: #20402
Release Notes:
- python: Zed now searches for virtual environments in intermediate
directories between a root of the worktree and the location of
pyproject.toml applicable to the currently focused file.
Enables LSP log tracing in both remote collab and remote ssh
environments.
Server logs and server RPC traces can now be viewed remotely, and the
LSP button is now shown in such projects too.
Closes https://github.com/zed-industries/zed/issues/28557
Co-Authored-By: Kirill <kirill@zed.dev>
Co-Authored-By: Lukas <lukas@zed.dev>
Release Notes:
- Enabled LSP log tracing in both remote collab and remote ssh
environments
---------
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
Co-authored-by: Lukas Wirth <lukas@zed.dev>