diff --git a/crates/debugger_ui/src/debugger_panel.rs b/crates/debugger_ui/src/debugger_panel.rs index 4700ae2ac7..7725409c3b 100644 --- a/crates/debugger_ui/src/debugger_panel.rs +++ b/crates/debugger_ui/src/debugger_panel.rs @@ -3,8 +3,8 @@ use anyhow::{anyhow, Result}; use collections::HashMap; use command_palette_hooks::CommandPaletteFilter; use dap::{ - client::SessionId, debugger_settings::DebuggerSettings, ContinuedEvent, LoadedSourceEvent, - ModuleEvent, OutputEvent, StoppedEvent, ThreadEvent, + client::SessionId, debugger_settings::DebuggerSettings, ContinuedEvent, DebugAdapterConfig, + LoadedSourceEvent, ModuleEvent, OutputEvent, StoppedEvent, ThreadEvent, }; use futures::{channel::mpsc, SinkExt as _}; use gpui::{ @@ -21,6 +21,7 @@ use settings::Settings; use std::{any::TypeId, path::PathBuf}; use terminal_view::terminal_panel::TerminalPanel; use ui::prelude::*; +use util::ResultExt; use workspace::{ dock::{DockPosition, Panel, PanelEvent}, pane, Continue, Disconnect, Pane, Pause, Restart, StepBack, StepInto, StepOut, StepOver, Stop, @@ -51,6 +52,7 @@ pub struct DebugPanel { project: WeakEntity, workspace: WeakEntity, _subscriptions: Vec, + pub(crate) last_inert_config: Option, } impl DebugPanel { @@ -63,6 +65,7 @@ impl DebugPanel { let project = workspace.project().clone(); let dap_store = project.read(cx).dap_store(); let weak_workspace = workspace.weak_handle(); + let debug_panel = cx.weak_entity(); let pane = cx.new(|cx| { let mut pane = Pane::new( workspace.weak_handle(), @@ -81,6 +84,7 @@ impl DebugPanel { pane.set_render_tab_bar_buttons(cx, { let project = project.clone(); let weak_workspace = weak_workspace.clone(); + let debug_panel = debug_panel.clone(); move |_, _, cx| { let project = project.clone(); let weak_workspace = weak_workspace.clone(); @@ -91,21 +95,34 @@ impl DebugPanel { .child( IconButton::new("new-debug-session", IconName::Plus) .icon_size(IconSize::Small) - .on_click(cx.listener(move |pane, _, window, cx| { - pane.add_item( - Box::new(DebugSession::inert( - project.clone(), - weak_workspace.clone(), + .on_click({ + let debug_panel = debug_panel.clone(); + + cx.listener(move |pane, _, window, cx| { + let config = debug_panel + .read_with(cx, |this: &DebugPanel, _| { + this.last_inert_config.clone() + }) + .log_err() + .flatten(); + + pane.add_item( + Box::new(DebugSession::inert( + project.clone(), + weak_workspace.clone(), + debug_panel.clone(), + config, + window, + cx, + )), + false, + false, + None, window, cx, - )), - false, - false, - None, - window, - cx, - ); - })), + ); + }) + }), ) .into_any_element(), ), @@ -116,6 +133,8 @@ impl DebugPanel { Box::new(DebugSession::inert( project.clone(), weak_workspace.clone(), + debug_panel.clone(), + None, window, cx, )), @@ -138,6 +157,7 @@ impl DebugPanel { pane, size: px(300.), _subscriptions, + last_inert_config: None, project: project.downgrade(), workspace: workspace.weak_handle(), }; @@ -280,8 +300,14 @@ impl DebugPanel { // We already have an item for this session. return; } - let session_item = - DebugSession::running(project, self.workspace.clone(), session, window, cx); + let session_item = DebugSession::running( + project, + self.workspace.clone(), + session, + cx.weak_entity(), + window, + cx, + ); self.pane.update(cx, |pane, cx| { pane.add_item(Box::new(session_item), true, true, None, window, cx); @@ -504,12 +530,16 @@ impl Panel for DebugPanel { let Some(project) = self.project.clone().upgrade() else { return; }; + let config = self.last_inert_config.clone(); + let panel = cx.weak_entity(); // todo: We need to revisit it when we start adding stopped items to pane (as that'll cause us to add two items). self.pane.update(cx, |this, cx| { this.add_item( Box::new(DebugSession::inert( project, self.workspace.clone(), + panel, + config, window, cx, )), diff --git a/crates/debugger_ui/src/session.rs b/crates/debugger_ui/src/session.rs index c28aff90f8..310b38507d 100644 --- a/crates/debugger_ui/src/session.rs +++ b/crates/debugger_ui/src/session.rs @@ -6,6 +6,7 @@ mod starting; use std::time::Duration; use dap::client::SessionId; +use dap::DebugAdapterConfig; use failed::FailedState; use gpui::{ percentage, Animation, AnimationExt, AnyElement, App, Entity, EventEmitter, FocusHandle, @@ -19,11 +20,14 @@ use rpc::proto::{self, PeerId}; use running::RunningState; use starting::{StartingEvent, StartingState}; use ui::prelude::*; +use util::ResultExt; use workspace::{ item::{self, Item}, FollowableItem, ViewId, Workspace, }; +use crate::debugger_panel::DebugPanel; + pub(crate) enum DebugSessionState { Inert(Entity), Starting(Entity), @@ -44,6 +48,7 @@ pub struct DebugSession { remote_id: Option, mode: DebugSessionState, dap_store: WeakEntity, + debug_panel: WeakEntity, worktree_store: WeakEntity, workspace: WeakEntity, _subscriptions: [Subscription; 1], @@ -67,6 +72,8 @@ impl DebugSession { pub(super) fn inert( project: Entity, workspace: WeakEntity, + debug_panel: WeakEntity, + config: Option, window: &mut Window, cx: &mut App, ) -> Entity { @@ -77,7 +84,8 @@ impl DebugSession { .and_then(|tree| tree.read(cx).abs_path().to_str().map(|str| str.to_string())) .unwrap_or_default(); - let inert = cx.new(|cx| InertState::new(workspace.clone(), &default_cwd, window, cx)); + let inert = + cx.new(|cx| InertState::new(workspace.clone(), &default_cwd, config, window, cx)); let project = project.read(cx); let dap_store = project.dap_store().downgrade(); @@ -89,6 +97,7 @@ impl DebugSession { mode: DebugSessionState::Inert(inert), dap_store, worktree_store, + debug_panel, workspace, _subscriptions, } @@ -99,6 +108,7 @@ impl DebugSession { project: Entity, workspace: WeakEntity, session: Entity, + debug_panel: WeakEntity, window: &mut Window, cx: &mut App, ) -> Entity { @@ -111,6 +121,7 @@ impl DebugSession { remote_id: None, mode: DebugSessionState::Running(mode), dap_store: project.read(cx).dap_store().downgrade(), + debug_panel, worktree_store: project.read(cx).worktree_store().downgrade(), workspace, }) @@ -148,6 +159,11 @@ impl DebugSession { let dap_store = self.dap_store.clone(); let InertEvent::Spawned { config } = event; let config = config.clone(); + + self.debug_panel + .update(cx, |this, _| this.last_inert_config = Some(config.clone())) + .log_err(); + let worktree = self .worktree_store .update(cx, |this, _| this.worktrees().next()) diff --git a/crates/debugger_ui/src/session/inert.rs b/crates/debugger_ui/src/session/inert.rs index a6a9337b56..d7a2f5a2ca 100644 --- a/crates/debugger_ui/src/session/inert.rs +++ b/crates/debugger_ui/src/session/inert.rs @@ -32,6 +32,15 @@ impl SpawnMode { } } +impl From for SpawnMode { + fn from(request: DebugRequestType) -> Self { + match request { + DebugRequestType::Launch => SpawnMode::Launch, + DebugRequestType::Attach(_) => SpawnMode::Attach, + } + } +} + pub(crate) struct InertState { focus_handle: FocusHandle, selected_debugger: Option, @@ -46,27 +55,56 @@ impl InertState { pub(super) fn new( workspace: WeakEntity, default_cwd: &str, + debug_config: Option, window: &mut Window, cx: &mut Context, ) -> 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 spawn_mode = debug_config + .as_ref() + .map(|config| config.request.clone().into()) + .unwrap_or_default(); + + let program = debug_config + .as_ref() + .and_then(|config| config.program.to_owned()); + let program_editor = cx.new(|cx| { let mut editor = Editor::single_line(window, cx); - editor.set_placeholder_text("Program path", cx); + if let Some(program) = program { + editor.insert(&program, window, cx); + } else { + editor.set_placeholder_text("Program path", cx); + } editor }); + + let cwd = debug_config + .and_then(|config| config.cwd.map(|cwd| cwd.to_owned())) + .unwrap_or_else(|| PathBuf::from(default_cwd)); + let cwd_editor = cx.new(|cx| { let mut editor = Editor::single_line(window, cx); - editor.insert(default_cwd, window, cx); + editor.insert(cwd.to_str().unwrap_or_else(|| default_cwd), window, cx); editor.set_placeholder_text("Working directory", cx); editor }); + Self { workspace, cwd_editor, program_editor, - selected_debugger: None, + selected_debugger, + spawn_mode, focus_handle: cx.focus_handle(), - spawn_mode: SpawnMode::default(), popover_handle: Default::default(), } }