- Add a separate `git_commit_buffer_font_size` setting, defaulting to
`12px` (the previous default before it was changed to use the buffer
font size)
- Add in-memory buffer font size overrides for zooming the commit modal
and in-panel editor
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Added a `git_commit_buffer_font_size` setting and made the in-panel
and modal commit message editors zoomable.
Seems to have been introduced in
1fbe1e3512.
These settings actually mean the opposite:
> Whether to use the system provided dialogs for Open and Save As. When
set to false, Zed will use the built-in keyboard-first pickers.
> Enables the simple file dialog for opening and saving files and
folders. The simple file dialog replaces the system file dialog when
enabled.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
~~Closes #ISSUE~~
Release Notes:
- Fixed import of VSCode setting `files.simpleDialog.enable` being
inverted
Adds a `markdown_preview_code_font_family` setting that overrides the
font used in the markdown preview for code — inline `code` spans and
fenced code blocks.
This is the counterpart to `markdown_preview_font_family` (#54003),
which already does this for body text. Together they let you choose a
typographically matched body + code font pair for the preview without
forcing the code font onto editor buffers, where it may not be a good
coding font:
```json
{
"markdown_preview_font_family": "Noto Serif",
"markdown_preview_code_font_family": "Noto Sans Mono"
}
```
Behavior mirrors `markdown_preview_font_family`:
- Scoped to the markdown preview only (`MarkdownFont::Preview`). The
agent panel, notifications, hover popovers, and REPL output are
unaffected — they keep using the buffer font for code.
- Falls back to the buffer font family when unset, so existing previews
are unchanged.
- Overrides the font family only; fallbacks and features still come from
the buffer font.
Before (uses buffer font, here Iosevka):
<img width="509" height="368" alt="Screenshot 2026-05-14 at 1 39 51 PM"
src="https://github.com/user-attachments/assets/6b7e49b2-fc6e-4db1-9679-392b3447f411"
/>
After (uses specified font, here Noto Sans Mono):
<img width="508" height="368" alt="Screenshot 2026-05-14 at 1 40 51 PM"
src="https://github.com/user-attachments/assets/f911c99b-08f8-4336-83eb-54b555f11c54"
/>
Release Notes:
- Added `markdown_preview_code_font_family` to override the code font in
the markdown preview
Instead of manually handing hiding the cursor on keyboard input at the
editor level, GPUI will now take care of it.
This makes it significantly easier to handle the edge cases, and allows
delegating the cursor restoration to the platform itself in the macOS
case. On Linux and Windows, we still have to restore the cursor on
movement ourselves, but this now happens at the platform-specific level.
Bugs fixed by this change:
- No cursor when "Unsaved edits" prompt appears
- Cursor disappears when clicking a panel button if it contains a search
bar (e.g. collab panel)
### Setting rename
The `hide_mouse` setting value `"on_typing_and_movement"` has been
renamed to `"on_typing_and_action"` to better reflect what it actually
does — it hides the cursor when a keystroke resolves to an action (e.g.
cursor movement, deletion). Existing settings are migrated
automatically.
### Tested platforms
- [x] macOS
- [x] Wayland
- [x] X11
- [x] Windows
- [x] Web
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Renamed the `hide_mouse` setting value `on_typing_and_movement` to
`on_typing_and_action` to better describe its behavior (existing
settings are auto-migrated)
- Fixed a few situations where the mouse cursor would be incorrectly
hidden
When started working on "disable the profiler for all but Nightly and
Dev" users, I've tried to do that using the default OS settings and
discovered that those are ignored.
Release Notes:
- Fixed default.json profile and os settings not applying on startup
Allows to reconfigure behavior, including the previous one, `top`
Closes https://github.com/zed-industries/zed/issues/52173
Release Notes:
- Reworked go to definition to open its target in the center of the
editor. Can be reconfigured with `go_to_definition_scroll_strategy`.
## Summary
Adds two user-facing settings that let the markdown preview render with
a font family and theme independent from the editor. Both are optional
and fall back to the editor defaults when unset.
```json
{
"markdown_preview_font_family": "Georgia",
"markdown_preview_theme": "Solarized Light"
}
```
## Details
- New `MarkdownFont::Preview` variant, used only by the preview surface.
- New `MarkdownStyle::themed_with_overrides()` that accepts explicit
`ThemeColors` and `SyntaxTheme` so the preview can render with a theme
other than the active editor theme. Existing `themed()` callers are
unchanged.
- The preview pane background adopts the chosen theme's
`editor_background`.
- Follows the pattern already used by `agent_ui_font_size` /
`agent_buffer_font_size`.
## Scope
Sizing-related changes (`markdown_preview_font_size`,
`markdown_preview_line_height`, typography tweaks, responsive max-width
container) were in an earlier revision of this PR and have been removed
per review feedback — they interact with the Cmd+/- zoom behavior in
ways that still need design work, and will land in a follow-up.
## Files Changed
- `crates/settings_content/src/theme.rs` — schema
- `crates/theme_settings/src/settings.rs` — runtime + accessor
- `crates/markdown/src/markdown.rs` — `MarkdownFont::Preview` +
`themed_with_overrides()`
- `crates/markdown_preview/src/markdown_preview_view.rs` — theme
resolution, style selection, background
- `crates/markdown_preview/Cargo.toml` — `theme` dependency
- `crates/settings/src/vscode_import.rs` — new fields in struct literal
Release Notes:
- Added `markdown_preview_font_family` and `markdown_preview_theme`
settings to customize the markdown preview independently from the
editor.
Co-authored-by: Chris Biscardi <chris@christopherbiscardi.com>
Needs https://github.com/zed-industries/zed/pull/54635 for the profile
overrides added into default settings json to work.
Part of https://github.com/zed-industries/zed/issues/48968
Another part of the fix related seems to be
https://github.com/zed-industries/zed/pull/45669 ?
Using the steps from the issue and profiling on macOs had shown that Zed
has 2 memory "leaks" in play when a certain file is being rewritten a
lot of times.
* First, the thread profiler registers a lot of tasks' data and fills
its buffer to the limit:
<img width="3456" height="2158" alt="image"
src="https://github.com/user-attachments/assets/f183312d-4389-4072-8915-d54e60419b08"
/>
* Second, if the buffer gets open, the undo history fragments start to
creep up infinitely:
<img width="3456" height="2158" alt="image"
src="https://github.com/user-attachments/assets/61a2b66b-81fd-4973-9c3c-c339f886d9b2"
/>
The PR aims to solve the first issue by disabling the profiling by
default, yet leaving the way to turn in on quickly with settings.
The memory usage profiling shows that the memory usage is now
dynamically affected by the new setting:
<img width="2032" height="1136" alt="image"
src="https://github.com/user-attachments/assets/8a6c76b9-6fb7-44bc-ac1d-3c34afe7c575"
/>
While the test directory being thrashed with the script from the issue,
* first, Zed starts with the profiling disabled
* then gets the profiling enabled which results in the memory growth
close to 1 minute mark of the screenshot
* last, the profiling gets disabled again, releasing all the memory
accumulated
Release Notes:
- Improved Zed's default memory usage
Added support for `credentials_url`, falling back to `server_url`, to be
used as the key for storing information inside Keychain Access. This
allows two copies of Zed to be used side by side if the other is
launched with a custom `--user-data-dir`.
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
Release Notes:
- Added support for `credentials_url`, falling back to `server_url`, to
be used as the key for storing information inside Keychain Access.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] ~Unsafe blocks (if any) have justifying comments~
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Followup to #47531 to use the gpui feature in Zed. This just plumbs the
"system bell" feature into the terminal, behind a new setting (enabled
by default, like most other terminal applications).
Closes#5303
Relates to
https://github.com/zed-industries/zed/issues/40826#issuecomment-3684556858
Release Notes:
- Added audible BEL to Terminal; can be enabled by setting
`terminal.bell` to `"system"`.
---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Ben Kunkle <Ben.kunkle@gmail.com>
Closes#49581
Adds a `line_ending` language setting that controls how line endings are
handled for new files and during format/save:
- `detect` (default) — detects existing line endings; new files use the
platform default
- `prefer_lf` / `prefer_crlf` — sets LF or CRLF for new files and files
with no existing convention, while preserving existing files
- `enforce_lf` / `enforce_crlf` — normalizes all line endings to LF or
CRLF on every format/save
The setting can be configured globally, per-language, or via
`.editorconfig`'s `end_of_line` property (which maps to `enforce_lf` /
`enforce_crlf`).
Release Notes:
- Added `line_ending` setting to control how line endings are handled
for new files and normalized on save.
- Added support for `.editorconfig` `end_of_line` property to enforce
line endings.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
The `project_name` worktree setting was added in #36713 to let users
override the name shown in the window title. Its description ("The
displayed name of this project. If left empty, the root directory name
will be displayed.") suggests broader coverage, and #46440 reports the
reasonable expectation that it should also apply in the project
switcher. In practice the setting has only ever affected
`Workspace::update_window_title`, so everywhere else (recent projects,
the multi-worktree pane, ...) keeps falling back to the worktree root
name.
Rather than plumb the setting through each of those surfaces, I'm
removing it. Having a project-level setting control how your editor
displays the project has downsides. For example it means a checkout can
dictate UI in someone else's Zed. The natural home for a custom display
name is the workspace DB, set from the UI, which is what we should do if
we want this feature back.
If you want this back, the path forward is to store the display name in
`WorkspaceDb`, expose a UI affordance to edit it, and read it from
`update_window_title`, `recent_projects::get_recent_projects` /
`get_open_folders`, and any other places that currently derive a display
name from the worktree root.
Closes#46440
Release Notes:
- Removed the `project_name` project setting. It only ever affected the
OS window title, and the expectation that it would show up in the
project switcher and elsewhere is better served by a future UI-driven,
per-workspace setting stored locally.
Update the JSON schema generated for the settings file in order to be
able to provide the list of valid actions when editing the values for
the `command_aliases` setting.
While reviewing https://github.com/zed-industries/zed/pull/52892 , I
noticed that, even though we already have support for this in the keymap
file, we don't support it for the `command_aliases` setting, so went
ahead and refactored this a bit such that the existing functionality for
the keymap file JSON schema could also be re-used for the
`command_aliases` setting.
Here's a quick big-picture breakdown of the relevant changes:
* Add `settings_content::ActionName` newtype, representing a simple
named action without arguments. The
`settings_content::ActionName::build_schema` function can be used to
build the schema of all possible action names.
* Add `settings_content::ActionWithArguments` newtype, representing an
action with arguments. This was mostly done so as to keep both action
without arguments and action with arguments newtypes together,
even though we don't have
`settings_content::ActionWithArguments::build_schema`, as it is only
used by the keymap schema generation logic and probably doesn't warrant
moving it here right now.
* Update both
`settings_content::WorkspaceSettingsContent::command_aliases` and
`workspace::workspace_settings::WorkspaceSettings::command_aliases` to
now be of type `HashMap<String, ActionName>` such that, when the json
schema for `command_aliases` is generate, it'll now reference the
`#/$defs/ActionName` schema.
* Update `SettingsStore::json_schema` so as to populate the
`#/$defs/ActionName` schema at runtime, replacing it with the actual
list of valid action names.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Added support for auto-completing action names on `command_aliases`
setting
Fixes#52453Fixes#53246
Both issues were introduced by #51208 ("Handle Linux FS Rescan Events"),
which added `PathEventKind::Rescan` handling.
## Rules files not loading (#52453)
`load_worktree_info_for_system_prompt` called `load_worktree_rules_file`
synchronously, which uses `entry_for_path()` on the current worktree
snapshot. If the background scanner hasn't finished its initial scan,
the entry doesn't exist yet and the lookup returns `None` — the code
concludes no rules file exists. This was always a latent race condition,
but became more visible after Rescan events were introduced, since they
can trigger additional `WorktreeUpdatedEntries` churn that interacts
with the refresh mechanism.
The fix awaits `scan_complete()` on local worktrees before performing
the rules file lookup, ensuring the full directory tree is indexed
first.
## Config file rescan clearing OAuth tokens (#53246)
The `Rescan` handlers in `watch_config_dir` used
`fs.load(file_path).await.unwrap_or_default()`, which turns any
file-read error into an empty string. This empty string flows to
consumers like `CopilotChat`, where `extract_oauth_token("")` returns
`None`, causing the OAuth token to be unconditionally overwritten with
`None` — triggering re-authentication.
The fix changes both Rescan handlers to skip files that fail to load
(using `if let Ok(contents) = ...`), matching the pattern already used
by the `Created`/`Changed` handler.
Release Notes:
- Fixed rules files (AGENTS.md, CLAUDE.md, .rules, etc.) sometimes not
being applied in agent threads.
- Fixed GitHub Copilot re-prompting for authentication after filesystem
rescan events.
Closes#48729, closes#27263, closes#45954
This PR aims to make zed responsive on symlinked directory events
outside the editor.
Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
new-linked-folder is inside /zed-test/zed-project
output of ls -ld new-linked-folder
`lrwxr-xr-x 1 prayanshchhablani staff 42 28 Mar 23:20 new-linked-folder
-> /Users/prayanshchhablani/new-target-folder`
this shows new-linked-folder is a symlink folder whose target is
new-target-folder which is outside the root dir of the project opened in
zed.
https://github.com/user-attachments/assets/ffebafc3-2fc4-4293-bdbf-3a894a45e276
Release Notes:
- Fixed file watching of symlinks that point outside of the
project/watched directory. Zed should now properly respond to changes in
files in symlinked directories
This PR revamps our feature flag system, to enable richer iteration.
Feature flags can now:
- Support enum values, for richer configuration
- Be manually set via the settings file
- Be manually set via the settings UI
This PR also adds a feature flag to demonstrate this behavior, a
`agent-thread-worktree-label`, which controls which how the worktree tag
UI displays.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
Adds basic bookmark functionality to the editor, allowing users to mark
lines and later navigate between them. This is an MVP and will later be
expanded with a picker, vim marks integration and syntax tree based
bookmark positions. In this MVP bookmarks shift under external edits.
# UI
## Adding/Removing bookmarks
To add a bookmark:
- run the toggle bookmark action
- hold secondary and click in the gutter
- open the context menu by right clicking in the gutter and select add
bookmark To remove a bookmark:
- run the toggle bookmark action
- click on the bookmarks icon in the gutter
- open the context menu by right clicking in the gutter and select
remove bookmark
remove all bookmarks with `workspace: clear bookmarks`
# Implementation
This mirrors the implementation of breakpoints. The rendering of the
gutter was refactored to make place for bookmark icons and buttons:
- Code was extracted to a `Gutter` struct
- Runnables, breakpoints and bookmarks are now collected ahead of
layouting. Just before layouting we remove the items that collide and do
not have priority.
- The `phantom_breakpoint` is replaced by a `gutter_hover_button`
## In depth phantom breakpoint discussion:
This was phantom_breakpoint. It worked as follows:
- A fake breakpoint was added to the list of breakpoints.
- While rendering the breakpoints it a breakpoint turned out to be fake
it would get a different description and look.
- The breakpoint list was edited run_indicators ("play buttons")
rendering to removes the fake breakpoint if it collided.
This would not scale to more functionality. Now we only render
breakpoints, bookmarks and run indicators. Then we render a button if
there is not breakpoint, bookmark or run indicator already present. We
can do so since the rendering of such "gutter indicators" has been
refactored into two phases:
- collect the items.
- render them if no higher priority item collides.
This is far easier and more readable which enabled me to easily take the
phantom_breakpoint system and use it for placing bookmarks as well :)
Note: this was previously merged but it needed a better squashed commit
message. For the actual PR see: 51404. This reverts commit
7e523a2d2b.
Release Notes:
- Added Bookmarks
Co-authored-by: Austin Cummings <me@austincummings.com>
Closes#4526
Adds basic bookmark functionality to the editor, allowing users to mark
lines and later navigate between them.
### What's new
**Toggling bookmarks**
Users can toggle a bookmark on the current line(s) via the `editor:
toggle bookmark` action. A bookmark icon appears in the gutter for each
bookmarked line.
**Navigation**
Two new actions, `editor: go to next bookmark` and `editor: go to
previous bookmark`, navigate between bookmarks in the current buffer,
wrapping around at the ends of the buffer.
**Viewing all bookmarks**
`editor: view bookmarks` opens all bookmarks across the project in a
multibuffer, similar to how references and diagnostics are surfaced.
**Clearing bookmarks**
`workspace: clear bookmarks` removes all bookmarks in the current
project.
**Persistence**
Bookmarks are persisted to the workspace database and restored when the
workspace is reopened. They are stored as `(path, row)` pairs and
resolved back to text anchors. Out of range or unresolvable bookmarks
are skipped with a logged warning.
**Gutter rendering**
Bookmark icons are rendered in the gutter using the existing gutter
button layout system, consistent with breakpoints. They are suppressed
on lines that already show a breakpoint or phantom breakpoint indicator.
A new `gutter.bookmarks` setting (defaulting to `true`) controls their
visibility.
### What's left
- [x] Lazily load buffers that have bookmarks
- [x] Clean up test boilerplate
- [ ] Assign default keybindings
- [ ] Compare line of saved bookmarks with current buffer (gray out the
"stale" bookmarks)
### What's next (and nice to haves)
- [ ] Resilience against external edits
- [ ] Save column position with the bookmark
- [ ] Bookmarks attached to syntactic structures?
- [ ] Labeled bookmarks?
---
Release Notes:
- Added bookmarks: toggle bookmarks on lines with `editor: toggle
bookmark`, navigate with `editor: go to next bookmark` / `editor: go to
previous bookmark`, view all bookmarks with `editor: view bookmarks`,
and clear with `workspace: clear bookmarks`. Bookmarks are shown in the
gutter and persisted across sessions.
---------
Co-authored-by: Yara <git@yara.blue>
This fixes an issue reported by @Veykril where the "Try Now" button
would open a different panel than the agent panel. The bug was caused by
us attempting to focus the agent panel before layout settings updates
had been applied.
This should also make all programmatic settings updates more responsive,
because they won't have to wait for FS watchers to take effect.
Release Notes:
- N/A
---------
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
follow up #47471
As described in #47471, we introduced a direction-aware strategy to
improve user experience when interacting with hover popovers. In this
follow-up, we are adding `hover_popover_sticky` and
`hover_popover_hiding_delay` to control whether the feature introduced
in 47471 enabled, and to let users configure the delay to balance
responsiveness . Also `hover_popover_sticky` can now be imported from
`editor.hover.sticky`, as well as `hover_popover_hiding_delay` from
`editor.hover.hidingDelay` in VSCode.
Also this PR adds several tests:
- `test_hover_popover_cancel_hide_on_rehover`: when the cursor returns
to the hover after leaving once within the hiding delay, the hover
should persist while canceling the existing hiding timer.
- `test_hover_popover_enabled_false_ignores_sticky` : when
`hover_popover_enabled` is false, the `hover_popover_sticky` and
`hover_popover_hiding_delay` have no effect(since no hover is shown).
- `test_hover_popover_sticky_delay_restarts_when_mouse_gets_closer`:
when mouse gets closer to hover popover, we expect the timer to reset
and the hover remains visible.
- `test_hover_popover_hiding_delay`: check if the delay(in test, that's
500ms) works.
- `test_hover_popover_sticky_disabled`: when hover_popover_sticky is
false, the hover popover disappears immediately after the cursor leaving
the codes.
- VSCode import test in `settings_store.rs`
Release Notes:
- Added `hover_popover_sticky` and `hover_popover_hiding_delay` settings
to balance responsiveness of hover popovers.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This PR adds the `cli_default_open_behavior` setting and a first-run TUI
prompt
that appears when `zed <path>` is invoked without flags while existing
windows are
open and the setting hasn't been configured yet.
## What it does
### Setting and prompt
- Adds a new `cli_default_open_behavior` workspace setting with two
values:
`existing_window` (default) and `new_window`.
- When the user runs `zed <path>` for the first time with existing Zed
windows
open, a `dialoguer::Select` prompt in the CLI asks them to choose their
preferred behavior. The choice is persisted to `settings.json`.
- The prompt is skipped when:
- An explicit flag (`-n`, `-e`, `-a`) is given
- No existing Zed windows are open
- The setting is already configured in `settings.json`
- The paths being opened are already contained in an existing workspace
### IPC transport abstraction
- Introduces a `CliResponseSink` trait in the `cli` crate that abstracts
`IpcSender<CliResponse>`, with an implementation for the real IPC
sender.
- Replaces `IpcSender<CliResponse>` with `Box<dyn CliResponseSink>` /
`&dyn CliResponseSink` across all signatures in `open_listener.rs`:
`OpenRequestKind::CliConnection`, `handle_cli_connection`,
`maybe_prompt_open_behavior`, `open_workspaces`, `open_local_workspace`.
- Extracts the inline CLI response loop from `main.rs` into a testable
`cli::run_cli_response_loop` function.
- Switches the request channel from bounded `mpsc::channel(16)` to
`mpsc::unbounded()`, eliminating `smol::block_on` in the bridge thread.
### End-to-end tests
Seven new tests exercise both the CLI-side response loop and the
Zed-side
handler connected through in-memory channels, using `allow_parking()` so
the
real `cli::run_cli_response_loop` runs on an OS thread while the GPUI
executor
drives the Zed handler:
- No flags, no windows → no prompt, opens new window
- No flags, existing windows, user picks "existing window" → prompt,
setting persisted
- No flags, existing windows, user picks "new window" → prompt, setting
persisted
- Setting already configured → no prompt
- Paths already in existing workspace → no prompt
- Explicit `-e` flag → no prompt
- Explicit `-n` flag → no prompt
Existing tests that previously used `ipc::channel()` now use a
`DiscardResponseSink`, removing OS-level IPC from all tests.
Release Notes:
- Added a first-run prompt when using `zed <path>` to choose between
opening
in an existing window or a new window. The choice is saved to settings
and
can be changed later via the `cli_default_open_behavior` setting.
---------
Co-authored-by: Nathan Sobo <nathan@zed.dev>
_(Feature Requests #24962)_
_"Before you mark this PR as ready for review, make sure that you
have:"_
* [x] Added a solid test coverage and/or screenshots from doing manual
testing
* [x] Done a self-review taking into account security and performance
aspects
* [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- Added a `sort_order` to `project_panel` settings which dictates how
files and directories are sorted relative to each other in a
`sort_mode`.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
After chat functionality was removed, this panel became redundant. It
only displayed three notification types: incoming contact requests,
accepted contact requests, and channel invitations.
This PR moves those notifications into the collab experience by adding
toast popups and a badge count to the collab panel. It also removes the
notification-panel-specific settings, documentation, and Vim command.
Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- Removed the notification panel from Zed
Implements basic focus-follows-mouse behavior.
Right now, it's only applied in the `workspace` crate for `Pane`s, so
anything that lives outside of that container (panels and such for the
most part) won't have this behavior applied. The core logic is
implemented as an extension trait, and should be trivial to apply to
other elements as it makes sense.
https://github.com/user-attachments/assets/d338fa30-7f9c-439f-8b50-1720e3f509b1Closes#8167
Release Notes:
- Added "Focus Follows Mouse" for editor and terminal panes
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
## Context
This PR introduces a `base` field for settings profiles to allow
profiles to either overlay `user` settings or to overlay `default`,
which is simply zed's defaults (user settings are skipped). I'm not
entirely sure I love `default` because it's a bit confusing (there's a
setting called `default` but the default is `user`). Another idea I had
was `factory` (`user` (default) or `factory`) - curious to hear from the
reviewers. This will be useful for those of us who need to quickly flip
to a default state, or a default state with some customizations on top.
Additionally, from what I can tell, VS Code's profile system is more in
line with what this PR is offering in Zed - profiles overlay the default
settings, not the user's customization layer. So this will be familiar
for those users.
I've had no issue with the migrator, code is pretty simple there, but
would love for @smitbarmase to review the migration to make sure I'm not
missing something.
## Self-Review Checklist
<!-- Check before requesting review: -->
- [X] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [ ] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [X] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Improved the flexibility of settings profiles by offering a way for
profiles to lay atop of zed defaults, skipping user settings all
together. Settings Profiles now take the following form.
```json5
"Your Profile": {
"base": "user" // or "default"
"settings": {
// ...
},
},
```
### Summary
This PR starts work on adding basic hook support in the `TaskStore`. To
enable users to setup tasks that are ran when the agent panel creates a
new git worktree to start a thread in. It also adds a new task variable
called `ZED_MAIN_GIT_WORKTREE` that's the absolute path to the main repo
that the newly created linked worktree is based off of.
### Follow Ups
- Get this hook working with the git worktree picker as well
- Make a more general approach to the hook system in `TaskStore`
- Add `ZED_PORT_{1..10}` task variables
- Migrate the task context creation code from `task_ui` to the basic
context provider
Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A *or* Added/Fixed/Improved ...
---------
Co-authored-by: Remco Smits <djsmits12@gmail.com>
Co-authored-by: Richard Feldman <oss@rtfeldman.com>
🫡
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Removed legacy Text Threads feature to help streamline the new agentic
workflows in Zed. Thanks to all of you who were enthusiastic Text Thread
users over the years ❤️!
---------
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Release Notes:
- The git diff diff view now automatically switches from split mode to
unified mode when the pane is narrower than a configurable minimum
column count. You can configure this via the new
`minimum_split_diff_width` setting.
Use `AgentSettings::get_layout(cx)` to retrieve the current, exact value of the user's layout settings, and `AgentSettings::set_layout(WindowLayout::agent())` or `AgentSettings::set_layout(cached_user_settings)` to write to them.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- N/A
## Context
`update_settings_file` deletes unrelated settings when the settings file
contains deprecated keys that need migration. For example, changing the
model from the Agent Panel overwrites the entire `agent` block instead
of just updating `default_model`.
The root cause is that `edits_for_update` used
`parse_json_with_comments` (strict parser), which returns `Err` on
deprecated/unknown fields. The error is swallowed by `log_err()`,
falling back to `Default::default()` (empty settings). The diff then
sees everything as new and replaces the entire block.
The fix switches to `parse_json` (the fallible/lenient parser), which
returns `Some(parsed_value)` even when deprecated fields are present -
the same pattern already used by `parse_and_migrate_zed_settings`.
## Fixes#41344
## How to Review
Single-file change in `settings_store.rs`, focus on `edits_for_update` .
Compare with `parse_and_migrate_zed_settings` (line 702) which already
uses the same `parse_json` approach.
## Self-Review Checklist
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
## Video
[Screencast from 2026-03-21
00-36-12.webm](https://github.com/user-attachments/assets/31bd584a-2674-4c91-bdb2-69ed8fa35e88)
### Note : Reopens previous work from closed PR #52081 (fork was
deleted)
Release Notes:
- Fixed settings being overwritten when updating a single setting via UI
while the settings file contains deprecated keys.
This PR adds the ability to change both the terminal and agent panels
between fixed and flexible sizing using the status bar button right
click menu. The value persists in your settings, similar to the dock
position.
I've also slightly tweaked the styling of the "Dock Left" and "Dock
Right" items in the right-click menu, adding the current value as an
item with a check beside it, to make it clear that it's a selectable
option.
Release Notes:
- N/A
The watcher had been broken for some time, but became even more broken
after the recent move of the queries.
This PR restores the reloading behavior for debug builds so that
languages are reloaded once a scheme file is changed.
Release Notes:
- N/A
Context: if the toolbar and tab bar are both disabled, the current
filename is not visible. This adds it to the bottom bar, similar to vim.
Behind a setting, disabled by default
Release Notes:
- N/A or Added/Fixed/Improved ...
This PR adds Git status badges next to file names in the Project Panel,
following my older PR #49802
These are enabled by having "git_status" true.
Screenshot
<img width="343" height="320" alt="image"
src="https://github.com/user-attachments/assets/b2c208bf-5027-4947-a5ee-eeb74fadb02b"
/>
I'd love to hear feedback about any of this :)
Especially feedback on these:
- File name colour is determined only by Git status, the diagnostic
badges remain separate. Should diagnostics also affect the filename
colour?
- (Unstaged) Modified files and staged modifications share the same
colour, in vscode staged modifications use a brownish colour by default
which I could not find the colours. I think differentiating them is
definetely something to add.
Release Notes
- Added git status indicators in Project Panel. It can be enabled by
setting `git_status_indicator` to `true` in `project_panel` settings.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Many editors such as vim and emacs support "modelines", a comment at the
beginning of the file that allows the file type to be explicitly
specified along with per-file specific settings
- The amount of configurations, style and settings mapping cannot be
handled in one go, so this opens up a lot of potential improvements.
- I left out the possiblity to have "zed" specific modelines for now,
but this could be potentially interesting.
- Mapping the mode or filetype to zed language names isn't obvious
either. We may want to make it configurable.
This is my first contribution to zed, be kind. I struggled a bit to find
the right place to add those settings. I use a similar approach as done
with editorconfig (merge_with_editorconfig). There might be better ways.
Closes#4762
Release Notes:
- Add basic emacs/vim modeline support.
Supersedes #41899, changes:
- limit reading to the first and last 1kb
- add documentation
- more variables handled
- add Arc around ModelineSettings to avoid extra cloning
- changed the way mode -> language mapping is done, thanks to
`modeline_aliases` language config
- drop vim ex: support
- made "Local Variables:" handling a separate commit, so we can drop it
easily
- various code style improvements
---------
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
## Context
This PR builds on https://github.com/zed-industries/zed/pull/52047,
adding support for the new behavior to the keymap editor. The primary
change is replacing usages of `NoAction` with `Unbind` when updating the
users keymap, i.e. deleting/editing default bindings.
This PR does not completely solve the UI challenge of `Unbind`. For now,
we just don't show Unbind entries in the UI, and mark unbound
keybindings as unbound (shown in screenshot).
<img width="3854" height="2230" alt="Screenshot 2026-03-23 at 11 49
42 AM"
src="https://github.com/user-attachments/assets/843856c6-2c94-47c1-be44-21becfdf467e"
/>
## How to Review
- Check behavior changes in keymap updates
- Check UI changes and filters in keymap editor
<!-- Help reviewers focus their attention:
- For small PRs: note what to focus on (e.g., "error handling in
foo.rs")
- For large PRs (>400 LOC): provide a guided tour — numbered list of
files/commits to read in order. (The `large-pr` label is applied
automatically.)
- See the review process guidelines for comment conventions -->
## Self-Review Checklist
<!-- Check before requesting review: -->
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A or Added/Fixed/Improved ...
This PR adjusts the default panel layout for anyone on the agent v2
feature flag.
Note that this changes the right status bar items to show in reverse
priority order, and then adjusts priorities so that the "project
management" buttons appear to the right, and the outline panel appears
to the far left. The reversal "cancels out" most of the priority
changes, except the outline panel and the collab panel.
## Self-Review Checklist
<!-- Check before requesting review: -->
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Swapped the order of the collab and outline status bar buttons
## Context
This PR adds an `Unbind` action, as well as syntax sugar in the keymaps
for declaring it
```
{
"unbind": {
"tab: "editor::AcceptEditPrediction"
}
}
```
Is equivalent to
```
{
"bindings": {
"tab: ["zed::Unbind", "editor::AcceptEditPrediction"]
}
}
```
In the keymap, unbind is always parsed first, so that you can unbind and
rebind something in the same block.
The semantics of `Unbind` differ from `NoAction` in that `NoAction` is
treated _as an action_, `Unbind` is treated as a filter. In practice
this means that when resolving bindings, we stop searching when we hit a
`NoAction` (because we found a matching binding), but we keep looking
when we hit an `Unbind` and filter out keystroke:action pairs that match
previous unbindings. In essence `Unbind` is only an action so that it
fits cleanly in the existing logic. It is really just a storage of
deleted bindings.
The plan is to rework the edit predictions key bindings on top of this,
as well as use `Unbind` rather than `NoAction` in the keymap UI. Both
will be done in follow up PRs.
Additionally, in this initial implementation unbound actions are matched
by name only. The assumption is that actions with arguments are bound to
different keys in general. However, the current syntax allows providing
arguments to the unbound actions. Both so that copy-paste works, and so
that in the future if this functionality is added, keymaps will not
break.
## How to Review
- The dispatch logic in GPUI
- The parsing logic in `keymap_file.rs`
## Self-Review Checklist
<!-- Check before requesting review: -->
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Added support for unbinding key bindings from the default keymaps. You
can now remove default bindings you don't want, without having to
re-declare default bindings that use the same keys. For instance, to
unbind `tab` from `editor::AcceptEditPrediction`, you can put the
following in your `keymap.json`
```
[
{
"context": "Editor && edit_prediction",
"unbind": {
"tab": "editor::AcceptEditPrediction"
}
}
]
```
Closes #ISSUE
Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing
- [ ] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A *or* Added/Fixed/Improved ...
## Summary
Fixes#48725
When using the keymap editor to delete or re-bind default keybindings,
two issues caused stale entries to persist:
- **Deleting a default binding** created a `NoAction` suppression entry
in `keymap.json` (correct for GPUI-level suppression), but the keymap
editor displayed it as a phantom `<null>` row alongside the greyed-out
default. Searching by keystroke showed both entries, and clash detection
counted the phantom as a real binding.
- **Changing a default binding's keystroke** (e.g. `⌥⌘T` → `⇧⌃⌘T`) added
the new binding but never suppressed the original default under the old
keystroke. The old default continued appearing in keystroke searches and
clash warnings.
## Fix
1. **Filter `NoAction` suppression bindings from the keymap editor
display.** These remain in the internal binding list for conflict
detection (so overridden defaults are still correctly greyed out), but
are excluded from the visible match results.
2. **Append a `null` suppression for the old keystroke when replacing a
non-user binding with a different keystroke.** When `update_keybinding`
converts a `Replace` to `Add` for a non-user binding and the keystroke
changes, it now also writes `{"old-keystroke": null}` (with the original
context) to suppress the stale default.
## Reproduction steps (verified fixed)
1. Open the keymap editor
2. Click Search by Keystroke and press `⌥⌘T`
3. You should see "agent: new thread" and "pane: close other items"
(both Default)
4. Right-click "agent: new thread" and choose Delete
5. Double-click "pane: close other items", change keystroke to `⇧⌃⌘T`,
click Save
6. Verify no `<null>` phantom row appears, and no stale defaults remain
under `⌥⌘T`
7. Close and reopen the keymap editor, search `⌥⌘T` — no results
8. Search for "editor: wrap selections in tag" and assign `⌥⌘T` — no
clash warnings
## Test plan
- [x] Existing `keymap_update` and `test_keymap_remove` tests pass
- [x] Added test: replacing a non-user binding **without** changing the
keystroke produces no suppression
- [x] Added test: replacing a non-user binding **with** context and
keystroke change produces a suppression that preserves the context
- [x] Manual verification of all reproduction steps above
Release Notes:
- Fixed an issue with the keymap editor where where the defaults would not be completely removed when deleting or overriding default keybindings
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
## Summary
- Implements `icon_label` on `GitPanel` to return the total count of
uncommitted changes (`new_count + changes_count`) when non-zero, capped
at `"99+"` for large repos.
- Updates `PanelButtons::render()` to render that label as a small green
badge overlaid on the panel's sidebar icon, using absolute positioning
within a `div().relative()` wrapper.
- The badge uses `version_control_added` theme color and
`LabelSize::XSmall` text with `LineHeightStyle::UiLabel` for accurate
vertical centering, positioned at the top-right corner of the icon
button.
The `icon_label` method already existed on the `Panel`/`PanelHandle`
traits with a default `None` impl, and was already implemented by
`NotificationPanel` (unread notification count) and `TerminalPanel`
(open terminal count) — but was never rendered. This wires it up for all
three panels at once.
## Notes
- Badge is positioned with non-negative offsets (`top(0)`, `right(0)`)
to stay within the parent container's bounds. The status bar's
`render_left_tools()` uses `.overflow_x_hidden()`, which in GPUI clips
both axes (the `overflow_mask` returns a full content mask whenever any
axis is non-`Visible`), so negative offsets would be clipped.
- `LineHeightStyle::UiLabel` collapses line height to `relative(1.)` so
flex centering aligns the visual glyph rather than a
taller-than-necessary line box.
- No new data tracking logic — `GitPanel` already maintains `new_count`
and `changes_count` reactively.
- No feature flag or settings added per YAGNI.
## Suggested .rules additions
The following pattern came up repeatedly and would prevent future
sessions from hitting the same issue:
```
## GPUI overflow clipping
`overflow_x_hidden()` (and any single-axis overflow setter) clips **both** axes in GPUI.
The `overflow_mask()` implementation in `style.rs` returns a full `ContentMask` (bounding box)
whenever any axis is non-`Visible`. Absolute-positioned children that extend outside the element
bounds will be clipped even if only the X axis is set to Hidden.
Avoid negative `top`/`right`/`bottom`/`left` offsets on absolute children of containers
that have any overflow hidden — keep badge/overlay elements within the parent's bounds instead.
```
Release Notes:
- Added a numeric badge to the git panel sidebar icon showing the count
of uncommitted changes.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
This PR introduces the `project_panel.scrollbar.horizontal_scroll`
setting to allow users to toggle the horizontal scroll bar in the
project panel. This was Zed's design before PR #18513, and the default
behavior of VSCode (`workbench.list.horizontalScrolling`).
https://github.com/user-attachments/assets/f633f4e4-a585-4494-8f48-df77c6aca418
## Rationale
Zed's design used to be the same as the default behavior of VSCode.
I.e., no horizontal scrolling, and the view is always snapped to the
left, with long file names clipped of. If you want to see the content
that is out-of-frame, you'll need to drag the handle and expand the
project panel. This could be problematic, especially for large repos
with multiple levels of nested directories, as pointed out by issues
#5550 and #7001.
<img width="1398" height="992" alt="image"
src="https://github.com/user-attachments/assets/d86563f2-0f06-4e9e-818c-155ac45f0f56"
/>\
*VSCode's default setup, for reference.*
Then came PR #18513, which added horizontal scroll and addressed this
pain point, but users didn't have a choice. They're stuck with
horizontal scrolling always turned on. I, for instance, personally
prefer the old, VSCode-default behavior, for most projects I open are
small and don't need horizontal scrolling in the project panel. With
horizontal scrolling always turned on, I find it annoying to have my
project panel view accidentally scrolled to the middle, and I'll have to
grab my mouse and scroll it back. It's also visually redundant.
Thus, why not add an option like VSCode's
`workbench.list.horizontalScrolling` and let users choose? I'd love to
be able to, say, set a per-project override for the projects that need
horizontal scrolling, while having it disabled by default.
## Extra Notes
- I was originally thinking about using `ScrollbarAxes` from
`src/editor_settings.rs` and make the option
`project_panel.scrollbar.axes.horizontal` similar to the global editor
scrollbar settings, but this option is specific to the project panel and
it doesn't quite make sense to allow disabling vertical scrolling on the
project panel, so I added a standalone option for it instead, similar to
VSCode's `workbench.list.horizontalScrolling`.
- I went the conservative route and set horizontal scrolling to enabled
(current behavior) by default. Imo it might make more sense to disable
it by default instead, similar to VSCode, but I'll leave this for the
Zed team to decide.
- I named it `horizontal_scroll` instead of `horizontal_scrolling` to be
consistent with the adjacent setting `sticky_scroll`.
- As for tests, I don't see tests for the scrollbar, so I didn't add
any.
I'd be glad to update the PR if anything is not inline with the
project's requirements or conventions.
---
Release Notes:
- Added `project_panel.scrollbar.horizontal_scroll` setting to allow
toggling horizontal scrolling in the project panel
Signed-off-by: k4yt3x <i@k4yt3x.com>
Closes#47550
Changes the `auto_indent` setting from a boolean to an enum with three
modes:
- **`full`** (default): Adjusts indentation based on syntax context when
typing (previous `true` behavior)
- **`preserve_indent`**: Preserves the current line's indentation on new
lines, but doesn't adjust based on syntax
- **`none`**: No automatic indentation - new lines start at column 0
(previous `false` behavior)
This gives users more control over indentation behavior. Previously,
setting `auto_indent: false` would still preserve indentation on new
lines, which was unexpected.
Includes:
- Settings migration from boolean to enum values
- Settings UI dropdown renderer
Release Notes:
- Changed `auto_indent` setting from boolean to enum with `full`,
`preserve_indent`, and `none` options
<img width="1373" height="802" alt="Screenshot 2026-01-27 at 16 32 10"
src="https://github.com/user-attachments/assets/b629e1d8-7359-4853-8222-abfa71d6ebe2"
/>
---------
Co-authored-by: MrSubidubi <finn@zed.dev>
Discussed in #6668 specifically this comment from @zackangelo:
> The biggest thing keeping me from using Zed as a daily driver is error
indication in the project panel. When I'm making big project-wide
changes I can't clearly see which files have errors (in editors like
VSCode the filenames turn red).
> VSCode seems to use a letter on the right gutter to indicate git
status and a number next to it to indicate diagnostic status. The color
indicates either.
This PR implements that, I added an opt-in `diagnostic_badges` setting
(default is false) that shows error and warning counts as colored labels
on the right side of each project panel entry. Counts bubble up to
parent directories.
When `diagnostic_badges` is enabled, diagnostic severity takes priority
over git status for entry text color.
Since warnings and git-modified share the same yellow, git status with
this option on is readable through the file icon decoration and the
absence of a number badge on the right.
Example:
<img width="522" height="785" alt="image"
src="https://github.com/user-attachments/assets/2da62580-86fe-480b-9b57-ff137ea42285"
/>
<img width="884" height="580" alt="image"
src="https://github.com/user-attachments/assets/198e9a45-dacd-4f1e-a66c-f2b84fd4db63"
/>
Release Notes:
- Added diagnostic count badges to the project panel, displaying error
and warning counts next to file names. You can modify this setting using
the `diagnostic_badges` option, which is enabled by default.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>