on master help sign in
Add more event types, simplify event decoding
commit28658836eee9860666a114756e13e1fdf7fd4637 authorBlaž Hrastnik <blaz@mxxn.io> dateSun 22 Aug 2021, 16:05 (5 years ago) parent2aee5f0
4 files changed+158−40
helix-dap/src/lib.rs+2−1 helix-dap/src/transport.rs+3−10 helix-dap/src/types.rs+126−7 helix-term/src/application.rs+27−22
helix-dap/src/lib.rs+2−1
@@ -3,7 +3,8 @@ mod transport;
33mod types;
44
55pub use client::Client;
6−pub use transport::{Event, Payload, Response, Transport};
6+pub use events::Event;
7+pub use transport::{Payload, Response, Transport};
78pub use types::*;
89
910use thiserror::Error;
helix-dap/src/transport.rs+3−10
@@ -1,4 +1,4 @@
1−use crate::{Error, Result};
1+use crate::{Error, Event, Result};
22use anyhow::Context;
33use log::{error, info, warn};
44use serde::{Deserialize, Serialize};
@@ -32,13 +32,6 @@ pub struct Response {
3232 pub body: Option<Value>,
3333}
3434
35−#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
36−pub struct Event {
37− // seq is omitted as unused and is not sent by some implementations
38− pub event: String,
39− pub body: Option<Value>,
40−}
41−
4235#[derive(Debug, Clone, Deserialize, Serialize)]
4336#[serde(tag = "type", rename_all = "camelCase")]
4437pub enum Payload {
@@ -208,8 +201,8 @@ impl Transport {
208201 client_tx.send(msg).expect("Failed to send");
209202 Ok(())
210203 }
211− Payload::Event(Event { ref event, .. }) => {
212− info!("<- DAP event {}", event);
204+ Payload::Event(ref event) => {
205+ info!("<- DAP event {:?}", event);
213206 client_tx.send(msg).expect("Failed to send");
214207 Ok(())
215208 }
helix-dap/src/types.rs+126−7
@@ -206,6 +206,21 @@ pub struct Variable {
206206 pub memory_reference: Option<String>,
207207}
208208
209+#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
210+#[serde(rename_all = "camelCase")]
211+pub struct Module {
212+ pub id: String, // TODO: || number
213+ pub name: String,
214+ pub path: Option<PathBuf>,
215+ pub is_optimized: Option<bool>,
216+ pub is_user_code: Option<bool>,
217+ pub version: Option<String>,
218+ pub symbol_status: Option<String>,
219+ pub symbol_file_path: Option<String>,
220+ pub date_time_stamp: Option<String>,
221+ pub address_range: Option<String>,
222+}
223+
209224pub mod requests {
210225 use super::*;
211226 #[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
@@ -411,6 +426,69 @@ pub mod requests {
411426
412427pub mod events {
413428 use super::*;
429+
430+ #[derive(Debug, Clone, Serialize, Deserialize)]
431+ #[serde(rename_all = "camelCase")]
432+ #[serde(tag = "event", content = "body")]
433+ // seq is omitted as unused and is not sent by some implementations
434+ pub enum Event {
435+ Initialized,
436+ Stopped(Stopped),
437+ Continued(Continued),
438+ Exited(Exited),
439+ Terminated(Terminated),
440+ Thread(Thread),
441+ Output(Output),
442+ Breakpoint(Breakpoint),
443+ Module(Module),
444+ LoadedSource(LoadedSource),
445+ Process(Process),
446+ Capabilities(Capabilities),
447+ // ProgressStart(),
448+ // ProgressUpdate(),
449+ // ProgressEnd(),
450+ // Invalidated(),
451+ Memory(Memory),
452+ }
453+
454+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
455+ #[serde(rename_all = "camelCase")]
456+ pub struct Stopped {
457+ pub reason: String,
458+ pub description: Option<String>,
459+ pub thread_id: Option<usize>,
460+ pub preserve_focus_hint: Option<bool>,
461+ pub text: Option<String>,
462+ pub all_threads_stopped: Option<bool>,
463+ pub hit_breakpoint_ids: Option<Vec<usize>>,
464+ }
465+
466+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
467+ #[serde(rename_all = "camelCase")]
468+ pub struct Continued {
469+ pub thread_id: usize,
470+ pub all_threads_continued: Option<bool>,
471+ }
472+
473+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
474+ #[serde(rename_all = "camelCase")]
475+ pub struct Exited {
476+ pub exit_code: usize,
477+ }
478+
479+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
480+ #[serde(rename_all = "camelCase")]
481+ pub struct Terminated {
482+ pub restart: Option<Value>,
483+ }
484+
485+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
486+ #[serde(rename_all = "camelCase")]
487+ pub struct Thread {
488+ pub reason: String,
489+ pub thread_id: usize,
490+ }
491+
414492 #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
415493 #[serde(rename_all = "camelCase")]
416494 pub struct Output {
@@ -426,13 +504,54 @@ pub mod events {
426504
427505 #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
428506 #[serde(rename_all = "camelCase")]
429− pub struct Stopped {
507+ pub struct Breakpoint {
430508 pub reason: String,
431− pub description: Option<String>,
432− pub thread_id: Option<usize>,
433− pub preserve_focus_hint: Option<bool>,
434− pub text: Option<String>,
435− pub all_threads_stopped: Option<bool>,
436− pub hit_breakpoint_ids: Option<Vec<usize>>,
509+ pub breakpoint: super::Breakpoint,
510+ }
511+
512+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
513+ #[serde(rename_all = "camelCase")]
514+ pub struct Module {
515+ pub reason: String,
516+ pub module: super::Module,
517+ }
518+
519+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
520+ #[serde(rename_all = "camelCase")]
521+ pub struct LoadedSource {
522+ pub reason: String,
523+ pub source: super::Source,
524+ }
525+
526+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
527+ #[serde(rename_all = "camelCase")]
528+ pub struct Process {
529+ pub name: String,
530+ pub system_process_id: Option<usize>,
531+ pub is_local_process: Option<bool>,
532+ pub start_method: String, // TODO: use enum
533+ pub pointer_size: Option<usize>,
534+ }
535+
536+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
537+ #[serde(rename_all = "camelCase")]
538+ pub struct Capabilities {
539+ pub module: super::DebuggerCapabilities,
540+ }
541+
542+ // #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
543+ // #[serde(rename_all = "camelCase")]
544+ // pub struct Invalidated {
545+ // pub areas: Vec<InvalidatedArea>,
546+ // pub thread_id: Option<usize>,
547+ // pub stack_frame_id: Option<usize>,
548+ // }
549+
550+ #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
551+ #[serde(rename_all = "camelCase")]
552+ pub struct Memory {
553+ pub memory_reference: String,
554+ pub offset: usize,
555+ pub count: usize,
437556 }
438557}
helix-term/src/application.rs+27−22
@@ -2,7 +2,6 @@ use helix_core::syntax;
22use helix_dap::Payload;
33use helix_lsp::{lsp, util::lsp_pos_to_pos, LspProgressMap};
44use helix_view::{theme, Editor};
5−use serde_json::from_value;
65
76use crate::{args::Args, compositor::Compositor, config::Config, job::Jobs, ui};
87
@@ -251,40 +250,47 @@ impl Application {
251250 }
252251
253252 pub async fn handle_debugger_message(&mut self, payload: helix_dap::Payload) {
253+ use helix_dap::{events, Event};
254254 let mut debugger = match self.editor.debugger.as_mut() {
255255 Some(debugger) => debugger,
256256 None => return,
257257 };
258258
259259 match payload {
260− Payload::Event(ev) => match &ev.event[..] {
261− "stopped" => {
260+ Payload::Event(ev) => match ev {
261+ Event::Stopped(events::Stopped {
262+ thread_id,
263+ description,
264+ text,
265+ reason,
266+ all_threads_stopped,
267+ ..
268+ }) => {
262269 debugger.is_running = false;
263270 let main = debugger
264271 .threads()
265272 .await
266273 .ok()
267274 .and_then(|threads| threads.get(0).cloned());
275+
268276 if let Some(main) = main {
269277 let (bt, _) = debugger.stack_trace(main.id).await.unwrap();
270278 debugger.stack_pointer = bt.get(0).cloned();
271279 }
272280
273− let body: helix_dap::events::Stopped =
274− from_value(ev.body.expect("`stopped` event must have a body")).unwrap();
275− let scope = match body.thread_id {
281+ let scope = match thread_id {
276282 Some(id) => format!("Thread {}", id),
277283 None => "Target".to_owned(),
278284 };
279285
280− let mut status = format!("{} stopped because of {}", scope, body.reason);
281− if let Some(desc) = body.description {
286+ let mut status = format!("{} stopped because of {}", scope, reason);
287+ if let Some(desc) = description {
282288 status.push_str(&format!(" {}", desc));
283289 }
284− if let Some(text) = body.text {
290+ if let Some(text) = text {
285291 status.push_str(&format!(" {}", text));
286292 }
287− if body.all_threads_stopped == Some(true) {
293+ if all_threads_stopped.unwrap_or_default() {
288294 status.push_str(" (all threads stopped)");
289295 }
290296
@@ -302,31 +308,30 @@ impl Application {
302308 .unwrap();
303309 }
304310 self.editor.set_status(status);
305− self.render();
306311 }
307− "output" => {
308− let body: helix_dap::events::Output =
309− from_value(ev.body.expect("`output` event must have a body")).unwrap();
310−
311− let prefix = match body.category {
312+ Event::Output(events::Output {
313+ category, output, ..
314+ }) => {
315+ let prefix = match category {
312316 Some(category) => format!("Debug ({}):", category),
313317 None => "Debug:".to_owned(),
314318 };
315319
316− self.editor
317− .set_status(format!("{} {}", prefix, body.output));
318− self.render();
320+ self.editor.set_status(format!("{} {}", prefix, output));
319321 }
320− "initialized" => {
322+ Event::Initialized => {
321323 self.editor
322324 .set_status("Debugged application started".to_owned());
323− self.render();
324325 }
325− _ => {}
326+ ev => {
327+ log::warn!("Unhandled event {:?}", ev);
328+ return; // return early to skip render
329+ }
326330 },
327331 Payload::Response(_) => unreachable!(),
328332 Payload::Request(_) => todo!(),
329333 }
334+ self.render();
330335 }
331336
332337 pub async fn handle_language_server_message(