debugger: Start work on adding session snapshot feature (#44298)

This PR adds the basic logic for a feature that allows you to visit any
stopped information back in time. We will follow up with PRs to improve
this and actually add UI for it so the UX is better.


https://github.com/user-attachments/assets/42d8a5b3-8ab8-471a-bdd0-f579662eadd6


Edit Anthony:

We feature flagged this so external users won't be able to access this
until the feature is polished

Release Notes:

- N/A

---------

Co-authored-by: Anthony Eid <hello@anthonyeid.me>
This commit is contained in:
Remco Smits
2025-12-06 19:31:08 +00:00
committed by GitHub
co-authored by Anthony Eid
parent 16666f5357
commit a574ae8779
6 changed files with 215 additions and 94 deletions
+36 -1
View File
@@ -15,6 +15,7 @@ use dap::adapters::DebugAdapterName;
use dap::{DapRegistry, StartDebuggingRequestArguments};
use dap::{client::SessionId, debugger_settings::DebuggerSettings};
use editor::{Editor, MultiBufferOffset, ToPoint};
use feature_flags::{FeatureFlag, FeatureFlagAppExt as _};
use gpui::{
Action, App, AsyncWindowContext, ClipboardItem, Context, DismissEvent, Entity, EntityId,
EventEmitter, FocusHandle, Focusable, MouseButton, MouseDownEvent, Point, Subscription, Task,
@@ -42,6 +43,12 @@ use workspace::{
};
use zed_actions::ToggleFocus;
pub struct DebuggerHistoryFeatureFlag;
impl FeatureFlag for DebuggerHistoryFeatureFlag {
const NAME: &'static str = "debugger-history";
}
const DEBUG_PANEL_KEY: &str = "DebugPanel";
pub struct DebugPanel {
@@ -284,7 +291,7 @@ impl DebugPanel {
}
});
session.update(cx, |session, _| match &mut session.mode {
session.update(cx, |session, _| match &mut session.state {
SessionState::Booting(state_task) => {
*state_task = Some(boot_task);
}
@@ -805,6 +812,34 @@ impl DebugPanel {
}
}),
)
.when(cx.has_flag::<DebuggerHistoryFeatureFlag>(), |this| {
this.child(
IconButton::new(
"debug-back-in-history",
IconName::HistoryRerun,
)
.icon_size(IconSize::Small)
.on_click(
window.listener_for(
running_state,
|this, _, _window, cx| {
this.session().update(cx, |session, cx| {
let ix = session
.active_history()
.unwrap_or_else(|| {
session.history().len()
});
session.go_back_to_history(
Some(ix.saturating_sub(1)),
cx,
);
})
},
),
),
)
})
.child(Divider::vertical())
.child(
IconButton::new("debug-restart", IconName::RotateCcw)
+1 -1
View File
@@ -1743,7 +1743,7 @@ impl RunningState {
let is_building = self.session.update(cx, |session, cx| {
session.shutdown(cx).detach();
matches!(session.mode, session::SessionState::Booting(_))
matches!(session.state, session::SessionState::Booting(_))
});
if is_building {