diff --git a/src-tauri/src/commands/misc.rs b/src-tauri/src/commands/misc.rs index 61b0b47d6..40a27c80c 100644 --- a/src-tauri/src/commands/misc.rs +++ b/src-tauri/src/commands/misc.rs @@ -1002,21 +1002,46 @@ end tell"#, /// macOS: iTerm2 #[cfg(target_os = "macos")] -fn launch_macos_iterm2(script_file: &std::path::Path) -> Result<(), String> { - use std::process::Command; - - let applescript = format!( - r#"tell application "iTerm" - activate - tell current window - create tab with default profile - tell current session - write text "bash '{}'" - end tell +fn build_macos_iterm2_applescript(script_file: &std::path::Path) -> String { + format!( + r#"set launcher_script to "bash '{}'" +set was_running to application "iTerm" is running +tell application "iTerm" + if was_running then + activate + if (count of windows) = 0 then + create window with default profile + else + tell current window + create tab with default profile + end tell + end if + else + activate + set waited to 0 + repeat while (count of windows) = 0 + delay 0.1 + set waited to waited + 1 + if waited >= 30 then exit repeat + end repeat + if (count of windows) = 0 then + create window with default profile + end if + end if + tell current session of current window + write text launcher_script end tell end tell"#, script_file.display() - ); + ) +} + +/// macOS: iTerm2 +#[cfg(target_os = "macos")] +fn launch_macos_iterm2(script_file: &std::path::Path) -> Result<(), String> { + use std::process::Command; + + let applescript = build_macos_iterm2_applescript(script_file); let output = Command::new("osascript") .arg("-e") @@ -1727,6 +1752,43 @@ mod tests { assert_eq!(command, "cd '/tmp/project O'\"'\"'Brien' || exit 1\n"); } + #[cfg(target_os = "macos")] + #[test] + fn iterm2_applescript_cold_start_avoids_current_window_before_one_exists() { + let script = build_macos_iterm2_applescript(Path::new("/tmp/cc_switch_launcher.sh")); + + let cold_start_branch = script + .split("else\n activate") + .nth(1) + .expect("cold start branch should be present") + .split(" end if\n tell current session") + .next() + .expect("cold start branch should end before writing command"); + + assert!(cold_start_branch.contains("repeat while (count of windows) = 0")); + assert!(cold_start_branch.contains("create window with default profile")); + assert!(!cold_start_branch.contains("tell current window")); + assert!(!cold_start_branch.contains("create tab with default profile")); + } + + #[cfg(target_os = "macos")] + #[test] + fn iterm2_applescript_keeps_new_tab_behavior_for_existing_windows() { + let script = build_macos_iterm2_applescript(Path::new("/tmp/cc_switch_launcher.sh")); + + let running_branch = script + .split("if was_running then") + .nth(1) + .expect("already-running branch should be present") + .split("else\n activate") + .next() + .expect("already-running branch should end before cold start branch"); + + assert!(running_branch.contains("if (count of windows) = 0 then")); + assert!(running_branch.contains("create window with default profile")); + assert!(running_branch.contains("create tab with default profile")); + } + #[test] fn build_windows_cwd_command_str_uses_cd_for_drive_paths() { let command = build_windows_cwd_command_str(r"C:\work\repo");