aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--helix-dap/src/lib.rs3
-rw-r--r--helix-dap/src/transport.rs13
-rw-r--r--helix-dap/src/types.rs133
-rw-r--r--helix-term/src/application.rs49
4 files changed, 158 insertions, 40 deletions
diff --git a/helix-dap/src/lib.rs b/helix-dap/src/lib.rs
index 64cc87cc..f60b102c 100644
--- a/helix-dap/src/lib.rs
+++ b/helix-dap/src/lib.rs
@@ -3,7 +3,8 @@ mod transport;
mod types;
pub use client::Client;
-pub use transport::{Event, Payload, Response, Transport};
+pub use events::Event;
+pub use transport::{Payload, Response, Transport};
pub use types::*;
use thiserror::Error;
diff --git a/helix-dap/src/transport.rs b/helix-dap/src/transport.rs
index 062e0447..afb7694d 100644
--- a/helix-dap/src/transport.rs
+++ b/helix-dap/src/transport.rs
@@ -1,4 +1,4 @@
-use crate::{Error, Result};
+use crate::{Error, Event, Result};
use anyhow::Context;
use log::{error, info, warn};
use serde::{Deserialize, Serialize};
@@ -32,13 +32,6 @@ pub struct Response {
pub body: Option<Value>,
}
-#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
-pub struct Event {
- // seq is omitted as unused and is not sent by some implementations
- pub event: String,
- pub body: Option<Value>,
-}
-
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum Payload {
@@ -208,8 +201,8 @@ impl Transport {
client_tx.send(msg).expect("Failed to send");
Ok(())
}
- Payload::Event(Event { ref event, .. }) => {
- info!("<- DAP event {}", event);
+ Payload::Event(ref event) => {
+ info!("<- DAP event {:?}", event);
client_tx.send(msg).expect("Failed to send");
Ok(())
}
diff --git a/helix-dap/src/types.rs b/helix-dap/src/types.rs
index 3fd858de..fcbbf184 100644
--- a/helix-dap/src/types.rs
+++ b/helix-dap/src/types.rs
@@ -206,6 +206,21 @@ pub struct Variable {
pub memory_reference: Option<String>,
}
+#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct Module {
+ pub id: String, // TODO: || number
+ pub name: String,
+ pub path: Option<PathBuf>,
+ pub is_optimized: Option<bool>,
+ pub is_user_code: Option<bool>,
+ pub version: Option<String>,
+ pub symbol_status: Option<String>,
+ pub symbol_file_path: Option<String>,
+ pub date_time_stamp: Option<String>,
+ pub address_range: Option<String>,
+}
+
pub mod requests {
use super::*;
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
@@ -411,6 +426,69 @@ pub mod requests {
pub mod events {
use super::*;
+
+ #[derive(Debug, Clone, Serialize, Deserialize)]
+ #[serde(rename_all = "camelCase")]
+ #[serde(tag = "event", content = "body")]
+ // seq is omitted as unused and is not sent by some implementations
+ pub enum Event {
+ Initialized,
+ Stopped(Stopped),
+ Continued(Continued),
+ Exited(Exited),
+ Terminated(Terminated),
+ Thread(Thread),
+ Output(Output),
+ Breakpoint(Breakpoint),
+ Module(Module),
+ LoadedSource(LoadedSource),
+ Process(Process),
+ Capabilities(Capabilities),
+ // ProgressStart(),
+ // ProgressUpdate(),
+ // ProgressEnd(),
+ // Invalidated(),
+ Memory(Memory),
+ }
+
+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+ #[serde(rename_all = "camelCase")]
+ pub struct Stopped {
+ pub reason: String,
+ pub description: Option<String>,
+ pub thread_id: Option<usize>,
+ pub preserve_focus_hint: Option<bool>,
+ pub text: Option<String>,
+ pub all_threads_stopped: Option<bool>,
+ pub hit_breakpoint_ids: Option<Vec<usize>>,
+ }
+
+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+ #[serde(rename_all = "camelCase")]
+ pub struct Continued {
+ pub thread_id: usize,
+ pub all_threads_continued: Option<bool>,
+ }
+
+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+ #[serde(rename_all = "camelCase")]
+ pub struct Exited {
+ pub exit_code: usize,
+ }
+
+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+ #[serde(rename_all = "camelCase")]
+ pub struct Terminated {
+ pub restart: Option<Value>,
+ }
+
+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+ #[serde(rename_all = "camelCase")]
+ pub struct Thread {
+ pub reason: String,
+ pub thread_id: usize,
+ }
+
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Output {
@@ -426,13 +504,54 @@ pub mod events {
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
- pub struct Stopped {
+ pub struct Breakpoint {
pub reason: String,
- pub description: Option<String>,
- pub thread_id: Option<usize>,
- pub preserve_focus_hint: Option<bool>,
- pub text: Option<String>,
- pub all_threads_stopped: Option<bool>,
- pub hit_breakpoint_ids: Option<Vec<usize>>,
+ pub breakpoint: super::Breakpoint,
+ }
+
+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+ #[serde(rename_all = "camelCase")]
+ pub struct Module {
+ pub reason: String,
+ pub module: super::Module,
+ }
+
+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+ #[serde(rename_all = "camelCase")]
+ pub struct LoadedSource {
+ pub reason: String,
+ pub source: super::Source,
+ }
+
+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+ #[serde(rename_all = "camelCase")]
+ pub struct Process {
+ pub name: String,
+ pub system_process_id: Option<usize>,
+ pub is_local_process: Option<bool>,
+ pub start_method: String, // TODO: use enum
+ pub pointer_size: Option<usize>,
+ }
+
+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+ #[serde(rename_all = "camelCase")]
+ pub struct Capabilities {
+ pub module: super::DebuggerCapabilities,
+ }
+
+ // #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+ // #[serde(rename_all = "camelCase")]
+ // pub struct Invalidated {
+ // pub areas: Vec<InvalidatedArea>,
+ // pub thread_id: Option<usize>,
+ // pub stack_frame_id: Option<usize>,
+ // }
+
+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
+ #[serde(rename_all = "camelCase")]
+ pub struct Memory {
+ pub memory_reference: String,
+ pub offset: usize,
+ pub count: usize,
}
}
diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs
index c9be81e2..0f0a9ae5 100644
--- a/helix-term/src/application.rs
+++ b/helix-term/src/application.rs
@@ -2,7 +2,6 @@ use helix_core::syntax;
use helix_dap::Payload;
use helix_lsp::{lsp, util::lsp_pos_to_pos, LspProgressMap};
use helix_view::{theme, Editor};
-use serde_json::from_value;
use crate::{args::Args, compositor::Compositor, config::Config, job::Jobs, ui};
@@ -251,40 +250,47 @@ impl Application {
}
pub async fn handle_debugger_message(&mut self, payload: helix_dap::Payload) {
+ use helix_dap::{events, Event};
let mut debugger = match self.editor.debugger.as_mut() {
Some(debugger) => debugger,
None => return,
};
match payload {
- Payload::Event(ev) => match &ev.event[..] {
- "stopped" => {
+ Payload::Event(ev) => match ev {
+ Event::Stopped(events::Stopped {
+ thread_id,
+ description,
+ text,
+ reason,
+ all_threads_stopped,
+ ..
+ }) => {
debugger.is_running = false;
let main = debugger
.threads()
.await
.ok()
.and_then(|threads| threads.get(0).cloned());
+
if let Some(main) = main {
let (bt, _) = debugger.stack_trace(main.id).await.unwrap();
debugger.stack_pointer = bt.get(0).cloned();
}
- let body: helix_dap::events::Stopped =
- from_value(ev.body.expect("`stopped` event must have a body")).unwrap();
- let scope = match body.thread_id {
+ let scope = match thread_id {
Some(id) => format!("Thread {}", id),
None => "Target".to_owned(),
};
- let mut status = format!("{} stopped because of {}", scope, body.reason);
- if let Some(desc) = body.description {
+ let mut status = format!("{} stopped because of {}", scope, reason);
+ if let Some(desc) = description {
status.push_str(&format!(" {}", desc));
}
- if let Some(text) = body.text {
+ if let Some(text) = text {
status.push_str(&format!(" {}", text));
}
- if body.all_threads_stopped == Some(true) {
+ if all_threads_stopped.unwrap_or_default() {
status.push_str(" (all threads stopped)");
}
@@ -302,31 +308,30 @@ impl Application {
.unwrap();
}
self.editor.set_status(status);
- self.render();
}
- "output" => {
- let body: helix_dap::events::Output =
- from_value(ev.body.expect("`output` event must have a body")).unwrap();
-
- let prefix = match body.category {
+ Event::Output(events::Output {
+ category, output, ..
+ }) => {
+ let prefix = match category {
Some(category) => format!("Debug ({}):", category),
None => "Debug:".to_owned(),
};
- self.editor
- .set_status(format!("{} {}", prefix, body.output));
- self.render();
+ self.editor.set_status(format!("{} {}", prefix, output));
}
- "initialized" => {
+ Event::Initialized => {
self.editor
.set_status("Debugged application started".to_owned());
- self.render();
}
- _ => {}
+ ev => {
+ log::warn!("Unhandled event {:?}", ev);
+ return; // return early to skip render
+ }
},
Payload::Response(_) => unreachable!(),
Payload::Request(_) => todo!(),
}
+ self.render();
}
pub async fn handle_language_server_message(