debugger: Reuse parent's debug terminal for child sessions (#32493)

Cole Miller , Conrad Irwin , and Anthony Eid created

Closes #ISSUE

Release Notes:

- Debugger Beta: fixed an issue where the terminal pane of the debug
panel would be empty when debugging JavaScript.

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Co-authored-by: Anthony Eid <hello@anthonyeid.me>

Change summary

crates/debugger_ui/src/debugger_panel.rs  | 7 ++++++-
crates/debugger_ui/src/session.rs         | 7 +++----
crates/debugger_ui/src/session/running.rs | 4 +++-
3 files changed, 12 insertions(+), 6 deletions(-)

Detailed changes

crates/debugger_ui/src/debugger_panel.rs 🔗

@@ -1082,6 +1082,11 @@ async fn register_session_inner(
     .ok();
     let serialized_layout = persistence::get_serialized_layout(adapter_name).await;
     let debug_session = this.update_in(cx, |this, window, cx| {
+        let parent_session = this
+            .sessions
+            .iter()
+            .find(|p| Some(p.read(cx).session_id(cx)) == session.read(cx).parent_id(cx))
+            .cloned();
         this.sessions.retain(|session| {
             !session
                 .read(cx)
@@ -1095,8 +1100,8 @@ async fn register_session_inner(
         let debug_session = DebugSession::running(
             this.project.clone(),
             this.workspace.clone(),
+            parent_session.map(|p| p.read(cx).running_state().read(cx).debug_terminal.clone()),
             session,
-            cx.weak_entity(),
             serialized_layout,
             this.position(window, cx).axis(),
             window,

crates/debugger_ui/src/session.rs 🔗

@@ -1,6 +1,6 @@
 pub mod running;
 
-use crate::{StackTraceView, debugger_panel::DebugPanel, persistence::SerializedLayout};
+use crate::{StackTraceView, persistence::SerializedLayout, session::running::DebugTerminal};
 use dap::client::SessionId;
 use gpui::{
     App, Axis, Entity, EventEmitter, FocusHandle, Focusable, Subscription, Task, WeakEntity,
@@ -22,7 +22,6 @@ pub struct DebugSession {
     running_state: Entity<RunningState>,
     label: OnceLock<SharedString>,
     stack_trace_view: OnceCell<Entity<StackTraceView>>,
-    _debug_panel: WeakEntity<DebugPanel>,
     _worktree_store: WeakEntity<WorktreeStore>,
     workspace: WeakEntity<Workspace>,
     _subscriptions: [Subscription; 1],
@@ -38,8 +37,8 @@ impl DebugSession {
     pub(crate) fn running(
         project: Entity<Project>,
         workspace: WeakEntity<Workspace>,
+        parent_terminal: Option<Entity<DebugTerminal>>,
         session: Entity<Session>,
-        _debug_panel: WeakEntity<DebugPanel>,
         serialized_layout: Option<SerializedLayout>,
         dock_axis: Axis,
         window: &mut Window,
@@ -50,6 +49,7 @@ impl DebugSession {
                 session.clone(),
                 project.clone(),
                 workspace.clone(),
+                parent_terminal,
                 serialized_layout,
                 dock_axis,
                 window,
@@ -64,7 +64,6 @@ impl DebugSession {
             remote_id: None,
             running_state,
             label: OnceLock::new(),
-            _debug_panel,
             stack_trace_view: OnceCell::new(),
             _worktree_store: project.read(cx).worktree_store().downgrade(),
             workspace,

crates/debugger_ui/src/session/running.rs 🔗

@@ -605,6 +605,7 @@ impl RunningState {
         session: Entity<Session>,
         project: Entity<Project>,
         workspace: WeakEntity<Workspace>,
+        parent_terminal: Option<Entity<DebugTerminal>>,
         serialized_pane_layout: Option<SerializedLayout>,
         dock_axis: Axis,
         window: &mut Window,
@@ -617,7 +618,8 @@ impl RunningState {
             StackFrameList::new(workspace.clone(), session.clone(), weak_state, window, cx)
         });
 
-        let debug_terminal = cx.new(|cx| DebugTerminal::empty(window, cx));
+        let debug_terminal =
+            parent_terminal.unwrap_or_else(|| cx.new(|cx| DebugTerminal::empty(window, cx)));
 
         let variable_list =
             cx.new(|cx| VariableList::new(session.clone(), stack_frame_list.clone(), window, cx));