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.
This commit is contained in:
ClanEver 2024-09-17 17:17:29 +08:00 committed by GitHub
parent d56e3d99b4
commit 5f0925fb5d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 26 additions and 8 deletions

View file

@ -710,7 +710,7 @@
// to the current working directory. We recommend overriding this // to the current working directory. We recommend overriding this
// in your project's settings, rather than globally. // in your project's settings, rather than globally.
"directories": [".env", "env", ".venv", "venv"], "directories": [".env", "env", ".venv", "venv"],
// Can also be `csh`, `fish`, and `nushell` // Can also be `csh`, `fish`, `nushell` and `power_shell`
"activate_script": "default" "activate_script": "default"
} }
}, },

View file

@ -259,12 +259,16 @@ impl Project {
cx: &AppContext, cx: &AppContext,
) -> Option<PathBuf> { ) -> Option<PathBuf> {
let venv_settings = settings.detect_venv.as_option()?; let venv_settings = settings.detect_venv.as_option()?;
let bin_dir_name = match std::env::consts::OS {
"windows" => "Scripts",
_ => "bin",
};
venv_settings venv_settings
.directories .directories
.iter() .iter()
.map(|virtual_environment_name| abs_path.join(virtual_environment_name)) .map(|virtual_environment_name| abs_path.join(virtual_environment_name))
.find(|venv_path| { .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) self.find_worktree(&bin_path, cx)
.and_then(|(worktree, relative_path)| { .and_then(|(worktree, relative_path)| {
worktree.read(cx).entry_for_path(&relative_path) worktree.read(cx).entry_for_path(&relative_path)
@ -279,23 +283,36 @@ impl Project {
settings: &TerminalSettings, settings: &TerminalSettings,
) -> Option<String> { ) -> Option<String> {
let venv_settings = settings.detect_venv.as_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 { let activate_script_name = match venv_settings.activate_script {
terminal_settings::ActivateScript::Default => "activate", terminal_settings::ActivateScript::Default => "activate",
terminal_settings::ActivateScript::Csh => "activate.csh", terminal_settings::ActivateScript::Csh => "activate.csh",
terminal_settings::ActivateScript::Fish => "activate.fish", terminal_settings::ActivateScript::Fish => "activate.fish",
terminal_settings::ActivateScript::Nushell => "activate.nu", terminal_settings::ActivateScript::Nushell => "activate.nu",
terminal_settings::ActivateScript::PowerShell => "activate.ps1",
}; };
let path = venv_base_directory let path = venv_base_directory
.join("bin") .join(match std::env::consts::OS {
"windows" => "Scripts",
_ => "bin",
})
.join(activate_script_name) .join(activate_script_name)
.to_string_lossy() .to_string_lossy()
.to_string(); .to_string();
let quoted = shlex::try_quote(&path).ok()?; let quoted = shlex::try_quote(&path).ok()?;
let line_ending = match std::env::consts::OS {
Some(match venv_settings.activate_script { "windows" => "\r",
terminal_settings::ActivateScript::Nushell => format!("overlay use {}\n", quoted), _ => "\n",
_ => format!("source {}\n", quoted), };
}) Some(format!("{} {}{}", activate_keyword, quoted, line_ending))
} }
fn activate_python_virtual_environment( fn activate_python_virtual_environment(

View file

@ -87,6 +87,7 @@ pub enum ActivateScript {
Csh, Csh,
Fish, Fish,
Nushell, Nushell,
PowerShell,
} }
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)] #[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]