This PR greatly improves our handling of remote threads in the sidebar.
One primary issue was that many parts of the sidebar were only looking
at a thread's path list and not its remote connection information. The
fix here is to use `ProjectGroupKey` more consistently throughout the
sidebar which also includes remote connection information.
The second major change is to extend the MultiWorkspace with the ability
to initiate the creation of remote workspaces when needed. This involved
refactoring a lot of our remote workspace creation paths to share a
single code path for better consistency.
Release Notes:
- (Preview only) Fixed remote project threads appearing as a separate
local project in the sidebar
---------
Co-authored-by: Anthony Eid <anthony@zed.dev>
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
This PR adjusts how project group removal works in the sidebar to be
project group aware. Removal is now a batched operation, and supports a
contextually appropriate fallback active workspace fallback. In the
process of removing this, I had to chase down and fix other broken code:
- Removes the "move to new window" actions
- Changed the sidebar to store things in "most recently added" order
- The recent project UI was still using workspaces, instead of project
groups
- Adjusted the archive command to use the new APIs to remove the
workspace associated with that worktree (cc: @rtfeldman)
- The property tests where still using indexes and workspaces instead of
project groups
Self-Review Checklist:
- [ ] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- N/A
This PR improves the recent projects picker in the context of
multi-workspace:
- The currently active project now appears in the "This Window" section
with a checkmark indicator. Clicking it simply dismisses the picker,
since there's nothing to switch to. This feels like a better UX because
it gives you visual confirmation of where you are.
- The remove button is hidden for the current project entry, both in the
row and the footer, to prevent accidentally removing the workspace
you're actively using.
- The "Add to Workspace" button now uses a more descriptive icon
(`FolderOpenAdd`) and shows a meta tooltip clarifying that it adds the
project as a multi-root folder project.
The primary click/enter behavior remains unchanged—it opens the selected
project in the current window's multi-workspace. The "Open in New
Window" action continues to be available via the icon button or
shift+enter.
Release Notes:
- Improved the recent projects picker to show the currently active
project in the "This Window" section with a checkmark indicator.
Self-Review Checklist:
- [ ] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
## Context
When the dev container creation modal is showing "Creating Dev
Container", clicking anywhere on the workspace backdrop dismisses the
dialog. The container creation continues in the background, but the user
loses visual feedback and the subsequent `open_remote_project` call may
fail because the modal entity is gone.
This adds an `allow_dismissal` flag to `RemoteServerProjects` that
blocks accidental dismissal (backdrop clicks, focus loss) while a dev
container is being created, but allows explicit dismissal on success or
error.
## How to Review
Small PR — two files changed:
1. **`remote_servers.rs`** (the fix): `allow_dismissal` bool field
added, set to `false` when entering Creating state, set to `true` before
emitting `DismissEvent` on success/error. `on_before_dismiss` override
checks the flag.
2. **`recent_projects.rs`** (the test): Regression test that opens a dev
container modal, simulates a backdrop click, and asserts the modal stays
open.
## 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 dev container creation modal being dismissed when clicking
outside it
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This PR makes it so using that button from the sidebar's recent projects
picker _does not_ add a new window with that project, but rather, add it
to the current multi-workspace/sidebar. Previously, the `Open` action
was defaulting to true even if `false` was passed to its
`create_new_window` condition.
Release Notes:
- N/A
This PR adds tracking of project groups to the MultiWorkspace and
serialization/restoration of them. This will later be used by the
sidebar to provide reliable reloading of threads across Zed reloads.
Release Notes:
- N/A
---------
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
## Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
## Summary
Adds a `--dev-container` CLI flag that automatically triggers "Reopen in
Dev Container" when a `.devcontainer/` configuration is found in the
project directory.
```sh
zed --dev-container /path/to/project
```
## Motivation
This enables fully scripted dev container workflows — for example,
creating a git worktree and immediately opening it in a dev container
without any manual UI interaction:
```sh
git worktree add ../feature-branch
zed --dev-container ../feature-branch
```
The dev container modal fires automatically once the workspace finishes
initializing, so the environment is ready by the time you look at the
window. This is useful for automation scripts that prepare environments
and kick off agent runs for tasks like bug report triage.
Here's an [example
script](https://github.com/antont/todo-rs-ts/blob/main/scripts/devcontainer-new.sh)
that creates a worktree and opens it as a dev container in one step.
Related: #48682 requests a `devcontainer://` protocol for connecting to
already-running dev containers — a complementary but different use case.
This PR covers the "open project and trigger dev container setup" path.
## How it works
- The `--dev-container` flag flows through the CLI IPC protocol to the
workspace as an `open_in_dev_container` option.
- On the first worktree scan completion, if devcontainer configs are
detected, the dev container modal opens automatically.
- If no `.devcontainer/` config is found, the flag is cleared and a
warning is logged.
## Notable changes
- **`Workspace::worktree_scans_complete`** promoted from `#[cfg(test)]`
to production. It was only test-gated because it had no production
callers — it's a pure read-only future with no side effects.
- **`suggest_on_worktree_updated`** now takes `&mut Workspace` to read
and clear the CLI flag.
- Extracted **`open_dev_container_modal`** helper shared between the CLI
code path and the suggest notification.
## Test plan
- [x] `cargo test -p zed open_listener` — includes
`test_dev_container_flag_opens_modal` and
`test_dev_container_flag_cleared_without_config`
- [x] `cargo test -p recent_projects` — existing suggest tests still
pass
- [x] Manual: `cargo run -- --dev-container
/path/to/project-with-devcontainer` opens the modal
Release Notes:
- Added `--dev-container` CLI flag to automatically open a project in a
dev container when `.devcontainer/` configuration is present.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This PR adds a button in the sidebar's recent projects picker to open
the remote projects modal, matching how the recent project modal itself
is. Here's the result:
<img width="400" height="428" alt="Screenshot 2026-04-01 at 7 12@2x"
src="https://github.com/user-attachments/assets/b23ff896-6d42-4ea7-92ba-9d3d092c5f03"
/>
Release Notes:
- N/A
Previously, within the recent projects modal, the ability to add a
project to the workspace, delete a project from the "this window" or
"recent projects" sections, and remove a project from the current window
were only possible to do with the mouse. This PR enables them with the
keyboard, through buttons/keybindings exposed in the modal's footer and
"actions" menu. Here's a quick video for reference:
https://github.com/user-attachments/assets/b8980ed8-ba32-4e20-93b4-c0a9ea311309
Release Notes:
- Improved keyboard navigation for the recent projects modal.
## Context
Closes#11473
In-house Zed implementation of devcontainers. Replaces the dependency on
the [reference implementation](https://github.com/devcontainers/cli) via
Node.
This enables additional features with this implementation:
1. Zed extensions can be specified in the `customizations` block, via
this syntax in `devcontainer.json:
```
...
"customizations": {
"zed": {
"extensions": ["vue", "ruby"],
},
},
```
2.
[forwardPorts](https://containers.dev/implementors/json_reference/#general-properties)
are supported for multiple ports proxied to the host
## How to Review
<!-- Help reviewers focus their attention:
- For small PRs: note what to focus on (e.g., "error handling in
foo.rs")
- For large PRs (>400 LOC): provide a guided tour — numbered list of
files/commits to read in order. (The `large-pr` label is applied
automatically.)
- See the review process guidelines for comment conventions -->
## Self-Review Checklist
<!-- Check before requesting review: -->
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Improved devcontainer implementation by moving initialization and
creation in-house
This PR changes the API for the `ListItem`'s `end_hover` slot so that
whatever is in there is always part of the flex stack, as opposed to an
absolutely-positioned element. Additionally, I'm also improving the API
for swapping content between the default state and the hovered state
(e.g., list items where by default we render X, but when you hover, we
show something else). Lastly, I'm adding buttons to some Git picker
items that were only previously available through modal footer buttons.
Release Notes:
- N/A
## Context
TODO
## Self-Review Checklist
<!-- Check before requesting review: -->
- [ ] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable
Release Notes:
- N/A
---------
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
This PR upgrades the workspace's app state to a strong pointer. It's an
app-global concern, and it should only die when the app dies. When the
app dies the process exits, so the cyclic reference problem isn't an
issue.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
- Change the branch button's tooltip to be more accurate given it
displays more stuff than only branches
- Hide the worktree dropdown menu when in a non-Git repo project
- Improve provisioned title truncation
- Remove the plus icon from the "view more" item to improve sidebar's
overall feel
- Remove the always visible "new thread" button but make it visible only
when you're in an empty thread state
- Add worktree icon in the thread item and tooltip with full path
- Space out the worktree name from the branch name in the git picker in
the title bar
- Swap order of views in the git picker to "worktree | branches | stash"
- Improve the "creating worktree" loading indicator
---
<!-- Check before requesting review: -->
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
## Context
- Improve how we detect when the sidebar should render the empty state.
It was previously wrong using `content.entries.is_empty`, which would
also happen if there are no search matches.
- Improved archive view keyboard nav and design. Not using the ListItem
here anymore so as to avoid confusing hover and active states.
- Move archive and open folder buttons to the bottom of the sidebar.
- Add a new flavor of the recent projects for the sidebar that only
serves as a way to _add_ projects.
- Add the ability to add (and remove) folders to a given project group
in the sidebar through a dropdown menu
---
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
## Context
I have a project with a nested git repo inside a parent repo (separate
`.git` directory, not a submodule). The title bar shows the parent's
branch instead of the nested repo's own branch.
The issue is in `get_repository_for_worktree()` — it iterates
`git_store.repositories()` (an `FxHashMap`) and returns the first
`starts_with` match. Both the parent and nested repo match, and
whichever one FxHashMap iterates first wins. There's no reason it should
be one or the other.
The fix already exists elsewhere in the codebase —
`GitStore::repository_and_path_for_project_path()` at
`git_store.rs:1826` uses `.max_by_key()` to pick the most specific
(longest path) match. This PR applies the same approach to three
functions that have the same problem:
- `TitleBar::get_repository_for_worktree()` — branch display in title
bar
- `resolve_active_repository()` in `git_ui` — repository selection for
the git panel
- `get_branch_for_worktree()` in `recent_projects` — branch display in
the project switcher
Two other locations use a similar `starts_with` pattern
(`effective_active_worktree()` in `title_bar.rs` and worktree selection
in `recent_projects.rs`) but those iterate worktrees against a single
known repo, not repos against a worktree — so first-match and
longest-match give the same result. Left those unchanged.
Closes#7566
## How to Review
All three changes are the same transformation: first-match loop (or
`.find()`) → `.filter().max_by_key()` on path length. The reference is
at `crates/project/src/git_store.rs:1826`.
The primary fix is `get_repository_for_worktree()` in `title_bar.rs`.
The other two are the same pattern.
One difference from the reference: I used `.as_os_str().len()` instead
of `.clone()` for the `max_by_key` key — avoids cloning an `Arc<Path>`
per comparison. Among prefix-related paths (which is all that passes the
filter), the longer path is always the more specific match, so length
comparison is equivalent.
`title_bar` has no existing test infrastructure. Happy to add a test if
you'd like — the setup would follow the pattern in
`test_git_traversal_with_nested_repos`
(`crates/project/tests/integration/git_store.rs`).
```
cargo test -p title_bar -p git_ui -p recent_projects
./script/clippy
```
## Self-Review Checklist
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Fixed branch picker showing parent repository's branch instead of the
nested repository's branch when working in submodules or nested git
repos.
---------
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
- [x] I've reviewed my own diff for quality, security, and reliability
- [X] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
* [x] Display original project name as root folder in project panel,
titlebar
* [x] When manually creating worktrees, ensure final path component is
original project name
* [x] Display original project name, worktree name, and branch name in
titlebar
* [x] Only show main checkout in project switcher
Release Notes:
- N/A *or* Added/Fixed/Improved ...
---------
Co-authored-by: Richard Feldman <oss@rtfeldman.com>
Fixes https://github.com/zed-industries/zed/issues/50218
- For every `Host` block: collect its host patterns (handling
continuations and filtering `!`/`*/\`), remember any `Hostname`.
- When the block ends: if `Hostname` is a git provider → discard
everything.
- Else if `Hostname` exists → keep all host aliases.
- Else → keep only the host aliases that are not git providers.
Added more extensive test coverage as well to cover the above!
Release Notes:
- Fixed SSH host picker showing git provider domains (e.g. github.com,
gitlab.com) from SSH config.
---------
Co-authored-by: Nathan Sobo <nathan@zed.dev>
All of the important changes are in
[`db.rs`](https://github.com/zed-industries/zed/pull/51809/changes#diff-2f644eab943bfa58feec29256281a3d9e8d4d7784cd34783e845af8beb15b16d).
Consider reading the commit log in order to review this work.
The DB crate's macro and API was changed to fix flakiness observed in
the MultiWorkspace tests when run locally. This flakiness was caused by
a shared `static LazyLock`, that caused concurrent test runs to interact
with the same underlying in-memory database. This flakiness wasn't
possible on CI due to it's usage of `cargo nextest`, whose
process-per-test approach masked this problem.
Essentially, I've changed the `static_connection` macro to remove the
static database variable and redone the internal model. Now, all
database types are thin wrappers around a generic `AppDatabase`. The
`AppDatabase` collects all of the individual table's migrations via the
`inventory` crate, and so only runs the migrations once on startup,
rather than a dozen times on startup.
The new API requires a `cx` so that we can replace the database returned
at runtime, rather than relying exclusively on a process-global
thread-local. However, we are still using a `static LazyLock` so that we
only need to take an `&App`, instead of an `&mut App`. These databases
types are `Clone + Send + Sync`, so you can easily capture-and-move the
database into background tasks and other places that don't have a `cx`.
For tests that require database isolation, it is now possible to set
their own database in init. See
[`workspace::init_test`](https://github.com/zed-industries/zed/pull/51809/changes#diff-041673bbd1947a35d45945636c0055429dfc8b5985faf93f8a8a960c9ad31e28R13610),
for the flakiness fix.
Best part, this change should be entirely compiler driven, so the Zed
agent was able to make the app-wide refactor easily.
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
---------
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
The recent projects had two plus buttons inside of it which weren't
immediately clear what they did. Those buttons would add a project to
the current workspace, which turned out to be _not_ what people expected
it would do. Because of this, I removed one of them and swapped the icon
of the other, to hopefully make the distinction more clear.
<img width="500" height="484" alt="Screenshot 2026-03-18 at 11 59@2x"
src="https://github.com/user-attachments/assets/341769fb-771e-450b-8814-a641bd8b63d5"
/>
Release Notes:
- N/A
Closes#43329
## Summary
This fixes `path:line:column` navigation for files containing non-ASCII
text.
Before this change, open path flows were passing the external column
directly into `go_to_singleton_buffer_point`. That happened to work for
ASCII, but it was wrong for Unicode because external columns are
user-visible character positions while the editor buffer stores columns
as UTF-8 byte offsets.
This PR adds a shared text layer conversion for external row/column
coordinates and uses it in the affected open-path flows:
- file finder navigation
- recent project remote connection navigation
- recent project remote server navigation
It also adds regression coverage for the Unicode case that originally
failed.
As a small - necessary - prerequisite, this also adds
`remote_connection` test support to `file_finder`'s dev-deps so the
local regression test can build and run on this branch. That follows the
same feature mismatch pattern previously fixed in #48280. I wasn't able
to locally verify the tests/etc. w/o the addition... so I've rolled it
into this PR. Tests are green.
The earlier attempt in #47093 was headed in the right direction, but it
did not land and did not include the final regression coverage requested
in review.
## Verification
- `cargo fmt --all -- --check`
- `./script/clippy -p text`
- `./script/clippy -p file_finder`
- `./script/clippy -p recent_projects`
- `cargo test -p file_finder --lib --no-run`
- `cargo test -p file_finder
file_finder_tests::test_row_column_numbers_query_inside_file -- --exact`
- `cargo test -p file_finder
file_finder_tests::test_row_column_numbers_query_inside_unicode_file --
--exact`
- `cargo test -p text
tests::test_point_for_row_and_column_from_external_source -- --exact`
## Manual
I reproduced locally on my machine (macOS) w/ a stateless launch using a
Unicode file (Cyrillic)
Before:
- `:1:5` landed too far left
- `:1:10` landed around the 4th visible Cyrillic character
After:
- `:1:5` lands after 4 visible characters / before the 5th
- `:1:10` lands after 9 visible characters / before the 10th
Release Notes:
- Fixed `path:line:column` navigation so non-ASCII columns land on the
correct character.
---------
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
Previously, if you wanted to have a button that contains icons on both
edges, you'd need to use a `ButtonLike` component, which takes any
children. Meanwhile, the `Button` would only take one icon, where you
could control its position through the `IconPosition` enum. This has
always felt unnecessarily limiting. So, this PR removes this limitation
by adding two new methods to the button: `start_icon` and `end_icon`.
In the meantime, I have also been bothered by the unnecessary
indirection in the `IconButton` due to the existence of the `ButtonIcon`
component. So I figured I could also completely eliminate that by adding
some of its methods directly to the `IconButton` and in the Button, just
using a regular `Icon` component.
---
## Before
```rust
Button::new("id", "Label")
.icon(IconName::Plus)
.icon_position(IconPosition::Start)
.icon_size(IconSize::Small)
.icon_color(Color::Muted)
```
## After
```rust
Button::new("id", "Label")
.start_icon(Icon::new(IconName::Check))
.end_icon(Icon::new(IconName::ChevronDown).size(IconSize::XSmall))
```
This should have no visual impact to the UI.
Release Notes:
- N/A
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
Fixes https://github.com/zed-industries/zed/issues/48457
Hidden files (like .config, .ssh, etc.) were not showing in the Open
Folder dialog when browsing remote servers via SSH. This was because the
`OpenPathDelegate` was not configured to show hidden files.
This fix adds .show_hidden() when creating the delegate for remote
project picker.
Release Notes:
- Fixed the hidden files not showing in remote project's open folder
action
This will help with test times (in some cases), as nextest cannot figure
out whether a given rdep is actually an alive edge of the build graph
Closes #ISSUE
Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing
- [ ] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
Fixes ZED-517
Can be reproed by:
Going into server options of the last server on your list.
selecting "Remove server".
Clicking on the button AND issuing menu::Confirm action at the same time
(well, roughly the same time).
The result: OS pop-up is issued twice; if the user does confirm twice,
that's when that panic is hit.
Closes #ISSUE
Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing
- [ ] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- Fixed a potential crash when deleting SSH servers too eagerly.
This does not yet allow for finding task <-> entity cycles
unfortunately, but at least it does catch entity <-> entity cycles for
the time being
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Closes https://github.com/zed-industries/zed/issues/49363
When an existing remote workspace's connection is dead (e.g. the server
died and reconnect failed, leaving the client in `ServerNotRunning`
state), `remote_connection()` returns `None`. Previously this caused an
error dialog, blocking reconnection — the user had to manually switch to
another project and back to recover.
Now the code falls through to establish a fresh connection instead,
matching the previous behavior where clicking "Reconnect" would just
work.
Release Notes:
- Fixed remote reconnect failing with an error when the server is not
running, now establishes a fresh connection instead.
Before this PR we wouldn't always serialize workspaces when a
mutliworkspace adds/removes a workspace. This PR fixes this by adding a
test and calling serialization in remove
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
Re-lands https://github.com/zed-industries/zed/pull/48891, which was
reverted due to conflicts with multi-workspace.
Before you mark this PR as ready for review, make sure that you have:
- [X] Added a solid test coverage and/or screenshots from doing manual
testing
- [X] Done a self-review taking into account security and performance
aspects
Release Notes:
- N/A
Closes#42842
Previously, OpenFolderInWsl action assumed a valid path is on the host
and failed to open paths inside the WSL filesystem (accessed through
UNC)
Now the action checks for a WSL path and opens it with the appropriate
distro (skipping the choice modal)
This was manually confirmed to not regress as well as work with WSL
paths.
Code was written by hand, with extra checking by OpenAI Codex.
Release Notes:
- Fixed paths inside the WSL filesystem failing to open when using "open
folder in wsl"
Here's some backstory:
* on macOS, @cole-miller and I noticed that since roughly Oct 2025, due
to some changes to latest macOS Tahoe, for any spawned child process we
needed to reset Mach exception ports
(https://github.com/zed-industries/zed/issues/36754 +
https://github.com/RemiKalbe/zed/commit/6e8f2d2ebe5a93753625a3026aeb996de8cb436b)
* the changes in that PR achieve that via `pre_exec` hook on
`std::process::Command` which then abandons `posix_spawn` syscall for
`fork` + `execve` dance on macOS (we tracked it down in Rust's std
implementation)
* as it turns out, `fork` + `execve` is pretty expensive on macOS
(apparently way more so than on other OSes like Linux) and `fork` takes
a process-wide lock on the allocator which is bad
* however, since we wanna reset exception ports on the child, the only
official way supported by Rust's std is to use `pre_exec` hook
* posix_spawn on macOS exposes this tho via a macOS specific extension
to that syscall `posix_spawnattr_setexceptionports_np` but there is no
way to use that via any standard interfaces in `std::process::Command`
* thus, it seemed like a good idea to instead create our own custom
Command wrapper that on non-macOS hosts is a zero-cost wrapper of
`smol::process::Command`, while on macOS we reimplement the minimum to
achieve `smol::process::Command` with `posix_spawn` under-the-hood
Notably, this changeset improves git-blame in very large repos
significantly.
Release Notes:
- Fixed performance spawning child processes on macOS by always forcing
`posix_spawn` no matter what.
---------
Co-authored-by: Cole Miller <cole@zed.dev>
This PR adds the ability to, within the Recent Projects modal/popover,
quickly add a project in the recent projects section to the current
workspace. Note that this is currently limited to local projects only.
https://github.com/user-attachments/assets/6b72af11-9c94-45d3-a7df-76869b942727
Release Notes:
- Workspace: Enabled quickly adding a recent project to the current
workspace.
Closes#49055
**Heads up**: This might be a naïve solution. I ran into the issue after
merging latest main into
https://github.com/zed-industries/zed/pull/48896, and confirming that it
was unrelated to that PR and incoming from upstream.
Agent one-shot the fix, it works and tests pass. But I'm still wrapping
my head around the changes that led to the bug. I figured the breakage
is bad enough (I couldn't open devcontainers at all) to submit a
possibly naïve fix.
## Fix
Hoists the `find_devcontainer_configs` call out of `new_dev_container`
and into the call site, where we already have a direct `&mut Workspace`
reference that doesn't go through the entity map. The computed configs
are passed into `new_dev_container` as an argument.
## What was happening
After #48800 ("Re-add MultiWorkspace"), `with_active_or_new_workspace`
nests a `Workspace` entity lease inside a `MultiWorkspace` entity lease.
The `OpenDevContainer` handler was also changed from async to sync in
the same PR, so `RemoteServerProjects::new_dev_container` now runs while
`Workspace` is leased. Inside `new_dev_container`, a
`WeakEntity<Workspace>::read_with` call tries to read `Workspace`
through the entity map, finds it already leased, and panics.
Release Notes:
- Fixed a panic when opening the dev container modal via the
`OpenDevContainer` action.
This PR makes the remote projects a bit more consistent with other modal
dialogs by adding a footer to better expose the "open" and "open in new
window" options.
<img width="550" height="888" alt="Screenshot 2026-02-12 at 9 53@2x"
src="https://github.com/user-attachments/assets/1d7a67c4-fc69-40db-8dc4-8099bde4ebd7"
/>
- [x] Code Reviewed
- [x] Manual QA
Release Notes:
- N/A
Follow-up to https://github.com/zed-industries/zed/pull/46641.
In the PR linked above, I had introduced a dropdown that'd show up in
the title bar when the workspace contained more than one project.
Although that helped improve the multi-project use case, it created some
quirky designs:
- The project dropdown and the recent project pickers looked too
different from one another
- The transition between the 2 project case to the 1 project scenario,
from the dropdown, was not great, because you'd be then seeing the
bigger recent projects picker
- The `workspace: switch project` action was still reachable in the
command palette even if you had one project in the workspace
So, what this PR does is essentially fixing all of this by consolidating
it all in the Recent Projects picker. If you are in a multi-project
scenario, the picker will display a section with all of the projects on
the workspace allowing you to activate each one of them. The picker also
looks simpler when you reach it by clicking on the project name in the
title bar, as opposed to through the keybinding. I've then removed the
project dropdown code as well as the action, given we don't need them
anymore due to the consolidation. Lastly, I tackled the inconsistent
wording used between "Folders", "Projects", and "Workspaces".
Here's the result:
https://github.com/user-attachments/assets/9d8ef3e3-e57b-4558-9bc0-dcc401dec469
- [x] Code Reviewed
- [x] Manual QA
Release Notes:
- Workspace: Improved the recent projects picker by making it also
display active projects in case of a multi-project workspace.