debugger: Open debugger panel on session startup (#29186)

Now all debug sessions are routed through the debug panel and are
started synchronously instead of by a task that returns a session once
the initialization process is finished. A session is `Mode::Booting`
while it's starting the debug adapter process and then transitions to
`Mode::Running` once this is completed.

This PR also added new tests for the dap logger, reverse start debugging
request, and debugging over SSH.

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>
Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: Zed AI <ai@zed.dev>
Co-authored-by: Remco Smits <djsmits12@gmail.com>
This commit is contained in:
Conrad Irwin 2025-04-22 17:35:47 -06:00 committed by GitHub
parent 75ab8ff9a1
commit 6a009b447a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 1261 additions and 1021 deletions

View file

@ -4,7 +4,7 @@ use anyhow::{Result, anyhow};
use gpui::{Context, Task};
use project::TaskSourceKind;
use remote::ConnectionState;
use task::{ResolvedTask, SpawnInTerminal, TaskContext, TaskTemplate};
use task::{DebugTaskDefinition, ResolvedTask, SpawnInTerminal, TaskContext, TaskTemplate};
use ui::Window;
use crate::Workspace;
@ -109,14 +109,26 @@ impl Workspace {
debug_config.definition
};
project
.update(cx, |project, cx| project.start_debug_session(config, cx))?
.await?;
workspace.update_in(cx, |workspace, window, cx| {
workspace.start_debug_session(config, window, cx);
})?;
anyhow::Ok(())
})
.detach_and_log_err(cx);
}
pub fn start_debug_session(
&mut self,
definition: DebugTaskDefinition,
window: &mut Window,
cx: &mut Context<Self>,
) {
if let Some(provider) = self.debugger_provider.as_mut() {
provider.start_session(definition, window, cx)
}
}
pub fn spawn_in_terminal(
self: &mut Workspace,
spawn_in_terminal: SpawnInTerminal,

View file

@ -96,7 +96,7 @@ use std::{
sync::{Arc, LazyLock, Weak, atomic::AtomicUsize},
time::Duration,
};
use task::SpawnInTerminal;
use task::{DebugTaskDefinition, SpawnInTerminal};
use theme::{ActiveTheme, SystemAppearance, ThemeSettings};
pub use toolbar::{Toolbar, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView};
pub use ui;
@ -139,6 +139,10 @@ pub trait TerminalProvider {
) -> Task<Result<ExitStatus>>;
}
pub trait DebuggerProvider {
fn start_session(&self, definition: DebugTaskDefinition, window: &mut Window, cx: &mut App);
}
actions!(
workspace,
[
@ -860,6 +864,7 @@ pub struct Workspace {
on_prompt_for_new_path: Option<PromptForNewPath>,
on_prompt_for_open_path: Option<PromptForOpenPath>,
terminal_provider: Option<Box<dyn TerminalProvider>>,
debugger_provider: Option<Box<dyn DebuggerProvider>>,
serializable_items_tx: UnboundedSender<Box<dyn SerializableItemHandle>>,
serialized_ssh_project: Option<SerializedSshProject>,
_items_serializer: Task<Result<()>>,
@ -1186,6 +1191,7 @@ impl Workspace {
on_prompt_for_new_path: None,
on_prompt_for_open_path: None,
terminal_provider: None,
debugger_provider: None,
serializable_items_tx,
_items_serializer,
session_id: Some(session_id),
@ -1705,6 +1711,10 @@ impl Workspace {
self.terminal_provider = Some(Box::new(provider));
}
pub fn set_debugger_provider(&mut self, provider: impl DebuggerProvider + 'static) {
self.debugger_provider = Some(Box::new(provider));
}
pub fn serialized_ssh_project(&self) -> Option<SerializedSshProject> {
self.serialized_ssh_project.clone()
}