Allow enabling/disabling breakpoints (#27280)
This PR adds the ability to enable/disable breakpoints. It also fixes a bug where toggling a log breakpoint from the breakpoint context menu would add a standard breakpoint on top of the log breakpoint instead of deleting it. todo: - [x] Add `BreakpointState` field Breakpoint that manages if a breakpoint is active or not - [x] Don't send disabled breakpoints to DAP servers - in progress - [x] Half the opacity of disabled breakpoints - in progress - [x] Add `BreakpointState` to database - [x] Editor test for enabling/disabling breakpoints - [ ] Integration Test to make sure we don't send disabled breakpoints to DAP servers - [x] Database test to make sure we properly serialize/deserialize BreakpointState Release Notes: - N/A --------- Co-authored-by: Piotr <piotr@zed.dev> Co-authored-by: Conrad <conrad@zed.dev> Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
This commit is contained in:
parent
df583d73b9
commit
d70ac64fe4
9 changed files with 583 additions and 172 deletions
|
@ -256,6 +256,21 @@ impl BreakpointStore {
|
|||
breakpoint_set.breakpoints.push(breakpoint.clone());
|
||||
}
|
||||
}
|
||||
BreakpointEditAction::InvertState => {
|
||||
if let Some((_, bp)) = breakpoint_set
|
||||
.breakpoints
|
||||
.iter_mut()
|
||||
.find(|value| breakpoint == **value)
|
||||
{
|
||||
if bp.is_enabled() {
|
||||
bp.state = BreakpointState::Disabled;
|
||||
} else {
|
||||
bp.state = BreakpointState::Enabled;
|
||||
}
|
||||
} else {
|
||||
log::error!("Attempted to invert a breakpoint's state that doesn't exist ");
|
||||
}
|
||||
}
|
||||
BreakpointEditAction::EditLogMessage(log_message) => {
|
||||
if !log_message.is_empty() {
|
||||
breakpoint.1.kind = BreakpointKind::Log(log_message.clone());
|
||||
|
@ -351,7 +366,7 @@ impl BreakpointStore {
|
|||
&'a self,
|
||||
buffer: &'a Entity<Buffer>,
|
||||
range: Option<Range<text::Anchor>>,
|
||||
buffer_snapshot: BufferSnapshot,
|
||||
buffer_snapshot: &'a BufferSnapshot,
|
||||
cx: &App,
|
||||
) -> impl Iterator<Item = &'a (text::Anchor, Breakpoint)> + 'a {
|
||||
let abs_path = Self::abs_path_from_buffer(buffer, cx);
|
||||
|
@ -361,11 +376,10 @@ impl BreakpointStore {
|
|||
.flat_map(move |file_breakpoints| {
|
||||
file_breakpoints.breakpoints.iter().filter({
|
||||
let range = range.clone();
|
||||
let buffer_snapshot = buffer_snapshot.clone();
|
||||
move |(position, _)| {
|
||||
if let Some(range) = &range {
|
||||
position.cmp(&range.start, &buffer_snapshot).is_ge()
|
||||
&& position.cmp(&range.end, &buffer_snapshot).is_le()
|
||||
position.cmp(&range.start, buffer_snapshot).is_ge()
|
||||
&& position.cmp(&range.end, buffer_snapshot).is_le()
|
||||
} else {
|
||||
true
|
||||
}
|
||||
|
@ -417,6 +431,7 @@ impl BreakpointStore {
|
|||
position,
|
||||
path: path.clone(),
|
||||
kind: breakpoint.kind.clone(),
|
||||
state: breakpoint.state,
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
|
@ -439,6 +454,7 @@ impl BreakpointStore {
|
|||
position,
|
||||
path: path.clone(),
|
||||
kind: breakpoint.kind.clone(),
|
||||
state: breakpoint.state,
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
|
@ -487,9 +503,13 @@ impl BreakpointStore {
|
|||
|
||||
for bp in bps {
|
||||
let position = snapshot.anchor_before(PointUtf16::new(bp.position, 0));
|
||||
breakpoints_for_file
|
||||
.breakpoints
|
||||
.push((position, Breakpoint { kind: bp.kind }))
|
||||
breakpoints_for_file.breakpoints.push((
|
||||
position,
|
||||
Breakpoint {
|
||||
kind: bp.kind,
|
||||
state: bp.state,
|
||||
},
|
||||
))
|
||||
}
|
||||
new_breakpoints.insert(path, breakpoints_for_file);
|
||||
}
|
||||
|
@ -530,6 +550,7 @@ type LogMessage = Arc<str>;
|
|||
#[derive(Clone, Debug)]
|
||||
pub enum BreakpointEditAction {
|
||||
Toggle,
|
||||
InvertState,
|
||||
EditLogMessage(LogMessage),
|
||||
}
|
||||
|
||||
|
@ -569,16 +590,60 @@ impl Hash for BreakpointKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub enum BreakpointState {
|
||||
Enabled,
|
||||
Disabled,
|
||||
}
|
||||
|
||||
impl BreakpointState {
|
||||
#[inline]
|
||||
pub fn is_enabled(&self) -> bool {
|
||||
matches!(self, BreakpointState::Enabled)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_disabled(&self) -> bool {
|
||||
matches!(self, BreakpointState::Disabled)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_int(&self) -> i32 {
|
||||
match self {
|
||||
BreakpointState::Enabled => 0,
|
||||
BreakpointState::Disabled => 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub struct Breakpoint {
|
||||
pub kind: BreakpointKind,
|
||||
pub state: BreakpointState,
|
||||
}
|
||||
|
||||
impl Breakpoint {
|
||||
pub fn new_standard() -> Self {
|
||||
Self {
|
||||
kind: BreakpointKind::Standard,
|
||||
state: BreakpointState::Enabled,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_log(log_message: &str) -> Self {
|
||||
Self {
|
||||
kind: BreakpointKind::Log(log_message.to_owned().into()),
|
||||
state: BreakpointState::Enabled,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_proto(&self, _path: &Path, position: &text::Anchor) -> Option<client::proto::Breakpoint> {
|
||||
Some(client::proto::Breakpoint {
|
||||
position: Some(serialize_text_anchor(position)),
|
||||
|
||||
state: match self.state {
|
||||
BreakpointState::Enabled => proto::BreakpointState::Enabled.into(),
|
||||
BreakpointState::Disabled => proto::BreakpointState::Disabled.into(),
|
||||
},
|
||||
kind: match self.kind {
|
||||
BreakpointKind::Standard => proto::BreakpointKind::Standard.into(),
|
||||
BreakpointKind::Log(_) => proto::BreakpointKind::Log.into(),
|
||||
|
@ -599,8 +664,22 @@ impl Breakpoint {
|
|||
}
|
||||
None | Some(proto::BreakpointKind::Standard) => BreakpointKind::Standard,
|
||||
},
|
||||
state: match proto::BreakpointState::from_i32(breakpoint.state) {
|
||||
Some(proto::BreakpointState::Disabled) => BreakpointState::Disabled,
|
||||
None | Some(proto::BreakpointState::Enabled) => BreakpointState::Enabled,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_enabled(&self) -> bool {
|
||||
self.state.is_enabled()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_disabled(&self) -> bool {
|
||||
self.state.is_disabled()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||
|
@ -608,6 +687,7 @@ pub struct SerializedBreakpoint {
|
|||
pub position: u32,
|
||||
pub path: Arc<Path>,
|
||||
pub kind: BreakpointKind,
|
||||
pub state: BreakpointState,
|
||||
}
|
||||
|
||||
impl From<SerializedBreakpoint> for dap::SourceBreakpoint {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue