diff --git a/assets/keymaps/default-linux.json b/assets/keymaps/default-linux.json index 471bad98df..b652f8f488 100644 --- a/assets/keymaps/default-linux.json +++ b/assets/keymaps/default-linux.json @@ -31,8 +31,6 @@ "ctrl-,": "zed::OpenSettings", "ctrl-q": "zed::Quit", "f4": "debugger::Start", - "alt-f4": "debugger::RerunLastSession", - "f5": "debugger::Continue", "shift-f5": "debugger::Stop", "ctrl-shift-f5": "debugger::Restart", "f6": "debugger::Pause", @@ -583,11 +581,24 @@ "ctrl-alt-r": "task::Rerun", "alt-t": "task::Rerun", "alt-shift-t": "task::Spawn", - "alt-shift-r": ["task::Spawn", { "reveal_target": "center" }] + "alt-shift-r": ["task::Spawn", { "reveal_target": "center" }], // also possible to spawn tasks by name: // "foo-bar": ["task::Spawn", { "task_name": "MyTask", "reveal_target": "dock" }] // or by tag: // "foo-bar": ["task::Spawn", { "task_tag": "MyTag" }], + "f5": "debugger::RerunLastSession" + } + }, + { + "context": "Workspace && debugger_running", + "bindings": { + "f5": "zed::NoAction" + } + }, + { + "context": "Workspace && debugger_stopped", + "bindings": { + "f5": "debugger::Continue" } }, { diff --git a/assets/keymaps/default-macos.json b/assets/keymaps/default-macos.json index 701311f0f6..18c4d88d22 100644 --- a/assets/keymaps/default-macos.json +++ b/assets/keymaps/default-macos.json @@ -4,8 +4,6 @@ "use_key_equivalents": true, "bindings": { "f4": "debugger::Start", - "alt-f4": "debugger::RerunLastSession", - "f5": "debugger::Continue", "shift-f5": "debugger::Stop", "shift-cmd-f5": "debugger::Restart", "f6": "debugger::Pause", @@ -635,7 +633,8 @@ "cmd-k shift-right": "workspace::SwapPaneRight", "cmd-k shift-up": "workspace::SwapPaneUp", "cmd-k shift-down": "workspace::SwapPaneDown", - "cmd-shift-x": "zed::Extensions" + "cmd-shift-x": "zed::Extensions", + "f5": "debugger::RerunLastSession" } }, { @@ -652,6 +651,20 @@ // "foo-bar": ["task::Spawn", { "task_tag": "MyTag" }], } }, + { + "context": "Workspace && debugger_running", + "use_key_equivalents": true, + "bindings": { + "f5": "zed::NoAction" + } + }, + { + "context": "Workspace && debugger_stopped", + "use_key_equivalents": true, + "bindings": { + "f5": "debugger::Continue" + } + }, // Bindings from Sublime Text { "context": "Editor", diff --git a/crates/debugger_ui/src/debugger_panel.rs b/crates/debugger_ui/src/debugger_panel.rs index ef0e476d1a..ea98b44148 100644 --- a/crates/debugger_ui/src/debugger_panel.rs +++ b/crates/debugger_ui/src/debugger_panel.rs @@ -3,9 +3,10 @@ use crate::session::DebugSession; use crate::session::running::RunningState; use crate::{ ClearAllBreakpoints, Continue, Detach, FocusBreakpointList, FocusConsole, FocusFrames, - FocusLoadedSources, FocusModules, FocusTerminal, FocusVariables, Pause, Restart, - ShowStackTrace, StepBack, StepInto, StepOut, StepOver, Stop, ToggleIgnoreBreakpoints, - ToggleSessionPicker, ToggleThreadPicker, persistence, spawn_task_or_modal, + FocusLoadedSources, FocusModules, FocusTerminal, FocusVariables, NewProcessModal, + NewProcessMode, Pause, Restart, ShowStackTrace, StepBack, StepInto, StepOut, StepOver, Stop, + ToggleIgnoreBreakpoints, ToggleSessionPicker, ToggleThreadPicker, persistence, + spawn_task_or_modal, }; use anyhow::Result; use command_palette_hooks::CommandPaletteFilter; @@ -334,10 +335,17 @@ impl DebugPanel { let Some(task_inventory) = task_store.read(cx).task_inventory() else { return; }; + let workspace = self.workspace.clone(); let Some(scenario) = task_inventory.read(cx).last_scheduled_scenario().cloned() else { + window.defer(cx, move |window, cx| { + workspace + .update(cx, |workspace, cx| { + NewProcessModal::show(workspace, window, NewProcessMode::Launch, None, cx); + }) + .ok(); + }); return; }; - let workspace = self.workspace.clone(); cx.spawn_in(window, async move |this, cx| { let task_contexts = workspace @@ -1411,4 +1419,10 @@ impl workspace::DebuggerProvider for DebuggerProvider { fn debug_scenario_scheduled_last(&self, cx: &App) -> bool { self.0.read(cx).debug_scenario_scheduled_last } + + fn active_thread_state(&self, cx: &App) -> Option { + let session = self.0.read(cx).active_session()?; + let thread = session.read(cx).running_state().read(cx).thread_id()?; + session.read(cx).session(cx).read(cx).thread_state(thread) + } } diff --git a/crates/project/src/debugger/session.rs b/crates/project/src/debugger/session.rs index 080eede5c3..86ef00e4ba 100644 --- a/crates/project/src/debugger/session.rs +++ b/crates/project/src/debugger/session.rs @@ -2194,4 +2194,8 @@ impl Session { self.shutdown(cx).detach(); } } + + pub fn thread_state(&self, thread_id: ThreadId) -> Option { + self.thread_states.thread_state(thread_id) + } } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index fc2a93cb0d..40bd6c99ee 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -68,7 +68,7 @@ pub use persistence::{ use postage::stream::Stream; use project::{ DirectoryLister, Project, ProjectEntryId, ProjectPath, ResolvedPath, Worktree, WorktreeId, - debugger::breakpoint_store::BreakpointStoreEvent, + debugger::{breakpoint_store::BreakpointStoreEvent, session::ThreadStatus}, }; use remote::{SshClientDelegate, SshConnectionOptions, ssh_session::ConnectionIdentifier}; use schemars::JsonSchema; @@ -161,6 +161,8 @@ pub trait DebuggerProvider { fn task_scheduled(&self, cx: &mut App); fn debug_scenario_scheduled(&self, cx: &mut App); fn debug_scenario_scheduled_last(&self, cx: &App) -> bool; + + fn active_thread_state(&self, cx: &App) -> Option; } actions!( @@ -202,6 +204,7 @@ actions!( Unfollow, Welcome, RestoreBanner, + ToggleExpandItem, ] ); @@ -5802,6 +5805,20 @@ impl Render for Workspace { let mut context = KeyContext::new_with_defaults(); context.add("Workspace"); context.set("keyboard_layout", cx.keyboard_layout().name().to_string()); + if let Some(status) = self + .debugger_provider + .as_ref() + .and_then(|provider| provider.active_thread_state(cx)) + { + match status { + ThreadStatus::Running | ThreadStatus::Stepping => { + context.add("debugger_running"); + } + ThreadStatus::Stopped => context.add("debugger_stopped"), + ThreadStatus::Exited | ThreadStatus::Ended => {} + } + } + let centered_layout = self.centered_layout && self.center.panes().len() == 1 && self.active_item(cx).is_some();