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

@ -3,8 +3,8 @@ use fuzzy::{StringMatch, StringMatchCandidate};
use gpui::Subscription;
use gpui::{DismissEvent, Entity, EventEmitter, Focusable, Render};
use picker::{Picker, PickerDelegate};
use project::debugger::attach_processes;
use std::cell::LazyCell;
use std::sync::Arc;
use sysinfo::System;
use ui::{prelude::*, Context, Tooltip};
@ -13,10 +13,10 @@ use util::debug_panic;
use workspace::ModalView;
#[derive(Debug, Clone)]
struct Candidate {
pid: u32,
name: String,
command: Vec<String>,
pub(super) struct Candidate {
pub(super) pid: u32,
pub(super) name: SharedString,
pub(super) command: Vec<String>,
}
pub(crate) struct AttachModalDelegate {
@ -24,16 +24,20 @@ pub(crate) struct AttachModalDelegate {
matches: Vec<StringMatch>,
placeholder_text: Arc<str>,
project: Entity<project::Project>,
debug_config: task::DebugAdapterConfig,
candidates: Option<Vec<Candidate>>,
debug_config: task::DebugTaskDefinition,
candidates: Arc<[Candidate]>,
}
impl AttachModalDelegate {
pub fn new(project: Entity<project::Project>, debug_config: task::DebugAdapterConfig) -> Self {
fn new(
project: Entity<project::Project>,
debug_config: task::DebugTaskDefinition,
candidates: Arc<[Candidate]>,
) -> Self {
Self {
project,
debug_config,
candidates: None,
candidates,
selected_index: 0,
matches: Vec::default(),
placeholder_text: Arc::from("Select the process you want to attach the debugger to"),
@ -49,12 +53,56 @@ pub struct AttachModal {
impl AttachModal {
pub fn new(
project: Entity<project::Project>,
debug_config: task::DebugAdapterConfig,
debug_config: task::DebugTaskDefinition,
window: &mut Window,
cx: &mut Context<Self>,
) -> Self {
let mut processes: Vec<_> = System::new_all()
.processes()
.values()
.map(|process| {
let name = process.name().to_string_lossy().into_owned();
Candidate {
name: name.into(),
pid: process.pid().as_u32(),
command: process
.cmd()
.iter()
.map(|s| s.to_string_lossy().to_string())
.collect::<Vec<_>>(),
}
})
.collect();
processes.sort_by_key(|k| k.name.clone());
Self::with_processes(project, debug_config, processes, window, cx)
}
pub(super) fn with_processes(
project: Entity<project::Project>,
debug_config: task::DebugTaskDefinition,
processes: Vec<Candidate>,
window: &mut Window,
cx: &mut Context<Self>,
) -> Self {
let adapter = project
.read(cx)
.debug_adapters()
.adapter(&debug_config.adapter);
let filter = LazyCell::new(|| adapter.map(|adapter| adapter.attach_processes_filter()));
let processes = processes
.into_iter()
.filter(|process| {
filter
.as_ref()
.map_or(false, |filter| filter.is_match(&process.name))
})
.collect();
let picker = cx.new(|cx| {
Picker::uniform_list(AttachModalDelegate::new(project, debug_config), window, cx)
Picker::uniform_list(
AttachModalDelegate::new(project, debug_config, processes),
window,
cx,
)
});
Self {
_subscription: cx.subscribe(&picker, |_, _, _, cx| {
@ -116,32 +164,7 @@ impl PickerDelegate for AttachModalDelegate {
) -> gpui::Task<()> {
cx.spawn(async move |this, cx| {
let Some(processes) = this
.update(cx, |this, _| {
if let Some(processes) = this.delegate.candidates.clone() {
processes
} else {
let system = System::new_all();
let processes =
attach_processes(&this.delegate.debug_config.kind, &system.processes());
let candidates = processes
.into_iter()
.map(|(pid, process)| Candidate {
pid: pid.as_u32(),
name: process.name().to_string_lossy().into_owned(),
command: process
.cmd()
.iter()
.map(|s| s.to_string_lossy().to_string())
.collect::<Vec<_>>(),
})
.collect::<Vec<Candidate>>();
let _ = this.delegate.candidates.insert(candidates.clone());
candidates
}
})
.update(cx, |this, _| this.delegate.candidates.clone())
.ok()
else {
return;
@ -176,7 +199,6 @@ impl PickerDelegate for AttachModalDelegate {
let delegate = &mut this.delegate;
delegate.matches = matches;
delegate.candidates = Some(processes);
if delegate.matches.is_empty() {
delegate.selected_index = 0;
@ -195,7 +217,7 @@ impl PickerDelegate for AttachModalDelegate {
.get(self.selected_index())
.and_then(|current_match| {
let ix = current_match.candidate_id;
self.candidates.as_ref().map(|candidates| &candidates[ix])
self.candidates.get(ix)
});
let Some(candidate) = candidate else {
@ -206,7 +228,7 @@ impl PickerDelegate for AttachModalDelegate {
DebugRequestType::Attach(config) => {
config.process_id = Some(candidate.pid);
}
DebugRequestType::Launch => {
DebugRequestType::Launch(_) => {
debug_panic!("Debugger attach modal used on launch debug config");
return;
}
@ -214,7 +236,13 @@ impl PickerDelegate for AttachModalDelegate {
let config = self.debug_config.clone();
self.project
.update(cx, |project, cx| project.start_debug_session(config, cx))
.update(cx, |project, cx| {
#[cfg(any(test, feature = "test-support"))]
let ret = project.fake_debug_session(config.request, None, false, cx);
#[cfg(not(any(test, feature = "test-support")))]
let ret = project.start_debug_session(config.into(), cx);
ret
})
.detach_and_log_err(cx);
cx.emit(DismissEvent);
@ -222,7 +250,6 @@ impl PickerDelegate for AttachModalDelegate {
fn dismissed(&mut self, _window: &mut Window, cx: &mut Context<Picker<Self>>) {
self.selected_index = 0;
self.candidates.take();
cx.emit(DismissEvent);
}
@ -234,9 +261,8 @@ impl PickerDelegate for AttachModalDelegate {
_window: &mut Window,
_: &mut Context<Picker<Self>>,
) -> Option<Self::ListItem> {
let candidates = self.candidates.as_ref()?;
let hit = &self.matches[ix];
let candidate = &candidates.get(hit.candidate_id)?;
let candidate = self.candidates.get(hit.candidate_id)?;
Some(
ListItem::new(SharedString::from(format!("process-entry-{ix}")))
@ -279,9 +305,8 @@ impl PickerDelegate for AttachModalDelegate {
}
}
#[allow(dead_code)]
#[cfg(any(test, feature = "test-support"))]
pub(crate) fn process_names(modal: &AttachModal, cx: &mut Context<AttachModal>) -> Vec<String> {
pub(crate) fn _process_names(modal: &AttachModal, cx: &mut Context<AttachModal>) -> Vec<String> {
modal.picker.update(cx, |picker, _| {
picker
.delegate