From 5f0925fb5d26704e37ad943859af2db3ffa57892 Mon Sep 17 00:00:00 2001 From: ClanEver <562211524@qq.com> Date: Tue, 17 Sep 2024 17:17:29 +0800 Subject: [PATCH] Add Python venv activation support for Windows and PowerShell (#17839) Release Notes: - Add Python venv activation support for Windows and PowerShell Additional: I discovered a related bug on my Windows system. When first opening the project, it fails to detect the virtual environment folder `.venv`. After expanding the .venv folder in the Project Panel, it then becomes able to detect the virtual environment folder. However, I don't know how to fix it. --- assets/settings/default.json | 2 +- crates/project/src/terminals.rs | 31 ++++++++++++++++++------ crates/terminal/src/terminal_settings.rs | 1 + 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/assets/settings/default.json b/assets/settings/default.json index 7c0dc831c3..7f8c823210 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -710,7 +710,7 @@ // to the current working directory. We recommend overriding this // in your project's settings, rather than globally. "directories": [".env", "env", ".venv", "venv"], - // Can also be `csh`, `fish`, and `nushell` + // Can also be `csh`, `fish`, `nushell` and `power_shell` "activate_script": "default" } }, diff --git a/crates/project/src/terminals.rs b/crates/project/src/terminals.rs index 6793c028f7..136842d158 100644 --- a/crates/project/src/terminals.rs +++ b/crates/project/src/terminals.rs @@ -259,12 +259,16 @@ impl Project { cx: &AppContext, ) -> Option { let venv_settings = settings.detect_venv.as_option()?; + let bin_dir_name = match std::env::consts::OS { + "windows" => "Scripts", + _ => "bin", + }; venv_settings .directories .iter() .map(|virtual_environment_name| abs_path.join(virtual_environment_name)) .find(|venv_path| { - let bin_path = venv_path.join("bin"); + let bin_path = venv_path.join(bin_dir_name); self.find_worktree(&bin_path, cx) .and_then(|(worktree, relative_path)| { worktree.read(cx).entry_for_path(&relative_path) @@ -279,23 +283,36 @@ impl Project { settings: &TerminalSettings, ) -> Option { let venv_settings = settings.detect_venv.as_option()?; + let activate_keyword = match venv_settings.activate_script { + terminal_settings::ActivateScript::Default => match std::env::consts::OS { + "windows" => ".", + _ => "source", + }, + terminal_settings::ActivateScript::Nushell => "overlay use", + terminal_settings::ActivateScript::PowerShell => ".", + _ => "source", + }; let activate_script_name = match venv_settings.activate_script { terminal_settings::ActivateScript::Default => "activate", terminal_settings::ActivateScript::Csh => "activate.csh", terminal_settings::ActivateScript::Fish => "activate.fish", terminal_settings::ActivateScript::Nushell => "activate.nu", + terminal_settings::ActivateScript::PowerShell => "activate.ps1", }; let path = venv_base_directory - .join("bin") + .join(match std::env::consts::OS { + "windows" => "Scripts", + _ => "bin", + }) .join(activate_script_name) .to_string_lossy() .to_string(); let quoted = shlex::try_quote(&path).ok()?; - - Some(match venv_settings.activate_script { - terminal_settings::ActivateScript::Nushell => format!("overlay use {}\n", quoted), - _ => format!("source {}\n", quoted), - }) + let line_ending = match std::env::consts::OS { + "windows" => "\r", + _ => "\n", + }; + Some(format!("{} {}{}", activate_keyword, quoted, line_ending)) } fn activate_python_virtual_environment( diff --git a/crates/terminal/src/terminal_settings.rs b/crates/terminal/src/terminal_settings.rs index 6c95052612..4051caf864 100644 --- a/crates/terminal/src/terminal_settings.rs +++ b/crates/terminal/src/terminal_settings.rs @@ -87,6 +87,7 @@ pub enum ActivateScript { Csh, Fish, Nushell, + PowerShell, } #[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]