diff --git a/crates/languages/src/python.rs b/crates/languages/src/python.rs index f76bd8e793d8e391654cb6391086ade528d56264..5bdc4aa0d94a7355c60ab8912d9a328a657ad77f 100644 --- a/crates/languages/src/python.rs +++ b/crates/languages/src/python.rs @@ -328,41 +328,35 @@ impl LspAdapter for PythonLspAdapter { .unwrap_or_default(); // If we have a detected toolchain, configure Pyright to use it - if let Some(toolchain) = toolchain { + if let Some(toolchain) = toolchain + && let Ok(env) = serde_json::from_value::< + pet_core::python_environment::PythonEnvironment, + >(toolchain.as_json.clone()) + { if user_settings.is_null() { user_settings = Value::Object(serde_json::Map::default()); } let object = user_settings.as_object_mut().unwrap(); let interpreter_path = toolchain.path.to_string(); + if let Some(venv_dir) = env.prefix { + // Set venvPath and venv at the root level + // This matches the format of a pyrightconfig.json file + if let Some(parent) = venv_dir.parent() { + // Use relative path if the venv is inside the workspace + let venv_path = if parent == adapter.worktree_root_path() { + ".".to_string() + } else { + parent.to_string_lossy().into_owned() + }; + object.insert("venvPath".to_string(), Value::String(venv_path)); + } - // Detect if this is a virtual environment - if let Some(interpreter_dir) = Path::new(&interpreter_path).parent() - && let Some(venv_dir) = interpreter_dir.parent() - { - // Check if this looks like a virtual environment - if venv_dir.join("pyvenv.cfg").exists() - || venv_dir.join("bin/activate").exists() - || venv_dir.join("Scripts/activate.bat").exists() - { - // Set venvPath and venv at the root level - // This matches the format of a pyrightconfig.json file - if let Some(parent) = venv_dir.parent() { - // Use relative path if the venv is inside the workspace - let venv_path = if parent == adapter.worktree_root_path() { - ".".to_string() - } else { - parent.to_string_lossy().into_owned() - }; - object.insert("venvPath".to_string(), Value::String(venv_path)); - } - - if let Some(venv_name) = venv_dir.file_name() { - object.insert( - "venv".to_owned(), - Value::String(venv_name.to_string_lossy().into_owned()), - ); - } + if let Some(venv_name) = venv_dir.file_name() { + object.insert( + "venv".to_owned(), + Value::String(venv_name.to_string_lossy().into_owned()), + ); } } @@ -932,7 +926,8 @@ impl ToolchainLister for PythonToolchainProvider { }; let path = prefix.join(BINARY_DIR).join(activate_script_name); if fs.is_file(&path).await { - activation_script.push(format!("{activate_keyword} {}", path.display())); + activation_script + .push(format!("{activate_keyword} \"{}\"", path.display())); } } } @@ -944,9 +939,9 @@ impl ToolchainLister for PythonToolchainProvider { let pyenv = manager.executable; let pyenv = pyenv.display(); activation_script.extend(match shell { - ShellKind::Fish => Some(format!("{pyenv} shell - fish {version}")), - ShellKind::Posix => Some(format!("{pyenv} shell - sh {version}")), - ShellKind::Nushell => Some(format!("{pyenv} shell - nu {version}")), + ShellKind::Fish => Some(format!("\"{pyenv}\" shell - fish {version}")), + ShellKind::Posix => Some(format!("\"{pyenv}\" shell - sh {version}")), + ShellKind::Nushell => Some(format!("\"{pyenv}\" shell - nu {version}")), ShellKind::Powershell => None, ShellKind::Csh => None, ShellKind::Cmd => None, @@ -1108,10 +1103,10 @@ impl LspAdapter for PyLspAdapter { arguments: vec![], }) } else { - let venv = toolchain?; - let pylsp_path = Path::new(venv.path.as_ref()).parent()?.join("pylsp"); + let toolchain = toolchain?; + let pylsp_path = Path::new(toolchain.path.as_ref()).parent()?.join("pylsp"); pylsp_path.exists().then(|| LanguageServerBinary { - path: venv.path.to_string().into(), + path: toolchain.path.to_string().into(), arguments: vec![pylsp_path.into()], env: None, }) @@ -1575,41 +1570,35 @@ impl LspAdapter for BasedPyrightLspAdapter { .unwrap_or_default(); // If we have a detected toolchain, configure Pyright to use it - if let Some(toolchain) = toolchain { + if let Some(toolchain) = toolchain + && let Ok(env) = serde_json::from_value::< + pet_core::python_environment::PythonEnvironment, + >(toolchain.as_json.clone()) + { if user_settings.is_null() { user_settings = Value::Object(serde_json::Map::default()); } let object = user_settings.as_object_mut().unwrap(); let interpreter_path = toolchain.path.to_string(); + if let Some(venv_dir) = env.prefix { + // Set venvPath and venv at the root level + // This matches the format of a pyrightconfig.json file + if let Some(parent) = venv_dir.parent() { + // Use relative path if the venv is inside the workspace + let venv_path = if parent == adapter.worktree_root_path() { + ".".to_string() + } else { + parent.to_string_lossy().into_owned() + }; + object.insert("venvPath".to_string(), Value::String(venv_path)); + } - // Detect if this is a virtual environment - if let Some(interpreter_dir) = Path::new(&interpreter_path).parent() - && let Some(venv_dir) = interpreter_dir.parent() - { - // Check if this looks like a virtual environment - if venv_dir.join("pyvenv.cfg").exists() - || venv_dir.join("bin/activate").exists() - || venv_dir.join("Scripts/activate.bat").exists() - { - // Set venvPath and venv at the root level - // This matches the format of a pyrightconfig.json file - if let Some(parent) = venv_dir.parent() { - // Use relative path if the venv is inside the workspace - let venv_path = if parent == adapter.worktree_root_path() { - ".".to_string() - } else { - parent.to_string_lossy().into_owned() - }; - object.insert("venvPath".to_string(), Value::String(venv_path)); - } - - if let Some(venv_name) = venv_dir.file_name() { - object.insert( - "venv".to_owned(), - Value::String(venv_name.to_string_lossy().into_owned()), - ); - } + if let Some(venv_name) = venv_dir.file_name() { + object.insert( + "venv".to_owned(), + Value::String(venv_name.to_string_lossy().into_owned()), + ); } } diff --git a/crates/remote/src/transport/ssh.rs b/crates/remote/src/transport/ssh.rs index b6698014024ab48d171631a190b421dcb614edae..34f1ebf71c278538b57e486856f9b3315a41cf91 100644 --- a/crates/remote/src/transport/ssh.rs +++ b/crates/remote/src/transport/ssh.rs @@ -125,12 +125,13 @@ impl RemoteConnection for SshRemoteConnection { // shlex will wrap the command in single quotes (''), disabling ~ expansion, // replace ith with something that works const TILDE_PREFIX: &'static str = "~/"; - if working_dir.starts_with(TILDE_PREFIX) { + let working_dir = if working_dir.starts_with(TILDE_PREFIX) { let working_dir = working_dir.trim_start_matches("~").trim_start_matches("/"); - write!(&mut script, "cd \"$HOME/{working_dir}\"; ").unwrap(); + format!("$HOME/{working_dir}") } else { - write!(&mut script, "cd \"{working_dir}\"; ").unwrap(); - } + working_dir + }; + write!(&mut script, "cd \"{working_dir}\"; ",).unwrap(); } else { write!(&mut script, "cd; ").unwrap(); };