debugger: Add console indicator and resolve debug configs from NewSessionModal (#28489)

The debug console will now show an indicator when it's unopened and
there's unread messages.

`NewSessionModal` attempts to resolve debug configurations before using
the config to start debugging. This allows users to use zed's task
variables in the modal prompt.

I had to invert tasks_ui dependency on debugger_ui so `NewSessionModal`
could get the correct `TaskContexts` by calling tasks_ui functions. A
consequence of this workspace has a new event `ShowAttachModal` that I'm
not a big fan of. @osiewicz if you have time could you please take a
look to see if there's a way around adding the event. I'm open to pair
on it too.

Release Notes:

- N/A
This commit is contained in:
Anthony Eid 2025-04-10 18:29:03 -04:00 committed by GitHub
parent 66dd6726df
commit cf65d9437a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 204 additions and 82 deletions

View file

@ -26,8 +26,8 @@ use rpc::proto::ViewId;
use settings::Settings;
use stack_frame_list::StackFrameList;
use ui::{
App, Context, ContextMenu, DropdownMenu, InteractiveElement, IntoElement, ParentElement,
Render, SharedString, Styled, Window, div, h_flex, v_flex,
AnyElement, App, Context, ContextMenu, DropdownMenu, InteractiveElement, IntoElement, Label,
LabelCommon as _, ParentElement, Render, SharedString, Styled, Window, div, h_flex, v_flex,
};
use util::ResultExt;
use variable_list::VariableList;
@ -86,6 +86,7 @@ struct SubView {
inner: AnyView,
pane_focus_handle: FocusHandle,
tab_name: SharedString,
show_indicator: Box<dyn Fn(&App) -> bool>,
}
impl SubView {
@ -93,12 +94,14 @@ impl SubView {
pane_focus_handle: FocusHandle,
view: AnyView,
tab_name: SharedString,
show_indicator: Option<Box<dyn Fn(&App) -> bool>>,
cx: &mut App,
) -> Entity<Self> {
cx.new(|_| Self {
tab_name,
inner: view,
pane_focus_handle,
show_indicator: show_indicator.unwrap_or(Box::new(|_| false)),
})
}
}
@ -110,8 +113,27 @@ impl Focusable for SubView {
impl EventEmitter<()> for SubView {}
impl Item for SubView {
type Event = ();
fn tab_content_text(&self, _window: &Window, _cx: &App) -> Option<SharedString> {
Some(self.tab_name.clone())
fn tab_content(
&self,
params: workspace::item::TabContentParams,
_: &Window,
cx: &App,
) -> AnyElement {
let label = Label::new(self.tab_name.clone())
.color(params.text_color())
.into_any_element();
if !params.selected && self.show_indicator.as_ref()(cx) {
return h_flex()
.justify_between()
.child(ui::Indicator::dot())
.gap_2()
.child(label)
.into_any_element();
}
label
}
}
@ -315,6 +337,7 @@ impl RunningState {
this.focus_handle(cx),
stack_frame_list.clone().into(),
SharedString::new_static("Frames"),
None,
cx,
)),
true,
@ -329,6 +352,7 @@ impl RunningState {
breakpoints.focus_handle(cx),
breakpoints.into(),
SharedString::new_static("Breakpoints"),
None,
cx,
)),
true,
@ -346,6 +370,7 @@ impl RunningState {
variable_list.focus_handle(cx),
variable_list.clone().into(),
SharedString::new_static("Variables"),
None,
cx,
)),
true,
@ -359,6 +384,7 @@ impl RunningState {
this.focus_handle(cx),
module_list.clone().into(),
SharedString::new_static("Modules"),
None,
cx,
)),
false,
@ -371,11 +397,17 @@ impl RunningState {
});
let rightmost_pane = new_debugger_pane(workspace.clone(), project.clone(), window, cx);
rightmost_pane.update(cx, |this, cx| {
let weak_console = console.downgrade();
this.add_item(
Box::new(SubView::new(
this.focus_handle(cx),
console.clone().into(),
SharedString::new_static("Console"),
Some(Box::new(move |cx| {
weak_console
.read_with(cx, |console, cx| console.show_indicator(cx))
.unwrap_or_default()
})),
cx,
)),
true,