From 0386c0d82dd878bffca60e9e8d8920128dbdd5d8 Mon Sep 17 00:00:00 2001 From: Remco Smits Date: Tue, 24 Sep 2024 22:29:48 +0200 Subject: [PATCH 1/8] Only include dap store if editor.mode is FULL --- crates/editor/src/editor.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index bf31bf08985e2..bf1d8c4f9c772 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -1871,7 +1871,11 @@ impl Editor { None }; - let dap_store = project.as_ref().map(|project| project.read(cx).dap_store()); + let dap_store = if mode == EditorMode::Full { + project.as_ref().map(|project| project.read(cx).dap_store()) + } else { + None + }; let mut this = Self { focus_handle, From 7565ac3b4ba78e6630507f02543dbcb9756d91fd Mon Sep 17 00:00:00 2001 From: Remco Smits Date: Tue, 24 Sep 2024 22:32:44 +0200 Subject: [PATCH 2/8] Move go to stack frame to debug_panel_item --- crates/debugger_ui/src/debugger_panel.rs | 185 ++++-------------- crates/debugger_ui/src/debugger_panel_item.rs | 122 +++++++++--- crates/editor/src/editor.rs | 1 + 3 files changed, 133 insertions(+), 175 deletions(-) diff --git a/crates/debugger_ui/src/debugger_panel.rs b/crates/debugger_ui/src/debugger_panel.rs index d9e9da2aaf4f2..0095199298689 100644 --- a/crates/debugger_ui/src/debugger_panel.rs +++ b/crates/debugger_ui/src/debugger_panel.rs @@ -9,7 +9,6 @@ use dap::{ Capabilities, ContinuedEvent, ExitedEvent, OutputEvent, Scope, StackFrame, StoppedEvent, TerminatedEvent, ThreadEvent, ThreadEventReason, Variable, }; -use editor::Editor; use futures::future::try_join_all; use gpui::{ actions, Action, AppContext, AsyncWindowContext, EventEmitter, FocusHandle, FocusableView, @@ -18,7 +17,6 @@ use gpui::{ use project::dap_store::DapStore; use settings::Settings; use std::collections::{BTreeMap, HashMap, HashSet}; -use std::path::Path; use std::sync::Arc; use std::u64; use ui::prelude::*; @@ -28,11 +26,13 @@ use workspace::{ }; use workspace::{pane, Pane, Start}; -enum DebugCurrentRowHighlight {} - pub enum DebugPanelEvent { Exited(DebugAdapterClientId), - Stopped((DebugAdapterClientId, StoppedEvent)), + Stopped { + client_id: DebugAdapterClientId, + event: StoppedEvent, + go_to_stack_frame: bool, + }, Thread((DebugAdapterClientId, ThreadEvent)), Continued((DebugAdapterClientId, ContinuedEvent)), Output((DebugAdapterClientId, OutputEvent)), @@ -213,6 +213,19 @@ impl DebugPanel { }) .ok(); } + pane::Event::ActivateItem { local } => { + if !local { + return; + } + + if let Some(active_item) = self.pane.read(cx).active_item() { + if let Some(debug_item) = active_item.downcast::() { + debug_item.update(cx, |panel, cx| { + panel.go_to_stack_frame(cx); + }); + } + } + } _ => {} } } @@ -255,129 +268,6 @@ impl DebugPanel { } } - pub async fn go_to_stack_frame( - workspace: WeakView, - stack_frame: StackFrame, - clear_highlights: bool, - mut cx: AsyncWindowContext, - ) -> Result<()> { - let Some(path) = &stack_frame.source.and_then(|s| s.path) else { - return Err(anyhow::anyhow!( - "Cannot go to stack frame, path doesn't exist" - )); - }; - - let row = (stack_frame.line.saturating_sub(1)) as u32; - let column = (stack_frame.column.saturating_sub(1)) as u32; - - if clear_highlights { - Self::remove_highlights(workspace.clone(), cx.clone())?; - } - - let task = workspace.update(&mut cx, |workspace, cx| { - let project_path = workspace.project().read_with(cx, |project, cx| { - project.project_path_for_absolute_path(&Path::new(&path), cx) - }); - - if let Some(project_path) = project_path { - workspace.open_path_preview(project_path, None, false, true, cx) - } else { - Task::ready(Err(anyhow::anyhow!( - "No project path found for path: {}", - path - ))) - } - })?; - - let editor = task.await?.downcast::().unwrap(); - - workspace.update(&mut cx, |_, cx| { - editor.update(cx, |editor, cx| { - editor.go_to_line::( - row, - column, - Some(cx.theme().colors().editor_debugger_active_line_background), - cx, - ); - }) - }) - } - - fn remove_highlights(workspace: WeakView, mut cx: AsyncWindowContext) -> Result<()> { - workspace.update(&mut cx, |workspace, cx| { - let editor_views = workspace - .items_of_type::(cx) - .collect::>>(); - - for editor_view in editor_views { - editor_view.update(cx, |editor, _| { - editor.clear_row_highlights::(); - }); - } - }) - } - - // async fn remove_highlights_for_thread( - // workspace: WeakView, - // client: Arc, - // thread_id: u64, - // cx: AsyncWindowContext, - // ) -> Result<()> { - // let mut tasks = Vec::new(); - // let mut paths: HashSet = HashSet::new(); - // let thread_state = client.thread_state_by_id(thread_id); - - // for stack_frame in thread_state.stack_frames.into_iter() { - // let Some(path) = stack_frame.source.clone().and_then(|s| s.path.clone()) else { - // continue; - // }; - - // if paths.contains(&path) { - // continue; - // } - - // paths.insert(path.clone()); - // tasks.push(Self::remove_editor_highlight( - // workspace.clone(), - // path, - // cx.clone(), - // )); - // } - - // if !tasks.is_empty() { - // try_join_all(tasks).await?; - // } - - // anyhow::Ok(()) - // } - - // async fn remove_editor_highlight( - // workspace: WeakView, - // path: String, - // mut cx: AsyncWindowContext, - // ) -> Result<()> { - // let task = workspace.update(&mut cx, |workspace, cx| { - // let project_path = workspace.project().read_with(cx, |project, cx| { - // project.project_path_for_absolute_path(&Path::new(&path), cx) - // }); - - // if let Some(project_path) = project_path { - // workspace.open_path(project_path, None, false, cx) - // } else { - // Task::ready(Err(anyhow::anyhow!( - // "No project path found for path: {}", - // path - // ))) - // } - // })?; - - // let editor = task.await?.downcast::().unwrap(); - - // editor.update(&mut cx, |editor, _| { - // editor.clear_row_highlights::(); - // }) - // } - fn handle_initialized_event( &mut self, client_id: &DebugAdapterClientId, @@ -561,31 +451,24 @@ impl DebugPanel { }); } - cx.emit(DebugPanelEvent::Stopped((client_id, event))); - - cx.notify(); - - if let Some(item) = this.pane.read(cx).active_item() { - if let Some(pane) = item.downcast::() { + let go_to_stack_frame = if let Some(item) = this.pane.read(cx).active_item() { + item.downcast::().map_or(false, |pane| { let pane = pane.read(cx); - if pane.thread_id() == thread_id && pane.client_id() == client_id { - let workspace = this.workspace.clone(); - return cx.spawn(|_, cx| async move { - Self::go_to_stack_frame( - workspace, - current_stack_frame.clone(), - true, - cx, - ) - .await - }); - } - } - } - Task::ready(anyhow::Ok(())) - })? - .await + pane.thread_id() == thread_id && pane.client_id() == client_id + }) + } else { + true + }; + + cx.emit(DebugPanelEvent::Stopped { + client_id, + event, + go_to_stack_frame, + }); + + cx.notify(); + }) } }) .detach_and_log_err(cx); diff --git a/crates/debugger_ui/src/debugger_panel_item.rs b/crates/debugger_ui/src/debugger_panel_item.rs index 68a104c42a3d3..66c092f60e815 100644 --- a/crates/debugger_ui/src/debugger_panel_item.rs +++ b/crates/debugger_ui/src/debugger_panel_item.rs @@ -1,3 +1,6 @@ +use std::any::Any; +use std::path::Path; + use crate::console::Console; use crate::debugger_panel::{DebugPanel, DebugPanelEvent, ThreadState}; use crate::variable_list::VariableList; @@ -10,8 +13,8 @@ use dap::{ }; use editor::Editor; use gpui::{ - list, AnyElement, AppContext, EventEmitter, FocusHandle, FocusableView, ListState, Model, - Subscription, View, WeakView, + list, AnyElement, AppContext, Entity, EventEmitter, FocusHandle, FocusableView, ListState, + Model, Subscription, Task, View, WeakView, }; use project::dap_store::DapStore; use settings::Settings; @@ -93,9 +96,11 @@ impl DebugPanelItem { let _subscriptions = vec![cx.subscribe(&debug_panel, { move |this: &mut Self, _, event: &DebugPanelEvent, cx| { match event { - DebugPanelEvent::Stopped((client_id, event)) => { - this.handle_stopped_event(client_id, event, cx) - } + DebugPanelEvent::Stopped { + client_id, + event, + go_to_stack_frame, + } => this.handle_stopped_event(client_id, event, *go_to_stack_frame, cx), DebugPanelEvent::Thread((client_id, event)) => { this.handle_thread_event(client_id, event, cx) } @@ -178,6 +183,7 @@ impl DebugPanelItem { &mut self, client_id: &DebugAdapterClientId, event: &StoppedEvent, + go_to_stack_frame: bool, cx: &mut ViewContext, ) { if self.should_skip_event(client_id, event.thread_id.unwrap_or(self.thread_id)) { @@ -188,7 +194,7 @@ impl DebugPanelItem { self.stack_frame_list.reset(thread_state.stack_frames.len()); if let Some(stack_frame) = thread_state.stack_frames.first() { - self.update_stack_frame_id(stack_frame.id, cx); + self.update_stack_frame_id(stack_frame.id, go_to_stack_frame, cx); }; cx.notify(); @@ -268,6 +274,8 @@ impl DebugPanelItem { self.update_thread_state_status(ThreadStatus::Stopped, cx); + self.remove_highlights(cx); + cx.emit(Event::Close); } @@ -299,15 +307,15 @@ impl DebugPanelItem { } fn stack_frame_for_index(&self, ix: usize, cx: &mut ViewContext) -> StackFrame { - self.thread_state - .read(cx) - .stack_frames - .get(ix) - .cloned() - .unwrap() + self.thread_state.read(cx).stack_frames[ix].clone() } - fn update_stack_frame_id(&mut self, stack_frame_id: u64, cx: &mut ViewContext) { + fn update_stack_frame_id( + &mut self, + stack_frame_id: u64, + go_to_stack_frame: bool, + cx: &mut ViewContext, + ) { self.current_stack_frame_id = stack_frame_id; self.variable_list.update(cx, |variable_list, cx| { @@ -315,9 +323,85 @@ impl DebugPanelItem { variable_list.build_entries(true, false, cx); }); + if go_to_stack_frame { + self.go_to_stack_frame(cx); + } + cx.notify(); } + fn remove_highlights(&self, cx: &mut ViewContext) { + self.workspace + .update(cx, |workspace, cx| { + let editor_views = workspace + .items_of_type::(cx) + .collect::>>(); + + for editor_view in editor_views { + editor_view.update(cx, |editor, _| { + editor.clear_row_highlights::(); + }); + } + }) + .ok(); + } + + pub fn go_to_stack_frame(&mut self, cx: &mut ViewContext) { + self.remove_highlights(cx); + + let Some(stack_frame) = self + .thread_state + .read(cx) + .stack_frames + .iter() + .find(|s| s.id == self.current_stack_frame_id) + else { + return; + }; + + let Some(path) = stack_frame.source.as_ref().and_then(|s| s.path.as_ref()) else { + return; + }; + + let row = (stack_frame.line.saturating_sub(1)) as u32; + let column = (stack_frame.column.saturating_sub(1)) as u32; + + cx.spawn({ + let workspace = self.workspace.clone(); + let path = path.clone(); + |this, mut cx| async move { + let task = workspace.update(&mut cx, |workspace, cx| { + let project_path = workspace.project().read_with(cx, |project, cx| { + project.project_path_for_absolute_path(&Path::new(&path), cx) + }); + + if let Some(project_path) = project_path { + workspace.open_path_preview(project_path, None, false, true, cx) + } else { + Task::ready(Err(anyhow::anyhow!( + "No project path found for path: {}", + path + ))) + } + })?; + + let editor = task.await?.downcast::().unwrap(); + + workspace.update(&mut cx, |_, cx| { + editor.update(cx, |editor, cx| { + editor.go_to_line::( + row, + column, + Some(cx.theme().colors().editor_debugger_active_line_background), + cx, + ); + }) + }) + } + }) + .detach_and_log_err(cx); + } + fn render_stack_frames(&self, _cx: &mut ViewContext) -> impl IntoElement { v_flex() .size_full() @@ -352,18 +436,8 @@ impl DebugPanelItem { }) .on_click(cx.listener({ let stack_frame_id = stack_frame.id; - let stack_frame = stack_frame.clone(); move |this, _, cx| { - this.update_stack_frame_id(stack_frame_id, cx); - - let workspace = this.workspace.clone(); - let stack_frame = stack_frame.clone(); - cx.spawn(|_, cx| async move { - DebugPanel::go_to_stack_frame(workspace, stack_frame, true, cx).await - }) - .detach_and_log_err(cx); - - cx.notify(); + this.update_stack_frame_id(stack_frame_id, true, cx); } })) .hover(|s| s.bg(cx.theme().colors().element_hover).cursor_pointer()) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index bf1d8c4f9c772..792ef3bfa1111 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -264,6 +264,7 @@ impl InlayId { } } +pub enum DebugCurrentRowHighlight {} enum DiffRowHighlight {} enum DocumentHighlightRead {} enum DocumentHighlightWrite {} From fb15b67cdf1cfa8cefbc3890483b74e51f5030a7 Mon Sep 17 00:00:00 2001 From: Remco Smits Date: Tue, 24 Sep 2024 22:38:26 +0200 Subject: [PATCH 3/8] Notify dap_store when updating active breakpoints location --- crates/project/src/buffer_store.rs | 4 ++-- crates/project/src/dap_store.rs | 13 +++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/crates/project/src/buffer_store.rs b/crates/project/src/buffer_store.rs index 9bf5db93efae8..5fe503051beaa 100644 --- a/crates/project/src/buffer_store.rs +++ b/crates/project/src/buffer_store.rs @@ -121,7 +121,7 @@ impl BufferStore { let buffer = self.get_by_path(&project_path, cx); if let Some(existing_buffer) = buffer { self.dap_store.update(cx, |store, cx| { - store.set_active_breakpoints(&project_path, &existing_buffer.read(cx)); + store.on_open_buffer(&project_path, &existing_buffer, cx); }); return Task::ready(Ok(existing_buffer)); } @@ -162,7 +162,7 @@ impl BufferStore { let buffer = load_result.map_err(Arc::new)?; this.dap_store.update(cx, |store, cx| { - store.set_active_breakpoints(&project_path, buffer.read(cx)); + store.on_open_buffer(&project_path, &buffer, cx); }); Ok(buffer) diff --git a/crates/project/src/dap_store.rs b/crates/project/src/dap_store.rs index 9f5a70acf0634..a9ed4f3f39a58 100644 --- a/crates/project/src/dap_store.rs +++ b/crates/project/src/dap_store.rs @@ -17,7 +17,7 @@ use dap::{ SteppingGranularity, TerminateArguments, TerminateThreadsArguments, Variable, VariablesArguments, }; -use gpui::{EventEmitter, ModelContext, Task}; +use gpui::{EventEmitter, Model, ModelContext, Task}; use language::{Buffer, BufferSnapshot}; use serde_json::Value; use settings::WorktreeId; @@ -112,16 +112,25 @@ impl DapStore { &self.breakpoints } - pub fn set_active_breakpoints(&mut self, project_path: &ProjectPath, buffer: &Buffer) { + pub fn on_open_buffer( + &mut self, + project_path: &ProjectPath, + buffer: &Model, + cx: &mut ModelContext, + ) { let entry = self.breakpoints.remove(project_path).unwrap_or_default(); let mut set_bp: HashSet = HashSet::default(); + let buffer = buffer.read(cx); + for mut bp in entry.into_iter() { bp.set_active_position(&buffer); set_bp.insert(bp); } self.breakpoints.insert(project_path.clone(), set_bp); + + cx.notify(); } pub fn deserialize_breakpoints( From 3836a8466b95b5e444ff5275ef93ff8f29100d8c Mon Sep 17 00:00:00 2001 From: Remco Smits Date: Tue, 24 Sep 2024 22:43:33 +0200 Subject: [PATCH 4/8] Fix clippyyyy --- crates/debugger_ui/src/debugger_panel_item.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/crates/debugger_ui/src/debugger_panel_item.rs b/crates/debugger_ui/src/debugger_panel_item.rs index 66c092f60e815..eb75ef263efc0 100644 --- a/crates/debugger_ui/src/debugger_panel_item.rs +++ b/crates/debugger_ui/src/debugger_panel_item.rs @@ -1,4 +1,3 @@ -use std::any::Any; use std::path::Path; use crate::console::Console; @@ -13,8 +12,8 @@ use dap::{ }; use editor::Editor; use gpui::{ - list, AnyElement, AppContext, Entity, EventEmitter, FocusHandle, FocusableView, ListState, - Model, Subscription, Task, View, WeakView, + list, AnyElement, AppContext, EventEmitter, FocusHandle, FocusableView, ListState, Model, + Subscription, Task, View, WeakView, }; use project::dap_store::DapStore; use settings::Settings; @@ -369,7 +368,7 @@ impl DebugPanelItem { cx.spawn({ let workspace = self.workspace.clone(); let path = path.clone(); - |this, mut cx| async move { + |_, mut cx| async move { let task = workspace.update(&mut cx, |workspace, cx| { let project_path = workspace.project().read_with(cx, |project, cx| { project.project_path_for_absolute_path(&Path::new(&path), cx) From b1def274509a37f92ef74b32bbad4263e437a149 Mon Sep 17 00:00:00 2001 From: Remco Smits Date: Wed, 25 Sep 2024 15:04:23 +0200 Subject: [PATCH 5/8] Show active debug line when you reopen a buffer --- crates/debugger_ui/src/debugger_panel_item.rs | 64 ++++++++++--------- crates/editor/src/editor.rs | 27 ++++++++ crates/project/src/dap_store.rs | 30 ++++++++- 3 files changed, 91 insertions(+), 30 deletions(-) diff --git a/crates/debugger_ui/src/debugger_panel_item.rs b/crates/debugger_ui/src/debugger_panel_item.rs index eb75ef263efc0..687fbeb7e16e2 100644 --- a/crates/debugger_ui/src/debugger_panel_item.rs +++ b/crates/debugger_ui/src/debugger_panel_item.rs @@ -13,9 +13,10 @@ use dap::{ use editor::Editor; use gpui::{ list, AnyElement, AppContext, EventEmitter, FocusHandle, FocusableView, ListState, Model, - Subscription, Task, View, WeakView, + Subscription, View, WeakView, }; use project::dap_store::DapStore; +use project::ProjectPath; use settings::Settings; use task::DebugAdapterKind; use ui::WindowContext; @@ -345,56 +346,61 @@ impl DebugPanelItem { .ok(); } + pub fn project_path_from_stack_frame( + &self, + stack_frame: &StackFrame, + cx: &mut ViewContext, + ) -> Option { + let Some(path) = stack_frame.source.as_ref().and_then(|s| s.path.as_ref()) else { + return None; + }; + + self.workspace + .update(cx, |workspace, cx| { + workspace.project().read_with(cx, |project, cx| { + project.project_path_for_absolute_path(&Path::new(path), cx) + }) + }) + .ok()? + } + pub fn go_to_stack_frame(&mut self, cx: &mut ViewContext) { self.remove_highlights(cx); - let Some(stack_frame) = self + let stack_frame = self .thread_state .read(cx) .stack_frames .iter() .find(|s| s.id == self.current_stack_frame_id) - else { - return; - }; + .cloned(); - let Some(path) = stack_frame.source.as_ref().and_then(|s| s.path.as_ref()) else { - return; + let Some(stack_frame) = stack_frame else { + return; // this could never happen }; let row = (stack_frame.line.saturating_sub(1)) as u32; let column = (stack_frame.column.saturating_sub(1)) as u32; + let Some(project_path) = self.project_path_from_stack_frame(&stack_frame, cx) else { + return; + }; + + self.dap_store.update(cx, |store, cx| { + store.set_active_debug_line(&project_path, row, column, cx); + }); + cx.spawn({ let workspace = self.workspace.clone(); - let path = path.clone(); - |_, mut cx| async move { + move |_, mut cx| async move { let task = workspace.update(&mut cx, |workspace, cx| { - let project_path = workspace.project().read_with(cx, |project, cx| { - project.project_path_for_absolute_path(&Path::new(&path), cx) - }); - - if let Some(project_path) = project_path { - workspace.open_path_preview(project_path, None, false, true, cx) - } else { - Task::ready(Err(anyhow::anyhow!( - "No project path found for path: {}", - path - ))) - } + workspace.open_path_preview(project_path, None, false, true, cx) })?; let editor = task.await?.downcast::().unwrap(); workspace.update(&mut cx, |_, cx| { - editor.update(cx, |editor, cx| { - editor.go_to_line::( - row, - column, - Some(cx.theme().colors().editor_debugger_active_line_background), - cx, - ); - }) + editor.update(cx, |editor, cx| editor.go_to_active_debug_line(cx)) }) } }) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 792ef3bfa1111..029c9196ceac7 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -2024,6 +2024,8 @@ impl Editor { this.git_blame_inline_enabled = true; this.start_git_blame_inline(false, cx); } + + this.go_to_active_debug_line(cx); } this.report_editor_event("open", None, cx); @@ -11310,6 +11312,31 @@ impl Editor { } } + pub fn go_to_active_debug_line(&mut self, cx: &mut ViewContext) { + let Some(dap_store) = self.dap_store.as_ref() else { + return; + }; + + let Some(buffer) = self.buffer.read(cx).as_singleton() else { + return; + }; + + let Some(project_path) = buffer.read_with(cx, |buffer, cx| buffer.project_path(cx)) else { + return; + }; + + if let Some((path, position)) = dap_store.read(cx).active_debug_line() { + if path == project_path { + self.go_to_line::( + position.row, + position.column, + Some(cx.theme().colors().editor_debugger_active_line_background), + cx, + ); + } + } + } + pub fn toggle_git_blame(&mut self, _: &ToggleGitBlame, cx: &mut ViewContext) { self.show_git_blame_gutter = !self.show_git_blame_gutter; diff --git a/crates/project/src/dap_store.rs b/crates/project/src/dap_store.rs index a9ed4f3f39a58..6efad12331241 100644 --- a/crates/project/src/dap_store.rs +++ b/crates/project/src/dap_store.rs @@ -49,11 +49,18 @@ pub enum DebugAdapterClientState { Running(Arc), } +#[derive(Clone, Debug)] +pub struct DebugPosition { + pub row: u32, + pub column: u32, +} + pub struct DapStore { next_client_id: AtomicUsize, clients: HashMap, breakpoints: BTreeMap>, capabilities: HashMap, + active_debug_line: Option<(ProjectPath, DebugPosition)>, } impl EventEmitter for DapStore {} @@ -63,9 +70,10 @@ impl DapStore { cx.on_app_quit(Self::shutdown_clients).detach(); Self { + active_debug_line: None, clients: Default::default(), - capabilities: HashMap::default(), breakpoints: Default::default(), + capabilities: HashMap::default(), next_client_id: Default::default(), } } @@ -108,6 +116,26 @@ impl DapStore { } } + pub fn active_debug_line(&self) -> Option<(ProjectPath, DebugPosition)> { + self.active_debug_line.clone() + } + + pub fn set_active_debug_line( + &mut self, + project_path: &ProjectPath, + row: u32, + column: u32, + cx: &mut ModelContext, + ) { + self.active_debug_line = Some((project_path.clone(), DebugPosition { row, column })); + + cx.notify(); + } + + pub fn remove_active_debug_line(&mut self) { + self.active_debug_line.take(); + } + pub fn breakpoints(&self) -> &BTreeMap> { &self.breakpoints } From 7ab561efb6497b0e674facc817b0449115dc2e89 Mon Sep 17 00:00:00 2001 From: Remco Smits Date: Wed, 25 Sep 2024 16:19:00 +0200 Subject: [PATCH 6/8] Remove uncommented code This is not needed anymore, we already clear the highlights when thread exited --- crates/debugger_ui/src/debugger_panel.rs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/crates/debugger_ui/src/debugger_panel.rs b/crates/debugger_ui/src/debugger_panel.rs index 0095199298689..f909d3d9f1013 100644 --- a/crates/debugger_ui/src/debugger_panel.rs +++ b/crates/debugger_ui/src/debugger_panel.rs @@ -494,19 +494,6 @@ impl DebugPanel { (*client_id, thread_id), cx.new_model(|_| ThreadState::default()), ); - } else { - // TODO debugger: we want to figure out for witch clients/threads we should remove the highlights - // cx.spawn({ - // let client = client.clone(); - // |this, mut cx| async move { - // let workspace = this.update(&mut cx, |this, _| this.workspace.clone())?; - - // Self::remove_highlights_for_thread(workspace, client, thread_id, cx).await?; - - // anyhow::Ok(()) - // } - // }) - // .detach_and_log_err(cx); } cx.emit(DebugPanelEvent::Thread((*client_id, event.clone()))); From b0f92c15a2e33eebbb4cf970a371887e013a2d2a Mon Sep 17 00:00:00 2001 From: Remco Smits Date: Wed, 25 Sep 2024 17:39:49 +0200 Subject: [PATCH 7/8] Make clippy happy --- crates/debugger_ui/src/debugger_panel_item.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/debugger_ui/src/debugger_panel_item.rs b/crates/debugger_ui/src/debugger_panel_item.rs index 687fbeb7e16e2..9cee6d99c0e10 100644 --- a/crates/debugger_ui/src/debugger_panel_item.rs +++ b/crates/debugger_ui/src/debugger_panel_item.rs @@ -351,9 +351,7 @@ impl DebugPanelItem { stack_frame: &StackFrame, cx: &mut ViewContext, ) -> Option { - let Some(path) = stack_frame.source.as_ref().and_then(|s| s.path.as_ref()) else { - return None; - }; + let path = stack_frame.source.as_ref().and_then(|s| s.path.as_ref())?; self.workspace .update(cx, |workspace, cx| { From e8e1ddad15dde8c2d825fb3973721cc1539c3a9a Mon Sep 17 00:00:00 2001 From: Remco Smits Date: Wed, 25 Sep 2024 17:48:44 +0200 Subject: [PATCH 8/8] Fix todo for removing highlights on exited event --- crates/debugger_ui/src/debugger_panel.rs | 5 +++-- crates/debugger_ui/src/debugger_panel_item.rs | 19 ++++++++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/crates/debugger_ui/src/debugger_panel.rs b/crates/debugger_ui/src/debugger_panel.rs index f909d3d9f1013..63950610863c8 100644 --- a/crates/debugger_ui/src/debugger_panel.rs +++ b/crates/debugger_ui/src/debugger_panel.rs @@ -28,6 +28,7 @@ use workspace::{pane, Pane, Start}; pub enum DebugPanelEvent { Exited(DebugAdapterClientId), + Terminated(DebugAdapterClientId), Stopped { client_id: DebugAdapterClientId, event: StoppedEvent, @@ -516,8 +517,6 @@ impl DebugPanel { ) { let restart_args = event.clone().and_then(|e| e.restart); - // TODO debugger: remove current highlights - self.dap_store.update(cx, |store, cx| { if restart_args.is_some() { store @@ -527,6 +526,8 @@ impl DebugPanel { store.shutdown_client(&client_id, cx).detach_and_log_err(cx); } }); + + cx.emit(DebugPanelEvent::Terminated(*client_id)); } fn handle_output_event( diff --git a/crates/debugger_ui/src/debugger_panel_item.rs b/crates/debugger_ui/src/debugger_panel_item.rs index 9cee6d99c0e10..8337511f07052 100644 --- a/crates/debugger_ui/src/debugger_panel_item.rs +++ b/crates/debugger_ui/src/debugger_panel_item.rs @@ -113,8 +113,8 @@ impl DebugPanelItem { DebugPanelEvent::Continued((client_id, event)) => { this.handle_thread_continued_event(client_id, event, cx); } - DebugPanelEvent::Exited(client_id) => { - this.handle_client_exited_event(client_id, cx); + DebugPanelEvent::Exited(client_id) | DebugPanelEvent::Terminated(client_id) => { + this.handle_client_exited_and_terminated_event(client_id, cx); } }; } @@ -159,6 +159,13 @@ impl DebugPanelItem { cx.notify(); }); + if status == ThreadStatus::Exited + || status == ThreadStatus::Ended + || status == ThreadStatus::Stopped + { + self.clear_highlights(cx); + } + cx.notify(); } @@ -274,12 +281,10 @@ impl DebugPanelItem { self.update_thread_state_status(ThreadStatus::Stopped, cx); - self.remove_highlights(cx); - cx.emit(Event::Close); } - fn handle_client_exited_event( + fn handle_client_exited_and_terminated_event( &mut self, client_id: &DebugAdapterClientId, cx: &mut ViewContext, @@ -330,7 +335,7 @@ impl DebugPanelItem { cx.notify(); } - fn remove_highlights(&self, cx: &mut ViewContext) { + fn clear_highlights(&self, cx: &mut ViewContext) { self.workspace .update(cx, |workspace, cx| { let editor_views = workspace @@ -363,7 +368,7 @@ impl DebugPanelItem { } pub fn go_to_stack_frame(&mut self, cx: &mut ViewContext) { - self.remove_highlights(cx); + self.clear_highlights(cx); let stack_frame = self .thread_state