Skip to content

Commit

Permalink
Implement stdio debugger connection type (#5)
Browse files Browse the repository at this point in the history
* Add support for DAP to use std for communication

* Add more descriptive error logs for DAP

* Implement handler for continued event

* Add PR feedback to handle_continued_event function
  • Loading branch information
Anthony-Eid authored and RemcoSmitsDev committed Jul 15, 2024
1 parent 77a3143 commit ffa0609
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 13 deletions.
49 changes: 42 additions & 7 deletions crates/dap/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,49 @@ impl DebugAdapterClient {
}

async fn create_stdio_client(
_id: DebugAdapterClientId,
_config: DebugAdapterConfig,
_command: &str,
_args: Vec<&str>,
_project_path: PathBuf,
_cx: &mut AsyncAppContext,
id: DebugAdapterClientId,
config: DebugAdapterConfig,
command: &str,
args: Vec<&str>,
project_path: PathBuf,
cx: &mut AsyncAppContext,
) -> Result<Self> {
todo!("not implemented")
let mut command = process::Command::new(command);
command
.current_dir(project_path)
.args(args)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.kill_on_drop(true);

let mut process = command
.spawn()
.with_context(|| "failed to spawn command.")?;

// give the adapter some time to start std
cx.background_executor()
.timer(Duration::from_millis(1000))
.await;

let stdin = process
.stdin
.take()
.ok_or_else(|| anyhow!("Failed to open stdin"))?;
let stdout = process
.stdout
.take()
.ok_or_else(|| anyhow!("Failed to open stdout"))?;
let stderr = process
.stderr
.take()
.ok_or_else(|| anyhow!("Failed to open stderr"))?;

let stdin = Box::new(stdin);
let stdout = Box::new(BufReader::new(stdout));
let stderr = Box::new(BufReader::new(stderr));

Self::handle_transport(id, config, stdout, stdin, Some(stderr), Some(process), cx)
}

pub fn handle_transport(
Expand Down
4 changes: 2 additions & 2 deletions crates/dap/src/transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ impl Transport {
loop {
buffer.truncate(0);
if reader.read_line(buffer).await? == 0 {
return Err(anyhow!("stream closed"));
return Err(anyhow!("reader stream closed"));
};

if buffer == "\r\n" {
Expand Down Expand Up @@ -140,7 +140,7 @@ impl Transport {
) -> Result<()> {
buffer.truncate(0);
if err.read_line(buffer).await? == 0 {
return Err(anyhow!("stream closed"));
return Err(anyhow!("error stream closed"));
};

Ok(())
Expand Down
28 changes: 24 additions & 4 deletions crates/debugger_ui/src/debugger_panel.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use anyhow::Result;
use dap::client::{DebugAdapterClientId, ThreadState, ThreadStatus};
use dap::client::{self, DebugAdapterClientId, ThreadState, ThreadStatus};
use dap::requests::{Disconnect, Scopes, StackTrace, Variables};
use dap::{client::DebugAdapterClient, transport::Events};
use dap::{
DisconnectArguments, Scope, ScopesArguments, StackFrame, StackTraceArguments, StoppedEvent,
TerminatedEvent, ThreadEvent, ThreadEventReason, Variable, VariablesArguments,
ContinuedEvent, DisconnectArguments, Scope, ScopesArguments, StackFrame, StackTraceArguments,
StoppedEvent, TerminatedEvent, ThreadEvent, ThreadEventReason, Variable, VariablesArguments,
};
use editor::Editor;
use futures::future::try_join_all;
Expand Down Expand Up @@ -134,7 +134,7 @@ impl DebugPanel {
.detach_and_log_err(cx);
}
Events::Stopped(event) => Self::handle_stopped_event(this, client_id, event, cx),
Events::Continued(_) => {}
Events::Continued(event) => Self::handle_continued_event(this, client_id, event, cx),
Events::Exited(_) => {}
Events::Terminated(event) => Self::handle_terminated_event(this, client_id, event, cx),
Events::Thread(event) => Self::handle_thread_event(this, client_id, event, cx),
Expand Down Expand Up @@ -272,6 +272,26 @@ impl DebugPanel {
})
}

fn handle_continued_event(
this: &mut Self,
client_id: &DebugAdapterClientId,
event: &ContinuedEvent,
cx: &mut ViewContext<Self>,
) {
let all_threads = event.all_threads_continued.unwrap_or(false);
let client = this.debug_client_by_id(*client_id, cx);

if all_threads {
for thread in client.thread_states().values_mut() {
thread.status = ThreadStatus::Running;
}
} else {
client.update_thread_state_status(event.thread_id, ThreadStatus::Running);
}

cx.notify();
}

fn handle_stopped_event(
this: &mut Self,
client_id: &DebugAdapterClientId,
Expand Down

0 comments on commit ffa0609

Please sign in to comment.