Add the ability for tasks to target the center pane (#22004)
Closes #20060 Closes #20720 Closes #19873 Closes #9445 Release Notes: - Fixed a bug where tasks would be spawned with their working directory set to a file in some cases - Added the ability to spawn tasks in the center pane, when spawning from a keybinding: ```json5 [ { // Assuming you have a task labeled "echo hello" "ctrl--": [ "task::Spawn", { "task_name": "echo hello", "target": "center" } ] } ] ```
This commit is contained in:
parent
85c3aec6e7
commit
4f96706161
18 changed files with 263 additions and 106 deletions
|
@ -255,7 +255,10 @@ impl TerminalPanel {
|
|||
terminal_panel
|
||||
.update(&mut cx, |_, cx| {
|
||||
cx.subscribe(&workspace, |terminal_panel, _, e, cx| {
|
||||
if let workspace::Event::SpawnTask(spawn_in_terminal) = e {
|
||||
if let workspace::Event::SpawnTask {
|
||||
action: spawn_in_terminal,
|
||||
} = e
|
||||
{
|
||||
terminal_panel.spawn_task(spawn_in_terminal, cx);
|
||||
};
|
||||
})
|
||||
|
@ -450,83 +453,17 @@ impl TerminalPanel {
|
|||
|
||||
fn spawn_task(&mut self, spawn_in_terminal: &SpawnInTerminal, cx: &mut ViewContext<Self>) {
|
||||
let mut spawn_task = spawn_in_terminal.clone();
|
||||
// Set up shell args unconditionally, as tasks are always spawned inside of a shell.
|
||||
let Some((shell, mut user_args)) = (match spawn_in_terminal.shell.clone() {
|
||||
Shell::System => {
|
||||
match self
|
||||
.workspace
|
||||
.update(cx, |workspace, cx| workspace.project().read(cx).is_local())
|
||||
{
|
||||
Ok(local) => {
|
||||
if local {
|
||||
retrieve_system_shell().map(|shell| (shell, Vec::new()))
|
||||
} else {
|
||||
Some(("\"${SHELL:-sh}\"".to_string(), Vec::new()))
|
||||
}
|
||||
}
|
||||
Err(_no_window_e) => return,
|
||||
}
|
||||
}
|
||||
Shell::Program(shell) => Some((shell, Vec::new())),
|
||||
Shell::WithArguments { program, args, .. } => Some((program, args)),
|
||||
}) else {
|
||||
let Ok(is_local) = self
|
||||
.workspace
|
||||
.update(cx, |workspace, cx| workspace.project().read(cx).is_local())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
#[cfg(target_os = "windows")]
|
||||
let windows_shell_type = to_windows_shell_type(&shell);
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
if let ControlFlow::Break(_) =
|
||||
Self::fill_command(is_local, spawn_in_terminal, &mut spawn_task)
|
||||
{
|
||||
spawn_task.command_label = format!("{shell} -i -c '{}'", spawn_task.command_label);
|
||||
return;
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
use crate::terminal_panel::WindowsShellType;
|
||||
|
||||
match windows_shell_type {
|
||||
WindowsShellType::Powershell => {
|
||||
spawn_task.command_label = format!("{shell} -C '{}'", spawn_task.command_label)
|
||||
}
|
||||
WindowsShellType::Cmd => {
|
||||
spawn_task.command_label = format!("{shell} /C '{}'", spawn_task.command_label)
|
||||
}
|
||||
WindowsShellType::Other => {
|
||||
spawn_task.command_label =
|
||||
format!("{shell} -i -c '{}'", spawn_task.command_label)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let task_command = std::mem::replace(&mut spawn_task.command, shell);
|
||||
let task_args = std::mem::take(&mut spawn_task.args);
|
||||
let combined_command = task_args
|
||||
.into_iter()
|
||||
.fold(task_command, |mut command, arg| {
|
||||
command.push(' ');
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
command.push_str(&arg);
|
||||
#[cfg(target_os = "windows")]
|
||||
command.push_str(&to_windows_shell_variable(windows_shell_type, arg));
|
||||
command
|
||||
});
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
user_args.extend(["-i".to_owned(), "-c".to_owned(), combined_command]);
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
use crate::terminal_panel::WindowsShellType;
|
||||
|
||||
match windows_shell_type {
|
||||
WindowsShellType::Powershell => {
|
||||
user_args.extend(["-C".to_owned(), combined_command])
|
||||
}
|
||||
WindowsShellType::Cmd => user_args.extend(["/C".to_owned(), combined_command]),
|
||||
WindowsShellType::Other => {
|
||||
user_args.extend(["-i".to_owned(), "-c".to_owned(), combined_command])
|
||||
}
|
||||
}
|
||||
}
|
||||
spawn_task.args = user_args;
|
||||
let spawn_task = spawn_task;
|
||||
|
||||
let allow_concurrent_runs = spawn_in_terminal.allow_concurrent_runs;
|
||||
|
@ -602,6 +539,81 @@ impl TerminalPanel {
|
|||
.detach()
|
||||
}
|
||||
|
||||
pub fn fill_command(
|
||||
is_local: bool,
|
||||
spawn_in_terminal: &SpawnInTerminal,
|
||||
spawn_task: &mut SpawnInTerminal,
|
||||
) -> ControlFlow<()> {
|
||||
let Some((shell, mut user_args)) = (match spawn_in_terminal.shell.clone() {
|
||||
Shell::System => {
|
||||
if is_local {
|
||||
retrieve_system_shell().map(|shell| (shell, Vec::new()))
|
||||
} else {
|
||||
Some(("\"${SHELL:-sh}\"".to_string(), Vec::new()))
|
||||
}
|
||||
}
|
||||
Shell::Program(shell) => Some((shell, Vec::new())),
|
||||
Shell::WithArguments { program, args, .. } => Some((program, args)),
|
||||
}) else {
|
||||
return ControlFlow::Break(());
|
||||
};
|
||||
#[cfg(target_os = "windows")]
|
||||
let windows_shell_type = to_windows_shell_type(&shell);
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
spawn_task.command_label = format!("{shell} -i -c '{}'", spawn_task.command_label);
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
use crate::terminal_panel::WindowsShellType;
|
||||
|
||||
match windows_shell_type {
|
||||
WindowsShellType::Powershell => {
|
||||
spawn_task.command_label = format!("{shell} -C '{}'", spawn_task.command_label)
|
||||
}
|
||||
WindowsShellType::Cmd => {
|
||||
spawn_task.command_label = format!("{shell} /C '{}'", spawn_task.command_label)
|
||||
}
|
||||
WindowsShellType::Other => {
|
||||
spawn_task.command_label =
|
||||
format!("{shell} -i -c '{}'", spawn_task.command_label)
|
||||
}
|
||||
}
|
||||
}
|
||||
let task_command = std::mem::replace(&mut spawn_task.command, shell);
|
||||
let task_args = std::mem::take(&mut spawn_task.args);
|
||||
let combined_command = task_args
|
||||
.into_iter()
|
||||
.fold(task_command, |mut command, arg| {
|
||||
command.push(' ');
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
command.push_str(&arg);
|
||||
#[cfg(target_os = "windows")]
|
||||
command.push_str(&to_windows_shell_variable(windows_shell_type, arg));
|
||||
command
|
||||
});
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
user_args.extend(["-i".to_owned(), "-c".to_owned(), combined_command]);
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
use crate::terminal_panel::WindowsShellType;
|
||||
|
||||
match windows_shell_type {
|
||||
WindowsShellType::Powershell => {
|
||||
user_args.extend(["-C".to_owned(), combined_command])
|
||||
}
|
||||
WindowsShellType::Cmd => user_args.extend(["/C".to_owned(), combined_command]),
|
||||
WindowsShellType::Other => {
|
||||
user_args.extend(["-i".to_owned(), "-c".to_owned(), combined_command])
|
||||
}
|
||||
}
|
||||
}
|
||||
spawn_task.args = user_args;
|
||||
// Set up shell args unconditionally, as tasks are always spawned inside of a shell.
|
||||
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
|
||||
pub fn spawn_in_new_terminal(
|
||||
&mut self,
|
||||
spawn_task: SpawnInTerminal,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue