Closes AI-267
This PR adds a skills subpage in the settings UI, where we display
global skills in the user tab and project skills in the corresponding
project tab. The approach taken here was the simplest one out of the
possible avenues we could've taken to implement this (which would
possibly require bigger refactors), given this is potentially the very
first page in the settings UI where we're displaying stuff that does not
correspond to data available in the `settings.json`.
Important to note that a major limitation of the global approach is that
it's dependent on the native agent having loaded the skill index,
meaning there's an edge case where, if you open the settings UI _before_
having opened the agent panel, you won't immediately see the available
skills. Something to discuss but that it felt like a viable option for a
first ship.
Release Notes:
- Agent: Added a skills section to the settings UI.
Closes TRA-150
This PR makes the restricted mode more obvious by:
- Immediately opening the restricted mode modal upon opening an
untrusted project
- Disabling dismissing the modal on escape or click away to force
choosing one of the two options (and avoid accidentally staying in
restricted mode by simply dismissing it)
- Showing the LSP button but with communication about language servers
being disabled for untrusted projects
- Showing a banner in the project settings with the same communication
The motivation for this change was that we tried to be minimal with how
we communicate a project is untrusted, but it was so minimal that people
were confused as to why language servers and other settings weren't
working. It was easy to miss the title bar button, for some reason. The
changes in this PR makes it so acting on this decision (trust or not a
project) is mandatory in order to even start to interact with the
project. I appreciate changes here are more aggressive, but I think it's
better to make you think about this decision vs. letting you be confused
as to why you don't see LS completions or formatting.
Release Notes:
- Made restricted mode more obvious, demanding immediate action when
opening an untrusted project.
Settings search treated multi-word queries as OR, so “tab size” matched
any document whose words contained a prefix of “tab” or “size” --
flooding results with unrelated entries like “Show Tab Bar” and “Maximum
Tabs”.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] 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)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable
Closes#56244.
Release Notes:
- Fixed settings UI search returning unrelated results for multi-word
queries
With long lines or a small viewport, the stage/restore buttons often
cover code.
Adds a setting to hide the buttons altogether. Defaults to showing them.
Release Notes:
- Added: Setting to hide Git Stage/Restore buttons
Treat `.agents/skills/` (project-local) and `~/.agents/skills/` (global)
as **sensitive paths**, on par with `.zed/` and the global config
directory. The agent's built-in editing tools (`edit_file`,
`write_file`, `create_directory`, `delete_path`, `move_path`,
`copy_path`) now require explicit user authorization before modifying
anything inside those paths, because the contents of skill files control
agent behavior.
This protection is worth landing on its own, ahead of Zed adding its own
skills support: other agents (e.g. Claude Code) already write skill
files into these locations, so a Zed installation may already have
skills on disk that should not be silently editable by the agent.
Also tightens the **pre-existing `.zed/` check** to compare path
components case-insensitively. macOS and Windows use case-insensitive
filesystems by default, so without this fix a malicious settings author
could bypass the local-settings classifier with `.ZED/settings.json`
(the canonicalized inode would match, but the path-component comparison
would miss it). The new `.agents/skills/` check has the same hazard and
now shares a single `component_matches_ignore_ascii_case` helper with
the `.zed/` check.
Introduces the `agent_skills` crate, scoped for now to just the path
constants and helpers (`global_skills_dir`,
`project_skills_relative_path`, `SKILL_FILE_NAME`) so the
tool-permission machinery can recognize the agent skills tree without
depending on a skill discovery / parsing / loading layer. Those will
land in follow-up PRs.
Closes AI-217
Release Notes:
- Agent: Require user confirmation before letting tools modify files
inside `.agents/skills/` (per-project) or `~/.agents/skills/` (global),
so skills installed by any agent are protected from unsolicited edits
---------
Co-authored-by: MartinYe1234 <52641447+MartinYe1234@users.noreply.github.com>
Co-authored-by: Martin Ye <martinye022@gmail.com>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Streamline the instructions around communication, tool use, planning,
and project roots.
Remove the `now` tool and also clean up several tool descriptions.
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
---------
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
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
Closes https://github.com/zed-industries/zed/issues/52585
Release Notes:
- Fixed local zeta2 edit predictions using the wrong prompt format.
Before:
1. Agent tries to edit unsaved file
2. Tool call fails with error telling the agent to ask the user to save
or discard edits
3. User types save/restore
4. Agent uses save/restore tool
https://github.com/user-attachments/assets/c94dd361-e8e0-48ee-be31-da8afe594419
After:
1. Agent tries to edit unsaved file
2. User is prompted to save/restore file
3. User accepts/rejects or saves/discards file manually
https://github.com/user-attachments/assets/1d98a0c4-4420-4426-94f2-42355de230be
Release Notes:
- agent: Improved UX when agent tries to edit unsaved buffer
---------
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
`render_settings_item_link` was calling `cx.read_from_clipboard()`
during render so it could show a check icon next to the copy-link button
when the matching link was on the clipboard. This had two problems:
- A clipboard read per visible setting per frame is too expensive.
- On Windows, reading the clipboard pumps the system message queue. If a
queued message handler updates `App` while we're still rendering, GPUI
panics with `RefCell already borrowed` (many occurrences observed).
Track the `json_path` of the most recently copied setting locally
instead. The check icon now reflects what was copied in this session via
this UI rather than whatever is on the system clipboard.
While this removes the most common offender, the underlying
`gpui_windows` reentrancy bug still exists: `on_close` /
`on_request_frame` callbacks can be invoked while `App` is already
borrowed on Windows, and can be triggered by any other
clipboard-touching code path. We should consider a follow-up PR that
handles this at the platform layer -- either by deferring callbacks that
re-borrow `App`, or by guarding individual handlers in
`gpui_windows::events` against reentrant `borrow_mut` calls.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Fixed a crash on Windows that could occur when closing the settings
window
- Improved the overall performance of the settings window
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:
- Added a setting
[vim.show_edit_predictions_in_normal_mode](zed://settings/vim.show_edit_predictions_in_normal_mode)
to control whether edit predictions are shown in normal mode.
Splits the edit tool into two separate tools `write_file` (previously
`mode = write`), and `edit_file` (previously `mode = edit`).
This makes the JSON schema for the `edit_tool` much simpler. We've seen
models (especially older ones) struggle with providing `mode = edit +
edits` and `mode = write + content` fields. This seems to improve eval
scores for Sonnet 4.6 slightly.
Also added two unit evals to ensure that the model uses the tool to
create new/override existing files
Release Notes:
- N/A
---------
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
Adds 4 (technically 5) new tools to the zed agent, corresponding to LSP
actions:
- `find_references`
- `goto_definition`
- `rename_symbol`
- `get_code_actions` and `apply_code_actions`
Notes:
- `rename_symbol` skips doing a `prepare_rename`. If there is nothing to
rename at the position, it will forward the error to the agent
- The code action tools are stateful. The state is stored in the
`get_code_actions` tool itself as a `PendingCodeActions`. It is not
passed into/out of subagents. Calling `apply_code_actions` without
calling `get_code_actions` first is an error, but I've never seen an
agent do this
Symbols are identified by:
- file name
- line number
- symbol
If there is no substring match on that line for the symbol text, it is
an error. If there are multiple, it chooses the first. This may not be
great if you have a line like: `fn convert(x: foo::Something) ->
bar::Something` - the second `Something` is a different symbol, but is
inacessible to these tools. Probably fine for now, but we can look into
improving
Release Notes:
- Added: New tools for the Zed Agent for interacting with language
servers
---------
Co-authored-by: Lukas Wirth <me@lukaswirth.dev>
Settings navbar root entries can now be expanded or collapsed by
double-clicking the row itself.
Single-click navigation is preserved, so clicking a root entry still
opens the selected Settings page. The double-click handler only toggles
on `click_count() == 2`, so triple-clicking the row does not toggle it
again.
The double-click path reuses the same toggle-and-focus behavior as the
disclosure chevron.
Testing:
- `cargo fmt --check --package settings_ui`
- `cargo check -p settings_ui`
- `cargo test -p settings_ui`
- Manually verified that:
- single-clicking a Settings navbar root entry still opens the selected
Settings page
- double-clicking a Settings navbar root entry expands or collapses it
- triple-clicking the row does not toggle the entry again
- clicking the disclosure chevron still expands or collapses the entry
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:
- Improved Settings navigation by allowing root navbar entries to expand
or collapse on double-click.
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
This is following up from #39609 to add the line endings button setting
into settings ui.
Release Notes:
- Added the line endings button setting to settings ui.
cc: @danilo-leal
This setting is from when we had the git worktree picker in the agent
panel, now that it is in the menu bar it doesn't make sense to keep it.
We plan to add a similar feature in the future to handle the "new thread
== new git worktree" workflow
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
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#54646
Release Notes:
- Fixed settings behavior where switching Icon Theme from "Dynamic"
(System mode) to "Static" now selects the icon theme that matches the
current OS appearance (light or dark), instead of always defaulting to
the dark variant.
---------
Co-authored-by: Marshall Bowers <git@maxdeviant.com>
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`.
No, sadly, the title is not a typo. See
https://www.githubstatus.com/incidents/zsg1lk7w13cf for the context.
I'll read with joy and popcorn through that root cause analysis.
It makes literally zero sense what happened here, but for some completly
bonkers reason GitHub completely messed up the merge queue with
https://github.com/zed-industries/zed/pull/54632.
I have no idea how it happened. It makes literally zero sense. A PR
going into the merge queue should have the same LoC when getting out of
it. GitHub obviously does not check this. GitHub causes extra work with
a feature that is supposed to save time.
Thanks, I guess.
Release Notes:
- N/A
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.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
This PR brings back the button to filter remote branches when accessing
the title bar's branch picker with the mouse. It was unintentionally
removed when we introduced the new worktree picker.
Release Notes:
- N/A
Closes#48394
Moves the data collection preference for Zed's Edit Predictions out of
the internal KV store and into `settings.json` as a proper
`allow_data_collection` setting under `edit_predictions`.
**Migration:** Existing users' choices are preserved. When
`allow_data_collection` is absent from `settings.json`, the resolved
value falls back to the legacy KV entry
(`zed_predict_data_collection_choice`). Once the user toggles the
setting or sets it explicitly, the new setting takes precedence and the
KV entry is ignored.
**Bug fixed:** The original implementation of `toggle_data_collection`
read the raw (unresolved) settings content to determine the current
state. When `allow_data_collection` was absent from `settings.json` but
the KV store held `"true"`, the raw read returned `None → false`,
causing the first toggle click to write `Some(true)` (re-enabling)
instead of `Some(false)` (disabling). The fix reads the resolved
`is_data_collection_enabled()` value before entering the
`update_settings_file` closure.
## Manual testing
**Setting takes effect:**
1. Open settings (`cmd+,`) and add `"allow_data_collection": true` under
`edit_predictions`. Save.
2. Open a file — the data collection indicator in the editor should
reflect the enabled state.
3. Flip to `false` and confirm it updates.
**Toggle correctly disables from KV-enabled state (migration bug fix):**
1. Remove `allow_data_collection` from `settings.json`.
2. Write the legacy KV entry directly:
```
sqlite3 ~/Library/Application\ Support/Zed/db/0-dev/db.sqlite \
"INSERT OR REPLACE INTO kv_store(key,value)
VALUES('zed_predict_data_collection_choice','true');"
```
3. Restart Zed. The data collection toggle should show as **enabled**
(reading from KV store).
4. Click the toggle once to disable. `allow_data_collection` should
appear as `false` in `settings.json` — not `true`, which was the pre-fix
behaviour.
**Upsell modal still appears for new users:**
1. Clear both KV keys and restart:
```
sqlite3 ~/Library/Application\ Support/Zed/db/0-dev/db.sqlite \
"DELETE FROM kv_store WHERE key IN
('zed_predict_data_collection_choice','dismissed-edit-predict-upsell');"
```
2. Open any file so the status bar is visible.
3. Click the edit prediction button (bottom-right status bar) — it
should have a muted dot indicator.
4. The upsell modal should appear. Dismissing it should prevent it from
reappearing.
## Release Notes:
- `allow_data_collection` for Zed's Edit Predictions can now be set
explicitly in `settings.json` under `edit_predictions`. Existing
preferences stored in the internal database are preserved as a fallback.
---------
Co-authored-by: Ben Kunkle <ben.kunkle@gmail.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
Closes#54607
Release Notes:
- Settings UI theme conversion now respects system appearance.
When switching Theme Mode from Dynamic (System) to Static, Zed now picks
the static theme that matches the current OS app appearance (light or
dark) instead of always defaulting to the dark variant.
---------
Co-authored-by: Lukas Wirth <lukas@zed.dev>
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.
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:
- N/A
Follow up to https://github.com/zed-industries/zed/pull/52730.
This PR adds a boolean setting `limit_content_width` in the Agent Panel
settings that allows turning off the content max-width entirely, which
was added for better readability. We had a handful of requests for it,
so it feels fair.
<img width="500" alt="Screenshot 2026-04-20 at 8 57@2x"
src="https://github.com/user-attachments/assets/d2540b35-3fa8-4424-895d-dc499ac4839c"
/>
Release Notes:
- Agent: Added a new `limit_content_width` setting in the agent panel
that allows turning off the content max-width limit.
This PR makes Zed only have one worktree picker, as opposed to a flavor
of it in the title bar and another in the agent panel. It then moves it
to the title bar, making it always present, so that its trigger is
separate from the branch picker (which now contains only two views:
branches and stashes). For the worktree picker, I'm mostly favoring the
behavior we've introduced in the agent-panel-flavored version.
It also updates the title bar settings migration to use the JSON
`migrate_settings` helper instead of a shallow Tree-sitter rewrite, so
old `show_branch_icon = true` values are promoted to
`show_branch_status_icon = true` across root, platform, release-channel,
and profile settings scopes.
- [x] Move worktree creation logic to the `git_ui` crate to make this
more generic and less agent-specific
- [x] Double-check the remote use case and ensure nothing broke there
- [x] Improve the UX for the detached HEAD state; better invite people
to create a branch
- [x] Migrate `show_branch_icon = true` to `show_branch_status_icon =
true` across nested settings scopes
Suggested .rules additions
When migrating renamed settings keys that can appear in platform
overrides, release-channel overrides, or profiles, prefer the JSON
`migrations::migrate_settings` helper over shallow Tree-sitter key
rewrites unless tests explicitly cover every nested scope that can
contain the key.
Release Notes:
- Improved migration of the title bar branch status icon setting.
---------
Co-authored-by: Nathan Sobo <nathan@zed.dev>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
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>
When adding code lens to the long list of search items, I've failed to
find it when searching, as we always select first item in the matches
list, which is not necessarily the best one.
Left is before, right is after:
https://github.com/user-attachments/assets/9033dfd8-abde-4a45-a214-ae859105d6ad
Release Notes:
- Improved settings search ergonomics
The `cli_default_open_behavior` setting controls how `zed <path>` opens
directories, but the underlying behavior is gated behind the
`AgentV2FeatureFlag` in `open_listener.rs`. Without the flag enabled,
the setting has no effect — Zed always falls back to `NewWindow`
behavior.
This change gates the settings UI entry behind the same feature flag so
it only appears when the feature is actually active.
**Changes:**
- Converted `general_settings_section()` from a fixed-size array to a
`Vec` so the CLI setting can be conditionally appended
- Added `feature_flags` as a dependency to `settings_ui`
Release Notes:
- N/A
This fixes a regression where `zed -n .` in a subdirectory of an
already-open
project would redirect to the parent window instead of creating a new
one.
The root cause was that commit 66d2cb20c9 ("Adjust `zed -n` behavior")
made
`-n` run the worktree matching loop with subdirectory matching enabled,
when
previously `-n` skipped matching entirely.
## Changes
### Bug fix
- **Restore `-n` to always create a new window.** No worktree matching,
no
exceptions. This matches the behavior from when `-n` was first
introduced.
### New `--classic` flag
- Adds a hidden `--classic` CLI flag that explicitly selects the
pre-sidebar
default behavior: new window for directories, reuse existing window for
files already in an open worktree.
- The `cli_default_open_behavior` setting now toggles between `-e` (add
to
sidebar) and `--classic` behavior. When set to `new_window`, the classic
logic is used instead of unconditionally opening a new window.
### Refactor CLI open options
Replaces the old grab-bag of `open_new_workspace: Option<bool>`,
`force_existing_window: bool`, `classic: bool`, and `reuse: bool` with:
- **`cli::CliOpenBehavior` enum** — a single enum on the IPC boundary
with
variants `Default`, `AlwaysNew`, `Add`, `ExistingWindow`, `Classic`, and
`Reuse`.
- **`workspace::WorkspaceMatching` enum** — describes how to match paths
against existing worktrees (`None`, `MatchExact`, `MatchSubdirectory`).
- **`workspace::OpenOptions`** — uses `WorkspaceMatching` plus a simple
`add_dirs_to_sidebar: bool` instead of overlapping boolean flags.
The translation from CLI enum to workspace options happens in
`open_listener.rs`, keeping both layers clean and independent.
Release Notes:
- N/A
Based on a partial revert of: 7bcdb12b4c
The main difference is instead of a feature flag we now check
`ReleaseChannel::Stable` != current_release_channel when the UI checks
if agent v2 (sidebar) features should be enabled.
Self-Review Checklist:
- [ ] I've reviewed my own diff for quality, security, and reliability
- [ ] 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)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- N/A or Added/Fixed/Improved ...
---------
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
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>
Self-Review Checklist:
- [ ] 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
_(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>
The "Hover Popover → Delay" setting item had its json_path set to
"hover_popover_enabled" (copy-paste error from the item above it),
introduced in #40739. This caused:
- "Copy Link" generating a wrong zed://settings/hover_popover_enabled
URL
- #hover_popover_delay filter returning no results in settings search
- Telemetry reporting delay changes as hover_popover_enabled
The pick/write closures were always correct, so the setting itself
functioned normally.
after the fix, filter works correctly
<img width="1793" height="752" alt="image"
src="https://github.com/user-attachments/assets/b7c459bf-c0d6-4988-ae87-087e859c6666"
/>
and the copy link button return the correct result
<img width="1787" height="120" alt="image"
src="https://github.com/user-attachments/assets/e2184f89-c400-453b-8e7d-f8ef8771e1d6"
/>
Release Notes:
- N/A
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
It's happening.
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