Reuse values from last debug panel inert state if they exist (#27211)
This should allow the team to iterate faster when using the debug panel to set up a session Release Notes: - N/A
This commit is contained in:
parent
ac452799b0
commit
a74f2bb18b
3 changed files with 106 additions and 22 deletions
|
@ -3,8 +3,8 @@ use anyhow::{anyhow, Result};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use command_palette_hooks::CommandPaletteFilter;
|
use command_palette_hooks::CommandPaletteFilter;
|
||||||
use dap::{
|
use dap::{
|
||||||
client::SessionId, debugger_settings::DebuggerSettings, ContinuedEvent, LoadedSourceEvent,
|
client::SessionId, debugger_settings::DebuggerSettings, ContinuedEvent, DebugAdapterConfig,
|
||||||
ModuleEvent, OutputEvent, StoppedEvent, ThreadEvent,
|
LoadedSourceEvent, ModuleEvent, OutputEvent, StoppedEvent, ThreadEvent,
|
||||||
};
|
};
|
||||||
use futures::{channel::mpsc, SinkExt as _};
|
use futures::{channel::mpsc, SinkExt as _};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
|
@ -21,6 +21,7 @@ use settings::Settings;
|
||||||
use std::{any::TypeId, path::PathBuf};
|
use std::{any::TypeId, path::PathBuf};
|
||||||
use terminal_view::terminal_panel::TerminalPanel;
|
use terminal_view::terminal_panel::TerminalPanel;
|
||||||
use ui::prelude::*;
|
use ui::prelude::*;
|
||||||
|
use util::ResultExt;
|
||||||
use workspace::{
|
use workspace::{
|
||||||
dock::{DockPosition, Panel, PanelEvent},
|
dock::{DockPosition, Panel, PanelEvent},
|
||||||
pane, Continue, Disconnect, Pane, Pause, Restart, StepBack, StepInto, StepOut, StepOver, Stop,
|
pane, Continue, Disconnect, Pane, Pause, Restart, StepBack, StepInto, StepOut, StepOver, Stop,
|
||||||
|
@ -51,6 +52,7 @@ pub struct DebugPanel {
|
||||||
project: WeakEntity<Project>,
|
project: WeakEntity<Project>,
|
||||||
workspace: WeakEntity<Workspace>,
|
workspace: WeakEntity<Workspace>,
|
||||||
_subscriptions: Vec<Subscription>,
|
_subscriptions: Vec<Subscription>,
|
||||||
|
pub(crate) last_inert_config: Option<DebugAdapterConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DebugPanel {
|
impl DebugPanel {
|
||||||
|
@ -63,6 +65,7 @@ impl DebugPanel {
|
||||||
let project = workspace.project().clone();
|
let project = workspace.project().clone();
|
||||||
let dap_store = project.read(cx).dap_store();
|
let dap_store = project.read(cx).dap_store();
|
||||||
let weak_workspace = workspace.weak_handle();
|
let weak_workspace = workspace.weak_handle();
|
||||||
|
let debug_panel = cx.weak_entity();
|
||||||
let pane = cx.new(|cx| {
|
let pane = cx.new(|cx| {
|
||||||
let mut pane = Pane::new(
|
let mut pane = Pane::new(
|
||||||
workspace.weak_handle(),
|
workspace.weak_handle(),
|
||||||
|
@ -81,6 +84,7 @@ impl DebugPanel {
|
||||||
pane.set_render_tab_bar_buttons(cx, {
|
pane.set_render_tab_bar_buttons(cx, {
|
||||||
let project = project.clone();
|
let project = project.clone();
|
||||||
let weak_workspace = weak_workspace.clone();
|
let weak_workspace = weak_workspace.clone();
|
||||||
|
let debug_panel = debug_panel.clone();
|
||||||
move |_, _, cx| {
|
move |_, _, cx| {
|
||||||
let project = project.clone();
|
let project = project.clone();
|
||||||
let weak_workspace = weak_workspace.clone();
|
let weak_workspace = weak_workspace.clone();
|
||||||
|
@ -91,21 +95,34 @@ impl DebugPanel {
|
||||||
.child(
|
.child(
|
||||||
IconButton::new("new-debug-session", IconName::Plus)
|
IconButton::new("new-debug-session", IconName::Plus)
|
||||||
.icon_size(IconSize::Small)
|
.icon_size(IconSize::Small)
|
||||||
.on_click(cx.listener(move |pane, _, window, cx| {
|
.on_click({
|
||||||
pane.add_item(
|
let debug_panel = debug_panel.clone();
|
||||||
Box::new(DebugSession::inert(
|
|
||||||
project.clone(),
|
cx.listener(move |pane, _, window, cx| {
|
||||||
weak_workspace.clone(),
|
let config = debug_panel
|
||||||
|
.read_with(cx, |this: &DebugPanel, _| {
|
||||||
|
this.last_inert_config.clone()
|
||||||
|
})
|
||||||
|
.log_err()
|
||||||
|
.flatten();
|
||||||
|
|
||||||
|
pane.add_item(
|
||||||
|
Box::new(DebugSession::inert(
|
||||||
|
project.clone(),
|
||||||
|
weak_workspace.clone(),
|
||||||
|
debug_panel.clone(),
|
||||||
|
config,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
)),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
None,
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
)),
|
);
|
||||||
false,
|
})
|
||||||
false,
|
}),
|
||||||
None,
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
})),
|
|
||||||
)
|
)
|
||||||
.into_any_element(),
|
.into_any_element(),
|
||||||
),
|
),
|
||||||
|
@ -116,6 +133,8 @@ impl DebugPanel {
|
||||||
Box::new(DebugSession::inert(
|
Box::new(DebugSession::inert(
|
||||||
project.clone(),
|
project.clone(),
|
||||||
weak_workspace.clone(),
|
weak_workspace.clone(),
|
||||||
|
debug_panel.clone(),
|
||||||
|
None,
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
)),
|
)),
|
||||||
|
@ -138,6 +157,7 @@ impl DebugPanel {
|
||||||
pane,
|
pane,
|
||||||
size: px(300.),
|
size: px(300.),
|
||||||
_subscriptions,
|
_subscriptions,
|
||||||
|
last_inert_config: None,
|
||||||
project: project.downgrade(),
|
project: project.downgrade(),
|
||||||
workspace: workspace.weak_handle(),
|
workspace: workspace.weak_handle(),
|
||||||
};
|
};
|
||||||
|
@ -280,8 +300,14 @@ impl DebugPanel {
|
||||||
// We already have an item for this session.
|
// We already have an item for this session.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let session_item =
|
let session_item = DebugSession::running(
|
||||||
DebugSession::running(project, self.workspace.clone(), session, window, cx);
|
project,
|
||||||
|
self.workspace.clone(),
|
||||||
|
session,
|
||||||
|
cx.weak_entity(),
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
|
||||||
self.pane.update(cx, |pane, cx| {
|
self.pane.update(cx, |pane, cx| {
|
||||||
pane.add_item(Box::new(session_item), true, true, None, window, cx);
|
pane.add_item(Box::new(session_item), true, true, None, window, cx);
|
||||||
|
@ -504,12 +530,16 @@ impl Panel for DebugPanel {
|
||||||
let Some(project) = self.project.clone().upgrade() else {
|
let Some(project) = self.project.clone().upgrade() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
let config = self.last_inert_config.clone();
|
||||||
|
let panel = cx.weak_entity();
|
||||||
// todo: We need to revisit it when we start adding stopped items to pane (as that'll cause us to add two items).
|
// todo: We need to revisit it when we start adding stopped items to pane (as that'll cause us to add two items).
|
||||||
self.pane.update(cx, |this, cx| {
|
self.pane.update(cx, |this, cx| {
|
||||||
this.add_item(
|
this.add_item(
|
||||||
Box::new(DebugSession::inert(
|
Box::new(DebugSession::inert(
|
||||||
project,
|
project,
|
||||||
self.workspace.clone(),
|
self.workspace.clone(),
|
||||||
|
panel,
|
||||||
|
config,
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
)),
|
)),
|
||||||
|
|
|
@ -6,6 +6,7 @@ mod starting;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use dap::client::SessionId;
|
use dap::client::SessionId;
|
||||||
|
use dap::DebugAdapterConfig;
|
||||||
use failed::FailedState;
|
use failed::FailedState;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
percentage, Animation, AnimationExt, AnyElement, App, Entity, EventEmitter, FocusHandle,
|
percentage, Animation, AnimationExt, AnyElement, App, Entity, EventEmitter, FocusHandle,
|
||||||
|
@ -19,11 +20,14 @@ use rpc::proto::{self, PeerId};
|
||||||
use running::RunningState;
|
use running::RunningState;
|
||||||
use starting::{StartingEvent, StartingState};
|
use starting::{StartingEvent, StartingState};
|
||||||
use ui::prelude::*;
|
use ui::prelude::*;
|
||||||
|
use util::ResultExt;
|
||||||
use workspace::{
|
use workspace::{
|
||||||
item::{self, Item},
|
item::{self, Item},
|
||||||
FollowableItem, ViewId, Workspace,
|
FollowableItem, ViewId, Workspace,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::debugger_panel::DebugPanel;
|
||||||
|
|
||||||
pub(crate) enum DebugSessionState {
|
pub(crate) enum DebugSessionState {
|
||||||
Inert(Entity<InertState>),
|
Inert(Entity<InertState>),
|
||||||
Starting(Entity<StartingState>),
|
Starting(Entity<StartingState>),
|
||||||
|
@ -44,6 +48,7 @@ pub struct DebugSession {
|
||||||
remote_id: Option<workspace::ViewId>,
|
remote_id: Option<workspace::ViewId>,
|
||||||
mode: DebugSessionState,
|
mode: DebugSessionState,
|
||||||
dap_store: WeakEntity<DapStore>,
|
dap_store: WeakEntity<DapStore>,
|
||||||
|
debug_panel: WeakEntity<DebugPanel>,
|
||||||
worktree_store: WeakEntity<WorktreeStore>,
|
worktree_store: WeakEntity<WorktreeStore>,
|
||||||
workspace: WeakEntity<Workspace>,
|
workspace: WeakEntity<Workspace>,
|
||||||
_subscriptions: [Subscription; 1],
|
_subscriptions: [Subscription; 1],
|
||||||
|
@ -67,6 +72,8 @@ impl DebugSession {
|
||||||
pub(super) fn inert(
|
pub(super) fn inert(
|
||||||
project: Entity<Project>,
|
project: Entity<Project>,
|
||||||
workspace: WeakEntity<Workspace>,
|
workspace: WeakEntity<Workspace>,
|
||||||
|
debug_panel: WeakEntity<DebugPanel>,
|
||||||
|
config: Option<DebugAdapterConfig>,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> Entity<Self> {
|
) -> Entity<Self> {
|
||||||
|
@ -77,7 +84,8 @@ impl DebugSession {
|
||||||
.and_then(|tree| tree.read(cx).abs_path().to_str().map(|str| str.to_string()))
|
.and_then(|tree| tree.read(cx).abs_path().to_str().map(|str| str.to_string()))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let inert = cx.new(|cx| InertState::new(workspace.clone(), &default_cwd, window, cx));
|
let inert =
|
||||||
|
cx.new(|cx| InertState::new(workspace.clone(), &default_cwd, config, window, cx));
|
||||||
|
|
||||||
let project = project.read(cx);
|
let project = project.read(cx);
|
||||||
let dap_store = project.dap_store().downgrade();
|
let dap_store = project.dap_store().downgrade();
|
||||||
|
@ -89,6 +97,7 @@ impl DebugSession {
|
||||||
mode: DebugSessionState::Inert(inert),
|
mode: DebugSessionState::Inert(inert),
|
||||||
dap_store,
|
dap_store,
|
||||||
worktree_store,
|
worktree_store,
|
||||||
|
debug_panel,
|
||||||
workspace,
|
workspace,
|
||||||
_subscriptions,
|
_subscriptions,
|
||||||
}
|
}
|
||||||
|
@ -99,6 +108,7 @@ impl DebugSession {
|
||||||
project: Entity<Project>,
|
project: Entity<Project>,
|
||||||
workspace: WeakEntity<Workspace>,
|
workspace: WeakEntity<Workspace>,
|
||||||
session: Entity<Session>,
|
session: Entity<Session>,
|
||||||
|
debug_panel: WeakEntity<DebugPanel>,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> Entity<Self> {
|
) -> Entity<Self> {
|
||||||
|
@ -111,6 +121,7 @@ impl DebugSession {
|
||||||
remote_id: None,
|
remote_id: None,
|
||||||
mode: DebugSessionState::Running(mode),
|
mode: DebugSessionState::Running(mode),
|
||||||
dap_store: project.read(cx).dap_store().downgrade(),
|
dap_store: project.read(cx).dap_store().downgrade(),
|
||||||
|
debug_panel,
|
||||||
worktree_store: project.read(cx).worktree_store().downgrade(),
|
worktree_store: project.read(cx).worktree_store().downgrade(),
|
||||||
workspace,
|
workspace,
|
||||||
})
|
})
|
||||||
|
@ -148,6 +159,11 @@ impl DebugSession {
|
||||||
let dap_store = self.dap_store.clone();
|
let dap_store = self.dap_store.clone();
|
||||||
let InertEvent::Spawned { config } = event;
|
let InertEvent::Spawned { config } = event;
|
||||||
let config = config.clone();
|
let config = config.clone();
|
||||||
|
|
||||||
|
self.debug_panel
|
||||||
|
.update(cx, |this, _| this.last_inert_config = Some(config.clone()))
|
||||||
|
.log_err();
|
||||||
|
|
||||||
let worktree = self
|
let worktree = self
|
||||||
.worktree_store
|
.worktree_store
|
||||||
.update(cx, |this, _| this.worktrees().next())
|
.update(cx, |this, _| this.worktrees().next())
|
||||||
|
|
|
@ -32,6 +32,15 @@ impl SpawnMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<DebugRequestType> for SpawnMode {
|
||||||
|
fn from(request: DebugRequestType) -> Self {
|
||||||
|
match request {
|
||||||
|
DebugRequestType::Launch => SpawnMode::Launch,
|
||||||
|
DebugRequestType::Attach(_) => SpawnMode::Attach,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) struct InertState {
|
pub(crate) struct InertState {
|
||||||
focus_handle: FocusHandle,
|
focus_handle: FocusHandle,
|
||||||
selected_debugger: Option<SharedString>,
|
selected_debugger: Option<SharedString>,
|
||||||
|
@ -46,27 +55,56 @@ impl InertState {
|
||||||
pub(super) fn new(
|
pub(super) fn new(
|
||||||
workspace: WeakEntity<Workspace>,
|
workspace: WeakEntity<Workspace>,
|
||||||
default_cwd: &str,
|
default_cwd: &str,
|
||||||
|
debug_config: Option<DebugAdapterConfig>,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let selected_debugger = debug_config.as_ref().and_then(|config| match config.kind {
|
||||||
|
DebugAdapterKind::Lldb => Some("LLDB".into()),
|
||||||
|
DebugAdapterKind::Go(_) => Some("Delve".into()),
|
||||||
|
DebugAdapterKind::Php(_) => Some("PHP".into()),
|
||||||
|
DebugAdapterKind::Javascript(_) => Some("JavaScript".into()),
|
||||||
|
DebugAdapterKind::Python(_) => Some("Debugpy".into()),
|
||||||
|
_ => None,
|
||||||
|
});
|
||||||
|
|
||||||
|
let spawn_mode = debug_config
|
||||||
|
.as_ref()
|
||||||
|
.map(|config| config.request.clone().into())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let program = debug_config
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|config| config.program.to_owned());
|
||||||
|
|
||||||
let program_editor = cx.new(|cx| {
|
let program_editor = cx.new(|cx| {
|
||||||
let mut editor = Editor::single_line(window, cx);
|
let mut editor = Editor::single_line(window, cx);
|
||||||
editor.set_placeholder_text("Program path", cx);
|
if let Some(program) = program {
|
||||||
|
editor.insert(&program, window, cx);
|
||||||
|
} else {
|
||||||
|
editor.set_placeholder_text("Program path", cx);
|
||||||
|
}
|
||||||
editor
|
editor
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let cwd = debug_config
|
||||||
|
.and_then(|config| config.cwd.map(|cwd| cwd.to_owned()))
|
||||||
|
.unwrap_or_else(|| PathBuf::from(default_cwd));
|
||||||
|
|
||||||
let cwd_editor = cx.new(|cx| {
|
let cwd_editor = cx.new(|cx| {
|
||||||
let mut editor = Editor::single_line(window, cx);
|
let mut editor = Editor::single_line(window, cx);
|
||||||
editor.insert(default_cwd, window, cx);
|
editor.insert(cwd.to_str().unwrap_or_else(|| default_cwd), window, cx);
|
||||||
editor.set_placeholder_text("Working directory", cx);
|
editor.set_placeholder_text("Working directory", cx);
|
||||||
editor
|
editor
|
||||||
});
|
});
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
workspace,
|
workspace,
|
||||||
cwd_editor,
|
cwd_editor,
|
||||||
program_editor,
|
program_editor,
|
||||||
selected_debugger: None,
|
selected_debugger,
|
||||||
|
spawn_mode,
|
||||||
focus_handle: cx.focus_handle(),
|
focus_handle: cx.focus_handle(),
|
||||||
spawn_mode: SpawnMode::default(),
|
|
||||||
popover_handle: Default::default(),
|
popover_handle: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue