debugger: Remove fake adapter and un-gate GDB (#27557)

This is a clean-up PR in anticipation of introduction of Debugger
Registry. I wanna get rid of DebugAdapterKind (or rather, it being an
enum).
Release Notes:

- N/A

---------

Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Anthony <anthony@zed.dev>
This commit is contained in:
Piotr Osiewicz 2025-03-27 23:31:58 +01:00 committed by GitHub
parent 56eb650f09
commit 4839195003
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
53 changed files with 1315 additions and 924 deletions

View file

@ -1,10 +1,10 @@
use std::path::PathBuf;
use dap::{DebugAdapterConfig, DebugAdapterKind, DebugRequestType};
use dap::DebugRequestType;
use editor::{Editor, EditorElement, EditorStyle};
use gpui::{App, AppContext, Entity, EventEmitter, FocusHandle, Focusable, TextStyle, WeakEntity};
use settings::Settings as _;
use task::TCPHost;
use task::{DebugTaskDefinition, LaunchConfig, TCPHost};
use theme::ThemeSettings;
use ui::{
div, h_flex, relative, v_flex, ActiveTheme as _, ButtonCommon, ButtonLike, Clickable, Context,
@ -35,7 +35,7 @@ impl SpawnMode {
impl From<DebugRequestType> for SpawnMode {
fn from(request: DebugRequestType) -> Self {
match request {
DebugRequestType::Launch => SpawnMode::Launch,
DebugRequestType::Launch(_) => SpawnMode::Launch,
DebugRequestType::Attach(_) => SpawnMode::Attach,
}
}
@ -55,18 +55,13 @@ impl InertState {
pub(super) fn new(
workspace: WeakEntity<Workspace>,
default_cwd: &str,
debug_config: Option<DebugAdapterConfig>,
debug_config: Option<DebugTaskDefinition>,
window: &mut Window,
cx: &mut Context<Self>,
) -> Self {
let selected_debugger = debug_config.as_ref().and_then(|config| match config.kind {
DebugAdapterKind::Lldb => Some("LLDB".into()),
DebugAdapterKind::Go(_) => Some("Delve".into()),
DebugAdapterKind::Php(_) => Some("PHP".into()),
DebugAdapterKind::Javascript(_) => Some("JavaScript".into()),
DebugAdapterKind::Python(_) => Some("Debugpy".into()),
_ => None,
});
let selected_debugger = debug_config
.as_ref()
.map(|config| SharedString::from(config.adapter.clone()));
let spawn_mode = debug_config
.as_ref()
@ -75,7 +70,10 @@ impl InertState {
let program = debug_config
.as_ref()
.and_then(|config| config.program.to_owned());
.and_then(|config| match &config.request {
DebugRequestType::Attach(_) => None,
DebugRequestType::Launch(launch_config) => Some(launch_config.program.clone()),
});
let program_editor = cx.new(|cx| {
let mut editor = Editor::single_line(window, cx);
@ -88,7 +86,10 @@ impl InertState {
});
let cwd = debug_config
.and_then(|config| config.cwd.map(|cwd| cwd.to_owned()))
.and_then(|config| match &config.request {
DebugRequestType::Attach(_) => None,
DebugRequestType::Launch(launch_config) => launch_config.cwd.clone(),
})
.unwrap_or_else(|| PathBuf::from(default_cwd));
let cwd_editor = cx.new(|cx| {
@ -116,7 +117,7 @@ impl Focusable for InertState {
}
pub(crate) enum InertEvent {
Spawned { config: DebugAdapterConfig },
Spawned { config: DebugTaskDefinition },
}
impl EventEmitter<InertEvent> for InertState {}
@ -130,6 +131,7 @@ impl Render for InertState {
cx: &mut ui::Context<'_, Self>,
) -> impl ui::IntoElement {
let weak = cx.weak_entity();
let workspace = self.workspace.clone();
let disable_buttons = self.selected_debugger.is_none();
let spawn_button = ButtonLike::new_rounded_left("spawn-debug-session")
.child(Label::new(self.spawn_mode.label()).size(LabelSize::Small))
@ -137,21 +139,26 @@ impl Render for InertState {
if this.spawn_mode == SpawnMode::Launch {
let program = this.program_editor.read(cx).text(cx);
let cwd = PathBuf::from(this.cwd_editor.read(cx).text(cx));
let kind =
kind_for_label(this.selected_debugger.as_deref().unwrap_or_else(|| {
let kind = this
.selected_debugger
.as_deref()
.unwrap_or_else(|| {
unimplemented!(
"Automatic selection of a debugger based on users project"
)
}));
})
.to_string();
cx.emit(InertEvent::Spawned {
config: DebugAdapterConfig {
config: DebugTaskDefinition {
label: "hard coded".into(),
kind,
request: DebugRequestType::Launch,
program: Some(program),
cwd: Some(cwd),
adapter: kind,
request: DebugRequestType::Launch(LaunchConfig {
program,
cwd: Some(cwd),
}),
tcp_connection: Some(TCPHost::default()),
initialize_args: None,
supports_attach: false,
},
});
} else {
@ -159,6 +166,7 @@ impl Render for InertState {
}
}))
.disabled(disable_buttons);
v_flex()
.track_focus(&self.focus_handle)
.size_full()
@ -179,28 +187,36 @@ impl Render for InertState {
.as_ref()
.unwrap_or_else(|| &SELECT_DEBUGGER_LABEL)
.clone(),
ContextMenu::build(window, cx, move |this, _, _| {
let setter_for_name = |name: &'static str| {
ContextMenu::build(window, cx, move |mut this, _, cx| {
let setter_for_name = |name: SharedString| {
let weak = weak.clone();
move |_: &mut Window, cx: &mut App| {
let name = name;
(&weak)
.update(cx, move |this, _| {
this.selected_debugger = Some(name.into());
})
.ok();
let name = name.clone();
weak.update(cx, move |this, cx| {
this.selected_debugger = Some(name.clone());
cx.notify();
})
.ok();
}
};
this.entry("GDB", None, setter_for_name("GDB"))
.entry("Delve", None, setter_for_name("Delve"))
.entry("LLDB", None, setter_for_name("LLDB"))
.entry("PHP", None, setter_for_name("PHP"))
.entry(
"JavaScript",
let available_adapters = workspace
.update(cx, |this, cx| {
this.project()
.read(cx)
.debug_adapters()
.enumerate_adapters()
})
.ok()
.unwrap_or_default();
for adapter in available_adapters {
this = this.entry(
adapter.0.clone(),
None,
setter_for_name("JavaScript"),
)
.entry("Debugpy", None, setter_for_name("Debugpy"))
setter_for_name(adapter.0.clone()),
);
}
this
}),
)),
),
@ -265,18 +281,6 @@ impl Render for InertState {
}
}
fn kind_for_label(label: &str) -> DebugAdapterKind {
match label {
"LLDB" => DebugAdapterKind::Lldb,
"Debugpy" => DebugAdapterKind::Python(TCPHost::default()),
"JavaScript" => DebugAdapterKind::Javascript(TCPHost::default()),
"PHP" => DebugAdapterKind::Php(TCPHost::default()),
"Delve" => DebugAdapterKind::Go(TCPHost::default()),
_ => {
unimplemented!()
} // Maybe we should set a toast notification here
}
}
impl InertState {
fn render_editor(editor: &Entity<Editor>, cx: &Context<Self>) -> impl IntoElement {
let settings = ThemeSettings::get_global(cx);
@ -302,19 +306,20 @@ impl InertState {
}
fn attach(&self, window: &mut Window, cx: &mut Context<Self>) {
let cwd = PathBuf::from(self.cwd_editor.read(cx).text(cx));
let kind = kind_for_label(self.selected_debugger.as_deref().unwrap_or_else(|| {
unimplemented!("Automatic selection of a debugger based on users project")
}));
let kind = self
.selected_debugger
.as_deref()
.map(|s| s.to_string())
.unwrap_or_else(|| {
unimplemented!("Automatic selection of a debugger based on users project")
});
let config = DebugAdapterConfig {
let config = DebugTaskDefinition {
label: "hard coded attach".into(),
kind,
adapter: kind,
request: DebugRequestType::Attach(task::AttachConfig { process_id: None }),
program: None,
cwd: Some(cwd),
initialize_args: None,
supports_attach: true,
tcp_connection: Some(TCPHost::default()),
};
let _ = self.workspace.update(cx, |workspace, cx| {