debugger: More tidy up for SSH (#28993)
Split `locator` out of DebugTaskDefinition to make it clearer when location needs to happen. Release Notes: - N/A --------- Co-authored-by: Anthony Eid <hello@anthonyeid.me> Co-authored-by: Anthony <anthony@zed.dev> Co-authored-by: Cole Miller <m@cole-miller.net>
This commit is contained in:
parent
d13cd007a2
commit
9d35f0389d
57 changed files with 1146 additions and 884 deletions
|
@ -1,4 +1,4 @@
|
|||
use std::{cmp, ops::ControlFlow, path::PathBuf, sync::Arc, time::Duration};
|
||||
use std::{cmp, ops::ControlFlow, path::PathBuf, process::ExitStatus, sync::Arc, time::Duration};
|
||||
|
||||
use crate::{
|
||||
TerminalView, default_working_directory,
|
||||
|
@ -9,7 +9,7 @@ use crate::{
|
|||
use breadcrumbs::Breadcrumbs;
|
||||
use collections::HashMap;
|
||||
use db::kvp::KEY_VALUE_STORE;
|
||||
use futures::future::join_all;
|
||||
use futures::{channel::oneshot, future::join_all};
|
||||
use gpui::{
|
||||
Action, AnyView, App, AsyncApp, AsyncWindowContext, Context, Corner, Entity, EventEmitter,
|
||||
ExternalPaths, FocusHandle, Focusable, IntoElement, ParentElement, Pixels, Render, Styled,
|
||||
|
@ -279,17 +279,9 @@ impl TerminalPanel {
|
|||
};
|
||||
|
||||
if let Some(workspace) = workspace.upgrade() {
|
||||
terminal_panel
|
||||
.update_in(&mut cx, |_, window, cx| {
|
||||
cx.subscribe_in(&workspace, window, |terminal_panel, _, e, window, cx| {
|
||||
if let workspace::Event::SpawnTask {
|
||||
action: spawn_in_terminal,
|
||||
} = e
|
||||
{
|
||||
terminal_panel.spawn_task(spawn_in_terminal, window, cx);
|
||||
};
|
||||
})
|
||||
.detach();
|
||||
workspace
|
||||
.update(&mut cx, |workspace, _| {
|
||||
workspace.set_terminal_provider(TerminalProvider(terminal_panel.clone()))
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
|
@ -486,12 +478,17 @@ impl TerminalPanel {
|
|||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
fn spawn_task(&mut self, task: &SpawnInTerminal, window: &mut Window, cx: &mut Context<Self>) {
|
||||
fn spawn_task(
|
||||
&mut self,
|
||||
task: &SpawnInTerminal,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<Entity<Terminal>>> {
|
||||
let Ok(is_local) = self
|
||||
.workspace
|
||||
.update(cx, |workspace, cx| workspace.project().read(cx).is_local())
|
||||
else {
|
||||
return;
|
||||
return Task::ready(Err(anyhow!("Project is not local")));
|
||||
};
|
||||
|
||||
let builder = ShellBuilder::new(is_local, &task.shell);
|
||||
|
@ -506,58 +503,53 @@ impl TerminalPanel {
|
|||
};
|
||||
|
||||
if task.allow_concurrent_runs && task.use_new_terminal {
|
||||
self.spawn_in_new_terminal(task, window, cx)
|
||||
.detach_and_log_err(cx);
|
||||
return;
|
||||
return self.spawn_in_new_terminal(task, window, cx);
|
||||
}
|
||||
|
||||
let mut terminals_for_task = self.terminals_for_task(&task.full_label, cx);
|
||||
let Some(existing) = terminals_for_task.pop() else {
|
||||
self.spawn_in_new_terminal(task, window, cx)
|
||||
.detach_and_log_err(cx);
|
||||
return;
|
||||
return self.spawn_in_new_terminal(task, window, cx);
|
||||
};
|
||||
|
||||
let (existing_item_index, task_pane, existing_terminal) = existing;
|
||||
if task.allow_concurrent_runs {
|
||||
self.replace_terminal(
|
||||
return self.replace_terminal(
|
||||
task,
|
||||
task_pane,
|
||||
existing_item_index,
|
||||
existing_terminal,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
.detach();
|
||||
return;
|
||||
);
|
||||
}
|
||||
|
||||
let (tx, rx) = oneshot::channel();
|
||||
|
||||
self.deferred_tasks.insert(
|
||||
task.id.clone(),
|
||||
cx.spawn_in(window, async move |terminal_panel, cx| {
|
||||
wait_for_terminals_tasks(terminals_for_task, cx).await;
|
||||
let task = terminal_panel.update_in(cx, |terminal_panel, window, cx| {
|
||||
if task.use_new_terminal {
|
||||
terminal_panel
|
||||
.spawn_in_new_terminal(task, window, cx)
|
||||
.detach_and_log_err(cx);
|
||||
None
|
||||
terminal_panel.spawn_in_new_terminal(task, window, cx)
|
||||
} else {
|
||||
Some(terminal_panel.replace_terminal(
|
||||
terminal_panel.replace_terminal(
|
||||
task,
|
||||
task_pane,
|
||||
existing_item_index,
|
||||
existing_terminal,
|
||||
window,
|
||||
cx,
|
||||
))
|
||||
)
|
||||
}
|
||||
});
|
||||
if let Ok(Some(task)) = task {
|
||||
task.await;
|
||||
if let Ok(task) = task {
|
||||
tx.send(task.await).ok();
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
cx.spawn(async move |_, _| rx.await?)
|
||||
}
|
||||
|
||||
pub fn spawn_in_new_terminal(
|
||||
|
@ -810,60 +802,47 @@ impl TerminalPanel {
|
|||
terminal_to_replace: Entity<TerminalView>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Option<()>> {
|
||||
) -> Task<Result<Entity<Terminal>>> {
|
||||
let reveal = spawn_task.reveal;
|
||||
let reveal_target = spawn_task.reveal_target;
|
||||
let window_handle = window.window_handle();
|
||||
let task_workspace = self.workspace.clone();
|
||||
cx.spawn_in(window, async move |terminal_panel, cx| {
|
||||
let project = terminal_panel
|
||||
.update(cx, |this, cx| {
|
||||
this.workspace
|
||||
.update(cx, |workspace, _| workspace.project().clone())
|
||||
.ok()
|
||||
})
|
||||
.ok()
|
||||
.flatten()?;
|
||||
let project = terminal_panel.update(cx, |this, cx| {
|
||||
this.workspace
|
||||
.update(cx, |workspace, _| workspace.project().clone())
|
||||
})??;
|
||||
let new_terminal = project
|
||||
.update(cx, |project, cx| {
|
||||
project.create_terminal(TerminalKind::Task(spawn_task), window_handle, cx)
|
||||
})
|
||||
.ok()?
|
||||
.await
|
||||
.log_err()?;
|
||||
terminal_to_replace
|
||||
.update_in(cx, |terminal_to_replace, window, cx| {
|
||||
terminal_to_replace.set_terminal(new_terminal, window, cx);
|
||||
})
|
||||
.ok()?;
|
||||
})?
|
||||
.await?;
|
||||
terminal_to_replace.update_in(cx, |terminal_to_replace, window, cx| {
|
||||
terminal_to_replace.set_terminal(new_terminal.clone(), window, cx);
|
||||
})?;
|
||||
|
||||
match reveal {
|
||||
RevealStrategy::Always => match reveal_target {
|
||||
RevealTarget::Center => {
|
||||
task_workspace
|
||||
.update_in(cx, |workspace, window, cx| {
|
||||
workspace
|
||||
.active_item(cx)
|
||||
.context("retrieving active terminal item in the workspace")
|
||||
.log_err()?
|
||||
.item_focus_handle(cx)
|
||||
.focus(window);
|
||||
Some(())
|
||||
})
|
||||
.ok()??;
|
||||
task_workspace.update_in(cx, |workspace, window, cx| {
|
||||
workspace
|
||||
.active_item(cx)
|
||||
.context("retrieving active terminal item in the workspace")?
|
||||
.item_focus_handle(cx)
|
||||
.focus(window);
|
||||
anyhow::Ok(())
|
||||
})??;
|
||||
}
|
||||
RevealTarget::Dock => {
|
||||
terminal_panel
|
||||
.update_in(cx, |terminal_panel, window, cx| {
|
||||
terminal_panel.activate_terminal_view(
|
||||
&task_pane,
|
||||
terminal_item_index,
|
||||
true,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.ok()?;
|
||||
terminal_panel.update_in(cx, |terminal_panel, window, cx| {
|
||||
terminal_panel.activate_terminal_view(
|
||||
&task_pane,
|
||||
terminal_item_index,
|
||||
true,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})?;
|
||||
|
||||
cx.spawn(async move |cx| {
|
||||
task_workspace
|
||||
|
@ -877,24 +856,20 @@ impl TerminalPanel {
|
|||
},
|
||||
RevealStrategy::NoFocus => match reveal_target {
|
||||
RevealTarget::Center => {
|
||||
task_workspace
|
||||
.update_in(cx, |workspace, window, cx| {
|
||||
workspace.active_pane().focus_handle(cx).focus(window);
|
||||
})
|
||||
.ok()?;
|
||||
task_workspace.update_in(cx, |workspace, window, cx| {
|
||||
workspace.active_pane().focus_handle(cx).focus(window);
|
||||
})?;
|
||||
}
|
||||
RevealTarget::Dock => {
|
||||
terminal_panel
|
||||
.update_in(cx, |terminal_panel, window, cx| {
|
||||
terminal_panel.activate_terminal_view(
|
||||
&task_pane,
|
||||
terminal_item_index,
|
||||
false,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.ok()?;
|
||||
terminal_panel.update_in(cx, |terminal_panel, window, cx| {
|
||||
terminal_panel.activate_terminal_view(
|
||||
&task_pane,
|
||||
terminal_item_index,
|
||||
false,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})?;
|
||||
|
||||
cx.spawn(async move |cx| {
|
||||
task_workspace
|
||||
|
@ -909,7 +884,7 @@ impl TerminalPanel {
|
|||
RevealStrategy::Never => {}
|
||||
}
|
||||
|
||||
Some(())
|
||||
Ok(new_terminal)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1158,7 +1133,7 @@ async fn wait_for_terminals_tasks(
|
|||
})
|
||||
.ok()
|
||||
});
|
||||
let _: Vec<()> = join_all(pending_tasks).await;
|
||||
let _: Vec<_> = join_all(pending_tasks).await;
|
||||
}
|
||||
|
||||
fn add_paths_to_terminal(
|
||||
|
@ -1475,6 +1450,34 @@ impl Panel for TerminalPanel {
|
|||
}
|
||||
}
|
||||
|
||||
struct TerminalProvider(Entity<TerminalPanel>);
|
||||
|
||||
impl workspace::TerminalProvider for TerminalProvider {
|
||||
fn spawn(
|
||||
&self,
|
||||
task: SpawnInTerminal,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<ExitStatus>> {
|
||||
let this = self.0.clone();
|
||||
window.spawn(cx, async move |cx| {
|
||||
let terminal = this
|
||||
.update_in(cx, |terminal_panel, window, cx| {
|
||||
terminal_panel.spawn_task(&task, window, cx)
|
||||
})?
|
||||
.await?;
|
||||
let Some(exit_code) = terminal
|
||||
.read_with(cx, |terminal, cx| terminal.wait_for_completed_task(cx))?
|
||||
.await
|
||||
else {
|
||||
return Err(anyhow!("Task cancelled"));
|
||||
};
|
||||
|
||||
Ok(exit_code)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct InlineAssistTabBarButton {
|
||||
focus_handle: FocusHandle,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue