@@ -38,8 +38,12 @@ pub fn capture(directory: &std::path::Path) -> Result<collections::HashMap<Strin
}
// cd into the directory, triggering directory specific side-effects (asdf, direnv, etc)
command_string.push_str(&format!("cd '{}';", directory.display()));
- command_string.push_str(&format!("sh -c '{zed_path} --printenv >&{ENV_OUTPUT_FD}';"));
+ command_string.push_str(&format!(
+ "sh -c \"{} --printenv >&{}\";",
+ zed_path, ENV_OUTPUT_FD
+ ));
command.args(["-i", "-c", &command_string]);
+
super::set_pre_exec_to_start_new_session(&mut command);
let (env_output, process_output) = spawn_and_read_fd(command, ENV_OUTPUT_FD)?;
@@ -1094,6 +1094,52 @@ mod tests {
assert_eq!(vec, &[1000, 101, 21, 19, 17, 13, 9, 8]);
}
+ #[test]
+ fn test_get_shell_safe_zed_path_with_spaces() {
+ // Test that shlex::try_quote handles paths with spaces correctly
+ let path_with_spaces = "/Applications/Zed Nightly.app/Contents/MacOS/zed";
+ let quoted = shlex::try_quote(path_with_spaces).unwrap();
+
+ // The quoted path should be properly escaped for shell use
+ assert!(quoted.contains(path_with_spaces));
+
+ // When used in a shell command, it should not be split at spaces
+ let command = format!("sh -c '{} --printenv'", quoted);
+ println!("Command would be: {}", command);
+
+ // Test that shlex can parse it back correctly
+ let parsed = shlex::split(&format!("{} --printenv", quoted)).unwrap();
+ assert_eq!(parsed.len(), 2);
+ assert_eq!(parsed[0], path_with_spaces);
+ assert_eq!(parsed[1], "--printenv");
+ }
+
+ #[test]
+ fn test_shell_command_construction_with_quoted_path() {
+ // Test the specific pattern used in shell_env.rs to ensure proper quoting
+ let path_with_spaces = "/Applications/Zed Nightly.app/Contents/MacOS/zed";
+ let quoted_path = shlex::try_quote(path_with_spaces).unwrap();
+
+ // This should be: '/Applications/Zed Nightly.app/Contents/MacOS/zed'
+ assert_eq!(
+ quoted_path,
+ "'/Applications/Zed Nightly.app/Contents/MacOS/zed'"
+ );
+
+ // Test the command construction pattern from shell_env.rs
+ // The fixed version should use double quotes around the entire sh -c argument
+ let env_fd = 0;
+ let command = format!("sh -c \"{} --printenv >&{}\";", quoted_path, env_fd);
+
+ // This should produce: sh -c "'/Applications/Zed Nightly.app/Contents/MacOS/zed' --printenv >&0";
+ let expected =
+ "sh -c \"'/Applications/Zed Nightly.app/Contents/MacOS/zed' --printenv >&0\";";
+ assert_eq!(command, expected);
+
+ // The command should not contain the problematic double single-quote pattern
+ assert!(!command.contains("''"));
+ }
+
#[test]
fn test_truncate_to_bottom_n_sorted_by() {
let mut vec: Vec<u32> = vec![5, 2, 3, 4, 1];