From d4736a54275ac67d13b28aa365b1a1208e7a435c Mon Sep 17 00:00:00 2001 From: Anthony Eid <56899983+Anthony-Eid@users.noreply.github.com> Date: Fri, 11 Apr 2025 04:04:12 -0400 Subject: [PATCH] debugger: Fix bug where deleting a breakpoint could delete multiple breakpoints (#28562) This PR fixes a bug when deleting a breakpoint with a (log, conditional, hit condition) message by removing the message. All breakpoints that contain that type of message were also deleted. Release Notes: - N/A --- crates/editor/src/editor.rs | 14 +++++-- .../project/src/debugger/breakpoint_store.rs | 40 ++++++++++++++----- 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 2e312351f1..8bbf9ec774 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -8960,10 +8960,16 @@ impl Editor { .map(|selection| { let cursor_position: Point = selection.head().to_point(&snapshot.buffer_snapshot); - let breakpoint_position = snapshot - .display_snapshot - .buffer_snapshot - .anchor_after(Point::new(cursor_position.row, 0)); + let breakpoint_position = self + .breakpoint_at_row(cursor_position.row, window, cx) + .map(|bp| bp.0) + .unwrap_or_else(|| { + snapshot + .display_snapshot + .buffer_snapshot + .anchor_after(Point::new(cursor_position.row, 0)) + }); + let breakpoint = self .breakpoint_at_anchor(breakpoint_position, &snapshot, cx) .map(|(anchor, breakpoint)| (anchor, Some(breakpoint))); diff --git a/crates/project/src/debugger/breakpoint_store.rs b/crates/project/src/debugger/breakpoint_store.rs index 31ef65dab3..33cc3d30a2 100644 --- a/crates/project/src/debugger/breakpoint_store.rs +++ b/crates/project/src/debugger/breakpoint_store.rs @@ -6,6 +6,7 @@ use breakpoints_in_file::BreakpointsInFile; use collections::BTreeMap; use dap::client::SessionId; use gpui::{App, AppContext, AsyncApp, Context, Entity, EventEmitter, Subscription, Task}; +use itertools::Itertools; use language::{Buffer, BufferSnapshot, proto::serialize_anchor as serialize_text_anchor}; use rpc::{ AnyProtoClient, TypedEnvelope, @@ -289,9 +290,16 @@ impl BreakpointStore { breakpoint_set.breakpoints.push(breakpoint.clone()); } } else if breakpoint.1.message.is_some() { - breakpoint_set.breakpoints.retain(|(other_pos, other)| { - &breakpoint.0 != other_pos && other.message.is_none() - }) + if let Some(position) = breakpoint_set + .breakpoints + .iter() + .find_position(|(pos, bp)| &breakpoint.0 == pos && bp == &breakpoint.1) + .map(|res| res.0) + { + breakpoint_set.breakpoints.remove(position); + } else { + log::error!("Failed to find position of breakpoint to delete") + } } } BreakpointEditAction::EditHitCondition(hit_condition) => { @@ -316,9 +324,16 @@ impl BreakpointStore { breakpoint_set.breakpoints.push(breakpoint.clone()); } } else if breakpoint.1.hit_condition.is_some() { - breakpoint_set.breakpoints.retain(|(other_pos, other)| { - &breakpoint.0 != other_pos && other.hit_condition.is_none() - }) + if let Some(position) = breakpoint_set + .breakpoints + .iter() + .find_position(|(pos, bp)| &breakpoint.0 == pos && bp == &breakpoint.1) + .map(|res| res.0) + { + breakpoint_set.breakpoints.remove(position); + } else { + log::error!("Failed to find position of breakpoint to delete") + } } } BreakpointEditAction::EditCondition(condition) => { @@ -343,9 +358,16 @@ impl BreakpointStore { breakpoint_set.breakpoints.push(breakpoint.clone()); } } else if breakpoint.1.condition.is_some() { - breakpoint_set.breakpoints.retain(|(other_pos, other)| { - &breakpoint.0 != other_pos && other.condition.is_none() - }) + if let Some(position) = breakpoint_set + .breakpoints + .iter() + .find_position(|(pos, bp)| &breakpoint.0 == pos && bp == &breakpoint.1) + .map(|res| res.0) + { + breakpoint_set.breakpoints.remove(position); + } else { + log::error!("Failed to find position of breakpoint to delete") + } } } }