From f565994da9787474c94f4254b361d1d97edfbbd3 Mon Sep 17 00:00:00 2001 From: Anthony Eid <56899983+Anthony-Eid@users.noreply.github.com> Date: Wed, 16 Apr 2025 13:41:24 -0400 Subject: [PATCH] debugger: Remove or move breakpoints on file deletion/rename (#28882) Release Notes: - N/A --------- Co-authored-by: Cole Miller --- .../project/src/debugger/breakpoint_store.rs | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/crates/project/src/debugger/breakpoint_store.rs b/crates/project/src/debugger/breakpoint_store.rs index 5cc361a73e..4426e55feb 100644 --- a/crates/project/src/debugger/breakpoint_store.rs +++ b/crates/project/src/debugger/breakpoint_store.rs @@ -18,7 +18,7 @@ use text::{Point, PointUtf16}; use crate::{Project, ProjectPath, buffer_store::BufferStore, worktree_store::WorktreeStore}; mod breakpoints_in_file { - use language::BufferEvent; + use language::{BufferEvent, DiskState}; use super::*; @@ -32,8 +32,9 @@ mod breakpoints_in_file { impl BreakpointsInFile { pub(super) fn new(buffer: Entity, cx: &mut Context) -> Self { - let subscription = - Arc::from(cx.subscribe(&buffer, |_, buffer, event, cx| match event { + let subscription = Arc::from(cx.subscribe( + &buffer, + |breakpoint_store, buffer, event, cx| match event { BufferEvent::Saved => { if let Some(abs_path) = BreakpointStore::abs_path_from_buffer(&buffer, cx) { cx.emit(BreakpointStoreEvent::BreakpointsUpdated( @@ -42,8 +43,44 @@ mod breakpoints_in_file { )); } } + BufferEvent::FileHandleChanged => { + let entity_id = buffer.entity_id(); + + if buffer.read(cx).file().is_none_or(|f| f.disk_state() == DiskState::Deleted) { + breakpoint_store.breakpoints.retain(|_, breakpoints_in_file| { + breakpoints_in_file.buffer.entity_id() != entity_id + }); + + cx.notify(); + return; + } + + if let Some(abs_path) = BreakpointStore::abs_path_from_buffer(&buffer, cx) { + if breakpoint_store.breakpoints.contains_key(&abs_path) { + return; + } + + if let Some(old_path) = breakpoint_store + .breakpoints + .iter() + .find(|(_, in_file)| in_file.buffer.entity_id() == entity_id) + .map(|values| values.0) + .cloned() + { + let Some(breakpoints_in_file) = + breakpoint_store.breakpoints.remove(&old_path) else { + log::error!("Couldn't get breakpoints in file from old path during buffer rename handling"); + return; + }; + + breakpoint_store.breakpoints.insert(abs_path, breakpoints_in_file); + cx.notify(); + } + } + } _ => {} - })); + }, + )); BreakpointsInFile { buffer,