diff --git a/crates/debugger_ui/src/console.rs b/crates/debugger_ui/src/console.rs index 1906a33d6ca39d..456a94e51e0005 100644 --- a/crates/debugger_ui/src/console.rs +++ b/crates/debugger_ui/src/console.rs @@ -2,19 +2,31 @@ use crate::{ stack_frame_list::{StackFrameList, StackFrameListEvent}, variable_list::VariableList, }; -use dap::client::DebugAdapterClientId; -use editor::{CompletionProvider, Editor, EditorElement, EditorStyle}; +use dap::{client::DebugAdapterClientId, OutputEvent, OutputEventGroup}; +use editor::{ + display_map::{Crease, CreaseId}, + Anchor, CompletionProvider, Editor, EditorElement, EditorStyle, FoldPlaceholder, +}; use fuzzy::StringMatchCandidate; use gpui::{Model, Render, Subscription, Task, TextStyle, View, ViewContext, WeakView}; use language::{Buffer, CodeLabel, LanguageServerId, ToOffsetUtf16}; use menu::Confirm; use project::{dap_store::DapStore, Completion}; use settings::Settings; -use std::{cell::RefCell, collections::HashMap, rc::Rc}; +use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc}; use theme::ThemeSettings; -use ui::prelude::*; +use ui::{prelude::*, ButtonLike, Disclosure, ElevationIndex}; + +pub struct OutputGroup { + pub start: Anchor, + pub collapsed: bool, + pub end: Option, + pub crease_ids: Vec, + pub placeholder: SharedString, +} pub struct Console { + groups: Vec, console: View, query_bar: View, dap_store: Model, @@ -36,7 +48,13 @@ impl Console { let mut editor = Editor::multi_line(cx); editor.move_to_end(&editor::actions::MoveToEnd, cx); editor.set_read_only(true); - editor.set_show_gutter(false, cx); + editor.set_show_gutter(true, cx); + editor.set_show_runnables(false, cx); + editor.set_show_code_actions(false, cx); + editor.set_show_line_numbers(false, cx); + editor.set_show_git_diff_gutter(false, cx); + editor.set_autoindent(false); + editor.set_input_enabled(false); editor.set_use_autoclose(false); editor.set_show_wrap_guides(false, cx); editor.set_show_indent_guides(false, cx); @@ -67,6 +85,7 @@ impl Console { variable_list, _subscriptions, client_id: *client_id, + groups: Vec::default(), stack_frame_list: stack_frame_list.clone(), } } @@ -93,15 +112,109 @@ impl Console { } } - pub fn add_message(&mut self, message: &str, cx: &mut ViewContext) { + pub fn add_message(&mut self, event: OutputEvent, cx: &mut ViewContext) { self.console.update(cx, |console, cx| { + let output = event.output.trim_end().to_string(); + + let snapshot = console.buffer().read(cx).snapshot(cx); + + let start = snapshot.anchor_before(snapshot.max_point()); + + let mut indent_size = self + .groups + .iter() + .filter(|group| group.end.is_none()) + .count(); + if Some(OutputEventGroup::End) == event.group { + indent_size = indent_size.saturating_sub(1); + } + + let indent = if indent_size > 0 { + " ".repeat(indent_size) + } else { + "".to_string() + }; + console.set_read_only(false); console.move_to_end(&editor::actions::MoveToEnd, cx); - console.insert(format!("{}\n", message.trim_end()).as_str(), cx); + console.insert(format!("{}{}\n", indent, output).as_str(), cx); console.set_read_only(true); + + let end = snapshot.anchor_before(snapshot.max_point()); + + match event.group { + Some(OutputEventGroup::Start) => { + self.groups.push(OutputGroup { + start, + end: None, + collapsed: false, + placeholder: output.clone().into(), + crease_ids: console.insert_creases( + vec![Self::create_crease(output.into(), start, end)], + cx, + ), + }); + } + Some(OutputEventGroup::StartCollapsed) => { + self.groups.push(OutputGroup { + start, + end: None, + collapsed: true, + placeholder: output.clone().into(), + crease_ids: console.insert_creases( + vec![Self::create_crease(output.into(), start, end)], + cx, + ), + }); + } + Some(OutputEventGroup::End) => { + if let Some(index) = self.groups.iter().rposition(|group| group.end.is_none()) { + let group = self.groups.remove(index); + + console.remove_creases(group.crease_ids.clone(), cx); + + let creases = + vec![Self::create_crease(group.placeholder, group.start, end)]; + console.insert_creases(creases.clone(), cx); + + if group.collapsed { + console.fold_creases(creases, false, cx); + } + } + } + None => {} + } + + cx.notify(); }); } + fn create_crease(placeholder: SharedString, start: Anchor, end: Anchor) -> Crease { + Crease::inline( + start..end, + FoldPlaceholder { + render: Arc::new({ + let placeholder = placeholder.clone(); + move |_id, _range, _cx| { + ButtonLike::new("output-group-placeholder") + .style(ButtonStyle::Transparent) + .layer(ElevationIndex::ElevatedSurface) + .child(Label::new(placeholder.clone()).single_line()) + .into_any_element() + } + }), + ..Default::default() + }, + move |row, is_folded, fold, _cx| { + Disclosure::new(("output-group", row.0 as u64), !is_folded) + .toggle_state(is_folded) + .on_click(move |_event, cx| fold(!is_folded, cx)) + .into_any_element() + }, + move |_id, _range, _cx| gpui::Empty.into_any_element(), + ) + } + pub fn evaluate(&mut self, _: &Confirm, cx: &mut ViewContext) { let expression = self.query_bar.update(cx, |editor, cx| { let expression = editor.text(cx); @@ -125,7 +238,19 @@ impl Console { let response = evaluate_task.await?; this.update(&mut cx, |console, cx| { - console.add_message(&response.result, cx); + console.add_message( + OutputEvent { + category: None, + output: response.result, + group: None, + variables_reference: Some(response.variables_reference), + source: None, + line: None, + column: None, + data: None, + }, + cx, + ); console.variable_list.update(cx, |variable_list, cx| { variable_list.invalidate(cx); diff --git a/crates/debugger_ui/src/debugger_panel_item.rs b/crates/debugger_ui/src/debugger_panel_item.rs index 54dd0f84648415..437a3de8654d86 100644 --- a/crates/debugger_ui/src/debugger_panel_item.rs +++ b/crates/debugger_ui/src/debugger_panel_item.rs @@ -38,7 +38,6 @@ enum ThreadItem { Console, LoadedSource, Modules, - Output, Variables, } @@ -48,7 +47,6 @@ impl ThreadItem { ThreadItem::Console => proto::DebuggerThreadItem::Console, ThreadItem::LoadedSource => proto::DebuggerThreadItem::LoadedSource, ThreadItem::Modules => proto::DebuggerThreadItem::Modules, - ThreadItem::Output => proto::DebuggerThreadItem::Output, ThreadItem::Variables => proto::DebuggerThreadItem::Variables, } } @@ -58,7 +56,6 @@ impl ThreadItem { proto::DebuggerThreadItem::Console => ThreadItem::Console, proto::DebuggerThreadItem::LoadedSource => ThreadItem::LoadedSource, proto::DebuggerThreadItem::Modules => ThreadItem::Modules, - proto::DebuggerThreadItem::Output => ThreadItem::Output, proto::DebuggerThreadItem::Variables => ThreadItem::Variables, } } @@ -72,7 +69,6 @@ pub struct DebugPanelItem { session_name: SharedString, dap_store: Model, session_id: DebugSessionId, - output_editor: View, show_console_indicator: bool, module_list: View, active_thread_item: ThreadItem, @@ -179,20 +175,6 @@ impl DebugPanelItem { ), ]; - let output_editor = cx.new_view(|cx| { - let mut editor = Editor::multi_line(cx); - editor.set_placeholder_text("Debug adapter and script output", cx); - editor.set_read_only(true); - editor.set_show_inline_completions(Some(false), cx); - editor.set_searchable(false); - editor.set_auto_replace_emoji_shortcode(false); - editor.set_show_indent_guides(false, cx); - editor.set_autoindent(false); - editor.set_show_gutter(false, cx); - editor.set_show_line_numbers(false, cx); - editor - }); - Self { console, thread_id, @@ -202,7 +184,6 @@ impl DebugPanelItem { module_list, thread_state, focus_handle, - output_editor, variable_list, _subscriptions, remote_id: None, @@ -347,6 +328,7 @@ impl DebugPanelItem { return; } + // skip telemetry output as it pollutes the users output view let output_category = event .category .as_ref() @@ -357,25 +339,11 @@ impl DebugPanelItem { return; } - match output_category { - OutputEventCategory::Console => { - self.console.update(cx, |console, cx| { - console.add_message(&event.output, cx); - }); - - if !matches!(self.active_thread_item, ThreadItem::Console) { - self.show_console_indicator = true; - } - } - _ => { - self.output_editor.update(cx, |editor, cx| { - editor.set_read_only(false); - editor.move_to_end(&editor::actions::MoveToEnd, cx); - editor.insert(format!("{}\n", &event.output.trim_end()).as_str(), cx); - editor.set_read_only(true); - }); - } - } + self.console.update(cx, |console, cx| { + console.add_message(event.clone(), cx); + }); + self.show_console_indicator = true; + cx.notify(); } fn handle_module_event( @@ -515,11 +483,6 @@ impl DebugPanelItem { &self.stack_frame_list } - #[cfg(any(test, feature = "test-support"))] - pub fn output_editor(&self) -> &View { - &self.output_editor - } - #[cfg(any(test, feature = "test-support"))] pub fn console(&self) -> &View { &self.console @@ -1046,11 +1009,6 @@ impl Render for DebugPanelItem { &SharedString::from("Console"), ThreadItem::Console, cx, - )) - .child(self.render_entry_button( - &SharedString::from("Output"), - ThreadItem::Output, - cx, )), ) .when(*active_thread_item == ThreadItem::Variables, |this| { @@ -1062,9 +1020,6 @@ impl Render for DebugPanelItem { .when(*active_thread_item == ThreadItem::LoadedSource, |this| { this.size_full().child(self.loaded_source_list.clone()) }) - .when(*active_thread_item == ThreadItem::Output, |this| { - this.child(self.output_editor.clone()) - }) .when(*active_thread_item == ThreadItem::Console, |this| { this.child(self.console.clone()) }), diff --git a/crates/debugger_ui/src/tests/console.rs b/crates/debugger_ui/src/tests/console.rs index 0dd5a00c272f30..8e9cf6912e5a01 100644 --- a/crates/debugger_ui/src/tests/console.rs +++ b/crates/debugger_ui/src/tests/console.rs @@ -14,6 +14,446 @@ use tests::{active_debug_panel_item, init_test, init_test_workspace}; use unindent::Unindent as _; use variable_list::{VariableContainer, VariableListEntry}; +#[gpui::test] +async fn test_handle_output_event(executor: BackgroundExecutor, cx: &mut TestAppContext) { + init_test(cx); + + let fs = FakeFs::new(executor.clone()); + + let project = Project::test(fs, [], cx).await; + let workspace = init_test_workspace(&project, cx).await; + let cx = &mut VisualTestContext::from_window(*workspace, cx); + + let task = project.update(cx, |project, cx| { + project.dap_store().update(cx, |store, cx| { + store.start_debug_session( + task::DebugAdapterConfig { + label: "test config".into(), + kind: task::DebugAdapterKind::Fake, + request: task::DebugRequestType::Launch, + program: None, + cwd: None, + initialize_args: None, + }, + cx, + ) + }) + }); + + let (session, client) = task.await.unwrap(); + + client + .on_request::(move |_, _| { + Ok(dap::Capabilities { + supports_step_back: Some(false), + ..Default::default() + }) + }) + .await; + + client.on_request::(move |_, _| Ok(())).await; + + client + .on_request::(move |_, _| { + Ok(dap::StackTraceResponse { + stack_frames: Vec::default(), + total_frames: None, + }) + }) + .await; + + client.on_request::(move |_, _| Ok(())).await; + + client + .fake_event(dap::messages::Events::Output(dap::OutputEvent { + category: None, + output: "First console output line before thread stopped!".to_string(), + data: None, + variables_reference: None, + source: None, + line: None, + column: None, + group: None, + })) + .await; + + client + .fake_event(dap::messages::Events::Output(dap::OutputEvent { + category: Some(dap::OutputEventCategory::Stdout), + output: "First output line before thread stopped!".to_string(), + data: None, + variables_reference: None, + source: None, + line: None, + column: None, + group: None, + })) + .await; + + client + .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent { + reason: dap::StoppedEventReason::Pause, + description: None, + thread_id: Some(1), + preserve_focus_hint: None, + text: None, + all_threads_stopped: None, + hit_breakpoint_ids: None, + })) + .await; + + cx.run_until_parked(); + + // assert we have output from before the thread stopped + workspace + .update(cx, |workspace, cx| { + let debug_panel = workspace.panel::(cx).unwrap(); + let active_debug_panel_item = debug_panel + .update(cx, |this, cx| this.active_debug_panel_item(cx)) + .unwrap(); + + assert_eq!(1, debug_panel.read(cx).message_queue().len()); + + assert_eq!( + "First console output line before thread stopped!\nFirst output line before thread stopped!\n", + active_debug_panel_item.read(cx).console().read(cx).editor().read(cx).text(cx).as_str() + ); + }) + .unwrap(); + + client + .fake_event(dap::messages::Events::Output(dap::OutputEvent { + category: Some(dap::OutputEventCategory::Stdout), + output: "Second output line after thread stopped!".to_string(), + data: None, + variables_reference: None, + source: None, + line: None, + column: None, + group: None, + })) + .await; + + client + .fake_event(dap::messages::Events::Output(dap::OutputEvent { + category: Some(dap::OutputEventCategory::Console), + output: "Second console output line after thread stopped!".to_string(), + data: None, + variables_reference: None, + source: None, + line: None, + column: None, + group: None, + })) + .await; + + cx.run_until_parked(); + + // assert we have output from before and after the thread stopped + workspace + .update(cx, |workspace, cx| { + let debug_panel = workspace.panel::(cx).unwrap(); + let active_debug_panel_item = debug_panel + .update(cx, |this, cx| this.active_debug_panel_item(cx)) + .unwrap(); + + assert!(debug_panel.read(cx).message_queue().is_empty()); + + assert_eq!( + "First console output line before thread stopped!\nFirst output line before thread stopped!\nSecond output line after thread stopped!\nSecond console output line after thread stopped!\n", + active_debug_panel_item.read(cx).console().read(cx).editor().read(cx).text(cx).as_str() + ); + }) + .unwrap(); + + let shutdown_session = project.update(cx, |project, cx| { + project.dap_store().update(cx, |dap_store, cx| { + dap_store.shutdown_session(&session.read(cx).id(), cx) + }) + }); + + shutdown_session.await.unwrap(); +} + +#[gpui::test] +async fn test_grouped_output(executor: BackgroundExecutor, cx: &mut TestAppContext) { + init_test(cx); + + let fs = FakeFs::new(executor.clone()); + + let project = Project::test(fs, [], cx).await; + let workspace = init_test_workspace(&project, cx).await; + let cx = &mut VisualTestContext::from_window(*workspace, cx); + + let task = project.update(cx, |project, cx| { + project.dap_store().update(cx, |store, cx| { + store.start_debug_session( + task::DebugAdapterConfig { + label: "test config".into(), + kind: task::DebugAdapterKind::Fake, + request: task::DebugRequestType::Launch, + program: None, + cwd: None, + initialize_args: None, + }, + cx, + ) + }) + }); + + let (session, client) = task.await.unwrap(); + + client + .on_request::(move |_, _| { + Ok(dap::Capabilities { + supports_step_back: Some(false), + ..Default::default() + }) + }) + .await; + + client.on_request::(move |_, _| Ok(())).await; + + client + .on_request::(move |_, _| { + Ok(dap::StackTraceResponse { + stack_frames: Vec::default(), + total_frames: None, + }) + }) + .await; + + client.on_request::(move |_, _| Ok(())).await; + + client + .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent { + reason: dap::StoppedEventReason::Pause, + description: None, + thread_id: Some(1), + preserve_focus_hint: None, + text: None, + all_threads_stopped: None, + hit_breakpoint_ids: None, + })) + .await; + + client + .fake_event(dap::messages::Events::Output(dap::OutputEvent { + category: None, + output: "First line".to_string(), + data: None, + variables_reference: None, + source: None, + line: None, + column: None, + group: None, + })) + .await; + + client + .fake_event(dap::messages::Events::Output(dap::OutputEvent { + category: Some(dap::OutputEventCategory::Stdout), + output: "First group".to_string(), + data: None, + variables_reference: None, + source: None, + line: None, + column: None, + group: Some(dap::OutputEventGroup::Start), + })) + .await; + + client + .fake_event(dap::messages::Events::Output(dap::OutputEvent { + category: Some(dap::OutputEventCategory::Stdout), + output: "First item in group 1".to_string(), + data: None, + variables_reference: None, + source: None, + line: None, + column: None, + group: None, + })) + .await; + + client + .fake_event(dap::messages::Events::Output(dap::OutputEvent { + category: Some(dap::OutputEventCategory::Stdout), + output: "Second item in group 1".to_string(), + data: None, + variables_reference: None, + source: None, + line: None, + column: None, + group: None, + })) + .await; + + client + .fake_event(dap::messages::Events::Output(dap::OutputEvent { + category: Some(dap::OutputEventCategory::Stdout), + output: "Second group".to_string(), + data: None, + variables_reference: None, + source: None, + line: None, + column: None, + group: Some(dap::OutputEventGroup::Start), + })) + .await; + + client + .fake_event(dap::messages::Events::Output(dap::OutputEvent { + category: Some(dap::OutputEventCategory::Stdout), + output: "First item in group 2".to_string(), + data: None, + variables_reference: None, + source: None, + line: None, + column: None, + group: None, + })) + .await; + + client + .fake_event(dap::messages::Events::Output(dap::OutputEvent { + category: Some(dap::OutputEventCategory::Stdout), + output: "Second item in group 2".to_string(), + data: None, + variables_reference: None, + source: None, + line: None, + column: None, + group: None, + })) + .await; + + client + .fake_event(dap::messages::Events::Output(dap::OutputEvent { + category: Some(dap::OutputEventCategory::Stdout), + output: "End group 2".to_string(), + data: None, + variables_reference: None, + source: None, + line: None, + column: None, + group: Some(dap::OutputEventGroup::End), + })) + .await; + + client + .fake_event(dap::messages::Events::Output(dap::OutputEvent { + category: Some(dap::OutputEventCategory::Stdout), + output: "Third group".to_string(), + data: None, + variables_reference: None, + source: None, + line: None, + column: None, + group: Some(dap::OutputEventGroup::StartCollapsed), + })) + .await; + + client + .fake_event(dap::messages::Events::Output(dap::OutputEvent { + category: Some(dap::OutputEventCategory::Stdout), + output: "First item in group 3".to_string(), + data: None, + variables_reference: None, + source: None, + line: None, + column: None, + group: None, + })) + .await; + + client + .fake_event(dap::messages::Events::Output(dap::OutputEvent { + category: Some(dap::OutputEventCategory::Stdout), + output: "Second item in group 3".to_string(), + data: None, + variables_reference: None, + source: None, + line: None, + column: None, + group: None, + })) + .await; + + client + .fake_event(dap::messages::Events::Output(dap::OutputEvent { + category: Some(dap::OutputEventCategory::Stdout), + output: "End group 3".to_string(), + data: None, + variables_reference: None, + source: None, + line: None, + column: None, + group: Some(dap::OutputEventGroup::End), + })) + .await; + + client + .fake_event(dap::messages::Events::Output(dap::OutputEvent { + category: Some(dap::OutputEventCategory::Stdout), + output: "Third item in group 1".to_string(), + data: None, + variables_reference: None, + source: None, + line: None, + column: None, + group: None, + })) + .await; + + client + .fake_event(dap::messages::Events::Output(dap::OutputEvent { + category: Some(dap::OutputEventCategory::Stdout), + output: "Second item".to_string(), + data: None, + variables_reference: None, + source: None, + line: None, + column: None, + group: Some(dap::OutputEventGroup::End), + })) + .await; + + cx.run_until_parked(); + + active_debug_panel_item(workspace, cx).update(cx, |debug_panel_item, cx| { + debug_panel_item.console().update(cx, |console, cx| { + console.editor().update(cx, |editor, cx| { + pretty_assertions::assert_eq!( + " + First line + First group + First item in group 1 + Second item in group 1 + Second group + First item in group 2 + Second item in group 2 + End group 2 + ⋯ End group 3 + Third item in group 1 + Second item + " + .unindent(), + editor.display_text(cx) + ); + }) + }); + }); + + let shutdown_session = project.update(cx, |project, cx| { + project.dap_store().update(cx, |dap_store, cx| { + dap_store.shutdown_session(&session.read(cx).id(), cx) + }) + }); + + shutdown_session.await.unwrap(); +} + #[gpui::test] async fn test_evaluate_expression(executor: BackgroundExecutor, cx: &mut TestAppContext) { init_test(cx); diff --git a/crates/debugger_ui/src/tests/debugger_panel.rs b/crates/debugger_ui/src/tests/debugger_panel.rs index db29446e5e9348..32fa8168b8d5b6 100644 --- a/crates/debugger_ui/src/tests/debugger_panel.rs +++ b/crates/debugger_ui/src/tests/debugger_panel.rs @@ -430,162 +430,6 @@ async fn test_client_can_open_multiple_thread_panels( .unwrap(); } -#[gpui::test] -async fn test_handle_output_event(executor: BackgroundExecutor, cx: &mut TestAppContext) { - init_test(cx); - - let fs = FakeFs::new(executor.clone()); - - let project = Project::test(fs, [], cx).await; - let workspace = init_test_workspace(&project, cx).await; - let cx = &mut VisualTestContext::from_window(*workspace, cx); - - let task = project.update(cx, |project, cx| { - project.dap_store().update(cx, |store, cx| { - store.start_debug_session( - task::DebugAdapterConfig { - label: "test config".into(), - kind: task::DebugAdapterKind::Fake, - request: task::DebugRequestType::Launch, - program: None, - cwd: None, - initialize_args: None, - }, - cx, - ) - }) - }); - - let (session, client) = task.await.unwrap(); - - client - .on_request::(move |_, _| { - Ok(dap::Capabilities { - supports_step_back: Some(false), - ..Default::default() - }) - }) - .await; - - client.on_request::(move |_, _| Ok(())).await; - - client - .on_request::(move |_, _| { - Ok(dap::StackTraceResponse { - stack_frames: Vec::default(), - total_frames: None, - }) - }) - .await; - - client.on_request::(move |_, _| Ok(())).await; - - client - .fake_event(dap::messages::Events::Output(dap::OutputEvent { - category: None, - output: "First console output line before thread stopped!".to_string(), - data: None, - variables_reference: None, - source: None, - line: None, - column: None, - group: None, - })) - .await; - - client - .fake_event(dap::messages::Events::Output(dap::OutputEvent { - category: Some(dap::OutputEventCategory::Stdout), - output: "First output line before thread stopped!".to_string(), - data: None, - variables_reference: None, - source: None, - line: None, - column: None, - group: None, - })) - .await; - - client - .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent { - reason: dap::StoppedEventReason::Pause, - description: None, - thread_id: Some(1), - preserve_focus_hint: None, - text: None, - all_threads_stopped: None, - hit_breakpoint_ids: None, - })) - .await; - - client - .fake_event(dap::messages::Events::Output(dap::OutputEvent { - category: Some(dap::OutputEventCategory::Stdout), - output: "Second output line after thread stopped!".to_string(), - data: None, - variables_reference: None, - source: None, - line: None, - column: None, - group: None, - })) - .await; - - client - .fake_event(dap::messages::Events::Output(dap::OutputEvent { - category: Some(dap::OutputEventCategory::Console), - output: "Second console output line after thread stopped!".to_string(), - data: None, - variables_reference: None, - source: None, - line: None, - column: None, - group: None, - })) - .await; - - cx.run_until_parked(); - - // assert we have output from before and after the thread stopped - workspace - .update(cx, |workspace, cx| { - let debug_panel = workspace.panel::(cx).unwrap(); - let active_debug_panel_item = debug_panel - .update(cx, |this, cx| this.active_debug_panel_item(cx)) - .unwrap(); - - assert_eq!(1, debug_panel.read(cx).message_queue().len()); - - assert_eq!( - "First output line before thread stopped!\nSecond output line after thread stopped!\n", - active_debug_panel_item.read(cx).output_editor().read(cx).text(cx).as_str() - ); - - assert_eq!( - "First console output line before thread stopped!\nSecond console output line after thread stopped!\n", - active_debug_panel_item.read(cx).console().read(cx).editor().read(cx).text(cx).as_str() - ); - }) - .unwrap(); - - let shutdown_session = project.update(cx, |project, cx| { - project.dap_store().update(cx, |dap_store, cx| { - dap_store.shutdown_session(&session.read(cx).id(), cx) - }) - }); - - shutdown_session.await.unwrap(); - - // assert output queue is empty - workspace - .update(cx, |workspace, cx| { - let debug_panel = workspace.panel::(cx).unwrap(); - - assert!(debug_panel.read(cx).message_queue().is_empty()); - }) - .unwrap(); -} - #[gpui::test] async fn test_handle_successful_run_in_terminal_reverse_request( executor: BackgroundExecutor, diff --git a/crates/proto/proto/zed.proto b/crates/proto/proto/zed.proto index a0397314d36c51..3f7cca1d62caa4 100644 --- a/crates/proto/proto/zed.proto +++ b/crates/proto/proto/zed.proto @@ -2499,8 +2499,7 @@ enum DebuggerThreadItem { Console = 0; LoadedSource = 1; Modules = 2; - Output = 3; - Variables = 4; + Variables = 3; } message DebuggerSetVariableState {