Skip to content

Commit d9498b4

Browse files
authored
debugger_ui: Improve some elements of the UI (#43344)
- In the launch tab of the new session mode, I've switched it to use the `InputField` component instead given that had all that we needed already. Allows for removing a good chunk of editor-related code - Also in the launch tab, added support for keyboard navigation between all of the elements there (dropdown, inputs, and switch component) - Added some simple an empty state treatment for the breakpoint column when there are none set https://github.com/user-attachments/assets/a441aa8a-360b-4e38-839f-786315a8a235 Release Notes: - debugger: Made the input elements within the launch tab in the new session modal keyboard navigable˙.
1 parent 7a5851e commit d9498b4

File tree

6 files changed

+88
-93
lines changed

6 files changed

+88
-93
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/debugger_ui/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ theme.workspace = true
7070
tree-sitter-json.workspace = true
7171
tree-sitter.workspace = true
7272
ui.workspace = true
73+
ui_input.workspace = true
7374
unindent = { workspace = true, optional = true }
7475
util.workspace = true
7576
workspace.workspace = true

crates/debugger_ui/src/debugger_panel.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,7 +1692,7 @@ impl Render for DebugPanel {
16921692
.child(
16931693
Button::new("spawn-new-session-empty-state", "New Session")
16941694
.icon(IconName::Plus)
1695-
.icon_size(IconSize::XSmall)
1695+
.icon_size(IconSize::Small)
16961696
.icon_color(Color::Muted)
16971697
.icon_position(IconPosition::Start)
16981698
.on_click(|_, window, cx| {
@@ -1702,8 +1702,7 @@ impl Render for DebugPanel {
17021702
.child(
17031703
Button::new("edit-debug-settings", "Edit debug.json")
17041704
.icon(IconName::Code)
1705-
.icon_size(IconSize::XSmall)
1706-
.color(Color::Muted)
1705+
.icon_size(IconSize::Small)
17071706
.icon_color(Color::Muted)
17081707
.icon_position(IconPosition::Start)
17091708
.on_click(|_, window, cx| {
@@ -1716,8 +1715,7 @@ impl Render for DebugPanel {
17161715
.child(
17171716
Button::new("open-debugger-docs", "Debugger Docs")
17181717
.icon(IconName::Book)
1719-
.color(Color::Muted)
1720-
.icon_size(IconSize::XSmall)
1718+
.icon_size(IconSize::Small)
17211719
.icon_color(Color::Muted)
17221720
.icon_position(IconPosition::Start)
17231721
.on_click(|_, _, cx| cx.open_url("https://zed.dev/docs/debugger")),
@@ -1728,8 +1726,7 @@ impl Render for DebugPanel {
17281726
"Debugger Extensions",
17291727
)
17301728
.icon(IconName::Blocks)
1731-
.color(Color::Muted)
1732-
.icon_size(IconSize::XSmall)
1729+
.icon_size(IconSize::Small)
17331730
.icon_color(Color::Muted)
17341731
.icon_position(IconPosition::Start)
17351732
.on_click(|_, window, cx| {
@@ -1746,6 +1743,15 @@ impl Render for DebugPanel {
17461743
}),
17471744
);
17481745

1746+
let has_breakpoints = self
1747+
.project
1748+
.read(cx)
1749+
.breakpoint_store()
1750+
.read(cx)
1751+
.all_source_breakpoints(cx)
1752+
.values()
1753+
.any(|breakpoints| !breakpoints.is_empty());
1754+
17491755
let breakpoint_list = v_flex()
17501756
.group("base-breakpoint-list")
17511757
.when_else(
@@ -1769,7 +1775,18 @@ impl Render for DebugPanel {
17691775
),
17701776
),
17711777
)
1772-
.child(self.breakpoint_list.clone());
1778+
.when(has_breakpoints, |this| {
1779+
this.child(self.breakpoint_list.clone())
1780+
})
1781+
.when(!has_breakpoints, |this| {
1782+
this.child(
1783+
v_flex().size_full().items_center().justify_center().child(
1784+
Label::new("No Breakpoints Set")
1785+
.size(LabelSize::Small)
1786+
.color(Color::Muted),
1787+
),
1788+
)
1789+
});
17731790

17741791
this.child(
17751792
v_flex()

crates/debugger_ui/src/new_process_modal.rs

Lines changed: 50 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,22 @@ use tasks_ui::{TaskOverrides, TasksModal};
1212
use dap::{
1313
DapRegistry, DebugRequest, TelemetrySpawnLocation, adapters::DebugAdapterName, send_telemetry,
1414
};
15-
use editor::{Editor, EditorElement, EditorStyle};
15+
use editor::Editor;
1616
use fuzzy::{StringMatch, StringMatchCandidate};
1717
use gpui::{
1818
Action, App, AppContext, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable,
19-
KeyContext, Render, Subscription, Task, TextStyle, WeakEntity,
19+
KeyContext, Render, Subscription, Task, WeakEntity,
2020
};
2121
use itertools::Itertools as _;
2222
use picker::{Picker, PickerDelegate, highlighted_match_with_paths::HighlightedMatch};
2323
use project::{DebugScenarioContext, Project, TaskContexts, TaskSourceKind, task_store::TaskStore};
24-
use settings::Settings;
2524
use task::{DebugScenario, RevealTarget, VariableName, ZedDebugConfig};
26-
use theme::ThemeSettings;
2725
use ui::{
2826
ContextMenu, DropdownMenu, FluentBuilder, IconWithIndicator, Indicator, KeyBinding, ListItem,
2927
ListItemSpacing, Switch, SwitchLabelPosition, ToggleButtonGroup, ToggleButtonSimple,
3028
ToggleState, Tooltip, prelude::*,
3129
};
30+
use ui_input::InputField;
3231
use util::{ResultExt, debug_panic, rel_path::RelPath, shell::ShellKind};
3332
use workspace::{ModalView, Workspace, notifications::DetachAndPromptErr, pane};
3433

@@ -448,7 +447,7 @@ impl NewProcessModal {
448447
&mut self,
449448
window: &mut Window,
450449
cx: &mut Context<Self>,
451-
) -> ui::DropdownMenu {
450+
) -> DropdownMenu {
452451
let workspace = self.workspace.clone();
453452
let weak = cx.weak_entity();
454453
let active_buffer = self.task_contexts(cx).and_then(|tc| {
@@ -508,6 +507,13 @@ impl NewProcessModal {
508507
menu
509508
}),
510509
)
510+
.style(ui::DropdownStyle::Outlined)
511+
.tab_index(0)
512+
.attach(gpui::Corner::BottomLeft)
513+
.offset(gpui::Point {
514+
x: px(0.0),
515+
y: px(2.0),
516+
})
511517
}
512518
}
513519

@@ -540,44 +546,6 @@ impl Focusable for NewProcessMode {
540546
}
541547
}
542548

543-
fn render_editor(editor: &Entity<Editor>, window: &mut Window, cx: &App) -> impl IntoElement {
544-
let settings = ThemeSettings::get_global(cx);
545-
let theme = cx.theme();
546-
547-
let text_style = TextStyle {
548-
color: cx.theme().colors().text,
549-
font_family: settings.buffer_font.family.clone(),
550-
font_features: settings.buffer_font.features.clone(),
551-
font_size: settings.buffer_font_size(cx).into(),
552-
font_weight: settings.buffer_font.weight,
553-
line_height: relative(settings.buffer_line_height.value()),
554-
background_color: Some(theme.colors().editor_background),
555-
..Default::default()
556-
};
557-
558-
let element = EditorElement::new(
559-
editor,
560-
EditorStyle {
561-
background: theme.colors().editor_background,
562-
local_player: theme.players().local(),
563-
text: text_style,
564-
..Default::default()
565-
},
566-
);
567-
568-
div()
569-
.rounded_md()
570-
.p_1()
571-
.border_1()
572-
.border_color(theme.colors().border_variant)
573-
.when(
574-
editor.focus_handle(cx).contains_focused(window, cx),
575-
|this| this.border_color(theme.colors().border_focused),
576-
)
577-
.child(element)
578-
.bg(theme.colors().editor_background)
579-
}
580-
581549
impl Render for NewProcessModal {
582550
fn render(
583551
&mut self,
@@ -788,22 +756,26 @@ impl RenderOnce for AttachMode {
788756

789757
#[derive(Clone)]
790758
pub(super) struct ConfigureMode {
791-
program: Entity<Editor>,
792-
cwd: Entity<Editor>,
759+
program: Entity<InputField>,
760+
cwd: Entity<InputField>,
793761
stop_on_entry: ToggleState,
794762
save_to_debug_json: ToggleState,
795763
}
796764

797765
impl ConfigureMode {
798766
pub(super) fn new(window: &mut Window, cx: &mut App) -> Entity<Self> {
799-
let program = cx.new(|cx| Editor::single_line(window, cx));
800-
program.update(cx, |this, cx| {
801-
this.set_placeholder_text("ENV=Zed ~/bin/program --option", window, cx);
767+
let program = cx.new(|cx| {
768+
InputField::new(window, cx, "ENV=Zed ~/bin/program --option")
769+
.label("Program")
770+
.tab_stop(true)
771+
.tab_index(1)
802772
});
803773

804-
let cwd = cx.new(|cx| Editor::single_line(window, cx));
805-
cwd.update(cx, |this, cx| {
806-
this.set_placeholder_text("Ex: $ZED_WORKTREE_ROOT", window, cx);
774+
let cwd = cx.new(|cx| {
775+
InputField::new(window, cx, "Ex: $ZED_WORKTREE_ROOT")
776+
.label("Working Directory")
777+
.tab_stop(true)
778+
.tab_index(2)
807779
});
808780

809781
cx.new(|_| Self {
@@ -815,9 +787,9 @@ impl ConfigureMode {
815787
}
816788

817789
fn load(&mut self, cwd: PathBuf, window: &mut Window, cx: &mut App) {
818-
self.cwd.update(cx, |editor, cx| {
819-
if editor.is_empty(cx) {
820-
editor.set_text(cwd.to_string_lossy(), window, cx);
790+
self.cwd.update(cx, |input_field, cx| {
791+
if input_field.is_empty(cx) {
792+
input_field.set_text(cwd.to_string_lossy(), window, cx);
821793
}
822794
});
823795
}
@@ -868,49 +840,44 @@ impl ConfigureMode {
868840
}
869841
}
870842

843+
fn on_tab(&mut self, _: &menu::SelectNext, window: &mut Window, _: &mut Context<Self>) {
844+
window.focus_next();
845+
}
846+
847+
fn on_tab_prev(
848+
&mut self,
849+
_: &menu::SelectPrevious,
850+
window: &mut Window,
851+
_: &mut Context<Self>,
852+
) {
853+
window.focus_prev();
854+
}
855+
871856
fn render(
872857
&mut self,
873858
adapter_menu: DropdownMenu,
874-
window: &mut Window,
859+
_: &mut Window,
875860
cx: &mut ui::Context<Self>,
876861
) -> impl IntoElement {
877862
v_flex()
863+
.tab_group()
864+
.track_focus(&self.program.focus_handle(cx))
865+
.on_action(cx.listener(Self::on_tab))
866+
.on_action(cx.listener(Self::on_tab_prev))
878867
.p_2()
879868
.w_full()
880-
.gap_2()
881-
.track_focus(&self.program.focus_handle(cx))
869+
.gap_3()
882870
.child(
883871
h_flex()
884-
.gap_2()
885-
.child(
886-
Label::new("Debugger")
887-
.size(LabelSize::Small)
888-
.color(Color::Muted),
889-
)
872+
.gap_1()
873+
.child(Label::new("Debugger:").color(Color::Muted))
890874
.child(adapter_menu),
891875
)
892-
.child(
893-
v_flex()
894-
.gap_0p5()
895-
.child(
896-
Label::new("Program")
897-
.size(LabelSize::Small)
898-
.color(Color::Muted),
899-
)
900-
.child(render_editor(&self.program, window, cx)),
901-
)
902-
.child(
903-
v_flex()
904-
.gap_0p5()
905-
.child(
906-
Label::new("Working Directory")
907-
.size(LabelSize::Small)
908-
.color(Color::Muted),
909-
)
910-
.child(render_editor(&self.cwd, window, cx)),
911-
)
876+
.child(self.program.clone())
877+
.child(self.cwd.clone())
912878
.child(
913879
Switch::new("debugger-stop-on-entry", self.stop_on_entry)
880+
.tab_index(3_isize)
914881
.label("Stop on Entry")
915882
.label_position(SwitchLabelPosition::Start)
916883
.label_size(LabelSize::Default)

crates/debugger_ui/src/session/running/breakpoint_list.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1407,7 +1407,6 @@ impl RenderOnce for BreakpointOptionsStrip {
14071407

14081408
h_flex()
14091409
.gap_px()
1410-
.mr_3() // Space to avoid overlapping with the scrollbar
14111410
.justify_end()
14121411
.when(has_logs || self.is_selected, |this| {
14131412
this.child(

crates/ui_input/src/input_field.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,20 @@ impl InputField {
120120
self.editor().read(cx).text(cx)
121121
}
122122

123+
pub fn clear(&self, window: &mut Window, cx: &mut App) {
124+
self.editor()
125+
.update(cx, |editor, cx| editor.clear(window, cx))
126+
}
127+
123128
pub fn set_text(&self, text: impl Into<Arc<str>>, window: &mut Window, cx: &mut App) {
124129
self.editor()
125130
.update(cx, |editor, cx| editor.set_text(text, window, cx))
126131
}
127132
}
128133

129134
impl Render for InputField {
130-
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
135+
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
136+
let editor = self.editor.clone();
131137
let settings = ThemeSettings::get_global(cx);
132138
let theme_color = cx.theme().colors();
133139

@@ -206,6 +212,10 @@ impl Render for InputField {
206212
.bg(style.background_color)
207213
.border_1()
208214
.border_color(style.border_color)
215+
.when(
216+
editor.focus_handle(cx).contains_focused(window, cx),
217+
|this| this.border_color(theme_color.border_focused),
218+
)
209219
.when_some(self.start_icon, |this, icon| {
210220
this.gap_1()
211221
.child(Icon::new(icon).size(IconSize::Small).color(Color::Muted))

0 commit comments

Comments
 (0)