Start improving support for keyboard-driven debugging (#29380)
Closes #ISSUE Release Notes: - N/A --------- Co-authored-by: Piotr Osiewicz <peterosiewicz@gmail.com> Co-authored-by: Anthony Eid <hello@anthonyeid.me>
This commit is contained in:
co-authored by
Piotr Osiewicz
Anthony Eid
parent
7f5c874a38
commit
7623fce4b4
@@ -37,8 +37,8 @@ use ui::{
|
||||
use util::ResultExt;
|
||||
use variable_list::VariableList;
|
||||
use workspace::{
|
||||
ActivePaneDecorator, DraggedTab, Item, ItemHandle, Member, Pane, PaneGroup, Workspace,
|
||||
item::TabContentParams, move_item, pane::Event,
|
||||
ActivePaneDecorator, DraggedTab, Item, ItemHandle, Member, Pane, PaneGroup, SplitDirection,
|
||||
Workspace, item::TabContentParams, move_item, pane::Event,
|
||||
};
|
||||
|
||||
pub struct RunningState {
|
||||
@@ -57,6 +57,7 @@ pub struct RunningState {
|
||||
_console: Entity<Console>,
|
||||
breakpoint_list: Entity<BreakpointList>,
|
||||
panes: PaneGroup,
|
||||
active_pane: Option<Entity<Pane>>,
|
||||
pane_close_subscriptions: HashMap<EntityId, Subscription>,
|
||||
_schedule_serialize: Option<Task<()>>,
|
||||
}
|
||||
@@ -167,8 +168,14 @@ impl Item for SubView {
|
||||
}
|
||||
|
||||
impl Render for SubView {
|
||||
fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
|
||||
v_flex().size_full().child(self.inner.clone())
|
||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
v_flex()
|
||||
.size_full()
|
||||
.when(self.pane_focus_handle.contains_focused(window, cx), |el| {
|
||||
// TODO better way of showing focus?
|
||||
el.border_1().border_color(gpui::red())
|
||||
})
|
||||
.child(self.inner.clone())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -576,6 +583,7 @@ impl RunningState {
|
||||
stack_frame_list,
|
||||
session_id,
|
||||
panes,
|
||||
active_pane: None,
|
||||
module_list,
|
||||
_console: console,
|
||||
breakpoint_list,
|
||||
@@ -616,7 +624,7 @@ impl RunningState {
|
||||
fn create_sub_view(
|
||||
&self,
|
||||
item_kind: DebuggerPaneItem,
|
||||
pane: &Entity<Pane>,
|
||||
_pane: &Entity<Pane>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Box<dyn ItemHandle> {
|
||||
match item_kind {
|
||||
@@ -624,7 +632,7 @@ impl RunningState {
|
||||
let weak_console = self._console.clone().downgrade();
|
||||
|
||||
Box::new(SubView::new(
|
||||
pane.focus_handle(cx),
|
||||
self._console.focus_handle(cx),
|
||||
self._console.clone().into(),
|
||||
item_kind,
|
||||
Some(Box::new(move |cx| {
|
||||
@@ -784,6 +792,9 @@ impl RunningState {
|
||||
debug_assert!(_did_find_pane);
|
||||
cx.notify();
|
||||
}
|
||||
Event::Focus => {
|
||||
this.active_pane = Some(source_pane.clone());
|
||||
}
|
||||
Event::ZoomIn => {
|
||||
source_pane.update(cx, |pane, cx| {
|
||||
pane.set_zoomed(true, cx);
|
||||
@@ -800,6 +811,27 @@ impl RunningState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn activate_pane_in_direction(
|
||||
&mut self,
|
||||
direction: SplitDirection,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if let Some(pane) = self
|
||||
.active_pane
|
||||
.as_ref()
|
||||
.and_then(|pane| self.panes.find_pane_in_direction(pane, direction, cx))
|
||||
{
|
||||
window.focus(&pane.focus_handle(cx));
|
||||
} else {
|
||||
self.workspace
|
||||
.update(cx, |workspace, cx| {
|
||||
workspace.activate_pane_in_direction(direction, window, cx)
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn go_to_selected_stack_frame(&self, window: &Window, cx: &mut Context<Self>) {
|
||||
if self.thread_id.is_some() {
|
||||
self.stack_frame_list
|
||||
@@ -838,8 +870,7 @@ impl RunningState {
|
||||
&self.module_list
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn activate_modules_list(&self, window: &mut Window, cx: &mut App) {
|
||||
pub(crate) fn activate_item(&self, item: DebuggerPaneItem, window: &mut Window, cx: &mut App) {
|
||||
let (variable_list_position, pane) = self
|
||||
.panes
|
||||
.panes()
|
||||
@@ -847,7 +878,7 @@ impl RunningState {
|
||||
.find_map(|pane| {
|
||||
pane.read(cx)
|
||||
.items_of_type::<SubView>()
|
||||
.position(|view| view.read(cx).view_kind().to_shared_string() == *"Modules")
|
||||
.position(|view| view.read(cx).view_kind() == item)
|
||||
.map(|view| (view, pane))
|
||||
})
|
||||
.unwrap();
|
||||
@@ -855,6 +886,7 @@ impl RunningState {
|
||||
this.activate_item(variable_list_position, true, true, window, cx);
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn variable_list(&self) -> &Entity<VariableList> {
|
||||
&self.variable_list
|
||||
|
||||
@@ -45,6 +45,7 @@ impl Focusable for BreakpointList {
|
||||
self.focus_handle.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl BreakpointList {
|
||||
pub(super) fn new(
|
||||
session: Entity<Session>,
|
||||
@@ -213,6 +214,7 @@ impl Render for BreakpointList {
|
||||
}
|
||||
v_flex()
|
||||
.id("breakpoint-list")
|
||||
.track_focus(&self.focus_handle)
|
||||
.on_hover(cx.listener(|this, hovered, window, cx| {
|
||||
if *hovered {
|
||||
this.show_scrollbar = true;
|
||||
|
||||
@@ -7,7 +7,9 @@ use collections::HashMap;
|
||||
use dap::OutputEvent;
|
||||
use editor::{CompletionProvider, Editor, EditorElement, EditorStyle, ExcerptId};
|
||||
use fuzzy::StringMatchCandidate;
|
||||
use gpui::{Context, Entity, Render, Subscription, Task, TextStyle, WeakEntity};
|
||||
use gpui::{
|
||||
Context, Entity, FocusHandle, Focusable, Render, Subscription, Task, TextStyle, WeakEntity,
|
||||
};
|
||||
use language::{Buffer, CodeLabel, ToOffset};
|
||||
use menu::Confirm;
|
||||
use project::{
|
||||
@@ -28,6 +30,7 @@ pub struct Console {
|
||||
stack_frame_list: Entity<StackFrameList>,
|
||||
last_token: OutputToken,
|
||||
update_output_task: Task<()>,
|
||||
focus_handle: FocusHandle,
|
||||
}
|
||||
|
||||
impl Console {
|
||||
@@ -56,6 +59,7 @@ impl Console {
|
||||
editor.set_show_edit_predictions(Some(false), window, cx);
|
||||
editor
|
||||
});
|
||||
let focus_handle = cx.focus_handle();
|
||||
|
||||
let this = cx.weak_entity();
|
||||
let query_bar = cx.new(|cx| {
|
||||
@@ -82,6 +86,7 @@ impl Console {
|
||||
stack_frame_list,
|
||||
update_output_task: Task::ready(()),
|
||||
last_token: OutputToken(0),
|
||||
focus_handle,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,6 +235,7 @@ impl Render for Console {
|
||||
});
|
||||
|
||||
v_flex()
|
||||
.track_focus(&self.focus_handle)
|
||||
.key_context("DebugConsole")
|
||||
.on_action(cx.listener(Self::evaluate))
|
||||
.size_full()
|
||||
@@ -242,6 +248,12 @@ impl Render for Console {
|
||||
}
|
||||
}
|
||||
|
||||
impl Focusable for Console {
|
||||
fn focus_handle(&self, _cx: &App) -> gpui::FocusHandle {
|
||||
self.focus_handle.clone()
|
||||
}
|
||||
}
|
||||
|
||||
struct ConsoleQueryBarCompletionProvider(WeakEntity<Console>);
|
||||
|
||||
impl CompletionProvider for ConsoleQueryBarCompletionProvider {
|
||||
|
||||
@@ -132,13 +132,6 @@ impl StackFrameList {
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn _get_main_stack_frame_id(&self, cx: &mut Context<Self>) -> u64 {
|
||||
self.stack_frames(cx)
|
||||
.first()
|
||||
.map(|stack_frame| stack_frame.dap.id)
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn selected_stack_frame_id(&self) -> Option<StackFrameId> {
|
||||
self.selected_stack_frame_id
|
||||
}
|
||||
@@ -557,6 +550,7 @@ impl StackFrameList {
|
||||
impl Render for StackFrameList {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
div()
|
||||
.track_focus(&self.focus_handle)
|
||||
.size_full()
|
||||
.p_1()
|
||||
.child(list(self.list.clone()).size_full())
|
||||
|
||||
@@ -929,12 +929,12 @@ impl Render for VariableList {
|
||||
self.build_entries(cx);
|
||||
|
||||
v_flex()
|
||||
.track_focus(&self.focus_handle)
|
||||
.key_context("VariableList")
|
||||
.id("variable-list")
|
||||
.group("variable-list")
|
||||
.overflow_y_scroll()
|
||||
.size_full()
|
||||
.track_focus(&self.focus_handle(cx))
|
||||
.on_action(cx.listener(Self::select_first))
|
||||
.on_action(cx.listener(Self::select_last))
|
||||
.on_action(cx.listener(Self::select_prev))
|
||||
|
||||
Reference in New Issue
Block a user