Cargo.lock 🔗
@@ -4427,6 +4427,7 @@ dependencies = [
"pretty_assertions",
"project",
"rpc",
+ "schemars",
"serde",
"serde_json",
"serde_json_lenient",
Anthony Eid created
Release Notes:
- Support specifying a data breakpoint's access type - Read, Write, Read
& Write
Cargo.lock | 1
crates/debugger_ui/Cargo.toml | 11 +
crates/debugger_ui/src/debugger_ui.rs | 20 +++
crates/debugger_ui/src/session/running/memory_view.rs | 2
crates/debugger_ui/src/session/running/variable_list.rs | 61 +++++++++-
5 files changed, 76 insertions(+), 19 deletions(-)
@@ -4427,6 +4427,7 @@ dependencies = [
"pretty_assertions",
"project",
"rpc",
+ "schemars",
"serde",
"serde_json",
"serde_json_lenient",
@@ -35,6 +35,7 @@ command_palette_hooks.workspace = true
dap.workspace = true
dap_adapters = { workspace = true, optional = true }
db.workspace = true
+debugger_tools.workspace = true
editor.workspace = true
file_icons.workspace = true
futures.workspace = true
@@ -54,6 +55,7 @@ picker.workspace = true
pretty_assertions.workspace = true
project.workspace = true
rpc.workspace = true
+schemars.workspace = true
serde.workspace = true
serde_json.workspace = true
serde_json_lenient.workspace = true
@@ -66,14 +68,13 @@ telemetry.workspace = true
terminal_view.workspace = true
text.workspace = true
theme.workspace = true
-tree-sitter.workspace = true
tree-sitter-json.workspace = true
+tree-sitter.workspace = true
ui.workspace = true
+unindent = { workspace = true, optional = true }
util.workspace = true
-workspace.workspace = true
workspace-hack.workspace = true
-debugger_tools.workspace = true
-unindent = { workspace = true, optional = true }
+workspace.workspace = true
zed_actions.workspace = true
[dev-dependencies]
@@ -83,8 +84,8 @@ debugger_tools = { workspace = true, features = ["test-support"] }
editor = { workspace = true, features = ["test-support"] }
gpui = { workspace = true, features = ["test-support"] }
project = { workspace = true, features = ["test-support"] }
+tree-sitter-go.workspace = true
unindent.workspace = true
util = { workspace = true, features = ["test-support"] }
workspace = { workspace = true, features = ["test-support"] }
zlog.workspace = true
-tree-sitter-go.workspace = true
@@ -3,10 +3,12 @@ use std::any::TypeId;
use dap::debugger_settings::DebuggerSettings;
use debugger_panel::DebugPanel;
use editor::Editor;
-use gpui::{App, DispatchPhase, EntityInputHandler, actions};
+use gpui::{Action, App, DispatchPhase, EntityInputHandler, actions};
use new_process_modal::{NewProcessModal, NewProcessMode};
use onboarding_modal::DebuggerOnboardingModal;
use project::debugger::{self, breakpoint_store::SourceBreakpoint, session::ThreadStatus};
+use schemars::JsonSchema;
+use serde::Deserialize;
use session::DebugSession;
use settings::Settings;
use stack_trace_view::StackTraceView;
@@ -83,11 +85,23 @@ actions!(
Rerun,
/// Toggles expansion of the selected item in the debugger UI.
ToggleExpandItem,
- /// Set a data breakpoint on the selected variable or memory region.
- ToggleDataBreakpoint,
]
);
+/// Extends selection down by a specified number of lines.
+#[derive(PartialEq, Clone, Deserialize, Default, JsonSchema, Action)]
+#[action(namespace = debugger)]
+#[serde(deny_unknown_fields)]
+/// Set a data breakpoint on the selected variable or memory region.
+pub struct ToggleDataBreakpoint {
+ /// The type of data breakpoint
+ /// Read & Write
+ /// Read
+ /// Write
+ #[serde(default)]
+ pub access_type: Option<dap::DataBreakpointAccessType>,
+}
+
actions!(
dev,
[
@@ -688,7 +688,7 @@ impl MemoryView {
menu = menu.action_disabled_when(
*memory_unreadable,
"Set Data Breakpoint",
- ToggleDataBreakpoint.boxed_clone(),
+ ToggleDataBreakpoint { access_type: None }.boxed_clone(),
);
}
menu.context(self.focus_handle.clone())
@@ -670,9 +670,9 @@ impl VariableList {
let focus_handle = self.focus_handle.clone();
cx.spawn_in(window, async move |this, cx| {
let can_toggle_data_breakpoint = if let Some(task) = can_toggle_data_breakpoint {
- task.await.is_some()
+ task.await
} else {
- true
+ None
};
cx.update(|window, cx| {
let context_menu = ContextMenu::build(window, cx, |menu, _, _| {
@@ -686,11 +686,35 @@ impl VariableList {
menu.action("Go To Memory", GoToMemory.boxed_clone())
})
.action("Watch Variable", AddWatch.boxed_clone())
- .when(can_toggle_data_breakpoint, |menu| {
- menu.action(
- "Toggle Data Breakpoint",
- crate::ToggleDataBreakpoint.boxed_clone(),
- )
+ .when_some(can_toggle_data_breakpoint, |mut menu, data_info| {
+ menu = menu.separator();
+ if let Some(access_types) = data_info.access_types {
+ for access in access_types {
+ menu = menu.action(
+ format!(
+ "Toggle {} Data Breakpoint",
+ match access {
+ dap::DataBreakpointAccessType::Read => "Read",
+ dap::DataBreakpointAccessType::Write => "Write",
+ dap::DataBreakpointAccessType::ReadWrite =>
+ "Read/Write",
+ }
+ ),
+ crate::ToggleDataBreakpoint {
+ access_type: Some(access),
+ }
+ .boxed_clone(),
+ );
+ }
+
+ menu
+ } else {
+ menu.action(
+ "Toggle Data Breakpoint",
+ crate::ToggleDataBreakpoint { access_type: None }
+ .boxed_clone(),
+ )
+ }
})
})
.when(entry.as_watcher().is_some(), |menu| {
@@ -729,7 +753,7 @@ impl VariableList {
fn toggle_data_breakpoint(
&mut self,
- _: &crate::ToggleDataBreakpoint,
+ data_info: &crate::ToggleDataBreakpoint,
_window: &mut Window,
cx: &mut Context<Self>,
) {
@@ -759,17 +783,34 @@ impl VariableList {
});
let session = self.session.downgrade();
+ let access_type = data_info.access_type;
cx.spawn(async move |_, cx| {
- let Some(data_id) = data_breakpoint.await.and_then(|info| info.data_id) else {
+ let Some((data_id, access_types)) = data_breakpoint
+ .await
+ .and_then(|info| Some((info.data_id?, info.access_types)))
+ else {
return;
};
+
+ // Because user's can manually add this action to the keymap
+ // we check if access type is supported
+ let access_type = match access_types {
+ None => None,
+ Some(access_types) => {
+ if access_type.is_some_and(|access_type| access_types.contains(&access_type)) {
+ access_type
+ } else {
+ None
+ }
+ }
+ };
_ = session.update(cx, |session, cx| {
session.create_data_breakpoint(
context,
data_id.clone(),
dap::DataBreakpoint {
data_id,
- access_type: None,
+ access_type,
condition: None,
hit_condition: None,
},