diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 08829ee53a..0296378624 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -8854,15 +8854,6 @@ impl Editor { }); } - fn breakpoint_at_cursor_head( - &self, - window: &mut Window, - cx: &mut Context, - ) -> Option<(Anchor, Breakpoint)> { - let cursor_position: Point = self.selections.newest(cx).head(); - self.breakpoint_at_row(cursor_position.row, window, cx) - } - pub(crate) fn breakpoint_at_row( &self, row: u32, @@ -8872,6 +8863,15 @@ impl Editor { let snapshot = self.snapshot(window, cx); let breakpoint_position = snapshot.buffer_snapshot.anchor_before(Point::new(row, 0)); + self.breakpoint_at_anchor(breakpoint_position, &snapshot, cx) + } + + pub(crate) fn breakpoint_at_anchor( + &self, + breakpoint_position: Anchor, + snapshot: &EditorSnapshot, + cx: &mut Context, + ) -> Option<(Anchor, Breakpoint)> { let project = self.project.clone()?; let buffer_id = breakpoint_position.buffer_id.or_else(|| { @@ -8929,29 +8929,51 @@ impl Editor { window: &mut Window, cx: &mut Context, ) { - let (anchor, bp) = self - .breakpoint_at_cursor_head(window, cx) - .unwrap_or_else(|| { - let cursor_position: Point = self.selections.newest(cx).head(); + for (anchor, breakpoint) in self.breakpoints_at_cursors(window, cx) { + let breakpoint = breakpoint.unwrap_or_else(|| Breakpoint { + message: None, + state: BreakpointState::Enabled, + condition: None, + hit_condition: None, + }); - let breakpoint_position = self - .snapshot(window, cx) + self.add_edit_breakpoint_block( + anchor, + &breakpoint, + BreakpointPromptEditAction::Log, + window, + cx, + ); + } + } + + fn breakpoints_at_cursors( + &self, + window: &mut Window, + cx: &mut Context, + ) -> Vec<(Anchor, Option)> { + let snapshot = self.snapshot(window, cx); + let cursors = self + .selections + .disjoint_anchors() + .into_iter() + .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 = self + .breakpoint_at_anchor(breakpoint_position, &snapshot, cx) + .map(|(anchor, breakpoint)| (anchor, Some(breakpoint))); - ( - breakpoint_position, - Breakpoint { - message: None, - state: BreakpointState::Enabled, - condition: None, - hit_condition: None, - }, - ) - }); + breakpoint.unwrap_or_else(|| (breakpoint_position, None)) + }) + // There might be multiple cursors on the same line; all of them should have the same anchors though as their breakpoints positions, which makes it possible to sort and dedup the list. + .collect::>(); - self.add_edit_breakpoint_block(anchor, &bp, BreakpointPromptEditAction::Log, window, cx); + cursors.into_iter().collect() } pub fn enable_breakpoint( @@ -8960,15 +8982,16 @@ impl Editor { window: &mut Window, cx: &mut Context, ) { - if let Some((anchor, breakpoint)) = self.breakpoint_at_cursor_head(window, cx) { - if breakpoint.is_disabled() { - self.edit_breakpoint_at_anchor( - anchor, - breakpoint, - BreakpointEditAction::InvertState, - cx, - ); - } + for (anchor, breakpoint) in self.breakpoints_at_cursors(window, cx) { + let Some(breakpoint) = breakpoint.filter(|breakpoint| breakpoint.is_disabled()) else { + continue; + }; + self.edit_breakpoint_at_anchor( + anchor, + breakpoint, + BreakpointEditAction::InvertState, + cx, + ); } } @@ -8978,15 +9001,16 @@ impl Editor { window: &mut Window, cx: &mut Context, ) { - if let Some((anchor, breakpoint)) = self.breakpoint_at_cursor_head(window, cx) { - if breakpoint.is_enabled() { - self.edit_breakpoint_at_anchor( - anchor, - breakpoint, - BreakpointEditAction::InvertState, - cx, - ); - } + for (anchor, breakpoint) in self.breakpoints_at_cursors(window, cx) { + let Some(breakpoint) = breakpoint.filter(|breakpoint| breakpoint.is_enabled()) else { + continue; + }; + self.edit_breakpoint_at_anchor( + anchor, + breakpoint, + BreakpointEditAction::InvertState, + cx, + ); } } @@ -8996,25 +9020,22 @@ impl Editor { window: &mut Window, cx: &mut Context, ) { - let edit_action = BreakpointEditAction::Toggle; - - if let Some((anchor, breakpoint)) = self.breakpoint_at_cursor_head(window, cx) { - self.edit_breakpoint_at_anchor(anchor, breakpoint, edit_action, cx); - } else { - let cursor_position: Point = self.selections.newest(cx).head(); - - let breakpoint_position = self - .snapshot(window, cx) - .display_snapshot - .buffer_snapshot - .anchor_after(Point::new(cursor_position.row, 0)); - - self.edit_breakpoint_at_anchor( - breakpoint_position, - Breakpoint::new_standard(), - edit_action, - cx, - ); + for (anchor, breakpoint) in self.breakpoints_at_cursors(window, cx) { + if let Some(breakpoint) = breakpoint { + self.edit_breakpoint_at_anchor( + anchor, + breakpoint, + BreakpointEditAction::Toggle, + cx, + ); + } else { + self.edit_breakpoint_at_anchor( + anchor, + Breakpoint::new_standard(), + BreakpointEditAction::Toggle, + cx, + ); + } } } diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 7c433c232b..b7354bdb9e 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -17999,7 +17999,15 @@ fn add_log_breakpoint_at_cursor( cx: &mut Context, ) { let (anchor, bp) = editor - .breakpoint_at_cursor_head(window, cx) + .breakpoints_at_cursors(window, cx) + .first() + .and_then(|(anchor, bp)| { + if let Some(bp) = bp { + Some((*anchor, bp.clone())) + } else { + None + } + }) .unwrap_or_else(|| { let cursor_position: Point = editor.selections.newest(cx).head();