project: Fix terminal activation scripts failing on Windows for new shells (#37986)
Tasks are still disabled as there seem to be more issues with it Release Notes: - N/A
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -9301,6 +9301,7 @@ dependencies = [
|
||||
"serde_json_lenient",
|
||||
"settings",
|
||||
"sha2",
|
||||
"shlex",
|
||||
"smol",
|
||||
"snippet_provider",
|
||||
"task",
|
||||
|
||||
@@ -1607,7 +1607,7 @@ impl AcpThreadView {
|
||||
task.shell = shell;
|
||||
|
||||
let terminal = terminal_panel.update_in(cx, |terminal_panel, window, cx| {
|
||||
terminal_panel.spawn_task(&login, window, cx)
|
||||
terminal_panel.spawn_task(login.clone(), window, cx)
|
||||
})?;
|
||||
|
||||
let terminal = terminal.await?;
|
||||
|
||||
@@ -92,6 +92,7 @@ tree-sitter-typescript = { workspace = true, optional = true }
|
||||
tree-sitter-yaml = { workspace = true, optional = true }
|
||||
util.workspace = true
|
||||
workspace-hack.workspace = true
|
||||
shlex.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions.workspace = true
|
||||
|
||||
@@ -918,9 +918,12 @@ impl ToolchainLister for PythonToolchainProvider {
|
||||
ShellKind::Cmd => "activate.bat",
|
||||
};
|
||||
let path = prefix.join(BINARY_DIR).join(activate_script_name);
|
||||
if fs.is_file(&path).await {
|
||||
activation_script
|
||||
.push(format!("{activate_keyword} \"{}\"", path.display()));
|
||||
|
||||
if let Ok(quoted) =
|
||||
shlex::try_quote(&path.to_string_lossy()).map(Cow::into_owned)
|
||||
&& fs.is_file(&path).await
|
||||
{
|
||||
activation_script.push(format!("{activate_keyword} {quoted}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ impl Project {
|
||||
)?,
|
||||
},
|
||||
None => match activation_script.clone() {
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
#[cfg(not(windows))]
|
||||
activation_script if !activation_script.is_empty() => {
|
||||
let activation_script = activation_script.join("; ");
|
||||
let to_run = if let Some(command) = spawn_task.command {
|
||||
@@ -214,7 +214,25 @@ impl Project {
|
||||
program: shell,
|
||||
args: vec![
|
||||
"-c".to_owned(),
|
||||
format!("{activation_script}; {to_run}",),
|
||||
// alacritty formats all args into a single string literally without extra quoting before handing it off to powershell
|
||||
// so we work around this here
|
||||
if cfg!(windows) {
|
||||
println!(
|
||||
"{}",
|
||||
shlex::try_quote(&format!(
|
||||
"{activation_script}; {to_run}",
|
||||
))
|
||||
.unwrap()
|
||||
.into_owned()
|
||||
);
|
||||
shlex::try_quote(&format!(
|
||||
"{activation_script}; {to_run}",
|
||||
))
|
||||
.unwrap()
|
||||
.into_owned()
|
||||
} else {
|
||||
format!("{activation_script}; {to_run}",)
|
||||
},
|
||||
],
|
||||
title_override: None,
|
||||
}
|
||||
|
||||
@@ -531,10 +531,14 @@ impl TerminalBuilder {
|
||||
},
|
||||
};
|
||||
|
||||
if cfg!(not(target_os = "windows")) && !activation_script.is_empty() && no_task {
|
||||
if !activation_script.is_empty() && no_task {
|
||||
for activation_script in activation_script {
|
||||
terminal.input(activation_script.into_bytes());
|
||||
terminal.write_to_pty(b"\n");
|
||||
terminal.write_to_pty(if cfg!(windows) {
|
||||
&b"\r\n"[..]
|
||||
} else {
|
||||
&b"\n"[..]
|
||||
});
|
||||
}
|
||||
terminal.clear();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ use itertools::Itertools;
|
||||
use project::{Fs, Project, ProjectEntryId};
|
||||
use search::{BufferSearchBar, buffer_search::DivRegistrar};
|
||||
use settings::Settings;
|
||||
use task::{RevealStrategy, RevealTarget, ShellBuilder, SpawnInTerminal, TaskId};
|
||||
use task::{RevealStrategy, RevealTarget, SpawnInTerminal, TaskId};
|
||||
use terminal::{
|
||||
Terminal,
|
||||
terminal_settings::{TerminalDockPosition, TerminalSettings},
|
||||
@@ -496,42 +496,10 @@ impl TerminalPanel {
|
||||
|
||||
pub fn spawn_task(
|
||||
&mut self,
|
||||
task: &SpawnInTerminal,
|
||||
task: SpawnInTerminal,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<WeakEntity<Terminal>>> {
|
||||
let remote_client = self
|
||||
.workspace
|
||||
.update(cx, |workspace, cx| {
|
||||
let project = workspace.project().read(cx);
|
||||
if project.is_via_collab() {
|
||||
Err(anyhow!("cannot spawn tasks as a guest"))
|
||||
} else {
|
||||
Ok(project.remote_client())
|
||||
}
|
||||
})
|
||||
.flatten();
|
||||
|
||||
let remote_client = match remote_client {
|
||||
Ok(remote_client) => remote_client,
|
||||
Err(e) => return Task::ready(Err(e)),
|
||||
};
|
||||
|
||||
let remote_shell = remote_client
|
||||
.as_ref()
|
||||
.and_then(|remote_client| remote_client.read(cx).shell());
|
||||
|
||||
let builder = ShellBuilder::new(remote_shell.as_deref(), &task.shell);
|
||||
let command_label = builder.command_label(&task.command_label);
|
||||
let (command, args) = builder.build(task.command.clone(), &task.args);
|
||||
|
||||
let task = SpawnInTerminal {
|
||||
command_label,
|
||||
command: Some(command),
|
||||
args,
|
||||
..task.clone()
|
||||
};
|
||||
|
||||
if task.allow_concurrent_runs && task.use_new_terminal {
|
||||
return self.spawn_in_new_terminal(task, window, cx);
|
||||
}
|
||||
@@ -1565,7 +1533,7 @@ impl workspace::TerminalProvider for TerminalProvider {
|
||||
window.spawn(cx, async move |cx| {
|
||||
let terminal = terminal_panel
|
||||
.update_in(cx, |terminal_panel, window, cx| {
|
||||
terminal_panel.spawn_task(&task, window, cx)
|
||||
terminal_panel.spawn_task(task, window, cx)
|
||||
})
|
||||
.ok()?
|
||||
.await;
|
||||
|
||||
Reference in New Issue
Block a user