From 9969971605dfff9f6561c794e5bd21d3468e6cf1 Mon Sep 17 00:00:00 2001 From: DuProcess <273172371+DuProcess@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:36:03 -0400 Subject: [PATCH] Try Windows VS Code command shims --- src/bin/dosh-client.rs | 68 +++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/src/bin/dosh-client.rs b/src/bin/dosh-client.rs index 7906417..dfa9d7e 100644 --- a/src/bin/dosh-client.rs +++ b/src/bin/dosh-client.rs @@ -2676,25 +2676,40 @@ fn vscode_safe_alias(value: &str) -> String { fn launch_vscode_remote(alias: &str, remote_path: Option<&str>) -> Result<()> { let remote = format!("ssh-remote+{alias}"); - let mut command = Command::new("code"); - command.arg("--remote").arg(&remote); - if let Some(path) = remote_path { - command.arg(path); - } - match command.status() { - Ok(status) if status.success() => Ok(()), - Ok(status) => Err(anyhow!("code exited with status {status}")), - Err(err) if err.kind() == std::io::ErrorKind::NotFound => { - println!( - "Run: code --remote {}{}", - shell_word(&remote), - remote_path - .map(|path| format!(" {}", shell_word(path))) - .unwrap_or_default() - ); - Ok(()) + let mut saw_not_found = false; + for candidate in vscode_command_candidates(std::env::consts::OS) { + let mut command = Command::new(candidate); + command.arg("--remote").arg(&remote); + if let Some(path) = remote_path { + command.arg(path); } - Err(err) => Err(err).context("launch VS Code"), + match command.status() { + Ok(status) if status.success() => return Ok(()), + Ok(status) => return Err(anyhow!("{candidate} exited with status {status}")), + Err(err) if err.kind() == std::io::ErrorKind::NotFound => saw_not_found = true, + Err(err) => { + return Err(err).with_context(|| format!("launch VS Code with {candidate}")); + } + } + } + if saw_not_found { + println!( + "Run: code --remote {}{}", + shell_word(&remote), + remote_path + .map(|path| format!(" {}", shell_word(path))) + .unwrap_or_default() + ); + return Ok(()); + } + Err(anyhow!("no VS Code command candidates configured")) +} + +fn vscode_command_candidates(os: &str) -> &'static [&'static str] { + if os == "windows" { + &["code.cmd", "code.exe", "code"] + } else { + &["code"] } } @@ -10351,9 +10366,10 @@ mod tests { terminal_private_mode_transition, toml_bare_key_or_quoted, top_trace_events, trace_report_warnings, unix_update_script, update_binary_version_for_installer, update_installer_url, update_version_status, upsert_managed_block, valid_forward_host, - vscode_safe_alias, wake_repaint_retry_deadline, windows_command_word, - windows_deferred_update_script, windows_effective_url_script, windows_mode_from_readonly, - windows_readonly_from_mode, windows_update_script, windows_url_reachable_script, + vscode_command_candidates, vscode_safe_alias, wake_repaint_retry_deadline, + windows_command_word, windows_deferred_update_script, windows_effective_url_script, + windows_mode_from_readonly, windows_readonly_from_mode, windows_update_script, + windows_url_reachable_script, }; use dosh::config::{ClientConfig, CommandExtension, HostConfig}; use dosh::native::EnvVar; @@ -10406,6 +10422,16 @@ mod tests { assert_eq!(vscode_safe_alias(":///"), "host"); } + #[test] + fn vscode_command_candidates_are_platform_native() { + assert_eq!(vscode_command_candidates("macos"), &["code"]); + assert_eq!(vscode_command_candidates("linux"), &["code"]); + assert_eq!( + vscode_command_candidates("windows"), + &["code.cmd", "code.exe", "code"] + ); + } + #[test] fn forward_agent_endpoint_disabled_is_none() { assert_eq!(resolve_forward_agent_endpoint(false).unwrap(), None);