From 95feefc1cf35e19584818d4a3206d47348eea372 Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Tue, 4 Nov 2025 17:48:42 +0530 Subject: [PATCH] remote: Fix terminal crash on Elvish shell (#41893) --- crates/languages/src/python.rs | 1 + crates/util/src/shell.rs | 27 +++++++++++++++++++-------- crates/util/src/shell_builder.rs | 6 ++++-- crates/util/src/shell_env.rs | 25 +++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/crates/languages/src/python.rs b/crates/languages/src/python.rs index b8956b55873b27b42ce94e12dd9239f33359420d..7bf667c72440279f7b23d6747bbd3887c410b562 100644 --- a/crates/languages/src/python.rs +++ b/crates/languages/src/python.rs @@ -1217,6 +1217,7 @@ impl ToolchainLister for PythonToolchainProvider { ShellKind::Cmd => None, ShellKind::Rc => None, ShellKind::Xonsh => None, + ShellKind::Elvish => None, }) } _ => {} diff --git a/crates/util/src/shell.rs b/crates/util/src/shell.rs index e2da1c394b7d151a9ac4c7059c7d4f25e0d5fea5..28affde71674e93c78ce2cb65648eb27dfe11819 100644 --- a/crates/util/src/shell.rs +++ b/crates/util/src/shell.rs @@ -60,6 +60,7 @@ pub enum ShellKind { Nushell, Cmd, Xonsh, + Elvish, } pub fn get_system_shell() -> String { @@ -216,6 +217,7 @@ impl fmt::Display for ShellKind { ShellKind::Cmd => write!(f, "cmd"), ShellKind::Rc => write!(f, "rc"), ShellKind::Xonsh => write!(f, "xonsh"), + ShellKind::Elvish => write!(f, "elvish"), } } } @@ -241,6 +243,7 @@ impl ShellKind { "tcsh" => ShellKind::Tcsh, "rc" => ShellKind::Rc, "xonsh" => ShellKind::Xonsh, + "elvish" => ShellKind::Elvish, "sh" | "bash" | "zsh" => ShellKind::Posix, _ if is_windows => ShellKind::PowerShell, // Some other shell detected, the user might install and use a @@ -260,6 +263,7 @@ impl ShellKind { Self::Rc => input.to_owned(), Self::Nushell => Self::to_nushell_variable(input), Self::Xonsh => input.to_owned(), + Self::Elvish => input.to_owned(), } } @@ -386,7 +390,8 @@ impl ShellKind { | ShellKind::Csh | ShellKind::Tcsh | ShellKind::Rc - | ShellKind::Xonsh => interactive + | ShellKind::Xonsh + | ShellKind::Elvish => interactive .then(|| "-i".to_owned()) .into_iter() .chain(["-c".to_owned(), combined_command]) @@ -404,7 +409,8 @@ impl ShellKind { | ShellKind::Rc | ShellKind::Fish | ShellKind::Cmd - | ShellKind::Xonsh => None, + | ShellKind::Xonsh + | ShellKind::Elvish => None, } } @@ -427,7 +433,8 @@ impl ShellKind { | ShellKind::Fish | ShellKind::PowerShell | ShellKind::Nushell - | ShellKind::Xonsh => ';', + | ShellKind::Xonsh + | ShellKind::Elvish => ';', } } @@ -441,7 +448,7 @@ impl ShellKind { | ShellKind::Fish | ShellKind::PowerShell | ShellKind::Xonsh => "&&", - ShellKind::Nushell => ";", + ShellKind::Nushell | ShellKind::Elvish => ";", } } @@ -457,7 +464,8 @@ impl ShellKind { | ShellKind::Rc | ShellKind::Fish | ShellKind::Nushell - | ShellKind::Xonsh => arg, + | ShellKind::Xonsh + | ShellKind::Elvish => arg, }) } @@ -511,7 +519,8 @@ impl ShellKind { | ShellKind::Tcsh | ShellKind::Posix | ShellKind::Rc - | ShellKind::Xonsh => "source", + | ShellKind::Xonsh + | ShellKind::Elvish => "source", } } @@ -525,7 +534,8 @@ impl ShellKind { | ShellKind::Fish | ShellKind::PowerShell | ShellKind::Nushell - | ShellKind::Xonsh => "clear", + | ShellKind::Xonsh + | ShellKind::Elvish => "clear", } } @@ -542,7 +552,8 @@ impl ShellKind { | ShellKind::Fish | ShellKind::PowerShell | ShellKind::Nushell - | ShellKind::Xonsh => true, + | ShellKind::Xonsh + | ShellKind::Elvish => true, } } } diff --git a/crates/util/src/shell_builder.rs b/crates/util/src/shell_builder.rs index 7e52b67b35f6f3d21ea5e3ad5a0632cd46344125..a4a0d21018447d229a6a95c4bf897804b5d6eaf9 100644 --- a/crates/util/src/shell_builder.rs +++ b/crates/util/src/shell_builder.rs @@ -54,7 +54,8 @@ impl ShellBuilder { | ShellKind::Csh | ShellKind::Tcsh | ShellKind::Rc - | ShellKind::Xonsh => { + | ShellKind::Xonsh + | ShellKind::Elvish => { let interactivity = self.interactive.then_some("-i ").unwrap_or_default(); format!( "{PROGRAM} {interactivity}-c '{command_to_use_in_label}'", @@ -93,7 +94,8 @@ impl ShellBuilder { | ShellKind::Csh | ShellKind::Tcsh | ShellKind::Rc - | ShellKind::Xonsh => { + | ShellKind::Xonsh + | ShellKind::Elvish => { combined_command.insert(0, '('); combined_command.push_str(") { + let output = crate::command::new_smol_command(shell_path) + .args([ + "-c", + &format!( + "cd '{}'; {} --printenv", + directory.display(), + zed_path.display() + ), + ]) + .stdin(Stdio::null()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .output() + .await?; + + anyhow::ensure!( + output.status.success(), + "Elvish command failed with {}. stdout: {:?}, stderr: {:?}", + output.status, + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr), + ); + output + } ShellKind::Nushell => { let output = crate::command::new_smol_command(shell_path) .args([