diff options
Diffstat (limited to 'helix-term/src/application.rs')
-rw-r--r-- | helix-term/src/application.rs | 96 |
1 files changed, 95 insertions, 1 deletions
diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 1fcca681..e64389ed 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -1,11 +1,11 @@ use helix_core::{merge_toml_values, syntax}; +use helix_dap::Payload; use helix_lsp::{lsp, util::lsp_pos_to_pos, LspProgressMap}; use helix_view::{theme, Editor}; use crate::{args::Args, compositor::Compositor, config::Config, job::Jobs, ui}; use log::error; - use std::{ io::{stdout, Write}, sync::Arc, @@ -191,6 +191,9 @@ impl Application { last_render = Instant::now(); } } + Some(payload) = self.editor.debugger_events.next() => { + self.handle_debugger_message(payload).await; + } Some(callback) = self.jobs.futures.next() => { self.jobs.handle_callback(&mut self.editor, &mut self.compositor, callback); self.render(); @@ -252,6 +255,97 @@ impl Application { } } + pub async fn handle_debugger_message(&mut self, payload: helix_dap::Payload) { + use crate::commands::dap::select_thread_id; + 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(events::Stopped { + thread_id, + description, + text, + reason, + all_threads_stopped, + .. + }) => { + debugger.is_running = false; + + // whichever thread stops is made "current" (if no previously selected thread). + if thread_id.is_none() || all_threads_stopped.unwrap_or_default() { + let main = debugger.threads().await.ok().and_then(|threads| { + // Workaround for debugging Go tests. Main thread has * in beginning of its name + let mut main = + threads.iter().find(|t| t.name.starts_with('*')).cloned(); + if main.is_none() { + main = threads.get(0).cloned(); + } + main.map(|t| t.id) + }); + if let Some(id) = main { + select_thread_id(&mut self.editor, id, true).await; + } + } else { + select_thread_id(&mut self.editor, thread_id.unwrap(), true).await; + } + + let scope = match thread_id { + Some(id) => format!("Thread {}", id), + None => "Target".to_owned(), + }; + + let mut status = format!("{} stopped because of {}", scope, reason); + if let Some(desc) = description { + status.push_str(&format!(" {}", desc)); + } + if let Some(text) = text { + status.push_str(&format!(" {}", text)); + } + if all_threads_stopped.unwrap_or_default() { + status.push_str(" (all threads stopped)"); + } + + self.editor.set_status(status); + } + Event::Output(events::Output { + category, output, .. + }) => { + let prefix = match category { + Some(category) => { + if &category == "telemetry" { + return; + } + format!("Debug ({}):", category) + } + None => "Debug:".to_owned(), + }; + + self.editor.set_status(format!("{} {}", prefix, output)); + } + Event::Initialized => { + self.editor + .set_status("Debugged application started".to_owned()); + } + Event::Continued(_) => { + debugger.is_running = true; + debugger.active_frame = None; + debugger.thread_id = None; + } + 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( &mut self, call: helix_lsp::Call, |