Add initial support for WSL (#37035)

Closes #36188

## Todo

* [x] CLI
* [x] terminals
* [x] tasks

## For future PRs
* debugging
* UI for opening WSL projects
* fixing workspace state restoration

Release Notes:

- Windows alpha: Zed now supports editing folders in WSL.

---------

Co-authored-by: Junkui Zhang <364772080@qq.com>
This commit is contained in:
Max Brunsfeld
2025-08-29 17:18:52 -07:00
committed by GitHub
co-authored by Junkui Zhang
parent 1c2e2a00fe
commit f78f3e7729
27 changed files with 1701 additions and 786 deletions
+17 -16
View File
@@ -1,9 +1,10 @@
pub mod disconnected_overlay;
mod remote_connections;
mod remote_servers;
mod ssh_config;
mod ssh_connections;
pub use ssh_connections::{is_connecting_over_ssh, open_ssh_project};
use remote::RemoteConnectionOptions;
pub use remote_connections::open_remote_project;
use disconnected_overlay::DisconnectedOverlay;
use fuzzy::{StringMatch, StringMatchCandidate};
@@ -16,9 +17,9 @@ use picker::{
Picker, PickerDelegate,
highlighted_match_with_paths::{HighlightedMatch, HighlightedMatchWithPaths},
};
pub use remote_connections::SshSettings;
pub use remote_servers::RemoteServerProjects;
use settings::Settings;
pub use ssh_connections::SshSettings;
use std::{path::Path, sync::Arc};
use ui::{KeyBinding, ListItem, ListItemSpacing, Tooltip, prelude::*, tooltip_container};
use util::{ResultExt, paths::PathExt};
@@ -290,7 +291,7 @@ impl PickerDelegate for RecentProjectsDelegate {
if workspace.database_id() == Some(*candidate_workspace_id) {
Task::ready(Ok(()))
} else {
match candidate_workspace_location {
match candidate_workspace_location.clone() {
SerializedWorkspaceLocation::Local => {
let paths = candidate_workspace_paths.paths().to_vec();
if replace_current_window {
@@ -320,7 +321,7 @@ impl PickerDelegate for RecentProjectsDelegate {
workspace.open_workspace_for_paths(false, paths, window, cx)
}
}
SerializedWorkspaceLocation::Ssh(connection) => {
SerializedWorkspaceLocation::Remote(mut connection) => {
let app_state = workspace.app_state().clone();
let replace_window = if replace_current_window {
@@ -334,18 +335,16 @@ impl PickerDelegate for RecentProjectsDelegate {
..Default::default()
};
let connection_options = SshSettings::get_global(cx)
.connection_options_for(
connection.host.clone(),
connection.port,
connection.user.clone(),
);
if let RemoteConnectionOptions::Ssh(connection) = &mut connection {
SshSettings::get_global(cx)
.fill_connection_options_from_settings(connection);
};
let paths = candidate_workspace_paths.paths().to_vec();
cx.spawn_in(window, async move |_, cx| {
open_ssh_project(
connection_options,
open_remote_project(
connection.clone(),
paths,
app_state,
open_options,
@@ -418,9 +417,11 @@ impl PickerDelegate for RecentProjectsDelegate {
SerializedWorkspaceLocation::Local => Icon::new(IconName::Screen)
.color(Color::Muted)
.into_any_element(),
SerializedWorkspaceLocation::Ssh(_) => Icon::new(IconName::Server)
.color(Color::Muted)
.into_any_element(),
SerializedWorkspaceLocation::Remote(_) => {
Icon::new(IconName::Server)
.color(Color::Muted)
.into_any_element()
}
})
})
.child({