diff --git a/crates/debugger_ui/src/session/running.rs b/crates/debugger_ui/src/session/running.rs index f13364cc5cafe2afdfff17e8199125b2ed0519fd..dab2d3c80e60d0b6365f5572785daaefec836c1a 100644 --- a/crates/debugger_ui/src/session/running.rs +++ b/crates/debugger_ui/src/session/running.rs @@ -628,10 +628,9 @@ impl RunningState { &workspace, &stack_frame_list, &variable_list, - &module_list, - &loaded_source_list, &console, &breakpoint_list, + &debug_terminal, dock_axis, &mut pane_close_subscriptions, window, @@ -1468,10 +1467,9 @@ impl RunningState { workspace: &WeakEntity, stack_frame_list: &Entity, variable_list: &Entity, - module_list: &Entity, - loaded_source_list: &Entity, console: &Entity, breakpoints: &Entity, + debug_terminal: &Entity, dock_axis: Axis, subscriptions: &mut HashMap, window: &mut Window, @@ -1512,12 +1510,17 @@ impl RunningState { let center_pane = new_debugger_pane(workspace.clone(), project.clone(), window, cx); center_pane.update(cx, |this, cx| { + let weak_console = console.downgrade(); this.add_item( Box::new(SubView::new( - variable_list.focus_handle(cx), - variable_list.clone().into(), - DebuggerPaneItem::Variables, - None, + console.focus_handle(cx), + console.clone().into(), + DebuggerPaneItem::Console, + Some(Box::new(move |cx| { + weak_console + .read_with(cx, |console, cx| console.show_indicator(cx)) + .unwrap_or_default() + })), cx, )), true, @@ -1526,30 +1529,16 @@ impl RunningState { window, cx, ); - this.add_item( - Box::new(SubView::new( - module_list.focus_handle(cx), - module_list.clone().into(), - DebuggerPaneItem::Modules, - None, - cx, - )), - false, - false, - None, - window, - cx, - ); this.add_item( Box::new(SubView::new( - loaded_source_list.focus_handle(cx), - loaded_source_list.clone().into(), - DebuggerPaneItem::LoadedSources, + variable_list.focus_handle(cx), + variable_list.clone().into(), + DebuggerPaneItem::Variables, None, cx, )), - false, + true, false, None, window, @@ -1560,20 +1549,15 @@ impl RunningState { let rightmost_pane = new_debugger_pane(workspace.clone(), project.clone(), window, cx); rightmost_pane.update(cx, |this, cx| { - let weak_console = console.downgrade(); this.add_item( Box::new(SubView::new( - this.focus_handle(cx), - console.clone().into(), - DebuggerPaneItem::Console, - Some(Box::new(move |cx| { - weak_console - .read_with(cx, |console, cx| console.show_indicator(cx)) - .unwrap_or_default() - })), + debug_terminal.focus_handle(cx), + debug_terminal.clone().into(), + DebuggerPaneItem::Terminal, + None, cx, )), - true, + false, false, None, window, diff --git a/crates/debugger_ui/src/session/running/console.rs b/crates/debugger_ui/src/session/running/console.rs index 90d4612cd9a9dad276e94582f6dcfae746e29e04..d12b88af0422b6be87911c458b2c8af8bc522e32 100644 --- a/crates/debugger_ui/src/session/running/console.rs +++ b/crates/debugger_ui/src/session/running/console.rs @@ -14,7 +14,7 @@ use language::{Buffer, CodeLabel, ToOffset}; use menu::Confirm; use project::{ Completion, - debugger::session::{CompletionsQuery, OutputToken, Session}, + debugger::session::{CompletionsQuery, OutputToken, Session, SessionEvent}, }; use settings::Settings; use std::{cell::RefCell, rc::Rc, usize}; @@ -79,6 +79,11 @@ impl Console { let _subscriptions = vec![ cx.subscribe(&stack_frame_list, Self::handle_stack_frame_list_events), + cx.subscribe_in(&session, window, |this, _, event, window, cx| { + if let SessionEvent::ConsoleOutput = event { + this.update_output(window, cx) + } + }), cx.on_focus_in(&focus_handle, window, |console, window, cx| { if console.is_running(cx) { console.query_bar.focus_handle(cx).focus(window); @@ -200,12 +205,11 @@ impl Console { fn render_query_bar(&self, cx: &Context) -> impl IntoElement { EditorElement::new(&self.query_bar, self.editor_style(cx)) } -} -impl Render for Console { - fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { + fn update_output(&mut self, window: &mut Window, cx: &mut Context) { let session = self.session.clone(); let token = self.last_token; + self.update_output_task = cx.spawn_in(window, async move |this, cx| { _ = session.update_in(cx, move |session, window, cx| { let (output, last_processed_token) = session.output(token); @@ -220,7 +224,11 @@ impl Render for Console { }); }); }); + } +} +impl Render for Console { + fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { v_flex() .track_focus(&self.focus_handle) .key_context("DebugConsole") diff --git a/crates/debugger_ui/src/session/running/variable_list.rs b/crates/debugger_ui/src/session/running/variable_list.rs index d87d8c9b7376971b1f4ddf6a4e163fe030dd40e3..4eb8575e0076c3536f5d75ef883fa079dc11cbf5 100644 --- a/crates/debugger_ui/src/session/running/variable_list.rs +++ b/crates/debugger_ui/src/session/running/variable_list.rs @@ -154,12 +154,15 @@ impl VariableList { let _subscriptions = vec![ cx.subscribe(&stack_frame_list, Self::handle_stack_frame_list_events), - cx.subscribe(&session, |this, _, event, _| match event { + cx.subscribe(&session, |this, _, event, cx| match event { SessionEvent::Stopped(_) => { this.selection.take(); this.edited_path.take(); this.selected_stack_frame_id.take(); } + SessionEvent::Variables => { + this.build_entries(cx); + } _ => {} }), cx.on_focus_out(&focus_handle, window, |this, _, _, cx| { @@ -300,7 +303,7 @@ impl VariableList { match event { StackFrameListEvent::SelectedStackFrameChanged(stack_frame_id) => { self.selected_stack_frame_id = Some(*stack_frame_id); - cx.notify(); + self.build_entries(cx); } StackFrameListEvent::BuiltEntries => {} } @@ -344,14 +347,14 @@ impl VariableList { }; entry.is_expanded = !entry.is_expanded; - cx.notify(); + self.build_entries(cx); } fn select_first(&mut self, _: &SelectFirst, window: &mut Window, cx: &mut Context) { self.cancel_variable_edit(&Default::default(), window, cx); if let Some(variable) = self.entries.first() { self.selection = Some(variable.path.clone()); - cx.notify(); + self.build_entries(cx); } } @@ -359,7 +362,7 @@ impl VariableList { self.cancel_variable_edit(&Default::default(), window, cx); if let Some(variable) = self.entries.last() { self.selection = Some(variable.path.clone()); - cx.notify(); + self.build_entries(cx); } } @@ -378,7 +381,7 @@ impl VariableList { index.and_then(|ix| self.entries.get(ix).map(|var| var.path.clone())) { self.selection = Some(new_selection); - cx.notify(); + self.build_entries(cx); } else { self.select_last(&SelectLast, window, cx); } @@ -402,7 +405,7 @@ impl VariableList { index.and_then(|ix| self.entries.get(ix).map(|var| var.path.clone())) { self.selection = Some(new_selection); - cx.notify(); + self.build_entries(cx); } else { self.select_first(&SelectFirst, window, cx); } @@ -464,7 +467,7 @@ impl VariableList { self.select_prev(&SelectPrevious, window, cx); } else { entry_state.is_expanded = false; - cx.notify(); + self.build_entries(cx); } } } @@ -485,7 +488,7 @@ impl VariableList { self.select_next(&SelectNext, window, cx); } else { entry_state.is_expanded = true; - cx.notify(); + self.build_entries(cx); } } } @@ -929,8 +932,6 @@ impl Focusable for VariableList { impl Render for VariableList { fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { - self.build_entries(cx); - v_flex() .track_focus(&self.focus_handle) .key_context("VariableList") @@ -946,7 +947,6 @@ impl Render for VariableList { .on_action(cx.listener(Self::collapse_selected_entry)) .on_action(cx.listener(Self::cancel_variable_edit)) .on_action(cx.listener(Self::confirm_variable_edit)) - // .child( uniform_list( cx.entity().clone(), diff --git a/crates/debugger_ui/src/tests/module_list.rs b/crates/debugger_ui/src/tests/module_list.rs index 379b064eac5bba76152c54d3a2150499e0bc7f25..49cfd6fcf88339c7d040d56d575dafce50f8d0f2 100644 --- a/crates/debugger_ui/src/tests/module_list.rs +++ b/crates/debugger_ui/src/tests/module_list.rs @@ -1,5 +1,6 @@ use crate::{ debugger_panel::DebugPanel, + persistence::DebuggerPaneItem, tests::{active_debug_session_panel, init_test, init_test_workspace, start_debug_session}, }; use dap::{ @@ -110,7 +111,8 @@ async fn test_module_list(executor: BackgroundExecutor, cx: &mut TestAppContext) }); running_state.update_in(cx, |this, window, cx| { - this.activate_item(crate::persistence::DebuggerPaneItem::Modules, window, cx); + this.ensure_pane_item(DebuggerPaneItem::Modules, window, cx); + this.activate_item(DebuggerPaneItem::Modules, window, cx); cx.refresh_windows(); }); diff --git a/crates/debugger_ui/src/tests/variable_list.rs b/crates/debugger_ui/src/tests/variable_list.rs index bdb39e0e4c3e8c4d26d7e4dc675300af54f028da..ae8cfcdc560242e3b144bfd5acd64b6e3588102d 100644 --- a/crates/debugger_ui/src/tests/variable_list.rs +++ b/crates/debugger_ui/src/tests/variable_list.rs @@ -5,6 +5,7 @@ use std::sync::{ use crate::{ DebugPanel, + persistence::DebuggerPaneItem, session::running::variable_list::{CollapseSelectedEntry, ExpandSelectedEntry}, tests::{active_debug_session_panel, init_test, init_test_workspace, start_debug_session}, }; @@ -706,7 +707,13 @@ async fn test_keyboard_navigation(executor: BackgroundExecutor, cx: &mut TestApp cx.focus_self(window); let running = item.running_state().clone(); - let variable_list = running.read_with(cx, |state, _| state.variable_list().clone()); + let variable_list = running.update(cx, |state, cx| { + // have to do this because the variable list pane should be shown/active + // for testing keyboard navigation + state.activate_item(DebuggerPaneItem::Variables, window, cx); + + state.variable_list().clone() + }); variable_list.update(cx, |_, cx| cx.focus_self(window)); running }); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 0e8b01292ff9f5f48635a4fd4e252afc032f93c9..31497e6409cd4e2fbc3fc3002eebb19912816abe 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -20244,6 +20244,7 @@ impl SemanticsProvider for Entity { fn inline_values( &self, buffer_handle: Entity, + range: Range, cx: &mut App, ) -> Option>>> { diff --git a/crates/project/src/debugger/session.rs b/crates/project/src/debugger/session.rs index 96367b063fb31e94f17b0e925c21939a3e92b1c8..19e2ba830661a09a60dd7765b9fe470e997391da 100644 --- a/crates/project/src/debugger/session.rs +++ b/crates/project/src/debugger/session.rs @@ -24,7 +24,7 @@ use dap::{ messages::{Events, Message}, }; use dap::{ - ExceptionBreakpointsFilter, ExceptionFilterOptions, OutputEventCategory, + ExceptionBreakpointsFilter, ExceptionFilterOptions, OutputEvent, OutputEventCategory, RunInTerminalRequestArguments, StartDebuggingRequestArguments, }; use futures::channel::{mpsc, oneshot}; @@ -674,6 +674,7 @@ pub enum SessionEvent { request: RunInTerminalRequestArguments, sender: mpsc::Sender>, }, + ConsoleOutput, } #[derive(Clone, Debug, PartialEq, Eq)] @@ -885,9 +886,8 @@ impl Session { cx.spawn(async move |this, cx| { while let Some(output) = rx.next().await { - this.update(cx, |this, _| { - this.output_token.0 += 1; - this.output.push_back(dap::OutputEvent { + this.update(cx, |this, cx| { + let event = dap::OutputEvent { category: None, output, group: None, @@ -897,7 +897,8 @@ impl Session { column: None, data: None, location_reference: None, - }); + }; + this.push_output(event, cx); })?; } anyhow::Ok(()) @@ -1266,8 +1267,7 @@ impl Session { return; } - self.output.push_back(event); - self.output_token.0 += 1; + self.push_output(event, cx); cx.notify(); } Events::Breakpoint(event) => self.breakpoint_store.update(cx, |store, _| { @@ -1445,6 +1445,12 @@ impl Session { }); } + fn push_output(&mut self, event: OutputEvent, cx: &mut Context) { + self.output.push_back(event); + self.output_token.0 += 1; + cx.emit(SessionEvent::ConsoleOutput); + } + pub fn any_stopped_thread(&self) -> bool { self.thread_states.any_stopped_thread() } @@ -2063,8 +2069,7 @@ impl Session { source: Option, cx: &mut Context, ) -> Task<()> { - self.output_token.0 += 1; - self.output.push_back(dap::OutputEvent { + let event = dap::OutputEvent { category: None, output: format!("> {expression}"), group: None, @@ -2074,7 +2079,8 @@ impl Session { column: None, data: None, location_reference: None, - }); + }; + self.push_output(event, cx); let request = self.mode.request_dap(EvaluateCommand { expression, context, @@ -2086,8 +2092,7 @@ impl Session { this.update(cx, |this, cx| { match response { Ok(response) => { - this.output_token.0 += 1; - this.output.push_back(dap::OutputEvent { + let event = dap::OutputEvent { category: None, output: format!("< {}", &response.result), group: None, @@ -2097,11 +2102,11 @@ impl Session { column: None, data: None, location_reference: None, - }); + }; + this.push_output(event, cx); } Err(e) => { - this.output_token.0 += 1; - this.output.push_back(dap::OutputEvent { + let event = dap::OutputEvent { category: None, output: format!("{}", e), group: None, @@ -2111,7 +2116,8 @@ impl Session { column: None, data: None, location_reference: None, - }); + }; + this.push_output(event, cx); } }; this.invalidate_command_type::();