debugger: Touchups to log breakpoints (#27675)
This is a slight refactor that flattens Breakpoint struct in anticipation of condition/hit breakpoints. It also adds a slight delay before breakpoints are shown on gutter hover to make breakpoints less attention grabbing. Release Notes: - N/A
This commit is contained in:
parent
8ecf553279
commit
f86977e2a7
8 changed files with 136 additions and 276 deletions
|
@ -147,7 +147,7 @@ use multi_buffer::{
|
|||
};
|
||||
use parking_lot::Mutex;
|
||||
use project::{
|
||||
debugger::breakpoint_store::{Breakpoint, BreakpointKind},
|
||||
debugger::breakpoint_store::Breakpoint,
|
||||
lsp_store::{CompletionDocumentation, FormatTrigger, LspFormatTarget, OpenLspBufferHandle},
|
||||
project_settings::{GitGutterSetting, ProjectSettings},
|
||||
CodeAction, Completion, CompletionIntent, CompletionSource, DocumentHighlight, InlayHint,
|
||||
|
@ -785,11 +785,11 @@ pub struct Editor {
|
|||
expect_bounds_change: Option<Bounds<Pixels>>,
|
||||
tasks: BTreeMap<(BufferId, BufferRow), RunnableTasks>,
|
||||
tasks_update_task: Option<Task<()>>,
|
||||
pub breakpoint_store: Option<Entity<BreakpointStore>>,
|
||||
breakpoint_store: Option<Entity<BreakpointStore>>,
|
||||
/// Allow's a user to create a breakpoint by selecting this indicator
|
||||
/// It should be None while a user is not hovering over the gutter
|
||||
/// Otherwise it represents the point that the breakpoint will be shown
|
||||
pub gutter_breakpoint_indicator: Option<DisplayPoint>,
|
||||
gutter_breakpoint_indicator: (Option<(DisplayPoint, bool)>, Option<Task<()>>),
|
||||
in_project_search: bool,
|
||||
previous_search_ranges: Option<Arc<[Range<Anchor>]>>,
|
||||
breadcrumb_header: Option<String>,
|
||||
|
@ -1549,7 +1549,7 @@ impl Editor {
|
|||
tasks: Default::default(),
|
||||
|
||||
breakpoint_store,
|
||||
gutter_breakpoint_indicator: None,
|
||||
gutter_breakpoint_indicator: (None, None),
|
||||
_subscriptions: vec![
|
||||
cx.observe(&buffer, Self::on_buffer_changed),
|
||||
cx.subscribe_in(&buffer, window, Self::on_buffer_event),
|
||||
|
@ -6226,10 +6226,7 @@ impl Editor {
|
|||
.breakpoint_at_row(row, window, cx)
|
||||
.map(|(_, bp)| Arc::from(bp));
|
||||
|
||||
let log_breakpoint_msg = if breakpoint
|
||||
.as_ref()
|
||||
.is_some_and(|bp| bp.kind.log_message().is_some())
|
||||
{
|
||||
let log_breakpoint_msg = if breakpoint.as_ref().is_some_and(|bp| bp.message.is_some()) {
|
||||
"Edit Log Breakpoint"
|
||||
} else {
|
||||
"Set Log Breakpoint"
|
||||
|
@ -6249,7 +6246,7 @@ impl Editor {
|
|||
let breakpoint = breakpoint.unwrap_or_else(|| {
|
||||
Arc::new(Breakpoint {
|
||||
state: BreakpointState::Enabled,
|
||||
kind: BreakpointKind::Standard,
|
||||
message: None,
|
||||
})
|
||||
});
|
||||
|
||||
|
@ -6308,16 +6305,17 @@ impl Editor {
|
|||
cx: &mut Context<Self>,
|
||||
) -> IconButton {
|
||||
let (color, icon) = {
|
||||
let icon = match (&breakpoint.kind, breakpoint.is_disabled()) {
|
||||
(BreakpointKind::Standard, false) => ui::IconName::DebugBreakpoint,
|
||||
(BreakpointKind::Log(_), false) => ui::IconName::DebugLogBreakpoint,
|
||||
(BreakpointKind::Standard, true) => ui::IconName::DebugDisabledBreakpoint,
|
||||
(BreakpointKind::Log(_), true) => ui::IconName::DebugDisabledLogBreakpoint,
|
||||
let icon = match (&breakpoint.message.is_some(), breakpoint.is_disabled()) {
|
||||
(false, false) => ui::IconName::DebugBreakpoint,
|
||||
(true, false) => ui::IconName::DebugLogBreakpoint,
|
||||
(false, true) => ui::IconName::DebugDisabledBreakpoint,
|
||||
(true, true) => ui::IconName::DebugDisabledLogBreakpoint,
|
||||
};
|
||||
|
||||
let color = if self
|
||||
.gutter_breakpoint_indicator
|
||||
.is_some_and(|point| point.row() == row)
|
||||
.0
|
||||
.is_some_and(|(point, is_visible)| is_visible && point.row() == row)
|
||||
{
|
||||
Color::Hint
|
||||
} else {
|
||||
|
@ -8654,7 +8652,7 @@ impl Editor {
|
|||
(
|
||||
breakpoint_position,
|
||||
Breakpoint {
|
||||
kind: BreakpointKind::Standard,
|
||||
message: None,
|
||||
state: BreakpointState::Enabled,
|
||||
},
|
||||
)
|
||||
|
@ -19758,8 +19756,8 @@ impl BreakpointPromptEditor {
|
|||
let buffer = cx.new(|cx| {
|
||||
Buffer::local(
|
||||
breakpoint
|
||||
.kind
|
||||
.log_message()
|
||||
.message
|
||||
.as_ref()
|
||||
.map(|msg| msg.to_string())
|
||||
.unwrap_or_default(),
|
||||
cx,
|
||||
|
|
|
@ -32,7 +32,7 @@ use multi_buffer::{IndentGuide, PathKey};
|
|||
use parking_lot::Mutex;
|
||||
use pretty_assertions::{assert_eq, assert_ne};
|
||||
use project::{
|
||||
debugger::breakpoint_store::{BreakpointKind, BreakpointState, SerializedBreakpoint},
|
||||
debugger::breakpoint_store::{BreakpointState, SourceBreakpoint},
|
||||
project_settings::{LspSettings, ProjectSettings},
|
||||
FakeFs,
|
||||
};
|
||||
|
@ -17390,12 +17390,12 @@ async fn assert_highlighted_edits(
|
|||
|
||||
#[track_caller]
|
||||
fn assert_breakpoint(
|
||||
breakpoints: &BTreeMap<Arc<Path>, Vec<SerializedBreakpoint>>,
|
||||
breakpoints: &BTreeMap<Arc<Path>, Vec<SourceBreakpoint>>,
|
||||
path: &Arc<Path>,
|
||||
expected: Vec<(u32, Breakpoint)>,
|
||||
) {
|
||||
if expected.len() == 0usize {
|
||||
assert!(!breakpoints.contains_key(path));
|
||||
assert!(!breakpoints.contains_key(path), "{}", path.display());
|
||||
} else {
|
||||
let mut breakpoint = breakpoints
|
||||
.get(path)
|
||||
|
@ -17403,9 +17403,9 @@ fn assert_breakpoint(
|
|||
.into_iter()
|
||||
.map(|breakpoint| {
|
||||
(
|
||||
breakpoint.position,
|
||||
breakpoint.row,
|
||||
Breakpoint {
|
||||
kind: breakpoint.kind.clone(),
|
||||
message: breakpoint.message.clone(),
|
||||
state: breakpoint.state,
|
||||
},
|
||||
)
|
||||
|
@ -17435,12 +17435,10 @@ fn add_log_breakpoint_at_cursor(
|
|||
.buffer_snapshot
|
||||
.anchor_before(Point::new(cursor_position.row, 0));
|
||||
|
||||
let kind = BreakpointKind::Log(Arc::from(log_message));
|
||||
|
||||
(
|
||||
breakpoint_position,
|
||||
Breakpoint {
|
||||
kind,
|
||||
message: Some(Arc::from(log_message)),
|
||||
state: BreakpointState::Enabled,
|
||||
},
|
||||
)
|
||||
|
@ -17738,7 +17736,7 @@ async fn test_log_breakpoint_editing(cx: &mut TestAppContext) {
|
|||
&abs_path,
|
||||
vec![
|
||||
(0, Breakpoint::new_standard()),
|
||||
(3, Breakpoint::new_log("hello Earth !!")),
|
||||
(3, Breakpoint::new_log("hello Earth!!")),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ use std::{
|
|||
ops::{Deref, Range},
|
||||
rc::Rc,
|
||||
sync::Arc,
|
||||
time::Duration,
|
||||
};
|
||||
use sum_tree::Bias;
|
||||
use text::BufferId;
|
||||
|
@ -907,7 +908,6 @@ impl EditorElement {
|
|||
let modifiers = event.modifiers;
|
||||
let gutter_hovered = gutter_hitbox.is_hovered(window);
|
||||
editor.set_gutter_hovered(gutter_hovered, cx);
|
||||
editor.gutter_breakpoint_indicator = None;
|
||||
editor.mouse_cursor_hidden = false;
|
||||
|
||||
if gutter_hovered {
|
||||
|
@ -924,8 +924,38 @@ impl EditorElement {
|
|||
.buffer_for_excerpt(buffer_anchor.excerpt_id)
|
||||
.is_some_and(|buffer| buffer.file().is_some())
|
||||
{
|
||||
editor.gutter_breakpoint_indicator = Some(new_point);
|
||||
let was_hovered = editor.gutter_breakpoint_indicator.0.is_some();
|
||||
let is_visible = editor
|
||||
.gutter_breakpoint_indicator
|
||||
.0
|
||||
.map_or(false, |(_, is_active)| is_active);
|
||||
editor.gutter_breakpoint_indicator.0 = Some((new_point, is_visible));
|
||||
|
||||
editor.gutter_breakpoint_indicator.1.get_or_insert_with(|| {
|
||||
cx.spawn(async move |this, cx| {
|
||||
if !was_hovered {
|
||||
cx.background_executor()
|
||||
.timer(Duration::from_millis(200))
|
||||
.await;
|
||||
}
|
||||
|
||||
this.update(cx, |this, cx| {
|
||||
if let Some((_, is_active)) =
|
||||
this.gutter_breakpoint_indicator.0.as_mut()
|
||||
{
|
||||
*is_active = true;
|
||||
}
|
||||
|
||||
cx.notify();
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
});
|
||||
} else {
|
||||
editor.gutter_breakpoint_indicator = (None, None);
|
||||
}
|
||||
} else {
|
||||
editor.gutter_breakpoint_indicator = (None, None);
|
||||
}
|
||||
|
||||
cx.notify();
|
||||
|
@ -6851,8 +6881,10 @@ impl Element for EditorElement {
|
|||
// has their mouse over that line when a breakpoint isn't there
|
||||
if cx.has_flag::<Debugger>() {
|
||||
let gutter_breakpoint_indicator =
|
||||
self.editor.read(cx).gutter_breakpoint_indicator;
|
||||
if let Some(gutter_breakpoint_point) = gutter_breakpoint_indicator {
|
||||
self.editor.read(cx).gutter_breakpoint_indicator.0;
|
||||
if let Some((gutter_breakpoint_point, _)) =
|
||||
gutter_breakpoint_indicator.filter(|(_, is_active)| *is_active)
|
||||
{
|
||||
breakpoint_rows
|
||||
.entry(gutter_breakpoint_point.row())
|
||||
.or_insert_with(|| {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue