Add more event types, simplify event decoding
This commit is contained in:
parent
2aee5f02d0
commit
28658836ee
4 changed files with 158 additions and 40 deletions
|
@ -3,7 +3,8 @@ mod transport;
|
||||||
mod types;
|
mod types;
|
||||||
|
|
||||||
pub use client::Client;
|
pub use client::Client;
|
||||||
pub use transport::{Event, Payload, Response, Transport};
|
pub use events::Event;
|
||||||
|
pub use transport::{Payload, Response, Transport};
|
||||||
pub use types::*;
|
pub use types::*;
|
||||||
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{Error, Result};
|
use crate::{Error, Event, Result};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -32,13 +32,6 @@ pub struct Response {
|
||||||
pub body: Option<Value>,
|
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)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
#[serde(tag = "type", rename_all = "camelCase")]
|
#[serde(tag = "type", rename_all = "camelCase")]
|
||||||
pub enum Payload {
|
pub enum Payload {
|
||||||
|
@ -208,8 +201,8 @@ impl Transport {
|
||||||
client_tx.send(msg).expect("Failed to send");
|
client_tx.send(msg).expect("Failed to send");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Payload::Event(Event { ref event, .. }) => {
|
Payload::Event(ref event) => {
|
||||||
info!("<- DAP event {}", event);
|
info!("<- DAP event {:?}", event);
|
||||||
client_tx.send(msg).expect("Failed to send");
|
client_tx.send(msg).expect("Failed to send");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,6 +206,21 @@ pub struct Variable {
|
||||||
pub memory_reference: Option<String>,
|
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 {
|
pub mod requests {
|
||||||
use super::*;
|
use super::*;
|
||||||
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
@ -411,6 +426,69 @@ pub mod requests {
|
||||||
|
|
||||||
pub mod events {
|
pub mod events {
|
||||||
use super::*;
|
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)]
|
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Output {
|
pub struct Output {
|
||||||
|
@ -426,13 +504,54 @@ pub mod events {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Stopped {
|
pub struct Breakpoint {
|
||||||
pub reason: String,
|
pub reason: String,
|
||||||
pub description: Option<String>,
|
pub breakpoint: super::Breakpoint,
|
||||||
pub thread_id: Option<usize>,
|
}
|
||||||
pub preserve_focus_hint: Option<bool>,
|
|
||||||
pub text: Option<String>,
|
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
pub all_threads_stopped: Option<bool>,
|
#[serde(rename_all = "camelCase")]
|
||||||
pub hit_breakpoint_ids: Option<Vec<usize>>,
|
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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ use helix_core::syntax;
|
||||||
use helix_dap::Payload;
|
use helix_dap::Payload;
|
||||||
use helix_lsp::{lsp, util::lsp_pos_to_pos, LspProgressMap};
|
use helix_lsp::{lsp, util::lsp_pos_to_pos, LspProgressMap};
|
||||||
use helix_view::{theme, Editor};
|
use helix_view::{theme, Editor};
|
||||||
use serde_json::from_value;
|
|
||||||
|
|
||||||
use crate::{args::Args, compositor::Compositor, config::Config, job::Jobs, ui};
|
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) {
|
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() {
|
let mut debugger = match self.editor.debugger.as_mut() {
|
||||||
Some(debugger) => debugger,
|
Some(debugger) => debugger,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
match payload {
|
match payload {
|
||||||
Payload::Event(ev) => match &ev.event[..] {
|
Payload::Event(ev) => match ev {
|
||||||
"stopped" => {
|
Event::Stopped(events::Stopped {
|
||||||
|
thread_id,
|
||||||
|
description,
|
||||||
|
text,
|
||||||
|
reason,
|
||||||
|
all_threads_stopped,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
debugger.is_running = false;
|
debugger.is_running = false;
|
||||||
let main = debugger
|
let main = debugger
|
||||||
.threads()
|
.threads()
|
||||||
.await
|
.await
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|threads| threads.get(0).cloned());
|
.and_then(|threads| threads.get(0).cloned());
|
||||||
|
|
||||||
if let Some(main) = main {
|
if let Some(main) = main {
|
||||||
let (bt, _) = debugger.stack_trace(main.id).await.unwrap();
|
let (bt, _) = debugger.stack_trace(main.id).await.unwrap();
|
||||||
debugger.stack_pointer = bt.get(0).cloned();
|
debugger.stack_pointer = bt.get(0).cloned();
|
||||||
}
|
}
|
||||||
|
|
||||||
let body: helix_dap::events::Stopped =
|
let scope = match thread_id {
|
||||||
from_value(ev.body.expect("`stopped` event must have a body")).unwrap();
|
|
||||||
let scope = match body.thread_id {
|
|
||||||
Some(id) => format!("Thread {}", id),
|
Some(id) => format!("Thread {}", id),
|
||||||
None => "Target".to_owned(),
|
None => "Target".to_owned(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut status = format!("{} stopped because of {}", scope, body.reason);
|
let mut status = format!("{} stopped because of {}", scope, reason);
|
||||||
if let Some(desc) = body.description {
|
if let Some(desc) = description {
|
||||||
status.push_str(&format!(" {}", desc));
|
status.push_str(&format!(" {}", desc));
|
||||||
}
|
}
|
||||||
if let Some(text) = body.text {
|
if let Some(text) = text {
|
||||||
status.push_str(&format!(" {}", 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)");
|
status.push_str(" (all threads stopped)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,31 +308,30 @@ impl Application {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
self.editor.set_status(status);
|
self.editor.set_status(status);
|
||||||
self.render();
|
|
||||||
}
|
}
|
||||||
"output" => {
|
Event::Output(events::Output {
|
||||||
let body: helix_dap::events::Output =
|
category, output, ..
|
||||||
from_value(ev.body.expect("`output` event must have a body")).unwrap();
|
}) => {
|
||||||
|
let prefix = match category {
|
||||||
let prefix = match body.category {
|
|
||||||
Some(category) => format!("Debug ({}):", category),
|
Some(category) => format!("Debug ({}):", category),
|
||||||
None => "Debug:".to_owned(),
|
None => "Debug:".to_owned(),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.editor
|
self.editor.set_status(format!("{} {}", prefix, output));
|
||||||
.set_status(format!("{} {}", prefix, body.output));
|
|
||||||
self.render();
|
|
||||||
}
|
}
|
||||||
"initialized" => {
|
Event::Initialized => {
|
||||||
self.editor
|
self.editor
|
||||||
.set_status("Debugged application started".to_owned());
|
.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::Response(_) => unreachable!(),
|
||||||
Payload::Request(_) => todo!(),
|
Payload::Request(_) => todo!(),
|
||||||
}
|
}
|
||||||
|
self.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_language_server_message(
|
pub async fn handle_language_server_message(
|
||||||
|
|
Loading…
Add table
Reference in a new issue