Commit Graph
1847 Commits
Author SHA1 Message Date
Rusty Raven 977458038b Correct wrong default values in the settings reference (#64196)
# Objective

Fixes #56544

The settings reference documents `format_on_save` as defaulting to `on`,
but `assets/settings/default.json` ships `"format_on_save": "off"`. The
reporter in #56544 hit exactly that: a fresh config, a C file, save, and
nothing happens.

The reason the documented default looks right to many people is that Zed
enables it per language for twelve languages (Astro, Dart, EEx, Elixir,
Elm, Go, GraphQL, HEEx, Kotlin, Rust, Starlark, Zig). Save formats a
Rust buffer and not a C one, and neither the reference nor the
reporter's mental model had anywhere to hang that difference.

Checking that one entry made me wonder how many others were stale, so I
compared every `Setting:`/`Default:` pair on the page against the
corresponding path in `default.json`. Six more were wrong.

## Solution

| Setting | Documented | Ships as |
| --- | --- | --- |
| `format_on_save` | `on` | `off` |
| `auto_indent` | `true`, "`boolean` values" | `syntax_aware`, a
three-way enum |
| `diagnostics_max_severity` | `null` | `all` |
| `terminal.cursor_shape` | `null` (defaults to block) | `block` |
| `terminal.alternate_scroll` | `off` | `on` |
| `edit_predictions.disabled_globs` | 7 globs | 10 globs |
| `git.gutter_debounce` | `null` | `0` |

Two of these needed more than a value swap:

`auto_indent` stopped being a boolean when it became `AutoIndentMode`
(`crates/settings_content/src/language.rs:411`), so the options list now
covers `syntax_aware`, `preserve_indent` and `none`, and the description
no longer reads as a yes/no toggle.

`format_on_save` gets a sentence naming the twelve languages, so the
difference between saving a Rust buffer and a C one has somewhere to
hang.

`diagnostics_max_severity` and `terminal.cursor_shape` were
self-contradicting rather than merely stale: each section's own prose
already described the real default while the `Default:` line said
`null`.

## Testing

`cd docs && npx prettier --check src/` passes, as required by
`docs/AGENTS.md`. The change is prose and adds no `{#action}` or `{#kb}`
references, so it does not depend on the action metadata that
`check_docs` generates. The `[\`languages\`](#languages)` link resolves
to the single `## Languages` heading on the same page.

Every value in the table above was read out of
`assets/settings/default.json` on `main`, and I confirmed `default.json`
is authoritative for each by following the resolved-settings path (the
`user_content.<x>.unwrap()` style accessors) rather than trusting the
file alone.

## Notes for review

Found while auditing, deliberately left out of this PR — happy to take
any of them in a follow-up, or here if you would rather:

- Two Rust doc comments carry the same wrong defaults and feed the
settings.json schema tooltips, so the in-editor hover still disagrees
with the site: `crates/settings_content/src/language.rs` says `///
Default: on` for `format_on_save`, and
`crates/settings_content/src/editor.rs` says `/// Default: warning` for
`diagnostics_max_severity` while also saying "Shows all diagnostics if
not specified". Fixing those is a source change rather than a docs one.
- `docs/src/diagnostics.md` and `docs/src/visual-customization.md` still
present `diagnostics_max_severity: null`, and the latter also shows
`cursor_shape: null` for the editor where `default.json` ships `bar`.
Same defect class, different pages and a different presentation
(defaults listings rather than a reference), so I kept this PR to the
reference page.
- The reference's `diagnostics_max_severity` options omit `off`, which
is a live variant (`DiagnosticSeverityContent` in
`crates/settings_content/src/project.rs`). That is a missing option
rather than a wrong default, so it is not in scope here.
- Neither the Format On Save nor the Autosave section mentions that
`"autosave": {"after_delay": {...}}` disables format on save outright
(`crates/workspace/src/pane.rs`), even though `default.json` carries
that warning as a comment.
- The twelve-language list is a maintenance cost: it has to be edited
whenever a language gains or loses a default. `default.json` sets
per-language defaults for `tab_size`, `soft_wrap`, `allow_rewrap`,
`hard_tabs` and others too, and none of them are called out anywhere. A
single general statement about per-language defaults overriding
top-level ones would cover all of them and never go stale. I kept the
explicit list because it is what actually answers #56544, but I will
happily swap it for the general version if you prefer.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- N/A
2026-09-15 03:06:39 +00:00
František GažoandKirill Bulatov f05265c624 outline_panel: Show deleted files inside the file tree (#63570)
# Objective

In a branch diff — or any multi-buffer containing deleted files —
deleted files render as flat "external file" rows above the outline
panel's tree, instead of at the path they used to occupy. They lose all
directory context and appear as a bare list of filenames detached from
the tree, which is confusing precisely when you are trying to review
what a branch changed.

The cause is that `File::project_entry_id` returns `None` for
`DiskState::Deleted`, while the outline panel's tree is keyed end-to-end
by `ProjectEntryId` — depth map, collapse state, children counts. A
deleted buffer therefore falls through to the external-file path in
`update_fs_entries`, even though its `File` still carries a perfectly
good worktree and path.

## Solution

Synthesize the missing entries at the point of classification and let
the existing pipeline run unchanged.

- Entries are synthesized for the deleted file **and** for any ancestor
directories that no longer exist, so a wholly-deleted folder still
appears nested at its old location. An ancestor is only taken from the
worktree if it is a directory; a path that is a file now but was a
directory when the deleted file existed is synthesized too, and sorted
after the file so the nesting pass keeps the directory on its stack.
- Ids come from a per-panel registry that hands them out sequentially
downward from just below `ProjectEntryId::MAX`, keyed by path and kind.
Real ids count up from zero, so the ranges cannot meet; sequential
allocation means two entries can never share an id (the entry maps are
keyed by id alone, so a collision would drop a row); and the registry is
kept across updates, so collapse state on synthesized rows survives.
- Whether a buffer with no worktree entry is a deletion is decided by
its `DiskState`: `Deleted` always, `Present` never, `Historic` by its
own flag, and `New` only when git status reports a deletion or the
excerpt's diff has a base text. The last case is a file deleted in a
commit on the branch: it is absent from disk, the working-tree status
says nothing about it, and `GitStore::display_status` only reflects
branch-diff statuses when `git.diff_base` is `default_branch`. A
deletion has a base version; a path that never existed has none. A
scan-excluded file, which also has no entry, is `Present` and stays an
external row.
- Auto-fold stops where deletion state changes, so a surviving `parent/`
is never struck through together with its deleted child, and
`select_parent` treats a folded row as a valid parent of the folded row
beneath it.
- Auto-reveal resolves a deleted row's ancestors from the panel's own
`fs_entries` rather than re-querying the worktree, and only real
directories are ever passed to `Project::expand_entry` (a synthesized id
would go out as an `ExpandProjectEntry` a remote host rejects). Opening
a deleted row resolves its excerpt from the buffer id, since
`path_for_entry` cannot resolve a synthesized entry.

Deleted rows are struck through by a `line_through` on the row's label
wrapper. `HighlightedLabel` builds its text runs from
`window.text_style()`, so an ancestor's style reaches them even though
`LabelLike`'s own `strikethrough()` does not; nothing outside
`crates/outline_panel` changes. Colour is deliberately left to git
status, matching deleted editor tabs — a committed deletion leaves the
working tree clean, so strikethrough is the only signal in a branch
diff.

## Testing

Thirteen new tests, each asserting the rendered tree through
`display_entries`, which now prints external files and marks deleted
rows:

- deleted file nests under its surviving parent; deleted file inside a
wholly-deleted directory gets synthesized ancestors at the right depth
- a file absent from disk and from git status nests when its excerpt
carries a base text, while a buffer on a path that never existed stays
an external file, unmarked
- a modified, scan-excluded tracked file stays an external file,
unmarked
- same-path file + synthesized directory: nesting and auto-reveal both
pick the directory
- auto-fold stops at the deletion boundary; `select_parent` climbs from
a folded deleted chain to the folded parent above it
- opening a deleted row scrolls the editor to its excerpt
- auto-reveal expands the ancestors of a deleted file and ignores an
external file on a nonexistent path
- buffers with no `File` still become `ExternalFile`
- synthetic ids are distinct per path and kind, and stable

`./script/clippy`, `cargo fmt --all -- --check`, `cargo test -p
outline_panel` (33) are green. Tested manually on macOS against a
fixture branch with a committed file deletion, a wholly-deleted
directory under a surviving empty one, a directory replaced by a
same-path file, an uncommitted deletion, a scan-excluded modified file,
and a modified and an added file.

## Suggested .rules additions

- `GitStore::display_status` only reflects branch-diff statuses when
`git.diff_base` is `default_branch`; the branch diff view can be open
while the setting is `head`. Do not use it to detect committed deletions
— a commit-deleted file's buffer is `DiskState::New`; check the
excerpt's diff for a base text instead.
- Outline panel: a directory with mixed children is marked unfolded
while `fs_entries` is built, so an auto-fold chain only forms through
single-subdirectory links. Tests for folding must use that shape.
- `HighlightedLabel` builds its runs from `window.text_style()` at
render time, so `LabelLike` modifiers such as `strikethrough()` and
`italic()` are no-ops on it; put the style on an ancestor element
instead.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

The same branch diff, which deletes `src/utils/format.rs` (its directory
survives) and the whole of `src/legacy/` (including a nested
`internal/`), alongside a modified and an added file.

| Before | After |
| --- | --- |
| <img
src="https://github.com/user-attachments/assets/bf503759-77a7-4f31-80bb-a85936de0b8a"
width="300"> | <img
src="https://github.com/user-attachments/assets/c558b94b-4ca5-447f-a049-a3ab280c679a"
width="300"> |
| Deleted files sit above the project root as bare filenames, detached
from the tree | Each is nested at its original path, with `legacy/` and
`internal/` synthesized since they no longer exist on disk |

Note that `utils/` renders normally while `legacy/` and `internal/` are
struck through: the marking is per-entry, not applied to every ancestor
on a deleted file's path.

---

Release Notes:

- Fixed deleted files appearing outside the file tree in the outline
panel when viewing a diff

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-09-12 19:03:48 +00:00
Maurício R Duarte d66b5d2050 agent_ui: Enable terminal thread renaming from the Agent Panel (#63660)
## Summary

- Follow up on #63578 by extending the existing
`agent::RenameSelectedThread` action to the active Terminal Thread in
the Agent Panel.
- Preserve the existing Threads Sidebar behavior and default
keybindings.
- Document custom keymap assignment and add focused Agent Panel
regression coverage.

## Testing

- `cargo test -p agent_ui
agent_panel::tests::test_rename_selected_thread_action --lib`
- `cargo test -p sidebar rename_selected_thread --lib`
- `cargo fmt --package agent_ui -- --check`
- `npx prettier --check src/ai/terminal-threads.md`
- Manually tested locally with a custom `AgentPanel > Terminal` keymap
binding.

Release Notes:

- Added support for custom keybindings to rename Terminal Thread titles
from the Agent Panel.

### screenshots
<img width="921" height="205" alt="Screenshot 2026-09-02 at 18 40 31"
src="https://github.com/user-attachments/assets/b1edabfc-35f9-42ef-b368-486003202349"
/>
2026-09-11 01:07:36 +00:00
Katie Geer 797fa3b3d9 Update Zed trial copy for the $5 GPT Luna offer (#63969)
## Summary

Updates Zed trial copy for
[CLO-1373](https://linear.app/zed-industries/issue/CLO-1373/update-zed-to-show-the-dollar5-gpt-luna-trial).

- Show $5 of GPT Luna and unlimited edit predictions across pre-sign-in,
Free-plan, and active-trial onboarding.
- Clarify that the 14 days begin when the trial starts, rather than when
the welcome panel is viewed, and retain no-credit-card messaging.
- Update hosted-model trial descriptions and use "Start Free Trial" for
onboarding and AI configuration trial CTAs.
- Document GPT Luna-only trial hosted-model access and the shared
Zed/Delta $5 trial balance.

This is a copy-only change. Trial eligibility, subscription creation,
trial timing, billing, model-access enforcement, button actions, URLs,
and telemetry are unchanged. Paid, Student, Business, and VIP plan
descriptions are unchanged. This does not implement the offer on the
backend.

## Verification

- Rust formatting and `git diff --check` passed.
- Prettier check passed for the pricing documentation.
- Source checks confirmed the offer wording and unchanged callbacks,
URLs, telemetry, and other plan definitions.
- Katie built and launched Zed with `cargo run -p zed --bin zed`, then
reviewed Component Preview and requested the final CTA wording.
Formatting and diff checks were rerun after that wording adjustment; the
final adjustment has not been rebuilt.
- Confirmed the branch merges cleanly with the latest `main`.

Release Notes:

- Improved trial descriptions to show $5 of GPT Luna and unlimited edit
predictions for 14 days from trial start.
2026-09-09 14:50:23 +00:00
Xiaobo LiuandKirill Bulatov 3d0649186f gpui: Prevent idle sleep during AI response streaming (#53130)
Release Notes:

- Added button tu prevent idle sleep during AI response streaming


**Context / Motivation:**
When an AI agent takes a long time to generate a response, the operating
system might enter an idle sleep (or display sleep) state if there is no
user interaction (mouse or keyboard). This can interrupt the workflow.
This PR aims to prevent the system from sleeping during an active AI
turn by invoking native OS APIs, and provides a UI toggle for users to
control this behavior.

**Key Changes:**

1. **Cross-Platform Idle Sleep Prevention in GPUI (`gpui`, `gpui_*`)**
- Added a new `prevent_idle_sleep` method to the `Platform` trait. It
returns a RAII-based `PreventIdleSleepToken`, which automatically
restores the original sleep policy when dropped.
- **macOS**: Utilizes `NSProcessInfo`'s `beginActivityWithOptions` with
`NSActivityIdleDisplaySleepDisabled`.
- **Windows**: Uses `SetThreadExecutionState` to prevent display and
system sleep, incorporating a reference counter to handle concurrent
requests safely.
- **Linux**: Uses `ashpd` to request `org.freedesktop.portal.Inhibit`
(inhibiting `Idle` and `Suspend` states) via D-Bus.

2. **AI Agent State Integration (`crates/acp_thread`)**
- Introduced idle sleep prevention logic in `AcpThread`: Acquires the
token at the beginning of `run_turn`, and automatically releases it when
the turn completes normally, errors out, or is explicitly canceled by
the user.
- Added comprehensive unit tests to ensure the token is correctly
acquired and released under various cancellation and concurrency
scenarios.

3. **Settings and UI (`crates/agent_settings`, `crates/agent_ui`)**
   - Added `AgentOutputIdleSleepControl` to global state.
- Added a new toggle button (screen icon) to the toolbar at the bottom
of the `ThreadView` (AI conversation panel). Users can hover to view the
tooltip and click to toggle the feature on or off.

<img width="419" height="132" alt="截屏2026-04-04 16 09 08"
src="https://github.com/user-attachments/assets/619da9ff-10f7-46e0-b959-d7c74b16b918"
/>

---------

Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-09-09 13:49:13 +00:00
Rusty Raven 3a904a7722 docs: Describe how preview tabs actually behave (#63875)
# Objective

- Fixes #33819
- The `preview_tabs` documentation says preview tabs "close
automatically when you switch to another file unless you explicitly pin
them". They do not close. Moving to another file leaves the preview tab
open — either still as the preview tab, or converted into a regular one.
Four people ran into this on the issue over the past year.
- The same section then lists the ways to turn a preview tab into a
regular tab, and two of them are missing, including the pinning that the
sentence above uses as its counter-example.

## Solution

Two corrections to the `Preview tabs` section of
`docs/src/reference/all-settings.md`. No behaviour was touched.

**The description.** A pane holds a single `preview_item_id`, so there
is at most one preview tab at a time. What happens to it when you move
to another file depends on the path:

- Opening a not-yet-open file in preview mode from the project panel or
file finder goes through `Pane::open_item`, which calls
`close_current_preview_item` — that really does close the old tab
(`remove_item`) and hands back its index, and the new file is inserted
there.
- Code navigation with the default
`enable_keep_preview_on_code_navigation: false` instead calls
`unpreview_item_if_preview` on the old item *before*
`replace_preview_item_id`, so the previous file stays open as a regular
tab.

A third path, the file finder with the default
`enable_preview_from_file_finder: false`, opens the new file as a
regular tab and leaves the existing preview tab alone entirely.

Rather than spell out every path in a settings description — the
`enable_preview_*` settings immediately below already cover them — the
new wording sticks to what holds in all of them: a pane keeps at most
one preview tab and opening another file in preview mode takes over that
slot, and switching to a file that is already open does not close the
preview tab. That second half is the case the issue actually reports.

**The list.** Two more ways to convert a preview tab into a regular tab:

- Pinning it — `change_tab_pin_state` calls `unpreview_item_if_preview`
on the `Pin` branch.
- `pane::TogglePreviewTab` — the action dedicated to exactly this,
registered whenever preview tabs are enabled.

## Testing

- Built a debug Zed and walked through the steps from the issue on a
scratch project of `a.txt` / `b.txt` / `c.txt`: with `a.txt` open as a
regular tab and `b.txt` opened as a preview tab, clicking back to
`a.txt` leaves the `b.txt` preview tab open, which is what the current
wording says should not happen. Single-clicking `c.txt` takes over the
same slot rather than adding a second preview tab, and pinning the
preview tab drops the italics.
- Ran the docs steps from `run_tests.yml` locally: `zed
--dump-all-actions > crates/docs_preprocessor/actions.json`, then
`mdbook build ./docs` on mdbook 0.4.37 to match CI. Exit 0 with no
preprocessor errors, and both new `{#action ...}` references resolve —
the rendered page reads "pane: toggle pin tab" and "pane: toggle preview
tab" in the same style as the existing "project panel: open permanent".
- `cargo test -p workspace --lib` — 272 passed, 0 failed, including
`test_close_other_items_unpreviews_active_item`,
`test_reopening_closed_item_after_unpreview`, and the proptest that
opens random paths with random `allow_preview` and asserts a pane never
holds more than one preview item.

## Notes for review

- Several people on the issue would rather the *behaviour* changed, so
that preview tabs close on any tab switch the way the docs currently
describe. I left that alone deliberately: the issue is typed `Docs`, so
this PR only makes the prose match the implementation. Happy to open a
discussion separately if it is worth pursuing.
- Saving a file also unpreviews it (`Pane::save_item`), but I left it
off the list as redundant — you have to edit a file before you can save
it, and editing is already there. Say the word if you would rather it
were explicit.
- The comment on `preview_tabs.enabled` in
`assets/settings/default.json` words this as "close automatically when
you open another preview tab". That is right for the project-panel path
and carries the same code-navigation caveat as above; I left it alone to
keep this diff to one file, and am happy to align it in a follow-up.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments — N/A
- [x] The content adheres to Zed's UI standards — N/A, docs only
- [x] Tests cover the new/changed behavior — N/A, no behaviour change;
the docs build is verified locally
- [x] Performance impact has been considered and is acceptable — N/A

---

Release Notes:

- N/A
2026-09-08 12:24:20 +00:00
Kirill Bulatov 2e9b4fe596 Unify copy actions for agent panel and markdown (#63884)
Before, it was not possible at all to copy the text from the agent
panel, only its markdown.
The PR breaks the existing ctrl/cmd-c binding there by using the same
approach markdown preview does: copy as text by default, allow to copy
as markdown via the context menu.

Before:


https://github.com/user-attachments/assets/2014f363-5167-4700-be86-9c0774d7e4fd

After:


https://github.com/user-attachments/assets/1dad253c-7a3b-4ca7-99c8-e8df8b3c3fd6


Release Notes:

- Changed agent panel to copy text with cmd/ctrl-c, as markdown preview
does. `markdown::CopyAsMarkdown` action is available still and can be
bound if needed.
2026-09-08 11:21:20 +00:00
99b0964454 agent_skills: Count description length in characters (#63766)
Closes #63620

Count Agent Skill descriptions by Unicode characters rather than UTF-8
bytes across validation, load-time warnings, the skill creator counter,
and imported-description truncation. This aligns Zed with the Agent
Skills specification and reference validator.

Testing:

- `cargo test -p agent_skills --lib`
- `cargo test -p settings_ui --lib`
- `cargo build -p zed`
- Manually verified that a 342-character CJK description containing
1,026 UTF-8 bytes can be saved successfully
- `./script/clippy -p agent_skills -p settings_ui --tests` is blocked by
an unrelated existing `clippy::drain_collect` diagnostic in
`crates/rpc/src/proto_client.rs`

<img width="667" height="210" alt="Successfully created Unicode test
skill"
src="https://github.com/user-attachments/assets/2427fce2-9f0f-462d-959f-e08ad160b3d1"
/>

Confirmed that the Codex agent panel discovers the skill and exposes it
in command completion without a length warning.

<img width="953" height="367" alt="image"
src="https://github.com/user-attachments/assets/8c100197-2e6e-4627-b3f8-862bdfaac918"
/>

Release Notes:

- Fixed valid multibyte Agent Skill descriptions being rejected for
exceeding a byte-based length limit.

---------

Co-authored-by: Chara <249489759+cmdr-chara@users.noreply.github.com>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-09-07 16:34:18 +00:00
d977c888b2 project_panel: Honor preview setting for keyboard opens (#63758)
Closes #63725

Honor `preview_tabs.enable_preview_from_project_panel` when opening
files with `project_panel::Open` (Space), matching the setting-aware
single-click behavior. Add a regression test covering previews disabled.

Testing:

- `cargo test -p project_panel --lib`
- `cargo build -p zed`
- Manually verified with the setting disabled that Space opens two
permanent tabs
- Manually verified with the setting enabled that Space replaces the
previous preview tab
- `./script/clippy -p project_panel --tests` is blocked by an unrelated
existing `clippy::drain_collect` diagnostic in
`crates/rpc/src/proto_client.rs`

Manual verification:

Preview disabled — Space opens both files as permanent tabs:

<img width="1920" height="1032" alt="Preview disabled: Space opens both
files as permanent tabs"
src="https://github.com/user-attachments/assets/4b772aad-031e-401d-ac85-5a7f82a74bc1"
/>

Preview enabled — Space replaces the previous preview tab:

<img width="1920" height="1032" alt="Preview enabled: Space replaces the
previous preview tab"
src="https://github.com/user-attachments/assets/cfef36af-0cd5-4522-99b5-99d3bb2c3f9d"
/>

Release Notes:

- Fixed the project panel preview-tab setting being ignored when opening
files with the keyboard.

---------

Co-authored-by: Chara <249489759+cmdr-chara@users.noreply.github.com>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-09-07 12:13:53 +00:00
Jake NelsonandKirill Bulatov 1aab982b0a workspace: Add configurable window title formatting (#54379)
## Summary
- Add `window_title_format` and `window_title_separator` settings for
customizing the window title
- Expose `${projectName}`, `${fileName}`, `${filePath}`,
`${relativePath}`, `${fileStem}`, `${remoteName}`, `${remoteHost}`,
`${appName}`, and `${separator}` as the native Zed window-title
variables
- Keep the collab `↗/↙` indicator hard-appended
- Translate VS Code `window.title` / `window.titleSeparator` aliases
into Zed's canonical variables during settings import, including
`${appName}` passthrough support and mapping VS Code's
`${activeEditorMedium}` onto Zed's `${relativePath}`
- Gate path-, remote-, and release-channel-derived lookups on whether
the active template references the corresponding variable, so the
default template avoids the extra work and still uses the existing
`last_window_title` cache to skip redundant platform updates

An alternative approach is at #49638. I went with `${variable}` names
over `$ZED_*`, canonical Zed variable names with VS Code aliases handled
at import time, kept `${separator}` as the only structural token, and
left `${dirty}` out of scope.

## Implementation reasoning and notes

### Variables considered but not included
- **collab/shared indicator variable**: kept hard-appended instead.
Folding it into the template would need whitespace/separator logic the
other variables don't need, and I'd rather not bake those semantics in
without a concrete need for it.
- **dirty variable**: The glyph choice and interaction with OS-level
edited indicators (like macOS's titlebar dot via `set_window_edited`)
felt like a separate design call I wasn't confident making here.

A separator-style config for each of collab/shared/dirty would solve the
above, but I didn't want to add too many additional settings initially.

### Performance
`update_window_title` is on a hot path, so two short-circuits apply:
- Path-, remote-, and release-channel-derived lookups (`absolute_path`,
relative-path string, `file_stem`, `remote_connection_options`,
`ReleaseChannel::try_global`) are gated on `template.contains(...)` via
`WindowTitleNeeds::from_template`, so the default template avoids the
extra work.
- The existing `last_window_title` cache still skips the platform call
when the rendered title is unchanged.

## Screenshots

Settings Editor entries for `window_title_format` and
`window_title_separator`:
<img width="774" height="324" alt="Settings Editor screenshot"
src="https://github.com/user-attachments/assets/b3378ec7-5649-4de3-9de6-164a42bce3fd"
/>

Customized Zed window titles in AltTab app switcher (remote, local,
empty):
<img width="774" height="324" alt="AltTab app switcher screenshot"
src="https://github.com/user-attachments/assets/a189945e-fc68-41b9-aab9-6dc04d5ef4ab"
/>

## 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 #14534

Release Notes:

- Added configurable window title formatting with `window_title_format`
/ `window_title_separator`, including `${appName}` / `${remoteName}` /
`${remoteHost}` variables and VS Code `window.title` import support

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-09-04 13:48:58 +00:00
Josh Kent cac6725147 markdown_preview: Group settings and add automatic preview opening (#63462)
## Objective

Markdown preview appearance settings are split between root theme
settings and
`markdown_preview`, and Markdown files always open as source editors
even when a user primarily
wants the rendered preview.

## Solution

- Group the Markdown preview font settings under `markdown_preview`,
migrate their legacy keys
across supported settings scopes, and update defaults, Settings UI, and
documentation.
- Add `markdown_preview.open_markdown_files_in_preview`, defaulting to
false. When enabled, clean
Markdown opens are replaced by a rendered preview while preserving dirty
editors, temporary-tab
behavior, pane activation and focus, targeted navigation, workspace
restoration, and the escape
  back to source.

## Testing

- Manually verified on macOS that enabling the setting opens Markdown
files as preview-only.
- `cargo test -p markdown_preview` (three consecutive runs)
- `cargo test -p migrator nest_markdown_preview`
- `cargo test -p settings_content`
- `cargo check -p markdown -p markdown_preview -p migrator -p settings
-p settings_content -p settings_ui -p theme_settings -p workspace`
- `./script/clippy -p gpui_apple -p markdown -p markdown_preview -p
migrator -p settings -p settings_content -p settings_ui -p
theme_settings -p workspace --features gpui_apple/runtime_shaders`
- `cargo fmt --all -- --check`
- `git diff --check`

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Recordings


https://github.com/user-attachments/assets/032ab36d-f934-4ef7-aa18-53f3955a7df8


https://github.com/user-attachments/assets/dc872265-2fe0-45ac-95eb-ff820d3a8164

Release Notes:

- Added a setting to open Markdown files directly in preview mode and
grouped Markdown preview settings together.
2026-09-04 10:54:29 +00:00
Smit BarmaseandKirill Bulatov d4424eec68 which_key: Add a pending key binding indicator (#63343)
This PR makes Zed's one-second key binding delay visible.

Say both ctrl-w and ctrl-w left have bindings. After you press ctrl-w,
Zed waits to see whether left follows. The PR shows that wait in the
status bar with a countdown. Hovering the indicator shows which bindings
can still match.

It also adds a setting to hide the indicator. It does not change how Zed
resolves key bindings.

<img height="100" alt="dyn-db84a840272e2f6250a3f527a59b1efd"
src="https://github.com/user-attachments/assets/e42c6a6c-4677-499f-a1d3-835960ebb21a"
/>
<br/>
<img height="100" alt="dyn-8012278d030b41bc8ebfae1540504eff"
src="https://github.com/user-attachments/assets/250928d5-f913-40f0-9068-00ccb5cdf59f"
/>
<br/>
<img height="100" alt="file-5e6ffa90944faa294e7870f471b4e65b"
src="https://github.com/user-attachments/assets/c250e6eb-a269-4e2c-a5a0-0be9b5006f99"
/>

Release Notes:

- Added a status bar countdown for pending multi-stroke key bindings.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-09-03 09:35:53 +00:00
Kirill Bulatov 9be65a8dfe Strip local symbols from macOS and Linux release bundles (#63429)
Not sure if this PR is 100% good, since it removes symbols from local
traces, leaving addresses only — but this what Windows seem to do
already, and we have those symbols on Sentry to restore from, which were
needed to normally read Linux perf traces already (see `perf.zip` in
https://github.com/zed-industries/zed/issues/59689#issuecomment-5452720248)

On the upside, uncompressed binaries' are now ~100MB less, which is a
lot — hence decided to open the PR for the review

-------------------

Strips debug info and local symbols from shipped macOS and Linux
binaries, matching what Windows already does with PDBs: `bundle-mac` now
always runs `dsymutil` before a new `strip -x` step, and `bundle-linux`
adds `--discard-all` plus `zed.dbg`/`remote_server.dbg` extraction via
`--only-keep-debug`.

Sentry uploads are unchanged and precede stripping.

The macOS binary UUID and the GNU build id survive stripping, so
user-provided traces stay recoverable without rebuilding at the
reporter's commit: `sample` output resolves via `atos` against the
archived `zed.dwarf`, and `perf.data` via `perf buildid-cache` against
the Sentry-archived binary.

zed binary:
macOS (2026-08-29 nightly): 420478976 -> 316503984 bytes (-24.7%,
-104.0MB)
Linux (v1.17.2 aarch64): 439417448 -> 336967256 bytes (-23.3%, -102.5MB)
Downloads shrink far less, symbols compress ~7:1: the macOS DMG loses
only ~15MB.

Release Notes:

- Improved installed size on macOS and Linux by stripping debug symbols
from release binaries (roughly -25%)
2026-09-02 19:38:12 +00:00
Finn Evers bfad3a6108 docs: Document focus_follows_mouse (#63646)
Release Notes:

- N/A
2026-09-02 18:54:48 +00:00
Kirill Bulatov 74f3fa1454 Support Emmet's wrap with abbreviation (#63383)
Closes https://github.com/zed-industries/zed/issues/15588


https://github.com/user-attachments/assets/2813d235-6dac-4fe6-9ae0-2783e16270ac

Release Notes:

- Added Emmet's wrap with abbreviation support
2026-09-02 18:21:02 +00:00
Albert Bogusz 7e7087a589 Add on_new_window setting (#63522)
> [!NOTE]
> This is a remake of #63335 as it's unlikely to be reopened just from
my
[mention](https://github.com/zed-industries/zed/pull/63335#issuecomment-5452544138).
Apologies for the noise!

# Objective

Closes #59368, where users (including me) are asking for a way to show
the Launchpad instead of an empty tab when opening a new window. As per
advice from
https://github.com/zed-industries/zed/issues/60720#issuecomment-4936162420,
adding a separate setting from `restore_on_startup` is more ideal.

`on_new_window` allows for two values:
- `empty_tab`
- `launchpad` (default)

## Testing

Added a regression test which opens a new window with `on_new_window`
set to `launchpad` and asserts that no item gets opened in the window's
pane. I've verified it fails without the setting gate, and confirmed
configuring this setting works manually (see Showcase).

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase


https://github.com/user-attachments/assets/bf339bd1-8c62-4243-ac9d-1045d1a14865

---

Release Notes:

- Added `on_new_window` setting to configure the opening of new windows.
2026-09-02 18:17:30 +00:00
Matei Oprea 04fc4edf86 Improve visibility and wording around close panel on toggle setting (#63548)
# Objective

- Improve documentation for `close_panel_on_toggle` setting. 

## Solution

- Previous docs were a bit ambiguous and since refactoring the setting
name is not possible at the time, I improved the documentation.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable

Release Notes:

- Added the`close_panel_on_toggle` setting to the settings UI and
improved its documentation.
2026-09-01 15:53:33 +00:00
Smit Barmase 7402d91b26 sidebar: Add title renaming for Terminal Threads (#63494)
The Agent Panel already lets users rename Terminal Threads. This adds
the same option to the Threads Sidebar. A rename in either place updates
the other.

<p>
<img width="321" height="89" alt="image"
src="https://github.com/user-attachments/assets/189a8598-f0da-4622-a5b0-b6a18a5750b7"
/>
</p>
<p>
<img width="324" height="77" alt="image"
src="https://github.com/user-attachments/assets/2fc9f7aa-c791-4568-8729-fd3a78322d63"
/>
</p>

Release Notes:

- Added support for renaming Terminal Threads from the Threads Sidebar.
2026-08-31 17:38:52 +00:00
František GažoandKirill Bulatov bb501d9221 outline_panel: Add setting to hide symbols in multi-buffer views (#63404)
Closes https://github.com/zed-industries/zed/issues/60242

# Objective

When reviewing a branch diff — or project search results — the outline
panel lists every affected excerpt and symbol beneath each file. On a
diff touching more than a handful of files, this consumes so much
vertical space that you cannot see the list of changed files at all,
which is usually the thing you want the panel for.

Existing settings don't cover this:

- `expand_outlines_with_depth: 0` still renders excerpt rows and
top-level symbol rows.
- Collapsing a file row in the panel is coupled to folding that buffer
in the editor, so it can't be used purely to tidy the panel.

## Solution

A display-only mode that reduces multi-buffer views to just the
directory/file tree.

- New `outline_panel.multi_buffer_hide_symbols` setting (default
`false`). When enabled, multi-buffer views render only directory, file
and folded-directory rows — excerpt, symbol and search-match rows are
hidden.
- New `outline panel: toggle symbols` action, plus a button in the panel
footer, which toggles an in-memory per-panel override of the setting
(the same pattern as `editor: toggle inlay hints`). Changing the setting
clears the override, so the setting wins.
- Single-file views are exempt, and the footer button is not shown there
— the panel contains only symbols in that case, so hiding them would
leave it empty.
- The filter is display-only: `collapsed_entries` and editor buffer
folding are never touched.
- Outline fetching is skipped while the mode is active, so large diffs
don't pay for outlines that will not be rendered. Turning the mode off
re-triggers fetching.

This adds one new icon, `file_code_off`, used by the footer button when
symbols are hidden. cc @zed-industries/design for review per the icon
guidelines — it is `file_code` with the slash and outline gaps from
`file_ignored`, keeping the parts of the chevrons that fall on the near
side of the slash.

## Testing

Three new tests in `crates/outline_panel/src/outline_panel.rs`:

- `test_hide_symbols_in_multibuffer` — outline rows are present by
default; only `Fs`/`FoldedDirs` entries remain once the mode is enabled
via the setting (which also exercises the settings observer) and via the
action; outline rows return when it is toggled off, confirming outlines
are re-fetched; asserts `collapsed_entries` is unchanged at every step,
covering the display-only guarantee.
- `test_hide_symbols_exempts_singleton` — a single-file view still
renders its outline with the setting enabled.
- `test_hide_symbols_hides_search_matches` — project search match rows
are hidden while files and directories still render, and return when
toggled off.

`cargo test -p outline_panel` (15 passing), `cargo test -p icons`,
`cargo test -p settings_ui -p settings_content`, and `./script/clippy`
on the touched crates are all green.

Tested manually on macOS against a branch diff, project search results,
and single-file buffers, checking both the setting and the action (from
the panel footer button and from the command palette with focus outside
the panel), and that expanding/collapsing directories and editor folding
still behave as before.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

<!-- Screenshots go here: branch-diff before/after, footer button icon
states, search before/after, single-file exemption -->


|  | Symbols shown (default) | Symbols hidden |
| --- | --- | --- |
| **Footer toggle** | <img
src="https://github.com/user-attachments/assets/393f128d-1a7c-43a8-97b8-8176a07b45c7"
width="260"> | <img
src="https://github.com/user-attachments/assets/87c60dd4-d5b7-48f8-9255-226c4a94a586"
width="260"> |
| **Branch diff** | <img
src="https://github.com/user-attachments/assets/79357325-7d7d-40f7-8067-4ae59a824f87"
width="420"> | <img
src="https://github.com/user-attachments/assets/8a3bbc7e-90d4-4638-9f1d-1ba3091eccfd"
width="420"> |
| **Project search** | <img
src="https://github.com/user-attachments/assets/76e3cf18-d624-42f8-8801-f496bf54a552"
width="420"> | <img
src="https://github.com/user-attachments/assets/2a34e899-b9f4-465e-b571-75d3d54d00eb"
width="420"> |

Single-file views are unaffected — symbols still render, and the toggle
is not offered:

<img
src="https://github.com/user-attachments/assets/76c47884-96db-4071-bcc1-931c4283e36f"
width="640">

---

Release Notes:

- Fixed too many outlines shown per excerpt in the outline panel. Added
an `outline_panel.multi_buffer_hide_symbols` setting and an `outline
panel: toggle symbols` action to show only files and directories in the
outline panel for multi-buffer views.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-31 14:36:04 +00:00
Kirill Bulatov c99db2149e Fix repo docs (#63486)
* ensures The Rule cannot be accidentall removed
* fixes the perf command example to capture call graphs, to avoid
round-trips like
https://github.com/zed-industries/zed/issues/59689#issuecomment-5453623044
(samples without call graphs are not quite usable for investigating bugs
like these)


Release Notes:

- N/A
2026-08-31 11:00:40 +00:00
951357a916 editor: Add language detection for untitled buffers (#61412)
# Objective

Closes #4868.

Reintroduce automatic language detection for user-created untitled
buffers without allowing it to override language choices made by users
or owning surfaces.

More details:
+ https://github.com/zed-industries/zed/pull/61201
+ https://github.com/zed-industries/zed/pull/61351

## Solution

VS Code distinguishes between inferred and explicitly selected
languages, and only continues automatic detection in the former state.
This change introduces a buffer-local opt-in flag with the same purpose.
It defaults to disabled and is enabled only for user-created untitled
buffers and restored untitled buffers that did not persist a language.
Choosing a language through the language picker disables detection,
while automatically detected languages remain eligible for later
redetection. Buffers whose language is assigned by their owning surface,
such as Channel Notes, never opt in.

Rather than adding persisted state or changing the database schema,
restoration reuses the existing optional serialized language. An
opted-in buffer that remains Plain Text is serialized without a language
and resumes detection after restoration. Once automatic detection has
selected a language, that language is serialized normally and
restoration leaves detection disabled, effectively treating it as an
explicit selection. This also matches VS Code's effective default after
restoration.

Candidate selection adopts VS Code's confidence-group filtering. Results
below the minimum confidence are discarded, and candidate groups are
accepted only after a clear confidence gap. The detector then selects
the first available Zed language without eagerly loading every
candidate. I then added a separate switching rule: Zed keeps the current
language unless another candidate has a clear confidence advantage,
reducing language changes as model scores fluctuate during editing.
Model inference runs off-thread on a bounded sample, and stale results
are discarded.

I also evaluated penalizing YAML and using stricter global switching
thresholds, but neither reliably resolves the ambiguity between Markdown
and YAML. In the reproduction from #61351, Betlang assigns YAML more
than 80% confidence during editing and peaks around 90%. This is
reasonable from the content alone: `#` denotes a YAML comment, while `-`
denotes a sequence item. Adding ordinary prose or a fenced code block
shifts the model strongly toward Markdown. A fixed penalty would overfit
this example and risk suppressing legitimate YAML detection. Since
known-language buffers do not opt in and manual language selection takes
precedence, I consider this level of ambiguity acceptable and prefer not
to introduce language-specific score tuning.

Model inference itself is fast. As noted in #61201:

> In release builds on Linux with an Intel Core i5-13600KF, the
`betlang::detect` call alone typically completes within 3 ms when
processing the maximum sampled input.

The main concern is the work surrounding inference. Without debouncing,
rapid typing creates a snapshot and launches a background detection task
on every keystroke, while the detected language may change before the
user has finished typing. This change therefore adds a 200 ms debounce
delay, allowing detection to run and update the language only after the
user pauses.

## Testing

Automated coverage verifies that short inputs remain Plain Text,
sufficient Rust content is detected as Rust, replacing it with Go
content triggers redetection, and manually selecting Plain Text prevents
subsequent automatic changes. Restoration coverage verifies that a
stored language keeps detection disabled, while an empty language-less
untitled buffer resumes detection.

Beyond the automated tests, I manually tested automatic language
detection while editing untitled buffers.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase


https://github.com/user-attachments/assets/103fc731-e12e-48d6-ae89-03978f1c9d74




---

Release Notes:

- Added automatic language detection for untitled buffers.

---------

Co-authored-by: Max Stevens <maxstevens2708@gmail.com>
Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2026-08-28 13:19:29 +00:00
VietHannandKunall Banerjee ee83eeca60 docs: Update documentation for YARA (#63340)
## Description
Fixed documentation bug in \docs/src/languages.md\:

- **Issue**: \Yara\ was incorrectly linked to \./languages/yarn.md\ and
there was a duplicate \Yarn\ entry
- **Fix**: Changed \Yara\ link to \./languages/yara.md\ and removed the
duplicate \Yarn\ entry

## Testing
- Verified both \yara.md\ and \yarn.md\ files exist in
\docs/src/languages/\
- Applied Prettier formatting to the file

---

Release Notes:

- N/A

---------

Co-authored-by: Kunall Banerjee <hey@kimchiii.space>
2026-08-28 10:09:06 +00:00
John Tur 0b1f4f4020 Delay-load ETW profiling DLLs (#62647)
Since we're here, improve the UX by prompting for a path when you save
rather than when recording begins.

Fixes #62334 

Release Notes:

- N/A
2026-08-28 08:13:20 +00:00
Mikhail Pertsev 05154a14af helix: Add m i m/m a m and preserve the selection after those actions (#59201)
# Objective

- Preserve Helix mode selections after surround-related commands such as
adding, deleting, and replacing surrounds.
- Add Helix-compatible closest-pair behavior for `m i m` / `m a m` and
surround commands that target `m`.
- Avoid long stalls in Helix text-object boundary scans by removing
repeated syntax-scope classification during textual scans.
- Keep workflows like selecting text with `m i w`, applying `m s`, and
continuing with `i`, `a`, or another surround command aligned with Helix
behavior.

## Solution

- Add selection anchors that preserve each pre-edit selection range and
direction through surround edits.
- Update Helix surround add so the resulting selection includes the
added delimiters, allowing surround commands to compose and
insert/append actions to land outside the pair.
- Apply preserved selections to Helix surround delete and replace so
non-empty selections are not collapsed to the cursor after the edit.
- Add Helix-specific text-object bindings so `m` selects the closest
surrounding pair, `t` selects types/classes, `c` selects comments, and
`x` selects XML/HTML elements in Helix mode.
- Match the current closest pair through language bracket queries, so
delimiters inside strings or comments do not count as surrounding pairs.
- Resolve the textual boundary scanner's `CharClassifier` once per scan
and pass it by reference instead of recomputing the same classifier for
every scanned character. Word and subword boundaries still clone it only
to apply the `ignore_punctuation` flag.

## Performance

The textual boundary scanner previously called
`char_classifier_at(from.0)` inside the per-character comparison
closures for the four `ImmediateBoundary` scan methods and
`FuzzyBoundary::to_boundary`. That lookup resolves the language scope
through the syntax layers, and the value was loop-invariant because
every iteration used the scan's starting offset.

Local debug benchmark, using `] m` in a roughly 540 KB buffer with no
pair characters so the scan runs to EOF across all pair boundaries:

|        | `] m` |
| ------ | -----: |
| Before | 36.3 s |
| After  | 210 ms |

This speeds up the remaining textual scanner paths, including `m i (` /
`m i "`-style pair objects, word/sentence/paragraph objects, `]` / `[`
text-object navigation, and `] m` / `[ m`. The current-pair `m i m`, `m
a m`, `m d m`, and `m r m` paths use the tree-sitter closest-pair path
instead.

## Testing

- Ran `cargo test -p vim test_helix_surround -- --nocapture`.
- The focused Helix surround test filter passed: 10 passed, 0 failed.
- Added coverage for closest-pair selection, Helix-specific text-object
keys, and surround selection preservation.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- Added Helix mode support for closest-pair text objects with `m i m`
and `m a m`.
- Fixed Helix mode surround commands to preserve selections after edits
and avoid slow textual boundary scans.
2026-08-27 23:24:52 +00:00
DongandKirill Bulatov 7472da6de7 Add folder_indicator setting to show chevron and folder icon together (#62393)
# Objective

- Enable panels to show chevron and icon at the same time.
- Closes #8661

## Solution

- Replaces `folder_icon` with a new `folder_indicator` which converts
from a boolean to enum (`both`, `chevron`, `icon`) for the three display
cases

## Testing

- gpui and migration tests had been applied

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

### project panel

both | chevron | icon
--- | --- | ---
<img width="400" alt="both_project_panel"
src="https://github.com/user-attachments/assets/4c21e1a1-a7a4-4471-b7de-fe867373ddbd"
/> | <img width="400" alt="chevron_project_panel"
src="https://github.com/user-attachments/assets/a626a82e-e5b7-470d-9d93-ed5787dc83d6"
/> | <img width="400" alt="icon_project_panel"
src="https://github.com/user-attachments/assets/20f9c55e-87c4-477a-b4c9-b070d6e5a1db"
/>

### git panel

both | chevron | icon
--- | --- | ---
<img width="400" alt="both_git_panel"
src="https://github.com/user-attachments/assets/3dc166dd-9e63-4943-b803-df3f167876b6"
/> | <img width="400" alt="chevron_git_panel"
src="https://github.com/user-attachments/assets/8dfd2c10-3a68-439a-8019-4951b72e17d1"
/> | <img width="400" alt="icon_git_panel"
src="https://github.com/user-attachments/assets/d78a9938-91e7-4d39-a3c8-04647da67768"
/>

### outline panel

both | chevron | icon
--- | --- | ---
<img width="400" alt="both_outline_panel"
src="https://github.com/user-attachments/assets/1b58c679-0bea-4600-a8ac-e800b0e8d24c"
/> | <img width="400" alt="chevron_outline_panel"
src="https://github.com/user-attachments/assets/0a9358e4-ec89-40d8-8d5e-a53b784ed30a"
/> | <img width="400" alt="icon_outline_panel"
src="https://github.com/user-attachments/assets/d8bf5199-5a8c-4de0-b516-00247e6531a5"
/>



---

Release Notes:

- Added a `folder_indicator` setting that can show the disclosure
chevron and folder icon at the same time in the project, outline, and
git panels.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-27 20:11:28 +00:00
c684a6a537 Add LSP call hierarchy modal (#53239)
<img width="1128" height="953" alt="image"
src="https://github.com/user-attachments/assets/b2017c0a-e25a-49d7-9342-d074014d085c"
/>

Closes #14203

Release Notes:
- Initial Call Hierarchy support in Zed

---------

Co-authored-by: Alexey Olshanskiy <gh@aohoy.dev>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-27 16:21:41 +00:00
Jacob WolfandSmit Barmase 3ba893e4ac editor: Add file permalink support to tabs and the Project Panel (#62177)
# Objective

- Add file-level hyperlink support for opening and copying hyperlinks
for Git remote source control to project panel and tabs
- Unify the language for Git remote hyperlinks across blame, project
panels, and tabs to be similar to GitLens' definitions (which are
commonly used in VS Code)

## Solution

- Updated the Git crate to expose relevant metadata to surface new
options within the editor
- Added new options for `Open File on Remote` and `Copy Remote File URL`
to project panel/file explorer and file tabs
- Altered the blame UI options to be consistent with new labels / more
clear

## Testing

- Ran `cargo run` to boot app and manually smoke test (see proof below)
- Added unit tests for this change

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase



https://github.com/user-attachments/assets/d600ca4f-47e7-438c-90e1-f40124a606b4

---

Release Notes:

- Added options to open or copy whole-file permalinks from file tabs and
the Project Panel.

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-08-26 18:21:33 +00:00
Kirill Bulatov 28c7f0cd8e Enable project search on type by default (#62506)
Closes https://github.com/zed-industries/zed/issues/9318

Most of the diff is tests.

Notable behavior changes during this mode, compared to current mode:

* unsaved changes in multi buffer won't spawn any "save or not" pop-ups
during typing — submitting the query still does it, as before.
Unsaved files will stay so after being sorted out on typing: we cannot
save them by default as file-less buffers need a save modal; Zed should
already be able to persist and restore such changes on restart.

* gutter may jump during search, if new excerpts with large line numbers
appear during query input — yet it would not shrink back to avoid
excessive flickering and rewraps

Release Notes:

- Enabled project search on type by default (use `{ "search": {
"search_on_type": false } }` to restore the previous behavior)
2026-08-26 14:33:03 +00:00
AltCodeandFinn Evers cc090319c1 docs: Add Elixir docs for debug adapter support (#63116)
# Objective

The Elixir extension has been shipping ElixirLS's debug adapter for a
while now. This finally documents it, providing examples on how to use
it with Zed too.

This also includes information about how the extension activates the
language servers/debug adapter, and an assortment of other minor changes

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable

---

Release Notes:

- N/A

---------

Co-authored-by: Finn Evers <finn.evers@outlook.de>
2026-08-24 10:21:35 +00:00
Jake Bailey 651a22d042 Document Tailwind CSS support for CSS files (#63110)
Fixes the CSS related item in Issue #43969 

## Summary

- Document how to enable Tailwind CSS IntelliSense for CSS files.
- Explain why the default CSS language server is disabled when using the
Tailwind CSS language server.
- Link CSS readers to the language-specific Tailwind configuration
examples for other languages and frameworks.

Release Notes:

- N/A
2026-08-24 04:55:09 +00:00
Johnny Arcitec d6d2f3c793 docs: Improve the Linux uninstall instructions (#63109)
# Objective

- Fixes incorrect Linux uninstall instructions.

## Solution

- Fixes a typo in the instructions and clarifies the correct uninstall
method when having parallel installations on Linux.

## Testing

- I tested the commands. 🤷‍♂️ 

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- N/A
2026-08-23 18:51:12 +00:00
Marshall Bowers 7dc5a34ef5 git_hosting_providers: Add Tangled support (#63051)
This PR adds support for [Tangled](https://tangled.org/) as a Git
hosting provider.

Release Notes:

- Added support for permalinks to [Tangled](https://tangled.org/)
repositories.
2026-08-21 21:31:55 +00:00
Smit Barmase 7ccf55c043 docs: Document language auto-indentation rules (#63009)
This PR updates the language extension docs for syntax-based rules,
line-based rules, and context-aware alignment. It is a follow-up to
#33370.

Release Notes:
- N/A
2026-08-21 10:43:42 +00:00
Finn Evers d6ec2f59ba Revise extension publishing documentation (#62767)
Release Notes:

- N/A
2026-08-21 10:06:24 +00:00
DanielandBen Kunkle 7c4fdc0321 Add configurable inline completion debounce timeout (#61568)
# Objective

Add configurable inline completion debounce timeout
Fixes/implements #23159

## Solution

I initially wanted to make a global setting for this, but it would
conflict with hardcoded debounces in codestral (150ms) and copilot
(75ms) which I assume are there for a reason.

So I ended up using the same mechanism used for the hardcoded debounce
in Codestral (`DEBOUNCE_TIMEOUT`) and Copilot
(`COPILOT_DEBOUNCE_TIMEOUT`)
and made it accessible and configurable for all providers.


Also fixed a bug with `DelayMs` `Display` trait adding "ms" into the
input field which then fails to parse something like "150ms" as a `u64`
by implementing `FromStr` which strips the "ms" suffix if present.

So now both "1000" and "1000ms" are parsed correctly and apply.

If the parsing fix is not relevant enough I can open a separate issue +
PR for that (and the inconsistent use and therefore display of
`Option<u64>` vs `Option<DelayMs>` in other ms input fields).

## Testing

#### Did you test these changes? If so, how?

Added a separate test which passes
`test_refresh_prediction_from_buffer_honors_debounce_duration`

Manually tested with openapi compatible prediction

All other tests in affected crates pass (`cargo test -p settings_content
-p settings_ui -p editor -p edit_prediction -p language
`)

#### How can other people (reviewers) test your changes? Is there
anything specific they need to know?

Open provider settings and adjust debounce, then see how long it takes
for a prediction to render.

#### If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?

Tested on Fedora 43 KDE, but it shouldn't matter as none of the affected
code is platform specific.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase


https://github.com/user-attachments/assets/14efa628-765e-4c2a-ac44-01aaa3657097

---

Release Notes:

- Added configurable inline completion debounce timeout, fixes #23159

---------

Co-authored-by: Ben Kunkle <ben@zed.dev>
2026-08-20 16:42:42 +00:00
a89202a036 docs: Fix WSL action name in remote development guide (#61073)
# Objective

Fixes #60922

The remote development documentation references action names as
hardcoded strings (`projects: open in wsl`, `projects: open wsl`). These
can drift out of sync with the actual action definitions in code and
don't benefit from the docs preprocessor's auto-rendering.

## Solution

Replaced hardcoded action name strings with the `{#action ...}`
preprocessor template syntax in `docs/src/remote-development.md`:

- `{#action projects::OpenFolderInWsl}` for "Opening a local folder in
WSL"
- `{#action projects::OpenWsl}` for "Opening a folder already in WSL"

This ensures the docs auto-resolve the human-readable action name from
the code definition, preventing future drift.

## Testing

- Verified the `{#action ...}` syntax is documented in
`docs/README.md:78-82` and implemented in
`crates/docs_preprocessor/src/main.rs`.
- Reviewed the action definitions in `crates/zed_actions/src/lib.rs:843`
(`OpenFolderInWsl`) and `lib.rs:852` (`OpenWsl`) to confirm correct
namespace and struct names.
- No code changes, docs only — no build or test required.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

N/A — documentation-only change.

---

Release Notes:

- N/A

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
Co-authored-by: Finn Evers <finn.evers@outlook.de>
2026-08-19 16:04:12 +00:00
Xin Zhao 45997391ba python: Support nested analysis settings for Pyright and basedpyright (#62673)
# Objective

Closes #62624

Recently, Pyright and BasedPyright changed how they retrieve analysis
settings through `workspace/configuration` in microsoft/pyright#11480
and DetachHead/basedpyright#1847, respectively. Older versions requested
the dotted `python.analysis` and `basedpyright.analysis` sections
directly. Recent versions instead request the parent `python` or
`basedpyright` section and read its nested `analysis` object. Because
Zed stores many existing configurations under the dotted top-level keys,
those settings are not included in its responses to the new
parent-section requests and are therefore silently ignored.

Zed's documentation and many users' settings still use configurations
like this:

https://github.com/zed-industries/zed/blob/4155155572601034cec5e5cfa9805bf88957553c/docs/src/languages/python.md?plain=1#L131-L148
all the configrations in `basedpyright.analysis` won't work now.

## Solution

To maintain compatibility with both old and new servers, we need to
support both configuration formats. This PR introduces
`normalize_pyright_analysis_configuration`, which copies the analysis
settings into both the dotted and nested formats. This ensures that the
settings are available regardless of which format the language server
requests.

The documentation, however, has been updated to use the nested
structure.

## Testing

New unit tests have been added, and the changes have also been built and
tested 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 adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- Fixed some Pyright and BasedPyright settings not being applied
properly.
2026-08-19 15:56:19 +00:00
Xin Zhao 731096c09a Fix project path handling when connecting from Unix to Windows remotes (#62038)
# Objective

Follow-up of #61374.

Zed now supports Windows as a remote target, but when connecting from a
Unix platform to Windows, some path handling still uses the native
client's path style (Unix) to construct paths, which causes weird path
displays in different areas.

One of them is the project path stored in the `settings.json` file,
which is related to the open path picker in the codebase:

https://github.com/zed-industries/zed/blob/0500fd9ee99a4a98b36e339f3674e391697690fd/crates/open_path_prompt/src/open_path_prompt.rs#L668-L679
For example, if I have a remote project at `D:\code\test_python` and
want to open it in remote development, I usually use path completions,
with `D:\code\` as the parent path and `test_python` as the selected
candidate. Zed directly joins them using `Path::join` on the Unix
platform, which results in `D:\code\/test_python`.

A second thing I found is the displayed name for the git repo. The
related source code is:

https://github.com/zed-industries/zed/blob/0500fd9ee99a4a98b36e339f3674e391697690fd/crates/title_bar/src/title_bar.rs#L262-L268
Also taking `D:\code\test_python` as an example: the passed-in
`common_dir_abs_path` is `D:\code\test_python\.git`, and
`repo_identity_path()` directly uses `Path::file_name()` and
`Path::parent()` from the standard library to handle this:

https://github.com/zed-industries/zed/blob/0500fd9ee99a4a98b36e339f3674e391697690fd/crates/project/src/git_store.rs#L9956-L9965
Ideally, this function should return `D:\code\test_python`. But due to
the platform mismatch, `D:\code\test_python\.git` is returned; after
further processing in the title bar, we get `D:\code\test_python\` as
the displayed name, while the expected display name is `test_python`.

In the past, only Unix-like systems could serve as remote servers, and
their path separator (`/`) is valid on Windows, so everything looked
fine. But Unix does not support `\` as a valid separator — that's the
root cause. We need to use `PathStyle`, which is designed for processing
paths across platforms, to deal with these cases.

## Solution

- Added new APIs `PathStyle::parent()` and `PathStyle::file_name()`,
which serve as replacements for `Path::parent()` and `Path::file_name()`
to process paths cross-platform.
- Adopted the new APIs in `repo_identity_path()`, and updated the
relevant call sites.
- For the open path picker, use `PathStyle::join_path()` instead of
`Path::join`.

## Testing

The added `PathStyle::parent()` and `PathStyle::file_name()` are covered
by detailed unit tests. These tests verify that the behavior matches the
corresponding methods in `Path`, just independent of the host platform.

For the path display issues, I built and tested manually; a comparison
is attached in the Showcase section.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

<details>
  <summary>Click to view showcase</summary>

| Content | Before | After |
|:--:|:--:|:--:|
|title bar|<img width="486" height="272" alt="title_bar_before"
src="https://github.com/user-attachments/assets/d14d0e37-a1b8-43ab-b51b-fe9dd1b977eb"
/> | <img width="406" height="274" alt="title_bar_after"
src="https://github.com/user-attachments/assets/fc9193f4-d42c-47a8-a254-4ed08c806a11"
/> |
|path storage| <img width="337" height="264" alt="project_path_before"
src="https://github.com/user-attachments/assets/3352add3-20df-43b9-8a20-10ee7d96e703"
/>| <img width="319" height="262" alt="project_path_after"
src="https://github.com/user-attachments/assets/fa3d7feb-f393-416a-868d-85eb0af5cfb8"
/>|
|open remote| <img width="554" height="135" alt="open_remote_before"
src="https://github.com/user-attachments/assets/62983eca-22ad-472f-8333-8561cfc17357"
/>|<img width="562" height="176" alt="open_remote_after"
src="https://github.com/user-attachments/assets/22528a6b-0e73-4a12-a825-673ba57a63da"
/> |
</details>


## Other things to note
This PR also did a little refactoring: it moved the `PathStyle`-related
tests from the `util` crate to the `path` crate, and updated the
documentation to reflect that Windows can serve as a remote platform.

The recent project picker also suffers from the same cross-platform bug,
but it is not fixed here, because a clean fix requires dealing with
database storage, unlike the direct API changes made here. I will
address it in a follow-up PR.

This PR looks very large, but most of the changes are the test migration
and the new API implementation. I hope the unit tests and comments can
offload some of the burden for reviewers.

---

Release Notes:

- Fixed project paths being built incorrectly when connecting from Unix
machines to Windows remote servers.
2026-08-19 12:16:37 +00:00
Vlad Ionescuanddino 29acba32d5 agent: OpenCode model updates (+6 Go, +7/-1 Zen, removed Free) (#61199)
Closes https://github.com/zed-industries/zed/issues/62559
Related discussion:
https://github.com/zed-industries/zed/discussions/61160

# Objective

Adding newly-released OpenCode models. Removing OpenCode Free models
completely.

## Solution

> [!TIP]
> This pull request is **best reviewed commit-by-commit**!

**OpenCode Go**:
- added **Kimi K3** as per
[[1]](https://github.com/anomalyco/models.dev/blob/89183a9646cf2fa30300f7203a5b4f2ca69d1374/providers/opencode-go/models/kimi-k3.toml)
and
[[2]](https://github.com/anomalyco/models.dev/blob/dev/models/moonshotai/kimi-k3.toml).
Currently, the only supported reasoning level available is `Max` which
was validated both with Models.dev data and OpenCode CLI.
- added **Grok 4.5** as per
[[1]](https://github.com/anomalyco/models.dev/blob/89183a9646cf2fa30300f7203a5b4f2ca69d1374/providers/opencode-go/models/grok-4.5.toml)
and
[[2]](https://github.com/anomalyco/models.dev/blob/89183a9646cf2fa30300f7203a5b4f2ca69d1374/models/xai/grok-4.5.toml)
- added **Tencent Hy3** as per
[[1]](https://github.com/anomalyco/models.dev/commit/b013d94872bb5993fad19ad35fadf74cb029516e)
and
[[2]](https://github.com/anomalyco/models.dev/blob/f63b5ce78dd78869faa0612353b1055f6608dc97/models/tencent/hy3.toml)
- added **GPT 5.6 Luna** as per
[[1]](https://github.com/anomalyco/opencode/pull/39812) and
[[2]](https://github.com/anomalyco/models.dev/blob/dev/providers/opencode-go/models/gpt-5.6-luna.toml)
- added **Qwen 3.8 Max** as per
[[1]](https://github.com/anomalyco/models.dev/commit/403a7bdd43ac7daeadc8bb755eccabf66a0afb9d)
and
[[2]](https://github.com/anomalyco/opencode/commit/e9e747245681127c9f3e300aa8c46f2554fdb294)
- added **GLM 5.3** as per
[[1]](https://github.com/anomalyco/models.dev/blob/3876740bf4f0290e014bc85340e1dba34f0e99a7/models/zhipuai/glm-5.3.toml)
and
[[2]](https://github.com/anomalyco/models.dev/commit/94a1629610b579fd80f7c488f5e4e8d78c8b6883)
and [[3]](https://github.com/anomalyco/opencode/pull/42518)

**OpenCode Zen**:
- added **Gemini 3.5 Flash Lite** as per
[[1]](https://github.com/anomalyco/models.dev/blob/f63b5ce78dd78869faa0612353b1055f6608dc97/providers/opencode/models/gemini-3.5-flash-lite.toml)
and
[[2]](https://github.com/anomalyco/models.dev/blob/f63b5ce78dd78869faa0612353b1055f6608dc97/models/google/gemini-3.5-flash-lite.toml)
- added **Gemini 3.6 Flash** as per
[[1]](https://github.com/anomalyco/models.dev/blob/f63b5ce78dd78869faa0612353b1055f6608dc97/providers/opencode/models/gemini-3.6-flash.toml)
and
[[2]](https://github.com/anomalyco/models.dev/blob/f63b5ce78dd78869faa0612353b1055f6608dc97/models/google/gemini-3.6-flash.toml)
- added **Gemini 3.7 Flash** as per
[[1]](https://github.com/anomalyco/models.dev/pull/4632) and
[[2]](https://github.com/anomalyco/models.dev/commit/b1810e30d7abb11af1092b51aa28cbafc2c440b8)
and [[3]](https://github.com/anomalyco/opencode/pull/42390) and
[[4]](https://github.com/anomalyco/opencode/pull/42393)
- added **Claude Opus 5** as per
[[1]](https://github.com/anomalyco/models.dev/commit/e3ae24cdd7fb524d73e1569ed1713991c5ba688c)
and
[[2]](https://github.com/anomalyco/models.dev/commit/342b5572a06735d0efa8c3c419589051199459d8)
- added **Kimi K3** as per
[[1]](https://github.com/anomalyco/opencode/commit/a9bebd36530dbab28c4644eb7b35b2b1460b8b90)
and
[[2]](https://github.com/anomalyco/models.dev/commit/38ccccc20d7d827f99d791d07cc4cedb8b4eec24)
- added **Grok 4.6** as per
[[1]](https://github.com/anomalyco/models.dev/commit/74789f5a02746cf6c40b75c342432a9d525c28b9)
and
[[2]](https://github.com/anomalyco/opencode/commit/d92d1e654bd1aa8ccb972b3059825314c1633eb8)
and [[3]](https://github.com/anomalyco/models.dev/pull/4575)
- added **Muse Spark 1.2** as per
[[1]](https://github.com/anomalyco/models.dev/commit/fa03dca90bad225a09263ad6ad227c7f47d0172d)
and
[[2]](https://github.com/anomalyco/models.dev/blob/3876740bf4f0290e014bc85340e1dba34f0e99a7/models/meta/muse-spark-1.2.toml)
and [[3]](https://github.com/anomalyco/opencode/pull/42508)
- removed **Claude Opus 4.1** as per
[[1]](https://github.com/anomalyco/models.dev/commit/6951484e985fe55646a741ccd3ca1d4b15008e3f)

**OpenCode Free**: removed all the models and the whole concept of
"OpenCode Free" from Zed. As confirmed [by an Anomaly employee on the
OpenCode
Discord](https://discord.com/channels/1391832426048651334/1394667004979445931/1537530485356363899),
free models are now OpenCode-only since they got abused waaaaay too much
by people. Testing shows that even with an active OpenCode Go
subscription configured, I can't use Free models in Zed — both Big
Pickle and DeepSeek V4 Flash Free failed to reply to a _"hello"_ message
and instead returned a rate-limit error.
A full removal of OpenCode Free from Zed was implemented in
https://github.com/zed-industries/zed/pull/61199/changes/49acbf7c92414c14c453113eb9b886f9bedff7cb
as there was no point in keeping a _"Show free models"_ toggle that
would confuse users.
Users that had `show_free_models` configures in Zed settings will get an
`Property show_free_models is not allowed.` notice. Users that had any
Custom OpenCode models with `"subscription": "free"` configured will get
an `Value is not accepted. Valid values: "zen", "go".` notice. Neither
are blocking errors.

## Testing

✅ Kimi K3 on OpenCode Go - happily confirmed Kimi K3 works by running a
simple "_rename this variable for me. add a function. delete the
function_" test.

✅ Grok 4.5 on OpenCode Go - bravely resisted the continuous and
relentless waves of disgust and confirmed Grok 4.5 works by running a
simple "_rename this variable for me. add a function. delete the
function_" test. I was a bit surprised this worked as I was located in
an EU country while testing this.

✅ Hy3 on OpenCode Go - happily confirmed Hy3 works by running a simple
"_rename this variable for me. add a function. delete the function_"
test.

✅ GPT 5.6 Luna on OpeCode Go - confirmed GPT 5.6 Luna works on OpenCode
Go by running a simple "_rename this variable for me. add a function.
delete the function_" test.

✅ Qwen 3.8 Max on OpeCode Go - confirmed Qwen 3.8 Max works on OpenCode
Go by running a simple "_rename this variable for me. add a function.
delete the function_" test.

✅ GLM 5.3 on OpeCode Go - confirmed GLM 5.3 works on OpenCode Go by
running a simple "_rename this variable for me. add a function. delete
the function_" test.


🤷 I did not test the new OpenCode Zen models (Claude Opus 5, Gemini 3.5
Flash Lite, Gemini 3.6 Flash, Kimi K3, Grok 4.6, Gemini 3.7 Flash, and
Muse Spark 1.2) as I don't have a Zen subscription and I am stubbornly
refusing to get one.

✅ Confirmed removal of OpenCode Free does not impact the rest of the
OpenCode. Confirmed that any Free-related settings generate notices and
not errors. Confirmed the OpenCode tab in Setting looks good.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

<details>
<summary>Screenshots of the OpenCode Free deprecation warnings</summary>

**Notice shown in the corner of Zed**:
<img width="345" height="90" alt="Notice banner shown in Zed"
src="https://github.com/user-attachments/assets/3e65ba96-582c-424e-9335-1b43d6c632a8"
/>

**Notice shown in Settings -> LLM Providers -> OpenCode**:
<img width="421" height="323" alt="Settings screen showing unexpected
values"
src="https://github.com/user-attachments/assets/a5eb6005-8576-4311-8b23-9c5baf314d8d"
/>

**Notice shown in `settings.json`**:
<img width="569" height="231" alt="Notices shown in settings.json"
src="https://github.com/user-attachments/assets/475375a1-268c-4420-8ef7-a896548e4498"
/>

</details>

---

Release Notes:

- Removed OpenCode Free models from Zed's built-in OpenCode provider
because they are only available through OpenCode surfaces, such as its
external agent through ACP.
- Added Kimi K3, Grok 4.5, Hy3, GPT 5.6 Luna, Qwen 3.8 Max, and GLM 5.3
to OpenCode Go.
- Added Claude Opus 5, Gemini 3.5 Flash Lite, Gemini 3.6 Flash, Gemini
3.7 Flash, Kimi K3, Grok 4.6, and Muse Spark 1.2 to OpenCode Zen.
- Removed the deprecated Claude Opus 4.1 model from OpenCode Zen.

----

> [!TIP]
> This pull request is **best reviewed commit-by-commit**!

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
2026-08-19 11:07:38 +00:00
ebd0e0b3a0 Fix the git_gutter_width setting (#62704)
# Objective

- Fixes #62645
## Solution
Since the default value isnt constant.It now has two options 1) Default
2) custom where user inputs a value.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable

## Showcase
<img width="798" height="361" alt="Screenshot 2026-08-16 at 4 29 54 PM"
src="https://github.com/user-attachments/assets/0af302f6-4733-4a23-9e93-1f9d98dd772f"
/>

<img width="798" height="92" alt="Screenshot 2026-08-16 at 4 30 13 PM"
src="https://github.com/user-attachments/assets/2c87c2a3-2947-45c7-8495-f6a0b36dd793"
/>

Release Notes:

- Added git_gutter_width setting to the Settings UI with default
(font-size-scaled) and custom (fixed pixel width) options

---------

Co-authored-by: Abdul Rafey Ahmed <abdul.r@hyperverge.co>
Co-authored-by: MrSubidubi <finn@zed.dev>
2026-08-18 12:40:18 +00:00
Dom Porada ef973c67c0 Add support for the "..." entry in file_scan_exclusions (#62769)
## Objective

`file_scan_exclusions` replaces the defaults instead of adding to them,
so excluding one extra directory means restating all eleven default
globs and never picking up defaults added in later Zed releases.

## Solution

`file_scan_exclusions` now accepts the `"..."` entry, which expands to
the value it overrides, so `["**/node_modules", "..."]` adds to the
inherited globs instead of replacing them. Entries listed by name keep
their position, and leaving `"..."` out still replaces the list
outright, so existing settings behave exactly as they do today.

## Testing

- Four unit tests in `crates/settings_content/src/project.rs` cover
splicing versus replacing, accumulation across successive layers, and
edge cases: a repeated `"..."`, an empty list clearing the value, and a
bare `["..."]` leaving it unchanged.
- To check by hand: set `"file_scan_exclusions": ["**/node_modules",
"..."]` in user settings and confirm `node_modules` disappears from the
project panel and file finder while `.git` and `.DS_Store` stay
excluded. Remove `"..."` and confirm only `node_modules` is excluded.
Repeat in a project's `.zed/settings.json` to confirm it splices the
resolved user settings rather than the defaults.
- Tested on macOS. This is platform-independent settings-merge logic
with no OS-specific code paths, so I did not test Linux or Windows.

## Self-Review Checklist:

- [x] I’ve reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed’s UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- Added support for the `"..."` entry in `file_scan_exclusions`. Custom
exclusions can now extend the defaults instead of replacing them.
2026-08-18 09:57:38 +00:00
Remco Smits e8fcbd476d gpui_macos: Add simple fullscreen mode that covers the notch (#60020)
Closes #60013

# Objective

Right now Zed can go full screen but it does not allow you to fix the
hole screen,
by that I mean that Zed can go behind the notch so you don't have extra
useless room left.

## Solution

You can now use the `fullscreen_mode` = `simple` setting to use the new
simple full screen feature, that lives besides the normal full screen
feature. But allows you to have an option to go 100% full screen without
losing any useless space on your macbook screen.
**Note** this is mostly usefull when you have a macbook that has a notch
whitch is kinda in the way of your work flow.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Showcase

**Before**
<img width="5712" height="4284" alt="IMG_0339"
src="https://github.com/user-attachments/assets/9f908ffd-7cef-4999-a454-c80f72c40dc8"
/>

**After** (Note now Zed is behind your notch when using the simple full
screen feature)
<img width="5712" height="4284" alt="IMG_0360"
src="https://github.com/user-attachments/assets/5917ed4d-2a64-4464-a794-bc46fd034521"
/>


---

Release Notes:

- Added support for simple fullscreen mode using the `fullscreen_mode`
setting, set it to `simple` to try it out.
2026-08-18 07:00:34 +00:00
PriyadharshanandChristopher Biscardi f652da59e8 Added Tracked , Staged options to stash (#62254)
# Objective

Closes #62252 

The Git Panel could only stash *everything* — `Stash All` runs
`git stash push --include-untracked`, sweeping tracked edits and
untracked files
into a single entry. There was no way to stash a subset, so the common
workflows
of "park my tracked edits but keep my new scratch files" and "park what
I've
staged and keep working on the rest" required dropping to the terminal.

## Images

<img width="389" height="358" alt="Screenshot 2026-08-10 at 3 10 50 PM"
src="https://github.com/user-attachments/assets/18e4c943-e320-4802-ada8-59e54bf4cefd"
/>

<img width="504" height="462" alt="Screenshot 2026-08-10 at 3 10 37 PM"
src="https://github.com/user-attachments/assets/783237eb-980d-47bc-a0f5-17b03a23a60c"
/>






## Solution

Add two stash variants alongside `Stash All`, surfaced in the Git
Panel's
overflow menu based on how the list is currently grouped, so the menu
mirrors the
sections the user can actually see:

| Group By | Stash entries offered |
| --- | --- |
| None | Stash All |
| Tracked & Untracked | Stash All, **Stash Tracked** |
| Staged & Unstaged | Stash All, **Stash Staged** |

- **`git::StashTracked`** stashes tracked changes and leaves untracked
files in
place. It reuses the existing pathspec plumbing
(`Repository::stash_entries`),
  filtering the status list down to the paths to stash.
- **`git::StashStaged`** stashes the index only, leaving unstaged
changes in
place. This *cannot* be expressed as a pathspec — a partially staged
file would
have its unstaged hunks stashed too — so it needs git's own `--staged`
flag.
  That meant a new `GitRepository::stash_staged` backend method and an
`optional bool staged` field on `proto::Stash` so remote projects work
too.

Both actions are unbound by default and are dispatchable from the
command palette
when the panel is focused.

One subtlety worth calling out for review: `Stash Tracked` filters on
`FileStatus::is_created()`, not `is_untracked()`. Staging a new file
flips it from
`Untracked` to `Tracked { Added }`, but the panel still lists it under
**Untracked** — using `is_untracked()` meant staged-new files were
silently
stashed. `is_created()` is the same predicate the panel uses to build
that section
(`git_panel.rs`), so the menu item and the list can no longer disagree.

This branch also includes a separate commit adding **per-section
staging**
(`git::StageSection` / `git::UnstageSection`) — right-click a file to
stage or
unstage every entry in its section. Happy to split that into its own PR
if
preferred.

## Testing

Manually tested on macOS against a scratch repo with a mix of states:
modified
tracked files, untracked files, and untracked files that had been
staged.

- `Stash Tracked` with tracked edits + untracked files → only tracked
edits
  stashed; untracked files remain.
- `Stash Tracked` with untracked files **staged** → they remain, staged.
This was
  broken in an earlier revision and drove the `is_created()` fix above.
- `Stash Staged` with one file staged and another modified-but-unstaged
→ only the
  staged file is stashed; the unstaged edit and untracked files survive.
- `Stash Pop` round-trips both cases back to the original state, with no
conflicts.
- Menu contents and disabled states verified in all three Group By
modes.
- Per-section staging covered by a new unit test,
  `test_stage_section_scopes_to_selected_section`.

Not covered by automated tests: the stash actions themselves.
`FakeGitRepository`
leaves every stash method `unimplemented!()`, so stash behavior isn't
reachable
from GPUI tests today — consistent with the existing untested
`StashAll`. Adding
fake-repo stash support looks like a worthwhile follow-up but felt out
of scope here.

Reviewers on non-macOS platforms: nothing here is platform-specific.
Note that
`Stash Staged` requires **git 2.35+** (Jan 2022) for `git stash push
--staged`;
older git surfaces a clear error toast rather than failing opaquely. The
remote
path (`proto::Stash.staged`) has not been exercised against a live
collab session.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Added `Stash Tracked` and `Stash Staged` options to the Git Panel,
letting you stash only tracked changes or only staged changes.

---------

Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2026-08-18 05:36:16 +00:00
Marshall Bowers f5a912e5f3 docs: Fix some links (#62758)
This PR fixes some links in the docs to use relative links instead of
pointing to `docs.zed.dev` (which isn't where the docs actually live).

Release Notes:

- N/A
2026-08-17 13:30:49 +00:00
f7356481e7 JetBrains keymap: Add CamelHump subword navigation (#51540)
Closes #21054

## Summary
• make the JetBrains base keymap use subword motions for
`Alt+Left/Right` and `Shift+Alt+Left/Right` in editors
• keep Zed's default keymaps and the underlying `word`/`subword`
primitives unchanged
 • document word vs. subword navigation in the key bindings docs
• document the JetBrains default in the IntelliJ, WebStorm, PyCharm, and
RustRover migration guides

## Testing
 • `./script/check-keymaps`
 • `cargo fmt --all -- --check`
 • `./script/clippy -p editor`
• `cd docs && pnpm dlx prettier@3.5.0 src/key-bindings.md
src/migrate/intellij.md src/migrate/webstorm.md src/migrate/pycharm.md
src/migrate/rustrover.md --check`

Related to #12816 and #34090, but does not actually address the
configurable word separators or broader subword semantics. Intentionally
scoped to JetBrains keymap defaults & docs.

Release Notes:

- Improved JetBrains keymap behavior by adding CamelHump-style subword
navigation in editors.

---------

Co-authored-by: Tom Houlé <tom@tomhoule.com>
Co-authored-by: Antonio Scandurra <me@as-cii.com>
2026-08-14 12:31:48 +00:00
Finn EversandKirill Bulatov 4cfa1d4749 docs: Split up extension publishing documentation (#62312)
While our extension ecosystem grows more and more, we simultaneously are
also enforcing more and more policies to have a better experience for
our users and ensure extensions meet a minimum standard. However, at the
same time, it has become increasingly difficult for extension authors to
keep track of what we enforce onto extensions and what specific rules
apply to their extension.

Thus, this PR splits out the publishing guidelines out of the
`Developing Extensions` page in an effort to make it easier to go
through our requirements and make it harder to miss those. This also
paves the way for more detailed publishing prerequisites, so that both
authors can more quickly see what applies to their extension as well as
reviewers having easier ways to point authors to what they are missing.

Release Notes:

- N/A

---------

Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
2026-08-13 21:02:09 +00:00
Kirill Bulatov 851bf3d499 Make file scanner less eager in non-git-tracked directory trees (#62583)
Fixes https://github.com/zed-industries/zed/issues/35780
Collab schema migration PR:
https://github.com/zed-industries/cloud/pull/3422
The corresponding database schema migration has been created in the
Cloud repo and applied to the production database.

Before, Zed scanned each and every entry in the tree down from the
directory it was opened in, except gitignored files and scan exclusions.
The approach is unchanged, if Zed detects it was open inside a git
repository: e.g. the directory open in Zed contains `.git` directory.

For the rest of the projects, 2 optimizations are made:

* Limit the depth of file scan traversal.
Now, `file_scan_depth` (default `5`) restricts Zed from traversing any
directory that has same number or more segments in its file path.


Such directories behave similar to gitignored directories: their
contents is not available in file finder, project search and project
panel, but can be lazily traversed when the directory is expanded (e.g.
project panel expands it or a nested file is open by path via terminal,
etc.)

To indicate that to the users, a status entry is shown firs time the
limitation is hit in the project:

<img width="858" height="133" alt="image"
src="https://github.com/user-attachments/assets/7da6cfbb-98b4-4cc3-bf2a-8902a9597a15"
/>

* During the scan, any git repositories that are not direct children of
the directory open in Zed (depth >= 2), are traversed and indexed
normally, but their git metadata is never fetched eagerly.

Only when Zed opens a buffer from that repo the git metadata is fetched
and applied.

All that combined now uses a way more moderate amount of CPU and RAM
when opening `~`:

<img width="1717" height="368" alt="Screenshot 2026-08-13 at 17 43 53"
src="https://github.com/user-attachments/assets/ec83e2a9-f7cc-452b-8eb7-af158284ca4e"
/>

File scan inclusions and exclusions are considered still for such
projects.
Set `file_scan_depth` to `0` to enable old behavior.
The setting is supported in the project settings, so custom values can
be set based on the project's structure.

---

Release Notes:

- Fixed Zed using a lot of memory and CPU in large, non-git-tracked,
directory trees
2026-08-13 17:07:06 +00:00
Kirill Bulatov 14bc768e44 Adjust language docs (#62551)
Closes https://github.com/zed-industries/zed/issues/62548

Puts
https://github.com/zed-industries/zed/issues/61908#issuecomment-5142104901
into docs.

Release Notes:

- N/A
2026-08-13 10:22:47 +00:00
Bechor Simhaev 7d34522515 docs: Rename brand-voice to brand-writer skill (#62384)
## What

`docs/.conventions/brand-voice/SKILL.md` declares:

```yaml
name: brand-writer
```

while sitting in a directory called `brand-voice`.

The Agent Skills specification requires the two to be identical:

> The required `name` field: … **Must match the parent directory name**
> — <https://agentskills.io/specification#name-field>

So this skill fails `skills-ref validate` today.

## Which side is wrong

The directory — and this repository settles it three separate ways, with
no outside context needed.

**1. The sibling copy already uses the matching name.**
`.factory/skills/brand-writer/` holds the same four files (`SKILL.md`,
`rubric.md`, `taboo-phrases.md`, `voice-examples.md`) under
`brand-writer`.

**2. `crates/agent_skills/README.md` documents the skill system using
this exact skill, and the name it documents is `brand-writer`:**

```
line 107:  <name>brand-writer</name>
line 149:  the model … calls `skill { name: "brand-writer" }`
line 151:  when the user types `/brand-writer`
line 158:  <skill_content name="brand-writer">
```

That name is load-bearing — it is what the skill tool invokes and what
the slash command types. The directory name is referenced twice, both
inside `docs/.conventions/CONVENTIONS.md`.

**3. Six of the repository's seven skills already match their
directory:**

| skill | matches? |
| --- | --- |
| `.agents/skills/gpui-test` | ✅ |
| `.agents/skills/lint-creator` | ✅ |
| `.agents/skills/zed-cherry-pick` | ✅ |
| `.factory/skills/brand-writer` | ✅ |
| `.factory/skills/humanizer` | ✅ |
| `crates/agent_skills/builtin/create-skill` | ✅ |
| **`docs/.conventions/brand-voice`** | ❌ the only one |

## The change

The frontmatter is untouched. Only the directory moves, plus the two
references to it:

- `docs/.conventions/brand-voice/` → `docs/.conventions/brand-writer/`
(4 files, pure rename)
- `CONVENTIONS.md:5` — `[brand-voice/](./brand-voice/)` →
`[brand-writer/](./brand-writer/)`
- `CONVENTIONS.md:368` — `` `brand-voice/rubric.md` `` → ``
`brand-writer/rubric.md` ``

`git grep brand-voice` returns nothing afterwards.

If you would rather keep the directory name and rename the field to
`brand-voice`, that is a one-line change instead and I am happy to
switch it — but it would give the two copies of one skill two different
names, and it would diverge from the name
`crates/agent_skills/README.md` documents.

## One thing I noticed but did not touch

The two copies have drifted. `.factory/skills/brand-writer/SKILL.md` is
279 lines and includes a *"Phase 4: Humanizer Pass"* section;
`docs/.conventions/`'s copy is 265 lines, lacks that section, and
renumbers Validation from Phase 5 to Phase 4. That is a separate
question about which copy is canonical, so it is left alone here.

---

Found with [AgentCompass](https://github.com/YoavLax/agent-compass), an
offline static analyzer for AI-agent repo readiness. Verified by hand
against the spec before opening.

Release Notes:

- N/A
2026-08-11 16:11:36 +00:00
PriyadharshanandChris Biscardi 1d8ba864ae Add optional message support to git stash (#62439)
Show a modal when invoking the stash action to allow users to provide an
optional custom message for the stash entry.

Closes #62430 


# Image

<img width="1622" height="1106" alt="Screenshot 2026-08-10 at 9 14
00 PM"
src="https://github.com/user-attachments/assets/0d26dac2-919d-4bb1-b6a7-433ceff18955"
/>

<img width="1622" height="1106" alt="Screenshot 2026-08-10 at 9 14
11 PM"
src="https://github.com/user-attachments/assets/896b68ff-999f-4ec9-a6a4-e0e7a6867286"
/>



# Objective

Zed's stash action runs `git stash push --quiet --include-untracked --`
with no `-m`, so every stash is labelled with git's auto-generated `WIP
on <branch>: <sha> <subject>`. That text describes the commit you were
sitting on, not what you stashed — so two stashes taken from the same
commit are indistinguishable.

This undercuts the stash picker (`git::ViewStash`), which lists entries
as `#<index>: <message>` and fuzzy-searches over exactly that string.
The search box already exists; there is just nothing meaningful to
search, because every candidate is a variation of the same
auto-generated line.

## Solution

`git::StashAll` now opens a single-line modal ("Optionally provide a
stash message") before stashing.

- Confirming with text passes `--message <text>` to `git stash push`.
- Confirming with the field empty omits the flag entirely, keeping git's
default description — so the prompt is a one-keystroke pass-through and
existing muscle memory still works.
- Cancelling aborts the stash, so the prompt doubles as a confirmation
step.

Implementation:

- `StashMessageModal` (`Editor::single_line`) in `git_panel.rs`, toggled
from `GitPanel::stash_all`. `menu::Confirm` trims the input and maps
empty to `None`.
- `message: Option<String>` threaded through `Repository::stash_all` →
`stash_entries` → `GitRepository::stash_paths`. The flag is appended
before the `--` separator so a message is never parsed as a pathspec.
- New `message` field on the `Stash` proto message, so remote and collab
projects behave identically.

One non-obvious detail: the modal is opened via `cx.defer_in` rather
than inline. `git::StashAll` is registered on the workspace
(`git_ui.rs`) as well as on the panel element, and
`Workspace::register_action` dispatches while `Workspace` is leased — so
opening the modal inline re-enters that update and hits GPUI's
`double_lease_panic`. This only reproduces when focus is *outside* the
Git Panel, which makes it easy to miss.

`Option<String>` rather than `String` is deliberate: `--message ""`
produces a blank stash description, which is strictly worse than git's
default.

## Testing

Manually verified the modal in a local build on macOS: the prompt
appears on `git::StashAll`, accepts a message, and the named entry shows
up in the stash picker.

Also verified at the git level by replaying the exact argument vector
`stash_paths` builds against a scratch repo with mixed staged / unstaged
/ untracked changes:

| Case | Result |
|---|---|
| `stash push --quiet --include-untracked --message "my named stash" --
<paths>` | `stash@{0}: my named stash`; worktree clean, untracked file
included |
| same, without `--message` | `stash@{0}: <sha> <subject>` — git's
default text |
| `--message "x" --` with no paths (clean repo) | exit 0, no stash
created — the empty pathspec does **not** stash everything |

`cargo fmt --check` clean, `./script/clippy -p git -p fs -p project -p
git_ui` passes with `--deny warnings`, and the existing suites pass
(`cargo test -p project -p git_ui`, 436 tests).

Worth a reviewer's attention: trigger `git::StashAll` with focus in the
**editor** rather than the Git Panel. That routes through the workspace
action registration and is the case the `cx.defer_in` deferral exists to
keep from panicking.

No new automated tests — the behavior is testable with the existing
`git_panel.rs` harness (`init_test`, `GitPanel::new`) if reviewers would
prefer coverage over a manual check.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments — n/a, no unsafe
added
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior — no new tests; see Testing
- [x] Performance impact has been considered and is acceptable — one
extra process argument; no new work on any hot path


---

Release Notes:

- Added an optional stash message prompt when stashing changes
`

---------

Co-authored-by: Chris Biscardi <chris@christopherbiscardi.com>
2026-08-11 04:38:21 +00:00