Add WSL opening UI (#38260)

This PR adds an option to open WSL machines from the UI.

- [x] Open wsl from open remote
- [ ] Open local folder in wsl action
- [ ] Open wsl shortcut (shortcuts to open remote)

Release Notes:

- N/A
This commit is contained in:
localcc
2025-09-17 09:44:16 +00:00
committed by GitHub
parent c5ac1e6218
commit 83d9f07547
4 changed files with 1219 additions and 430 deletions
Generated
+45 -9
View File
@@ -2977,7 +2977,7 @@ dependencies = [
"num-traits",
"serde",
"wasm-bindgen",
"windows-link",
"windows-link 0.1.1",
]
[[package]]
@@ -13790,6 +13790,7 @@ dependencies = [
"theme",
"ui",
"util",
"windows-registry 0.6.0",
"workspace",
"workspace-hack",
"zed_actions",
@@ -19613,7 +19614,7 @@ dependencies = [
"windows-collections",
"windows-core 0.61.0",
"windows-future",
"windows-link",
"windows-link 0.1.1",
"windows-numerics",
]
@@ -19683,7 +19684,7 @@ checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980"
dependencies = [
"windows-implement 0.60.0",
"windows-interface 0.59.1",
"windows-link",
"windows-link 0.1.1",
"windows-result 0.3.2",
"windows-strings 0.4.0",
]
@@ -19695,7 +19696,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a1d6bbefcb7b60acd19828e1bc965da6fcf18a7e39490c5f8be71e54a19ba32"
dependencies = [
"windows-core 0.61.0",
"windows-link",
"windows-link 0.1.1",
]
[[package]]
@@ -19770,6 +19771,12 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
[[package]]
name = "windows-link"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
[[package]]
name = "windows-numerics"
version = "0.2.0"
@@ -19777,7 +19784,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
dependencies = [
"windows-core 0.61.0",
"windows-link",
"windows-link 0.1.1",
]
[[package]]
@@ -19797,11 +19804,22 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad1da3e436dc7653dfdf3da67332e22bff09bb0e28b0239e1624499c7830842e"
dependencies = [
"windows-link",
"windows-link 0.1.1",
"windows-result 0.3.2",
"windows-strings 0.4.0",
]
[[package]]
name = "windows-registry"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f91f87ce112ffb7275000ea98eb1940912c21c1567c9312fde20261f3eadd29"
dependencies = [
"windows-link 0.2.0",
"windows-result 0.4.0",
"windows-strings 0.5.0",
]
[[package]]
name = "windows-result"
version = "0.1.2"
@@ -19826,7 +19844,16 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
dependencies = [
"windows-link",
"windows-link 0.1.1",
]
[[package]]
name = "windows-result"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f"
dependencies = [
"windows-link 0.2.0",
]
[[package]]
@@ -19845,7 +19872,7 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
dependencies = [
"windows-link",
"windows-link 0.1.1",
]
[[package]]
@@ -19854,7 +19881,16 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97"
dependencies = [
"windows-link",
"windows-link 0.1.1",
]
[[package]]
name = "windows-strings"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda"
dependencies = [
"windows-link 0.2.0",
]
[[package]]
+3
View File
@@ -44,6 +44,9 @@ workspace.workspace = true
zed_actions.workspace = true
workspace-hack.workspace = true
[target.'cfg(target_os = "windows")'.dependencies]
windows-registry = "0.6.0"
[dev-dependencies]
dap.workspace = true
editor = { workspace = true, features = ["test-support"] }
@@ -17,7 +17,7 @@ use markdown::{Markdown, MarkdownElement, MarkdownStyle};
use release_channel::ReleaseChannel;
use remote::{
ConnectionIdentifier, RemoteClient, RemoteConnectionOptions, RemotePlatform,
SshConnectionOptions, SshPortForwardOption,
SshConnectionOptions, SshPortForwardOption, WslConnectionOptions,
};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
@@ -33,6 +33,7 @@ use workspace::{AppState, ModalView, Workspace};
#[derive(Deserialize)]
pub struct SshSettings {
pub ssh_connections: Option<Vec<SshConnection>>,
pub wsl_connections: Option<Vec<WslConnection>>,
/// Whether to read ~/.ssh/config for ssh connection sources.
#[serde(default = "default_true")]
pub read_ssh_config: bool,
@@ -43,6 +44,10 @@ impl SshSettings {
self.ssh_connections.clone().into_iter().flatten()
}
pub fn wsl_connections(&self) -> impl Iterator<Item = WslConnection> + use<> {
self.wsl_connections.clone().into_iter().flatten()
}
pub fn fill_connection_options_from_settings(&self, options: &mut SshConnectionOptions) {
for conn in self.ssh_connections() {
if conn.host == options.host
@@ -116,6 +121,51 @@ impl From<SshConnection> for SshConnectionOptions {
}
}
#[derive(Clone, Default, Serialize, Deserialize, PartialEq, JsonSchema)]
pub struct WslConnection {
pub distro_name: SharedString,
#[serde(default)]
pub user: Option<String>,
#[serde(default)]
pub projects: BTreeSet<SshProject>,
}
impl From<WslConnection> for WslConnectionOptions {
fn from(val: WslConnection) -> Self {
WslConnectionOptions {
distro_name: val.distro_name.into(),
user: val.user,
}
}
}
#[derive(Clone, Serialize, Deserialize, PartialEq, JsonSchema)]
pub enum Connection {
Ssh(SshConnection),
Wsl(WslConnection),
}
impl From<Connection> for RemoteConnectionOptions {
fn from(val: Connection) -> Self {
match val {
Connection::Ssh(conn) => RemoteConnectionOptions::Ssh(conn.into()),
Connection::Wsl(conn) => RemoteConnectionOptions::Wsl(conn.into()),
}
}
}
impl From<SshConnection> for Connection {
fn from(val: SshConnection) -> Self {
Connection::Ssh(val)
}
}
impl From<WslConnection> for Connection {
fn from(val: WslConnection) -> Self {
Connection::Wsl(val)
}
}
#[derive(Clone, Default, Serialize, PartialEq, Eq, PartialOrd, Ord, Deserialize, JsonSchema)]
pub struct SshProject {
pub paths: Vec<String>,
@@ -125,6 +175,7 @@ pub struct SshProject {
#[settings_key(None)]
pub struct RemoteSettingsContent {
pub ssh_connections: Option<Vec<SshConnection>>,
pub wsl_connections: Option<Vec<WslConnection>>,
pub read_ssh_config: Option<bool>,
}
@@ -561,6 +612,36 @@ pub fn connect_over_ssh(
)
}
pub fn connect(
unique_identifier: ConnectionIdentifier,
connection_options: RemoteConnectionOptions,
ui: Entity<RemoteConnectionPrompt>,
window: &mut Window,
cx: &mut App,
) -> Task<Result<Option<Entity<RemoteClient>>>> {
let window = window.window_handle();
let known_password = match &connection_options {
RemoteConnectionOptions::Ssh(ssh_connection_options) => {
ssh_connection_options.password.clone()
}
_ => None,
};
let (tx, rx) = oneshot::channel();
ui.update(cx, |ui, _cx| ui.set_cancellation_tx(tx));
remote::RemoteClient::new(
unique_identifier,
connection_options,
rx,
Arc::new(RemoteClientDelegate {
window,
ui: ui.downgrade(),
known_password,
}),
cx,
)
}
pub async fn open_remote_project(
connection_options: RemoteConnectionOptions,
paths: Vec<PathBuf>,
File diff suppressed because it is too large Load Diff