Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions src/term_emu/terminal_emulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,37 @@ pub struct ShellConfig {
pub shell_path: Option<String>,
}

/// Check if a shell can be found, either as a direct path or via PATH lookup
fn shell_exists(name: &str) -> bool {
let path = std::path::Path::new(name);
if path.exists() {
return true;
}
// Only search PATH for bare names (no directory separators)
if name.contains('/') || name.contains('\\') {
return false;
}
if let Ok(path_var) = std::env::var("PATH") {
for dir in std::env::split_paths(&path_var) {
if dir.join(name).exists() {
return true;
Comment on lines +24 to +36
}
#[cfg(windows)]
{
if !name.contains('.') {
if dir.join(format!("{}.exe", name)).exists() {
return true;
}
if dir.join(format!("{}.cmd", name)).exists() {
return true;
}
}
}
}
}
false
}
Comment on lines +23 to +52

impl ShellConfig {
/// Create a shell config with a custom shell path
pub fn custom_shell(path: String) -> Self {
Expand All @@ -32,7 +63,7 @@ impl ShellConfig {
/// Returns Ok(()) if valid, Err with message if invalid
pub fn validate(&self) -> Result<(), String> {
if let Some(ref path) = self.shell_path {
if !std::path::Path::new(path).exists() {
if !shell_exists(path) {
return Err(format!("Shell '{}' not found", path));
}
// Check if file is executable on Unix
Expand Down Expand Up @@ -105,7 +136,7 @@ impl TerminalEmulator {
cmd
} else if let Some(ref shell_path) = shell_config.shell_path {
// Use custom shell if specified and valid
if std::path::Path::new(shell_path).exists() {
if shell_exists(shell_path) {
CommandBuilder::new(shell_path)
} else {
// Shell doesn't exist, fall back to default (validation should catch this earlier)
Expand Down
Loading