Skip to content

Commit

Permalink
Add loaded sources (#49)
Browse files Browse the repository at this point in the history
* Remove not needed notify

* Add loaded sources list

* Remove not needed double nested div.child()

* Remove not needed block

* Fix todo for updating loaded source
  • Loading branch information
RemcoSmitsDev authored Oct 14, 2024
1 parent b46b8aa commit 5758f66
Show file tree
Hide file tree
Showing 7 changed files with 254 additions and 27 deletions.
6 changes: 2 additions & 4 deletions crates/dap/src/transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,8 @@ impl Transport {
mut payload: Message,
) -> Result<()> {
if let Message::Request(request) = &mut payload {
{
if let Some(sender) = current_requests.lock().await.remove(&request.seq) {
pending_requests.lock().await.insert(request.seq, sender);
}
if let Some(sender) = current_requests.lock().await.remove(&request.seq) {
pending_requests.lock().await.insert(request.seq, sender);
}
}
Self::send_string_to_server(server_stdin, serde_json::to_string(&payload)?).await
Expand Down
20 changes: 15 additions & 5 deletions crates/debugger_ui/src/debugger_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use dap::debugger_settings::DebuggerSettings;
use dap::messages::{Events, Message};
use dap::requests::{Request, StartDebugging};
use dap::{
Capabilities, CapabilitiesEvent, ContinuedEvent, ExitedEvent, ModuleEvent, OutputEvent,
StoppedEvent, TerminatedEvent, ThreadEvent, ThreadEventReason,
Capabilities, CapabilitiesEvent, ContinuedEvent, ExitedEvent, LoadedSourceEvent, ModuleEvent,
OutputEvent, StoppedEvent, TerminatedEvent, ThreadEvent, ThreadEventReason,
};
use gpui::{
actions, Action, AppContext, AsyncWindowContext, EventEmitter, FocusHandle, FocusableView,
Expand Down Expand Up @@ -38,6 +38,7 @@ pub enum DebugPanelEvent {
Continued((DebugAdapterClientId, ContinuedEvent)),
Output((DebugAdapterClientId, OutputEvent)),
Module((DebugAdapterClientId, ModuleEvent)),
LoadedSource((DebugAdapterClientId, LoadedSourceEvent)),
ClientStopped(DebugAdapterClientId),
CapabilitiesChanged(DebugAdapterClientId),
}
Expand Down Expand Up @@ -258,7 +259,7 @@ impl DebugPanel {
Events::Output(event) => self.handle_output_event(&client_id, event, cx),
Events::Breakpoint(_) => {}
Events::Module(event) => self.handle_module_event(&client_id, event, cx),
Events::LoadedSource(_) => {}
Events::LoadedSource(event) => self.handle_loaded_source_event(&client_id, event, cx),
Events::Capabilities(event) => {
self.handle_capabilities_changed_event(client_id, event, cx);
}
Expand Down Expand Up @@ -497,6 +498,15 @@ impl DebugPanel {
cx.emit(DebugPanelEvent::Module((*client_id, event.clone())));
}

fn handle_loaded_source_event(
&mut self,
client_id: &DebugAdapterClientId,
event: &LoadedSourceEvent,
cx: &mut ViewContext<Self>,
) {
cx.emit(DebugPanelEvent::LoadedSource((*client_id, event.clone())));
}

fn handle_capabilities_changed_event(
&mut self,
client_id: &DebugAdapterClientId,
Expand All @@ -511,8 +521,8 @@ impl DebugPanel {
}

fn render_did_not_stop_warning(&self, cx: &mut ViewContext<Self>) -> impl IntoElement {
const TITLE: &str = "Debug session exited without hitting any breakpoints";
const DESCRIPTION: &str =
const TITLE: &'static str = "Debug session exited without hitting any breakpoints";
const DESCRIPTION: &'static str =
"Try adding a breakpoint, or define the correct path mapping for your debugger.";

div()
Expand Down
53 changes: 46 additions & 7 deletions crates/debugger_ui/src/debugger_panel_item.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use crate::console::Console;
use crate::debugger_panel::{DebugPanel, DebugPanelEvent, ThreadState};
use crate::loaded_source_list::LoadedSourceList;
use crate::module_list::ModuleList;
use crate::stack_frame_list::{StackFrameList, StackFrameListEvent};
use crate::variable_list::VariableList;

use dap::client::{DebugAdapterClientId, ThreadStatus};
use dap::debugger_settings::DebuggerSettings;
use dap::{
Capabilities, ContinuedEvent, ModuleEvent, OutputEvent, OutputEventCategory, StoppedEvent,
ThreadEvent,
Capabilities, ContinuedEvent, LoadedSourceEvent, ModuleEvent, OutputEvent, OutputEventCategory,
StoppedEvent, ThreadEvent,
};
use editor::Editor;
use gpui::{
Expand All @@ -31,10 +32,11 @@ pub enum DebugPanelItemEvent {

#[derive(Clone, PartialEq, Eq)]
enum ThreadItem {
Variables,
Modules,
Console,
LoadedSource,
Modules,
Output,
Variables,
}

pub struct DebugPanelItem {
Expand All @@ -52,6 +54,7 @@ pub struct DebugPanelItem {
variable_list: View<VariableList>,
_subscriptions: Vec<Subscription>,
stack_frame_list: View<StackFrameList>,
loaded_source_list: View<LoadedSourceList>,
}

impl DebugPanelItem {
Expand All @@ -78,6 +81,9 @@ impl DebugPanelItem {

let module_list = cx.new_view(|cx| ModuleList::new(dap_store.clone(), &client_id, cx));

let loaded_source_list =
cx.new_view(|cx| LoadedSourceList::new(&this, dap_store.clone(), &client_id, cx));

let console = cx.new_view(|cx| {
Console::new(
&stack_frame_list,
Expand Down Expand Up @@ -106,6 +112,9 @@ impl DebugPanelItem {
DebugPanelEvent::Module((client_id, event)) => {
this.handle_module_event(client_id, event, cx)
}
DebugPanelEvent::LoadedSource((client_id, event)) => {
this.handle_loaded_source_event(client_id, event, cx)
}
DebugPanelEvent::ClientStopped(client_id) => {
this.handle_client_stopped_event(client_id, cx)
}
Expand All @@ -126,7 +135,7 @@ impl DebugPanelItem {
&stack_frame_list,
move |this: &mut Self, _, event: &StackFrameListEvent, cx| match event {
StackFrameListEvent::ChangedStackFrame => this.clear_highlights(cx),
StackFrameListEvent::StackFramesUpdated => {}
_ => {}
},
),
];
Expand Down Expand Up @@ -157,6 +166,7 @@ impl DebugPanelItem {
variable_list,
_subscriptions,
stack_frame_list,
loaded_source_list,
client_id: *client_id,
client_kind: client_kind.clone(),
active_thread_item: ThreadItem::Variables,
Expand All @@ -176,8 +186,6 @@ impl DebugPanelItem {
{
self.clear_highlights(cx);
}

cx.notify();
}

fn should_skip_event(&self, client_id: &DebugAdapterClientId, thread_id: u64) -> bool {
Expand Down Expand Up @@ -275,6 +283,22 @@ impl DebugPanelItem {
});
}

fn handle_loaded_source_event(
&mut self,
client_id: &DebugAdapterClientId,
event: &LoadedSourceEvent,
cx: &mut ViewContext<Self>,
) {
if self.should_skip_event(client_id, self.thread_id) {
return;
}

self.loaded_source_list
.update(cx, |loaded_source_list, cx| {
loaded_source_list.on_loaded_source_event(event, cx);
});
}

fn handle_client_stopped_event(
&mut self,
client_id: &DebugAdapterClientId,
Expand Down Expand Up @@ -645,6 +669,18 @@ impl Render for DebugPanelItem {
))
},
)
.when(
capabilities
.supports_loaded_sources_request
.unwrap_or_default(),
|this| {
this.child(self.render_entry_button(
&SharedString::from("Loaded Sources"),
ThreadItem::LoadedSource,
cx,
))
},
)
.child(self.render_entry_button(
&SharedString::from("Console"),
ThreadItem::Console,
Expand All @@ -662,6 +698,9 @@ impl Render for DebugPanelItem {
.when(*active_thread_item == ThreadItem::Modules, |this| {
this.size_full().child(self.module_list.clone())
})
.when(*active_thread_item == ThreadItem::LoadedSource, |this| {
this.size_full().child(self.loaded_source_list.clone())
})
.when(*active_thread_item == ThreadItem::Output, |this| {
this.child(self.output_editor.clone())
})
Expand Down
1 change: 1 addition & 0 deletions crates/debugger_ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use workspace::{
mod console;
pub mod debugger_panel;
mod debugger_panel_item;
mod loaded_source_list;
mod module_list;
mod stack_frame_list;
mod variable_list;
Expand Down
155 changes: 155 additions & 0 deletions crates/debugger_ui/src/loaded_source_list.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
use anyhow::Result;
use dap::{client::DebugAdapterClientId, LoadedSourceEvent, Source};
use gpui::{
list, AnyElement, FocusHandle, FocusableView, ListState, Model, Subscription, Task, View,
};
use project::dap_store::DapStore;
use ui::prelude::*;

use crate::debugger_panel_item::{self, DebugPanelItem, DebugPanelItemEvent};

pub struct LoadedSourceList {
list: ListState,
sources: Vec<Source>,
focus_handle: FocusHandle,
dap_store: Model<DapStore>,
client_id: DebugAdapterClientId,
_subscriptions: Vec<Subscription>,
}

impl LoadedSourceList {
pub fn new(
debug_panel_item: &View<DebugPanelItem>,
dap_store: Model<DapStore>,
client_id: &DebugAdapterClientId,
cx: &mut ViewContext<Self>,
) -> Self {
let weakview = cx.view().downgrade();
let focus_handle = cx.focus_handle();

let list = ListState::new(0, gpui::ListAlignment::Top, px(1000.), move |ix, cx| {
weakview
.upgrade()
.map(|view| view.update(cx, |this, cx| this.render_entry(ix, cx)))
.unwrap_or(div().into_any())
});

let _subscriptions =
vec![cx.subscribe(debug_panel_item, Self::handle_debug_panel_item_event)];

Self {
list,
dap_store,
focus_handle,
_subscriptions,
client_id: *client_id,
sources: Vec::default(),
}
}

fn handle_debug_panel_item_event(
&mut self,
_: View<DebugPanelItem>,
event: &debugger_panel_item::DebugPanelItemEvent,
cx: &mut ViewContext<Self>,
) {
match event {
DebugPanelItemEvent::Stopped { .. } => {
self.fetch_loaded_sources(cx).detach_and_log_err(cx);
}
_ => {}
}
}

pub fn on_loaded_source_event(
&mut self,
event: &LoadedSourceEvent,
cx: &mut ViewContext<Self>,
) {
match event.reason {
dap::LoadedSourceEventReason::New => self.sources.push(event.source.clone()),
dap::LoadedSourceEventReason::Changed => {
let updated_source =
if let Some(ref_id) = event.source.source_reference.filter(|&r| r != 0) {
self.sources
.iter_mut()
.find(|s| s.source_reference == Some(ref_id))
} else if let Some(path) = &event.source.path {
self.sources
.iter_mut()
.find(|s| s.path.as_ref() == Some(path))
} else {
self.sources
.iter_mut()
.find(|s| s.name == event.source.name)
};

if let Some(loaded_source) = updated_source {
*loaded_source = event.source.clone();
}
}
dap::LoadedSourceEventReason::Removed => {
self.sources.retain(|source| *source != event.source)
}
}

self.list.reset(self.sources.len());
cx.notify();
}

fn fetch_loaded_sources(&self, cx: &mut ViewContext<Self>) -> Task<Result<()>> {
let task = self
.dap_store
.update(cx, |store, cx| store.loaded_sources(&self.client_id, cx));

cx.spawn(|this, mut cx| async move {
let mut sources = task.await?;

this.update(&mut cx, |this, cx| {
std::mem::swap(&mut this.sources, &mut sources);
this.list.reset(this.sources.len());

cx.notify();
})
})
}

fn render_entry(&mut self, ix: usize, cx: &mut ViewContext<Self>) -> AnyElement {
let source = &self.sources[ix];

v_flex()
.rounded_md()
.w_full()
.group("")
.p_1()
.hover(|s| s.bg(cx.theme().colors().element_hover))
.child(
h_flex()
.gap_0p5()
.text_ui_sm(cx)
.when_some(source.name.clone(), |this, name| this.child(name)),
)
.child(
h_flex()
.text_ui_xs(cx)
.text_color(cx.theme().colors().text_muted)
.when_some(source.path.clone(), |this, path| this.child(path)),
)
.into_any()
}
}

impl FocusableView for LoadedSourceList {
fn focus_handle(&self, _: &gpui::AppContext) -> gpui::FocusHandle {
self.focus_handle.clone()
}
}

impl Render for LoadedSourceList {
fn render(&mut self, _: &mut ViewContext<Self>) -> impl IntoElement {
div()
.size_full()
.p_1()
.child(list(self.list.clone()).size_full())
}
}
4 changes: 1 addition & 3 deletions crates/debugger_ui/src/module_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,7 @@ impl ModuleList {
h_flex()
.text_ui_xs(cx)
.text_color(cx.theme().colors().text_muted)
.when_some(module.path.clone(), |this, path| {
this.child(div().child(path))
}),
.when_some(module.path.clone(), |this, path| this.child(path)),
)
.into_any()
}
Expand Down
Loading

0 comments on commit 5758f66

Please sign in to comment.