Commit Graph
2542 Commits
Author SHA1 Message Date
Sean WoodandChristopher Biscardi a0608b889d feat: Add reveal buffer if already open (#63306)
# Objective

Fixes #12572

## Solution

- Adds an opt-in `reveal_if_open` setting which enables searching and
revealing an already open buffer
- Ensures this only happens if there is no pane target for the open
intent

## Testing

- Built for and tested on my Mac
- Tests added covering the scope of the feature

## 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/cdcc78cd-85fd-4b56-b562-feba375ecd03

---

Release Notes:

- Added configuration to reveal buffers already open in a different pane
instead of the active pane, via `reveal_if_open`

---------

Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2026-08-28 11:51:00 +00:00
Smit Barmase b16d08d473 gpui: Fix stale pending input when a window is blurred (#63271)
This prepares for the keybinding hints PR.

To reproduce, press `ctrl-b` in a GPUI app with `ctrl-b h` and `ctrl-b
j` bindings, then call `window.blur()`. The live pending state clears,
but observers still report `ctrl-b`.

`Window::blur` now clears pending input and notifies observers after the
current effect cycle. I don't think we currently exercise this path in
Zed, and I was only able to reproduce it with an example GPUI app.

Release Notes:

- N/A
2026-08-26 21:36:59 +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 f36284a155 Bump dependencies to dedupe the crate graph (#63231)
Deduplicates crates with different versions from the graph, drops unused
features.

`cargo tree -d duplicate` listing: 160 -> 112 lines.

<details>
<summary>Deduplicated list</summary>

```
base64 (v0.22.1, v0.21.7 -> v0.22.1)
convert_case (v0.11.0, v0.10.0, v0.8.0 -> v0.11.0, v0.10.0)
core-foundation (v0.10.0, v0.9.4 -> v0.10.0)
cssparser (v0.36.0, v0.35.0 -> v0.37.0, v0.36.0)
fancy-regex (v0.18.0, v0.16.2 -> v0.19.0)
fixedbitset (v0.5.7, v0.4.2 -> v0.5.7)
h2 (v0.4.12, v0.3.27 -> v0.4.12)
heck (v0.5.0, v0.4.1, v0.3.3 -> v0.5.0, v0.4.1)
html5ever (v0.39.0, v0.35.0 -> v0.39.0)
hyper (v1.7.0, v0.14.32 -> v1.7.0)
hyper-rustls (v0.27.9, v0.24.2 -> v0.27.9)
mach2 (v0.6.0, v0.5.0, v0.4.3 -> v0.6.0, v0.5.0)
markup5ever (v0.39.0, v0.35.0 -> v0.39.0)
phf (v0.13.1, v0.12.1, v0.11.3 -> v0.13.1, v0.11.3)
phf_codegen (v0.13.1, v0.11.3 -> v0.13.1)
phf_generator (v0.13.1, v0.12.1, v0.11.3 -> v0.13.1, v0.11.3)
phf_macros (v0.13.1, v0.12.1, v0.11.3 -> v0.13.1, v0.11.3)
phf_shared (v0.13.1, v0.12.1, v0.11.3 -> v0.13.1, v0.11.3)
prost (v0.12.6, v0.9.0 -> v0.14.4)
prost-build (v0.12.6, v0.9.0 -> v0.14.4)
prost-derive (v0.12.6, v0.9.0 -> v0.14.4)
prost-types (v0.12.6, v0.9.0 -> v0.14.4)
rustix (v1.1.4, v0.38.44 -> v1.1.4)
rustls (v0.23.40, v0.21.12 -> v0.23.40)
rustls-native-certs (v0.8.3, v0.6.3 -> v0.8.3)
rustls-pemfile (v2.2.0, v1.0.4 -> v2.2.0)
rustls-webpki (v0.103.13, v0.101.7 -> v0.103.13)
security-framework (v3.5.1, v2.11.1 -> v3.5.1)
socket2 (v0.6.3, v0.5.10 -> v0.6.3)
string_cache (v0.9.0, v0.8.9 -> v0.9.0)
string_cache_codegen (v0.6.1, v0.5.4 -> v0.6.1)
strum (v0.28.0, v0.27.2 -> v0.28.0)
strum_macros (v0.28.0, v0.27.2 -> v0.28.0)
tendril (v0.5.1, v0.4.3 -> v0.5.1)
tokio-rustls (v0.26.4, v0.24.1 -> v0.26.4)
tungstenite (v0.28.0, v0.27.0 -> v0.28.0)
web_atoms (v0.2.6, v0.1.3 -> v0.2.6)
which (v6.0.3, v4.4.2 -> v8.0.5)
```

</details>


Release Notes:

- N/A
2026-08-26 14:33:13 +00:00
Kirill BulatovandKostia R 677e8174b5 Flush all persistence threads for the rest for various shutdown cases (#63213)
Follow-up to https://github.com/zed-industries/zed/pull/60477
Closes #25022

We have more places that need a similar synchronization before quitting
the app: restarts on update, reloading the workspace.

On top of it, two more findings:

* `on_app_will_quit` was redundant: the global `on_app_quit` hook
flushes a strict superset of the same tasks and runs before windows are
cleared, while the entity hook held only a weak handle and could never
flush the `Window`-dependent workspace state anyway.

* previously, shutdown was run as `cx.spawn`, yet main threads got
parked on app shutdown: now using `cx.background_spawn` instead

Release Notes:

- Improved data persistence during various app shutdown cases

---------

Co-authored-by: Kostia R <k-bx@k-bx.com>
2026-08-26 14:33:10 +00:00
Caleul Raposo CaixetaandKirill Bulatov 35ce0efd7f Fix macOS workspace session restore when closing window via X button (#60477)
Closes https://github.com/zed-industries/zed/issues/48468

## Solution

This change addresses a macOS shutdown ordering issue where closing the
last window with the native close button could clear session state
before persistence tasks complete, causing next launch to open no
project/untitled.

-
[crates/workspace/src/workspace.rs](/Users/caleul/Documents/Work/Projects/zed/crates/workspace/src/workspace.rs)
- Make `save_last_workspace` dynamic on macOS based on whether closing
the last window will quit the app (`on_last_window_closed == quit_app`).
- Keeps `save_last_workspace` true only when the window close path is
equivalent to quit, so last-session data remains valid only in the
intended scenario.

-
[crates/workspace/src/multi_workspace.rs](/Users/caleul/Documents/Work/Projects/zed/crates/workspace/src/multi_workspace.rs)
  - In `close_window`, before removing the window, explicitly flush:
    - workspace serialization tasks
    - pending workspace removal tasks
    - multi-workspace serialization task
  - This prevents losing in-memory state on fast close/quit paths.

-
[crates/session/src/session.rs](/Users/caleul/Documents/Work/Projects/zed/crates/session/src/session.rs)
- Guard `app_will_quit` to only persist window stack when non-empty,
preventing empty-stack state from being written during close path that
destroys the window stack first.

## Testing

- Did you test these changes?  
- Manual repro/fix confirmed in local testing flow by the previous
author.
  - Please confirm after merge with:
    1) open 2–3 projects in workspace sidebar  
2) set `on_last_window_closed: "quit_app"` and `restore_on_startup:
"last_session"`
    3) close with red X  
    4) relaunch app and verify sessions restore all active workspaces

- Are there any parts that need more testing?  
- Multi-window mixed close scenarios and one-window with dirty
non-serializable items.
- Regression for non-quit close mode (`on_last_window_closed: "close")
to ensure behavior remains unchanged.

- How can others test this?  
  - Follow the 4-step repro path above on macOS.
- Check logs for `timed out waiting on app_will_quit` in
`~/Library/Logs/Zed/Zed.log` and confirm no restore regression.

- Platforms tested:  
  - Verified for macOS (target path of bug).  
  - Not validated on Linux/Windows in this patch path.

## 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 (no UI/UX diff here)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes

- Closing last macOS window via the red close button now correctly
preserves and restores last-session workspace state when configured to
quit on last-window close.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-24 10:41:04 +00:00
Kirill Bulatov f7f3b90dca Register terminal panel before restoring serialized terminals (#62712)
Closes https://github.com/zed-industries/zed/issues/62435
Part of https://github.com/zed-industries/zed/issues/60548

Before:


https://github.com/user-attachments/assets/6b5147da-44cb-40c7-9da5-c50145e2ab4e

After:


https://github.com/user-attachments/assets/c58423cc-ea99-40d9-ad18-23b31dfb8e5d


Previously, `TerminalPanel::load` awaited full deserialization of
serialized
terminals (each awaiting directory environment capture via a login
shell)
before the panel was registered in the dock. 

Until then, `terminal_panel::Toggle{Focus}` was a silent no-op: the
workspace finds no
panel in any dock, the keystroke is eaten, and nothing happens.

When it got eventually restored, it would close whatever panel in the
dock was open manually instead, wrecking the workflow.

Repro:
1. Add `case "$ZSH_EXECUTION_STRING" in *--printenv*) sleep 10;; esac`
to `~/.zshrc`.
2. Open a project, open at least one terminal in the panel, quit Zed
(Cmd+Q).
3. Relaunch via Dock/Spotlight (not the `zed` CLI, which skips env
capture via
   `cli_environment`).
4. Press the terminal shortcut within 10s: nothing happens; after ~10s
the
   panel appears and the shortcut works.

* `Register terminal panel before restoring serialized terminals` — the
panel
  is now created and registered immediately, and restoration runs in
  panel-owned tasks (cancelled on panel drop, nothing detached).
  Terminal-adding paths were initially queued behind restoration (later
  replaced by grafting, see below); the default shell spawns only if the
  panel ends up active and empty after restore.

* `Stop replaying serialized dock state over manual panel changes` —
fixes a
related race: `Dock::add_panel` replayed the serialized dock state
(active
panel, visibility, zoom) on every panel insertion, so a late-loading
panel
would re-activate the serialized panel over one the user had switched to
in
the meantime (e.g. the terminal panel yanking the dock away from the
agent
  panel), or re-open a dock the user had closed. Serialized state is now
applied at most once and is discarded as soon as the user changes the
dock
state manually. The new tests fail without this change and pass with it.

* `Show restoration progress in the terminal panel and allow spawning
terminals during it` — while terminals restore, the panel shows a
spinner
with "Restoring terminals…" instead of a blank pane, and logs the
restored
count and elapsed time. Supersedes the queuing from the first commit:
new
terminals spawn immediately, and any that land mid-restore are grafted
into
the restored layout instead of being lost. Serialization is paused
during
restoration, so quitting mid-restore can no longer persist a partial tab
  list and silently drop terminals.


Release Notes:

- Fixed the terminal panel not opening at all under certain
circumstances, made panels no longer switching back to the serialized
one when opened during startup.
2026-08-21 17:26:29 +00:00
Matei OpreaandKirill Bulatov 5d473cc6af editor: Prevent auto save formatting on read only files (#62921)
# Objective

Read-only marked files in zed could still be affected by format on save
feature. This PR fixes that.
FIXES #62899 

## Solution

These changes add an early return on Editor's `Item::save`
implementation so neither formatting nor the write to disk occurs.

## Testing

I've tested by reproducing the issue in the original ticket. 

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

---

Release Notes:

- Fixed read-only files being formatted and saved when `format_on_save`
is enabled

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-21 13:19:58 +00:00
Anıl Zeybek 1829879ca1 workspace: Persist recent navigation history across sessions (#55034)
Saves the recent navigation history (up to 20 entries) to the workspace
DB so it survives restarts. When reopening a workspace, persisted paths
that resolve to the current project are merged into the file finder's
history, deduplicated against files already opened in the session.


https://github.com/user-attachments/assets/3d8934e1-0da6-4445-8f3d-acc5597d7ac8

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: https://github.com/zed-industries/zed/issues/56271

Release Notes:

- Improved file finder history to include recently opened files from
previous sessions.
2026-08-20 11:27:03 +00:00
Neel 255880598d Switch from cargo-machete to cargo-shear (#62643)
This results in ~110 crates being removed, and some orphaned files also.

---

Release Notes:

- N/A

Signed-off-by: Neel <neel@zed.dev>
2026-08-20 10:08:48 +00:00
Nikita Demin 459fe185a4 editor: Add in_preview boolean context for keybindings (#61777)
# Objective

- Add an `in_preview` context that is available when the current editor
is in preview mode (opened from project panel or go to definition).
- closes https://github.com/zed-industries/zed/discussions/61765

## Solution

- In `editor.rs`, added a check in `key_context()` that detects if the
editor is the active preview item in its pane, and if so, adds
`"in_preview"` to the key context.
- Uses existing `workspace.pane_for_item_id()` and
`pane.is_active_preview_item()` methods — no new APIs introduced.

## Testing

- Added two tests in `editor_tests.rs`:
- `test_in_preview_context_added_when_in_preview_mode` — verifies
`in_preview` is present when editor is set as preview item.
- `test_in_preview_context_not_added_when_not_in_preview_mode` —
verifies `in_preview` is absent for regular (non-preview) tabs.
- Tested on Linux.

## 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 `in_preview` keybinding context for when an editor is in preview
mode.
2026-08-19 21:35:38 +00:00
Enzo GAZZOLIandKirill Bulatov 1155a5becd Render control characters in tab titles and project panel entries (#62875)
# Objective

Fixes #62664

File names may contain control characters (`\n`, `\r`, `\t`, …) on most
platforms. Zed rendered them verbatim, so a file named `notes\ndraft.md`
broke the layout of its tab and of its project panel entry instead of
showing a readable name. The same held anywhere else a name reached the
screen without going through `Label::single_line`.

## Solution

The substitution lives in one shared place,
`ui::utils::replace_control_characters`, reached through
`Label::single_line`. `\n` keeps rendering as the `⏎` Zed already used,
so nothing that renders correctly today changes; every other C0 control
character maps onto the Unicode "Control Pictures" block by a single
rule (`U+2400 + code point`), giving `␉` for tab and `␍` for carriage
return. `DEL` maps to `␡`. C1 controls are left alone, having no
equivalent there.

Where that is wired in:

- **`Label::single_line`** — replaces its previous `\n`-only
substitution. The project panel already used it everywhere, including
folded directory components, so the panel is fixed by this alone.
- **Editor tabs** and the **default `Item::tab_content`**, neither of
which called `single_line`.
- **Terminal tab titles**, which render through their own `tab_content`.
Those titles come from OSC escape sequences, so the control characters
in them are attacker-controlled.
- **`HighlightedLabel::single_line`**, which never substituted anything
— not even `\n`. See below.
- **The file finder**, for both the file name and the path.
- **Nine `tab_content` overrides in git_ui**, by deleting them.
- **`HighlightedMatchWithPaths`**, for both the match label and its
paths — it backs the tab switcher and the outline panel, among others.

### `HighlightedLabel` needs its offsets moved, not just its text

Its highlight indices are byte offsets, and every stand-in is wider in
bytes than the character it replaces, so the offsets have to move with
the text. Left alone they index into the middle of a character, and
`highlight_ranges` slices the string at exactly those offsets — which
panics in release builds too. The constructor's `debug_panic!` does not
cover this, since `single_line` runs after construction.

So `replace_control_characters_remapping_offsets` substitutes and remaps
in one pass, over an old-to-new byte offset table built the way
`ensure_uniform_list_compatible_label` does it in `lsp_store`. This also
fixes the call sites that already asked for a single line, including the
branch picker and the tabular column filter values.

### Deleting the git_ui overrides

Nine files replicated the default `Item::tab_content` verbatim except
for the colour, hardcoding `selected ? Default : Muted` instead of
`params.text_color()`. Deleting them lets those tabs inherit the fixed
default, and fixes a second bug along the way: none of them dimmed when
the pane lost focus. Titles and icons are unaffected — they come from
`tab_content_text` and `tab_icon`, which the default calls.
`git_graph.rs` already did it this way.

### Tabular column headers

These never went through a `Label` at all: the raw `SharedString` was a
child of a `div`. They now display stand-ins, while right-click-copy
still yields the real column name.

Two notes for reviewers:

- Both helpers avoid allocating when there is nothing to replace, so the
common path is untouched. The previous `self.label.replace('\n', "⏎")`
allocated a `String` on every render for every label — including every
visible project panel entry, every frame.
- Every stand-in is exactly one character, so character offsets are
preserved and the existing `truncate_and_trailoff` math on tab titles
stays correct.

## Testing

- Unit tests cover both helpers: each control character's substitution,
repeated occurrences, multi-byte characters (accents, emoji), the
borrow-vs-own behaviour, the preserved character count, C1 passthrough,
and — for the remapping — offsets before, at and after a replacement,
offsets at and past the end, and the invariant that every remapped
offset lands on a character boundary.
- Unit tests cover `Label::single_line` and
`HighlightedLabel::single_line`, the entry points every call site uses.
`highlighted_label.rs` had no tests before.
- `cargo test -p ui -p file_finder -p workspace -p project_panel -p
git_ui -p git_ui_core -p terminal_view -p tabular_data_preview` passes
(774 tests), as do `cargo clippy` and `cargo fmt --check`.
- No existing test changes behaviour: tests assert on
`tab_content_text`, which is untouched; only rendering paths changed.
- Verified manually on macOS (aarch64) — see Showcase.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments — none added
- [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

A directory holding `report<TAB>table.csv`, `notes<LF>draft.md`,
`carriage<CR>return.txt` and a normally named `normal.txt`, all four
open as tabs.

**Before**


![before](https://raw.githubusercontent.com/Taqinou/zed/0d5ee2b4f94db7bcb713298c38cf411458b75239/62664/before.png)

**After**


![after](https://raw.githubusercontent.com/Taqinou/zed/0d5ee2b4f94db7bcb713298c38cf411458b75239/62664/after.png)

Three things change:

1. **The `notes<LF>draft.md` tab** is the clearest one. Before, the
literal newline splits the tab across two lines — `notes` above
`draft.md` — distorting the whole tab bar. After, it stays on one line.
2. **`carriage<CR>return.txt` in the project panel** renders as
`carriagereturn.txt` before: the `\r` is completely invisible, so the
name reads as one word and there is no way to tell a character is there.
After, it renders as `carriage␍return.txt`.
3. **`report<TAB>table.csv`** shows a bare gap before, indistinguishable
from a space. After, it renders as `report␉table.csv`.

Note that `notes<LF>draft.md` looks the same in the project panel in
both shots: that entry already called `single_line`, which already
handled `\n`. That is precisely the asymmetry this PR removes.

### File finder

Before, the newline also breaks the list itself — the
`notes<LF>draft.md` row grows to two lines and overlaps the row beneath
it.

**Before**

![file finder
before](https://raw.githubusercontent.com/Taqinou/zed/0d5ee2b4f94db7bcb713298c38cf411458b75239/62664/finder-before.png)

**After**

![file finder
after](https://raw.githubusercontent.com/Taqinou/zed/0d5ee2b4f94db7bcb713298c38cf411458b75239/62664/finder-after.png)

Searching for `table` exercises the offset remapping, the match falling
after the control character:

**Before**

![match
before](https://raw.githubusercontent.com/Taqinou/zed/0d5ee2b4f94db7bcb713298c38cf411458b75239/62664/match-before.png)

**After**

![match
after](https://raw.githubusercontent.com/Taqinou/zed/0d5ee2b4f94db7bcb713298c38cf411458b75239/62664/match-after.png)

One thing this PR does **not** cover: the breadcrumb below the tab bar
still renders the raw tab character, as it goes through a different
path.

## Release Notes:

- Fixed file names containing control characters, such as tabs and
newlines, rendering unreadably in tabs, the project panel, the file
finder, the tab switcher and terminal tab titles.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-19 21:10:56 +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
ArneshandKirill Bulatov e440f6ee6e workspace: Activate the right tab when restoring a workspace (#62844)
@SomeoneToIgnore this is the follow up you asked for in #62692, done as
discussed.

`deserialize_to` keeps a `None` in `items` for every item that failed to
deserialize, and those are never added to the pane. Any later tab
therefore sits at a lower index in the pane than the one it was
serialized with, so activating and previewing by serialized index lands
on the tab that shifted into that slot. When the failing item is the
last one, the index points past the end of the pane and nothing is
activated or previewed.

The serialized index is now mapped to the pane's index by counting the
items before it that actually restored, and an index whose own item
failed to restore is skipped.

Closes #62843

Release Notes:

- Fixed the wrong tab being activated when restoring a workspace
containing items that fail to open

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-18 23:00:25 +00:00
Arnesh 22ba488f6d workspace: Keep pinned tabs correct when restoring a workspace (#62692)
Pinned tabs are the leading tabs of a pane, and that is persisted as a
plain count. Both sides of workspace serialization could leave the count
out of step with the tabs it is meant to describe:

- When serializing, `serialize_pane_handle` drops items that cannot be
serialized (a pinned diagnostics or project search tab, for example)
from the pane's children, but still stored the pane's raw pinned count.
- When restoring, `SerializedPane::deserialize_to` keeps a `None` in
`items` for every item that failed to deserialize. Those are never added
to the pane, but `self.pinned_count.min(items.len())` counted them
anyway.

In both cases the count ends up pointing past the tabs that were
actually pinned, so the tabs that shift into those slots come back
pinned even though they never were. This also explains the `Pinned tab
count (N) exceeds actual tab count (M)` warning from #33342.

Now the serialized count shrinks with each dropped pinned item, and on
restore only the pinned items that were actually restored are counted.

Closes #62003

Release Notes:

- Fixed tabs being wrongly marked as pinned after reloading a workspace
or updating Zed
2026-08-18 21:58:55 +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
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
Austin Cummingsanddino 33b0b39e40 workspace: Reset all configured dock panels (#62552)
Closes #57388.

When a dock is listed in `resize_all_panels_in_dock`, reset its
compatible panels to the active panel's default size. This applies to
the reset actions and resize-handle double-clicks. Docks not listed in
the setting continue to reset only the active panel.

Adds regression coverage for fixed panels with different defaults,
flexible panels, and active-panel-only resets.

Release Notes:

- Fixed dock size reset commands only resetting the active panel when
`resize_all_panels_in_dock` is enabled.

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
2026-08-17 22:28:04 +00:00
Akihiro Okuno 74247e797e sidebar: Make project reordering key-bindable (#62695)
# Objective

- The sidebar already supports moving project groups through its **Move
Up** and **Move Down** context-menu entries, but those entries use
callbacks that cannot be referenced from `keymap.json`. Moving a project
several positions therefore requires reopening the menu for every step.
- Follow-up to #57448. Related to #61647.

## Solution

- Add `multi_workspace::MoveProjectUp` and
`multi_workspace::MoveProjectDown` actions. The handlers resolve the
active project group and delegate to the existing `MultiWorkspace`
reordering methods, keeping ordering and persistence behavior unchanged.
- Associate the actions with the existing context-menu entries so
configured shortcuts are shown alongside the menu commands. The menu
callbacks still operate on the project that was clicked.

## Testing

- Added a GPUI test that dispatches both actions and verifies that the
active project group moves in the expected direction and remains
unchanged at list boundaries:
- `cargo test -p workspace test_move_active_project_group_actions --
--nocapture`
- Manually verified on macOS with an isolated Zed user-data directory
and three project folders:
  - Assigned custom shortcuts to both actions in `keymap.json`.
  - Confirmed that the active project moves up and down in the sidebar.
- Ran formatting, compilation, and lint checks:
  - `cargo fmt --all -- --check`
  - `cargo check -p sidebar`
- `./script/clippy -p workspace -p sidebar -p gpui_platform --features
gpui_platform/runtime_shaders`

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

<details>
  <summary>Move projects with custom keybindings</summary>


https://github.com/user-attachments/assets/09432817-318b-484e-b630-a6012e9599cd

</details>

---

Release Notes:

- Sidebar: Added key-bindable actions for moving projects up and down.
2026-08-17 07:49:57 +00:00
Kirill Bulatov 3a21e04379 Fixed the zoomed agent panel closing unexpectedly on rewind (#62711)
`ThreadView::regenerate` does `thread.rewind()` which de-focused the
message editor mid-flight causing the zoomed panel to disappear.

* workspace: Keep zoomed panels open when window focus is lost

Commit adds a test + tweaks a default, generic, fallback to be more
lenient: instead of focusing the workspace (and hiding all panels right
away), try to fall back to whatever panel open

* gpui: Restore focus to nearest surviving ancestor when focus is lost

Commit tries to push it down to a library level and add a way to fall
back to closest ancestor that's still visible with the focus instead.


Release Notes:

- Fixed the zoomed agent panel closing unexpectedly on rewind
2026-08-16 14:42:24 +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 3692029a80 Bump rustc to 1.97 (#62395)
Release Notes:

- N/A
2026-08-09 22:29:52 +00:00
Piotr Osiewicz ff50948537 deps: Bump pathfinder_simd & fix upcoming rustc warnings (#62170)
While building Zed with nightly rustc I've noticed it doesn't compile
because of good old pathfinder_simd. It also emits a bunch of warnings
about use of f64 literals where f32 is expected, so I've fixed them - it
should make future upgrades more straightforward.
2026-08-07 10:16:57 +00:00
Ben Kunkle 81db8c68b2 workspace: Choose the replacement workspace inside MultiWorkspace::remove (#62141)
# Objective

Follow-up to #62028. When archiving removed a thread's workspace, the
replacement
was derived from whichever sidebar row sat adjacent to the archived one.
Rows are
a flat list with project headers as separators, so archiving the oldest
thread in
a project selected the next project's newest thread and moved the user
out of the
project they were working in — and when that neighbor was remote,
connected to
its host just to pick a fallback.

# Solution

- `MultiWorkspace::remove` now chooses the replacement itself from a
`RemovalIntent` (keep the project vs close it): a live workspace in the
same
project, the project's own roots when kept, the nearest retained
neighbor,
an adjacent local project, then an empty workspace. The workspaces being
  removed are excluded from that search in one place instead of five.
- Sidebar neighbor selection stays within the entry's project section.
- The three archive paths now share one removal orchestration, and the
three
  "open the closed workspace first" helpers collapse into one.

# Testing

New tests cover: the keep-project fallback, neighbor selection staying
inside the
project section, and archiving with a mock-remote neighboring project
never
connecting to it. Each was verified to fail against the previous
behavior.

## 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 archiving a thread switching the window to a different project.
- Fixed a possible crash when archiving a thread while its window was
closing.
2026-08-05 02:48:46 +00:00
Ben Kunkle c9259c77dd workspace: Return the created workspace when opening a remote project (#62028)
# Objective

Fix the `fallback workspace must not be one of the workspaces being
removed` panic.

Fixes FR-148
Fixes ZED-AKR
Fixes ZED-97M

# Solution

The remote path of `find_or_create_workspace` opened a project, then
returned the
window's *active* workspace instead of the one it created. The open
awaits toolchain
loading and item restoration, and a save prompt from a concurrent
workspace removal
can re-activate a workspace being removed during that wait; the stale
return value
then trips the assert in `MultiWorkspace::remove`.

Return the created workspace from `open_remote_project_inner` and use it
at the
call sites instead of re-reading the active workspace after the await.

# Testing

Added
`test_find_or_create_workspace_returns_the_created_remote_workspace`:
opens a
mock remote project and re-activates the previous workspace mid-open
(standing in
for the save prompt), then asserts the open returns the workspace it
created.
Verified it fails against the pre-fix behavior.

## 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 a crash when a workspace was removed while a remote project was
opening in the same window.
2026-08-03 20:43:45 +00:00
Matei Opreaanddino 0e7fb8be2d multi_workspace: Allow closing of currently selected project (#60602)
# Objective

When working across multiple projects open in the same window, closing
the **currently selected** project requried a two-step flow: switch to
another project first then close the one that you initially wanted to.
The project's close button was hidden on the active project, so the only
way to remove the project was to navigate away first.

## Solution

Always render the close button in the project picker, including for the
active project. Closing the active project now removes it and switches
to a neighboring project automatically.
This worked well for local projects but broke for remote ones. For any
remote neighbor it actually fell through to an empty workspace.

There are 3 cases now: 
1. Activate the neighbor's already open workspace when one exists (now
either if its local or remote)
2. Load the neighbor through the host-aware **find_or_create_workspace**
which connects and opens a remote neighbor when it isn't already open
3. Fallback to an empty workspace only when no neighbor remains

## Testing

- Did you test these changes? If so, how?
- Are there any parts that need more testing?
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?

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

> This section is optional. If this PR does not include a visual change
or does not add a new user-facing feature, you can delete this section.

- Help others understand the result of this PR by showcasing your
awesome work!
- If this PR includes a visual change, consider adding a screenshot,
GIF, or video
- A before/after comparison is very useful for changes to existing
features!

While a showcase should aim to be brief and digestible, you can use a
toggleable section to save space on longer showcases:

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


https://github.com/user-attachments/assets/6e1d1968-702a-4f13-9442-5e90fe7ae9f9

</details>

---

Release Notes:

- Improved the project switcher to allow closing the currently selected
project, switching to a neighboring project (local or remote)
automatically.

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
2026-07-31 12:55:11 +00:00
CarboFish 9fb397d961 workspace: Fix dropping Windows files onto a WSL remote (#57146)
Dropping a local Windows file (e.g. `E:\foo\bar.md`) onto a Zed window
connected to a WSL remote previously forwarded the path verbatim. On the
remote Linux side `E:\foo\bar.md` isn't absolute, so it got joined with
the worktree CWD, producing nonsense like `/home/user/E:\foo\bar.md` and
a "failed to canonicalize root path" error from the worktree scanner.

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

before:
<img width="1343" height="331" alt="before"
src="https://github.com/user-attachments/assets/193cfbf6-d07e-4c5f-b941-75e4a0c62345"
/>

after:
<img width="1181" height="288" alt="after"
src="https://github.com/user-attachments/assets/7ad56e13-3723-4b48-aa3d-59eca6038a7f"
/>


Release Notes:

- Fixed dragging local Windows files onto a Zed window connected to a
WSL remote.
2026-07-31 10:49:11 +00:00
Tai Nguyen 5e022b02bc Reset panel saved size when default_size changes (#61855)
Closes #59235

When a panel's `default_size` changes (e.g. `git_panel.default_width` is
edited in settings), the persisted per-workspace size is now cleared so
the new default takes effect immediately. Previously the saved dragged
size took precedence forever, making `default_width` effectively useless
after the first manual resize.

This fix is at the Dock level (`crates/workspace/src/dock.rs`), so it
applies to all panels — Git Panel, Project Panel, Terminal Panel, etc.

Release Notes:

- Fixed panel `default_width` setting being ignored after manually
resizing the panel


https://github.com/user-attachments/assets/97ef69b2-387f-4e29-bc4c-0f336f24eb0b
2026-07-31 09:27:11 +00:00
Mayank Verma 938f8d7454 gpui: Add resizable and minimizable state to Window (#61473)
### Objective

PR #36859 made native macOS and Windows controls respect `is_resizable`
and `is_minimizable`, but custom window decorations cannot access those
values from `Window`. Linux custom controls and client-side resize
interactions remain active, macOS custom titlebar double-click does not
check either option and custom Windows caption buttons still appear
enabled even though the backend blocks their actions.

### Solution

Expose `is_resizable` and `is_minimizable` on `Window`. Use them to
disable custom window controls and titlebar actions and omit client-side
resize cursors and hitboxes for non-resizable windows.

## 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
- [x] Performance impact has been considered and is acceptable

Release Notes:

- N/A
2026-07-31 06:38:08 +00:00
Ayush Patil d8c3ed1acb Register Git submodules under their own project path (#61859)
Closes #61671

A submodule's `.git` is a file pointing into the superproject's
`.git/modules/<name>`, which looks just like a linked worktree's `.git`
file. The identity-path resolution used for recent projects and project
grouping treated them the same, so submodules got registered under
`.git/modules/<name>` instead of their own folder.

The fix detects submodule git dirs (`is_submodule_git_dir`) and skips
resolution for them, so a submodule keeps its own working directory as
its identity. Linked worktrees and bare repos are unaffected.

### Current vs. Expected

Current: opening submodule `Foo/Bar` registers the path as
`Foo/.git/modules/Bar`.
Expected: it registers as `Foo/Bar`, like any other project.

### Video


https://github.com/user-attachments/assets/e2eee5e7-ef64-47ed-9780-6fcafda5ae30

### Tests

- `is_submodule_git_dir` unit test
- `resolve_git_worktree_to_main_repo` returns `None` for a submodule
- persistence test asserting the submodule identity stays at its own
folder

Release Notes:

- Fixed Git submodules being registered under the parent repository's
`.git/modules` directory instead of their own path
2026-07-30 19:44:22 +00:00
Dino cf688465c7 project_panel: Refactor undo and redo error messages (#60186)
# Objective

Improve the error messages shown when undoing or redoing project panel
operations fail. Right now we're mostly relying on the error message
generated by the underlying function or method that attempts to apply
the inverse operation, which might not be the best UX.

## Solution

* Update the style used in the `Workspace::show_notification` call,
under `project_panel::undo::Inner::show_error`, in order to use markdown
styling. This allows paths to stand out a little bit better, which is
helpful seeing as pretty much all error messages will contain path
information in the notification's body.
* Update the way paths are displayed so as to show the full relative
path and, if multiple worktrees are present, include the worktree name.
This helps disambiguate cases where multiple worktrees might have the
same path, for example, `src/lib.rs`.
* Update each specific operation's error message to better convey what
exactly failed.

## Testing

Manually tested each of the scenarios outlined in the `Showcase`
section. Please refer to the screenshots in that section to see before
and after comparisons

## 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
- [x] Performance impact has been considered and is acceptable

## Showcase

### Undo failures

<details>
<summary>1. Move conflict</summary>

| Steps | Before | After |
| --- | --- | --- |
| 1. Move `a.txt` into `docs/` (cut/paste or drag)<br>2. Run `touch
a.txt`<br>3. Undo | <img width="2736" height="1586" alt="1_before"
src="https://github.com/user-attachments/assets/d60660d1-ba85-4a08-82a3-a6e3f6d84506"
/> | <img width="2736" height="1586" alt="1_after"
src="https://github.com/user-attachments/assets/c050f287-b186-42db-8995-57102d1db4d2"
/> |

</details>

<details>
<summary>2. Rename conflict</summary>

| Steps | Before | After |
| --- | --- | --- |
| 1. Rename `a.txt` → `b.txt`<br>2. Run `touch a.txt`<br>3. Undo | <img
width="2736" height="1586" alt="2_before"
src="https://github.com/user-attachments/assets/0c0eb0bc-ea01-4642-a63a-69687b2ba13e"
/> | <img width="2736" height="1586" alt="2_after"
src="https://github.com/user-attachments/assets/68dba045-60b2-462e-9f34-5bb038a4a245"
/> |

</details>

<details>
<summary>3. Source no longer exists</summary>

| Steps | Before | After |
| --- | --- | --- |
| 1. Move `a.txt` into `docs/`<br>2. Run `rm docs/a.txt`<br>3. Undo |
<img width="2736" height="1586" alt="3_before"
src="https://github.com/user-attachments/assets/2f55327c-d478-44f5-ac85-5e0b10044a52"
/> | <img width="2736" height="1586" alt="3_after"
src="https://github.com/user-attachments/assets/5296b431-c2a1-408e-8920-9f2d5c1d169a"
/> |

</details>

<details>
<summary>4. Restore from emptied Trash</summary>

| Steps | Before | After |
| --- | --- | --- |
| 1. Delete `a.txt` (moves it to Trash)<br>2. Empty it from the system
Trash<br>3. Undo | <img width="2736" height="1586" alt="4_before"
src="https://github.com/user-attachments/assets/41966e44-409a-4ae2-ada1-59992658f1b5"
/> | <img width="2736" height="1586" alt="4_after"
src="https://github.com/user-attachments/assets/f6df01f9-0702-4f28-80aa-eb2289077ea5"
/> |

</details>

<details>
<summary>5. Restore collision</summary>

| Steps | Before | After |
| --- | --- | --- |
| 1. Delete `a.txt` (to Trash)<br>2. Run `touch a.txt`<br>3. Undo | <img
width="2736" height="1586" alt="5_before"
src="https://github.com/user-attachments/assets/f4151e85-7668-4dab-8cf4-b45ef0fdb741"
/> | <img width="2736" height="1586" alt="5_after"
src="https://github.com/user-attachments/assets/3f25aa56-1b59-4230-9a15-b39a0d280a48"
/> |

</details>

<details>
<summary>6. Trash a file that's gone</summary>

| Steps | Before | After |
| --- | --- | --- |
| 1. Create `empty.txt` in the panel<br>2. Run `rm empty.txt`<br>3. Undo
| <img width="2736" height="1586" alt="6_before"
src="https://github.com/user-attachments/assets/077edeb8-3618-4b72-b49f-9d1cc3a801d5"
/> | <img width="2736" height="1586" alt="6_after"
src="https://github.com/user-attachments/assets/4b1d6689-93b1-4725-8829-2f71b4b586e9"
/> |

</details>

### Redo failures

<details>
<summary>7. Redo a move into an occupied destination</summary>

| Steps | Before | After |
| --- | --- | --- |
| 1. Move `a.txt` into `docs/`, then Undo (file back at root)<br>2. Run
`touch docs/a.txt`<br>3. Redo | <img width="2736" height="1586"
alt="7_before"
src="https://github.com/user-attachments/assets/d6591d08-b0a1-4992-866f-fcc26491ba8c"
/> | <img width="2736" height="1586" alt="7_after"
src="https://github.com/user-attachments/assets/b46d5fe2-09be-4264-9834-f5965f5f1150"
/> |

</details>

<details>
<summary>8. Redo a restore after the Trash was emptied</summary>

| Steps | Before | After |
| --- | --- | --- |
| 1. Create `empty.txt`, then Undo (it gets trashed)<br>2. Empty it from
the system Trash<br>3. Redo | <img width="2736" height="1586"
alt="8_before"
src="https://github.com/user-attachments/assets/9ced2696-1bdf-4b33-aaaf-abc015787505"
/> | <img width="2736" height="1586" alt="8_after"
src="https://github.com/user-attachments/assets/bfc84fc3-c97f-474d-857c-3d5137d06b83"
/> |

</details>

<details>
<summary>9. Redo a re-trash of a deleted file</summary>

| Steps | Before | After |
| --- | --- | --- |
| 1. Delete `a.txt` (to Trash), then Undo (restores it)<br>2. Run `rm
a.txt`<br>3. Redo | <img width="2736" height="1586" alt="9_before"
src="https://github.com/user-attachments/assets/3152787d-c02c-482e-a70a-600e97a44b3b"
/> | <img width="2736" height="1586" alt="9_after"
src="https://github.com/user-attachments/assets/7dd40497-0dfc-41fa-a6ac-772562d29258"
/> |

</details>

---

Release Notes:

- N/A
2026-07-28 12:22:11 +00:00
Kevin BravoandSmit Barmase 0c69ff7a3d markdown_preview: Open relative links at line (#60864)
Closes #60733

# Objective

Markdown Preview treats a relative `path:line[:column]` destination as a
literal filename. When that file does not exist, the link falls through
to the system URL handler instead of opening the workspace file at the
requested position.

## Solution

- Recognize position suffixes on relative Markdown links.
- Convert GitHub-style `#L42` fragments into the same positioned target
used by `path:42`, so both forms share one resolution and opening path.
- Resolve links with `workspace::path_link::possible_open_target` using
the Markdown source directory. This keeps the remote-project path
resolution added in #61438.
- Open resolved targets with `editor::items::open_resolved_target`,
including its one-based row and column handling.
- Preserve valid URI schemes and fall back to the existing Markdown link
behavior when no workspace target resolves.

## Testing

- Extended the Markdown Preview GPUI regression test to cover relative
`path:line:column`, GitHub-style `#Lline`, subfolder-relative
resolution, and custom URI schemes.
- `git diff --check` passes.
- The focused Rust test could not start in the current macOS environment
because the Rust toolchain binaries hang in the dynamic loader before
Cargo runs. PR Actions are awaiting maintainer approval.

## Self-Review Checklist:

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

Release Notes:

- Fixed Markdown Preview links using workspace-relative paths with line
and column suffixes.

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-07-28 05:45:13 +00:00
Ben Kunkle ecac6c00a6 Fix zoomed panels closing when focus moves within the panel (#59439)
Closes FR-139

Most focus-lost issues that close the agent panel in Zen mode stem from
panels returning a transient child editor's focus handle from
`Focusable::focus_handle`. The Zen-mode check closes the zoomed panel
when the focused element is not a descendant of the panel's focus
handle, so any focus movement inside the panel that landed outside that
child editor looked like the panel losing focus.

This PR separates the two roles that handle was serving:

- `Focusable::focus_handle` now always returns a stable handle tracked
at the panel's root element, used for containment checks (Zen-mode
auto-close, `toggle_panel_focus`, dock focus subscriptions).
- The new `Panel::activation_focus_handle` returns what should receive
focus when the panel is activated (e.g. a filter/commit/message editor)
and must be a focus-tree descendant of the root handle. All "focus the
panel" callsites in workspace/dock now use it.

Migrated panels: `AgentPanel` (including thread views and the toolbar
title editor), `CollabPanel`, `GitPanel`, `OutlinePanel`, and
`TerminalPanel` (previously delegated to the active pane, so focus in a
non-active pane dropped containment). `CollabPanel` activation falls
back to the panel root when signed out or collaboration is disabled,
since the filter editor isn't rendered in those states. Also fixes
duplicate element ids for tool calls with multiple content blocks.

Tests: a regression test that clicks tool-call output and focuses the
thread title editor while zoomed (both previously closed Zen mode), and
a dock-level test asserting the activation handle receives focus on
panel activation while the panel root reports containment.

Release Notes:

- Fixed zoomed panels (e.g. the agent panel in Zen mode) closing
unexpectedly when focus moved to elements inside the panel, such as tool
call output or the thread title editor.
2026-07-27 17:11:33 +00:00
Lukas Wirth b73d91382d workspace: Retain panes while saving (#61683)
Save tasks can suspend while waiting for prompts, formatting, or
filesystem I/O. Holding only a WeakEntity<Pane> allowed the pane to be
released during those suspension points, surfacing an internal 'entity
released' error as a failed save.

Instead upgrade the pane once the save operation starts so we can ensure
it finishes.


---

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-07-26 19:59:54 +00:00
Anthony Eid 3b9b83b354 collab: Fix multiworkspace location out of sync bugs (#61598)
### Summary

This PR fixes three small bugs that could cause a multi-workspace's
reported location to be out of sync with its actual location, which
causes following to break in multiplayer collaboration sessions.

The first bug was that each child workspace's title bar within a
multi-workspace had its own `cx.observe_window_activation` subscription
that would set the associated child workspace's project location. This
caused problems because it ran for all child workspaces instead of just
the active workspace within the multi-workspace. The fix was moving
`cx.observe_window_activation` to the `cx.observe_new` call in the
`call` crate that tracks newly created windows/multi-workspaces.

The second bug was caused by an incorrect `if` statement in a
`MultiWorkspace` subscription that would return early if the window was
active and the event emitted by `MultiWorkspace` wasn't
`ActiveWorkspaceChanged`. This caused issues when the window was
inactive because it would incorrectly set the active call's location to
the wrong project. The fix was making the early return happen if the
window wasn't active.

The third bug was that every child `Workspace` also observed window
activation and called `update_active_view_for_followers`. This allowed
hidden workspaces to report their active view instead of only the active
workspace.

### Testing

I added a property test for bugs one/two and another prop test for bug 3


Release Notes:

- collab: Fix out of sync following bugs
2026-07-25 03:39:45 +00:00
saberoueslatiandNathan Sobo 69518271c9 workspace: Rename read-only tab controls from File to Tab (#61202)
## Context

The editor tab's read-only controls used "File" terminology in their
tooltips and the tab context menu ("Make File Read-Only", "Locked File",
"Read-Only File", etc.). This was misleading in two ways: the option
also appears on unsaved and non-file tabs that have no file on disk, and
the toggle only controls whether the buffer is editable in the editor,
it does not change filesystem permissions. This renames the labels to
lock/unlock "Tab" language, matching the lock icon shown when the tab is
toggled.

Closes #60079.

Behavior after the change :

[Screencast from 2026-07-17
15-35-30.webm](https://github.com/user-attachments/assets/5fb018cb-515f-449c-a57e-0c0bead250bd)


## How to Review

1 file changed:

**crates/workspace/src/pane.rs**
Renames three sets of user-facing strings, all pure text changes with no
behavior change. The read-only toggle button tooltips become "Unlock
Tab" / "This will make this tab editable" and "Locked Tab" / "This tab
is read-only". The tab tooltip meta label becomes "Read-Only Tab". The
context menu entry, whose label already depends on
`capability.editable()`, becomes "Lock Tab for Editing" (when currently
editable) and "Unlock Tab for Editing" (when currently read-only); the
click handler still calls `toggle_read_only`, so the mapping from label
to action is preserved.

## 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 is consistent with the UI/UX checklist
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Improved read-only tab controls to use "Tab" instead of "File" in
tooltips and the tab context menu, since the toggle affects editability
in the editor rather than filesystem permissions.

---------

Co-authored-by: Nathan Sobo <nathan@zed.dev>
2026-07-24 22:54:30 +00:00
Richard Feldman 396cdc37c1 gpui: Defer element arena clears while an enclosing draw is in progress (#60295)
GPUI allocates every element for a draw in a single per-App bump arena,
and `Arena::clear()` assumed no draw was in progress. But draws can
nest: on Windows, the window procedure re-enters whenever the main
thread pumps messages mid-draw (cross-thread `SendMessage` dispatch,
modal message loops entered by COM/OLE calls such as clipboard reads),
and on any platform a draw can be triggered from within another draw
(e.g. `open_window`). When a nested draw finished, its arena clear freed
and rewound memory the outer draw was still using. The `ArenaBox`
validity flag only guards new derefs, so `&mut` references already held
by the outer draw silently pointed into reused memory. That
use-after-free corrupted element-state keys
(`GlobalElementId`/`SharedString` Arcs) and heap metadata, crashing
later in innocent-looking frames — seen in the wild as
`EXCEPTION_ACCESS_VIOLATION_READ / 0xffffffffffffffff` in
`Frame::finish` and element allocation
([ZED-9QN](https://zed-dev.sentry.io/issues/7577818040/),
[ZED-7JC](https://sentry.io/organizations/zed-dev/issues/7465778926/),
[ZED-7C6](https://zed-dev.sentry.io/issues/7460258444/)), plus
occasional "attempted to dereference an ArenaRef after its Arena was
cleared" panics (ZED-96P, ZED-8XN), Windows-dominant and spanning
versions 1.1.7–1.8.2.

The fix makes the arena sound under nesting: `ElementArenaScope` tracks
a scope depth on the arena, and `Arena::clear()` is deferred while any
scope is active — the outermost draw's clear drops both draws'
allocations. Since arena chunks are stable heap blocks and allocation
only appends, nested allocation was already safe; the mid-draw clear was
the only destructive operation. Scopes are ended via a consuming
`exit(arena)` call that asserts arena identity (by pointer comparison,
never dereferencing), and `ArenaClearNeeded::clear(cx)` reaches the
arena through the App, so this bookkeeping contains no unsafe code
beyond what existed before. A panic that unwinds a draw balances the
scope depth in the guard's `Drop`, so later clears still run; only the
unwound draw's own clear token is never produced, leaving the arena
populated until the next draw's clear — a one-frame leak at worst, never
a use-after-free.

Additionally, draws are no longer run re-entrantly: GPUI's
`on_request_frame` callback skips requests that arrive while a draw is
already on the thread's stack (remembering `force_render` for the next
frame), and on Windows a `DrawCoordinator` owned by the platform and
shared with every window additionally guards the wider `draw_window`
span (presentation, IME updates). Deferred windows validate their update
region (so nested message pumps don't busy-loop on WM_PAINT) and are
repainted at most one vsync later by the vsync thread's existing
per-tick invalidation.

An integration test opens a window from within an element's paint;
without the deferred clear it reproduces the exact "ArenaRef after its
Arena was cleared" panic seen in the wild. Deferrals are logged so the
diagnosis can be confirmed from user logs.

Closes FR-110

Closes FR-114

Release Notes:

- Fixed a crash on Windows caused by re-entrant window drawing
corrupting UI element memory.
2026-07-22 15:25:22 +00:00
Smit Barmase 1cd105ee93 markdown_preview: Fix relative links in remote Markdown subfolders (#61438)
Closes #58270

In remote projects, Markdown previews resolved relative links from the
project root instead of the Markdown file's folder. Links worked for
files in the root but could fail or open the wrong file for files in
subfolders.

Zed now resolves these links from the Markdown file's folder. The fix
updates base path handling in `open_url_or_file`. Only Markdown Preview
passes a base path to this function.

I tested it on macOS with a Linux SSH host and on Windows with WSL.

Release Notes:

- Fixed relative links in Markdown previews for files in subfolders when
using SSH or WSL.
2026-07-22 09:10:58 +00:00
DavidandYara 🏳️‍⚧️ 750848adb9 Fix workspace::ReopenLastPicker action when which_key helper is enabled (#61002)
# Objective

Fixes #60612 

`workspace::ReopenLastPicker` should open the stashed picker _after_ the
active model is dismissed

## Solution

Queue reopen requests when another modal is active, then reveal the
stashed modal after `hide_modal` clears the layer. Reset queued reveals
when explicitly opening a new modal.

## Testing

Confirmed `ReopenLastPicker` keybind working even when which_key is
enabled with delay=`0ms`. Tested with file_finder and text_finder.

## 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 `workspace::ReopenLastPicker` when `which_key` helper menu is
enabled

Co-authored-by: Yara 🏳️‍⚧️ <git@yara.blue>
2026-07-22 01:11:53 +00:00
Ruslan Semagin 5f865ffd69 Show runnable task results in gutter (#61095)
# Objective

- Make runnable task results visible directly in the editor gutter after
running a test or task.
- This makes it easier to see whether the last run passed or failed
without looking at the terminal output.

## Solution

- Track the completion result for scheduled runnable tasks.
- Show the last runnable result in the gutter:
  - running task: accent play icon
  - successful task: success check icon
  - failed/cancelled task: error icon
- Apply the same status update path when running from the gutter play
button and from inline code lens actions such as `Run Test`.

## Testing

- Ran `cargo check -p editor -p workspace`.
- Ran `cargo test -p workspace
test_schedule_resolved_task_with_completion_reports_success`.
- Manually tested running a GPUI test from the gutter play button.
- Manually tested running a GPUI test from the inline `Run Test` code
lens.
- Verified the gutter icon updates after completion in both cases.

## 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="1897" height="691" alt="before"
src="https://github.com/user-attachments/assets/614c2811-ee0a-43c0-8619-d0301836aa62"
/>

After:
<img width="1897" height="691" alt="after"
src="https://github.com/user-attachments/assets/a3db19f2-71e6-4c9b-824d-43a4f020a6b7"
/>

---

Release Notes:

- Improved runnable tasks by showing the last run result in the editor
gutter.
2026-07-21 05:36:42 +00:00
cf42c37f29 Fix active pane border and pane opacity dimming showing simultaneously on editor panes and terminal panes (#56595)
When `active_pane_modifiers.border_size` is set in `settings.json`, both
the active editor pane and the active terminal pane would display a
border simultaneously, making it impossible to tell which pane actually
has focus. The pane opacity dimming also renders simultaneously before
this fix.

1. Before fix: impossible to tell which pane has focus
<img width="901" height="732" alt="image"
src="https://github.com/user-attachments/assets/cbcad798-0d72-420c-9585-2dafa867ff2b"
/>

2. After fix: only one pane has focus
<img width="902" height="731" alt="image"
src="https://github.com/user-attachments/assets/97f2238e-4789-41b3-97e3-98cb9a0c82ef"
/>

The root cause is that both the workspace center and the terminal panel
pass their own `active_pane` to `PaneRenderContext`, so each pane group
unconditionally marks its active pane for border rendering. The fix adds
a focus check so `active_pane_ix` is only set when the pane actually has
keyboard focus, ensuring only the truly focused pane gets the border
(and the inactive_opacity dimming applies correctly to unfocused
groups).

Self-Review Checklist:

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


Release Notes:

- Fixed active pane border being drawn on both the editor pane and
terminal pane simultaneously

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-07-20 14:16:00 +00:00
Jakub Konkaandapoorva-01 913a81546d workspace: Fix crash when closing active item mid-update (#61336)
Closes https://github.com/zed-industries/zed/issues/61182

Supersedes https://github.com/zed-industries/zed/pull/61232

Closes FR-128

Release Notes:

- Fixed crash when closing active item while the workspace was
mid-update (double-lease panic).

Co-authored-by: apoorva-01 <vermaapoorva0510@gmail.com>
2026-07-20 12:39:07 +00:00
Agani Daniel .SandSmit Barmase a77838bb98 workspace: Rename "Discard" to "Discard Edits" in file conflict prompt (#55870)
When a file has unsaved edits and has also changed on disk, the conflict
prompt offered "Overwrite / Discard / Cancel". Both "Overwrite" and
"Discard" were directionally ambiguous, it wasn't clear whether the disk
contents or the buffer edits would be lost. "Discard Edits" makes it
explicit that the buffer edits are thrown away and the disk version is
reloaded.

Release Notes:

- Improved the file conflict prompt by renaming the "Discard" button to
"Discard Edits" to clarify that unsaved edits are discarded in favor of
the on-disk contents.

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-07-20 06:58:37 +00:00
Austin Cummings 4a1ed927ff Fix preview button acting on the focused editor instead of its own pane (#61218)
Closes #54951

## Problem

The quick action bar's preview button (markdown, SVG, and CSV behind the
feature flag) resolved everything through `workspace.active_item()` —
the globally *focused* item — instead of the item of the pane the button
sits in. With `A.md` in the left pane and focus in `B.md` in the right
pane:

- Clicking the eye button in **A.md's** toolbar opened a preview of
**B.md**, in the right pane.
- Focusing a non-previewable file (e.g. `B.sh`) in one pane hid the
button in **every** pane's toolbar, making `A.md` unpreviewable by
mouse.

Clicking the button dispatched the `OpenPreview` action, whose
workspace-level handler re-resolved the focused editor — so a click on a
specific pane's toolbar was functionally identical to pressing the
keybinding, discarding the pane the click happened in.

## Fix

Make the flow pane-explicit end to end:

- **Visibility:** each pane's `QuickActionBar` resolves the preview type
from its own `active_item` (set via `set_active_pane_item`) instead of
the workspace's focused item.
- **Click:** no more action dispatch. The handler resolves its pane via
`Workspace::pane_for` and calls new pane-explicit helpers —
`open_preview_in_pane` / `open_preview_to_the_side_of_pane` — extracted
from the action-handler bodies in all three preview crates. Keyboard
actions keep their focus-based semantics and route through the same
helpers with the focused editor and active pane.
- **Alt-click** (open in split) now splits relative to the button's pane
via the new `Workspace::adjacent_pane_of` (the existing `adjacent_pane`
delegates to it).

Notably *not* done: focusing the button's pane and re-dispatching the
action. `workspace.active_pane` only updates when pane focus-in
listeners fire at the end of the next draw, while dispatched actions run
before it — the handler would still read the stale pane.

## Additional changes

- Existing-preview lookup now happens **before** view construction,
instead of building a full preview view (subscriptions, initial parse)
and discarding it when one already exists.
- The `focus` flag now also applies to the activate-existing branch, so
open-to-the-side never steals focus — previously the *first* invocation
left focus in the editor but a *repeat* invocation focused the existing
preview (and cancelled collaborator-following in that pane as a side
effect).
- SVG handlers no longer double-check `is_svg_file`; CSV handlers reuse
`resolve_active_item_as_csv_editor` instead of inlining it;
`is_markdown_file` takes `&App` instead of a needless `&mut Context<V>`.

## Testing

- New regression test
`preview_opens_for_the_given_pane_not_the_focused_editor` reproducing
the issue's setup (two panes, focus in the second, preview invoked for
the first pane's editor), asserting the preview opens in the invoking
pane bound to that pane's editor with the focused pane untouched.
- Markdown/SVG/CSV preview suites and the full `workspace` suite pass;
`./script/clippy` is clean.

Release Notes:

- Fixed the preview button (Markdown/SVG) previewing the focused file
instead of the file in the pane the button belongs to when multiple
panes are open
2026-07-20 04:08:28 +00:00
ᴀᴍᴛᴏᴀᴇʀ 8f631833cf workspace: Fix bottom dock clipping when resizing windows (#61161)
# Objective

Fixes #59983.

Reducing the Zed window height with the terminal open can clip the
Bottom Dock and terminal content. The dock should shrink to remain
within the workspace instead of extending beyond the window.

## Solution

Restore height clamping for Bottom Dock panels by skipping
`clamp_panel_size` only when a panel actually uses flexible width.
Flexible sizing remains unchanged for the Left and Right Docks, while
Bottom Dock panels once again reduce their stored height to fit the
available workspace.

## Testing

Added a regression test that distinguishes flexible Bottom and Right
Dock behavior. It confirms that the Bottom Dock is clamped while the
flexible-width Right Dock is not. The test failed with the previous
condition and passed with this change.

Manually verified the reported window-resizing scenario 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

## Showcase

+ Before


https://github.com/user-attachments/assets/c56995a8-47c6-45b6-aeb4-b0b56477c737

+ After


https://github.com/user-attachments/assets/97b5ca6f-cf6f-4dd5-b981-e44bd8139490

---

Release Notes:

- Fixed bottom dock clipping when resizing windows.
2026-07-20 03:31:10 +00:00
Lukas Wirth 28b8e5812d workspace: Run possible_open_target logic on the background (#61257)
This is a lot of computation work which otherwise hangs the ui thread

Closes FR-122

Release Notes:

- Fixed a cause for ui hangs when interacting with the agent panel
2026-07-18 14:45:31 +00:00
Eric HolkandDanilo Leal ce3a79d607 Round window corners on the sidebar side on Linux (#61229)
On Linux with client-side decorations, opening the workspace sidebar
squared off the window corners on the sidebar's side while the rest of
the window stayed rounded:

Before:
<img width="366" height="239" alt="image"
src="https://github.com/user-attachments/assets/e0ee8d28-6143-42ea-bfd2-10d069df5492"
/>

After:
<img width="426" height="219" alt="image"
src="https://github.com/user-attachments/assets/51d2979d-0103-4742-90bd-a97f5837d99b"
/>

Previously, `client_side_decorations` took a `border_radius_tiling`
override that `MultiWorkspace` used to deliberately square the window
shape on the sidebar's side, since the sidebar painted a square
background that would otherwise poke out past the rounded window border.
The title bar and status bar already skip rounding their corners on the
sidebar side, implying the sidebar is expected to own those window
corners — it just never rounded them.

This PR makes the sidebar round its outer corners the same way the title
bar and status bar do (including overlapping the 1px window border on
untiled edges to avoid a transparent gap in the rounded corners), and
removes the now-unneeded `border_radius_tiling` parameter so the window
border and backdrop round purely based on actual tiling state.

Only applies when the window uses client-side decorations, so macOS and
Windows are unaffected.

Fixes #54724 

Release Notes:

- Fixed square window corners on the sidebar side of client-decorated
(Linux) windows when the workspace sidebar is open.

---------

Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
2026-07-17 23:58:06 +00:00
Daniel StrobuschandSmit Barmase 4d72db8bc9 file_finder: Add include_ignored parameter to Toggle action (#59568)
# Objective

Allow keybindings to open the file finder with ignored files
pre-included, regardless of the global `file_finder.include_ignored`
setting:

```json
  {
    "bindings": {
      "ctrl-shift-o": ["file_finder::Toggle", { "include_ignored": true }]
    }
  }
```

Closes https://github.com/zed-industries/zed/discussions/42575

## Solution

- Describe the solution used to achieve the objective above.

## Testing

- Did you test these changes? If so, how?
   manually locally and a unit test.
- Are there any parts that need more testing?
  no
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
   no
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
  macOS

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

> This section is optional. If this PR does not include a visual change
or does not add a new user-facing feature, you can delete this section.

- Help others understand the result of this PR by showcasing your
awesome work!
- If this PR includes a visual change, consider adding a screenshot,
GIF, or video
- A before/after comparison is very useful for changes to existing
features!

While a showcase should aim to be brief and digestible, you can use a
toggleable section to save space on longer showcases:

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

My super cool demos here

</details>

---

Release Notes:

- Added `include_ignored` parameter to `file_finder::Toggle` action,
allowing keybindings to open the file finder with ignored files
pre-included.

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-07-16 10:30:16 +00:00
i18uandKirill Bulatov 1f3ade2e04 workspace: Prevent overwriting window bounds when window is not active (#60950)
# Objective

- Prevent the Zed window height from shrinking to the built-in MacBook
screen's height after macOS screen lock or display sleep in
multi-monitor setups.
- Related to #41246.

## Solution

- Ignore window bounds change events in `observe_window_bounds` if the
window is currently inactive (`!window.is_window_active()`).
- **Explanation**: When the system locks or sleeps, macOS reconfigures
displays (monitors power down, and macOS temporarily treats the built-in
screen as the only primary display). This triggers a resize event on
inactive Zed windows to fit them onto the built-in display. Because the
window was inactive, the `observe_window_bounds` listener still
triggered and scheduled `save_window_bounds`, immediately overwriting
the workspace database with the temporary shrunk dimensions.
- By ignoring bounds updates when the window is inactive, we preserve
the correct original bounds in the database. Since a user-initiated
resize/move always activates/focuses the window first, bounds will still
be correctly persisted for intentional manual updates.

## Testing

- Yes, tested locally on macOS (Sequoia).
- Verified that compiling the `workspace` crate succeeds (`cargo check
-p workspace`).
- Ran all 220 unit tests in the `workspace` crate (`cargo test -p
workspace`), and all passed successfully.
- **How to test**:
1. Open Zed on an external monitor and set it to a large size (or
maximize).
  2. Lock the screen (or let the displays sleep).
  3. Wake/unlock the screen.
4. Verify that the window recovers and maintains its original height
instead of shrinking.

## 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 an issue where the Zed window would shrink to the built-in
display's height on macOS after screen lock or display sleep in
multi-monitor setups.

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-07-16 10:06:41 +00:00
Shuhei KadowakiandDanilo Leal e9882ea4d2 workspace: Add visual indicator for editor zoom (#61039)
The earlier editor-only zoom implementation in #32860 rendered the
active pane with padding, a border, rounded corners, and a shadow. In
addition to keeping docks visible, that treatment made the transient
editor zoom mode apparent.

The current `ToggleEditorZoom` implementation (#53911) only omits
sibling panes from the pane group, without any visual indication.
Without a persistent control or decoration, the result can look like an
ordinary single-pane layout, so users cannot tell whether toggling the
command will restore hidden splits.

So this commit renders the maximized pane as an inset card with padding,
a subtle theme border, rounded corners, and a shadow. Keeping this
treatment in `PaneGroup` makes it apply only to editor zoom, leaves
docks untouched, and distinguishes it from `ToggleZoom`'s square
workspace overlay.

## Showcase

<img width="862" height="415" alt="Screenshot 2026-07-15 at 18 51 30"
src="https://github.com/user-attachments/assets/f61c61ce-79b7-4e3a-a9c4-0775931fa90d"
/>

---

Release Notes:

- N/A

---------

Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
2026-07-15 23:21:16 +00:00