From 27c1b3f98b58edf690fda7caa2b14f34d6661598 Mon Sep 17 00:00:00 2001
From: Blaž Hrastnik
Date: Fri, 3 Sep 2021 11:30:25 +0900
Subject: dap: Extract a thread_states map

---
 helix-dap/src/client.rs        |  1 +
 helix-term/src/application.rs  | 23 ++++++++++++++---------
 helix-term/src/commands/dap.rs | 13 +++++++------
 3 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/helix-dap/src/client.rs b/helix-dap/src/client.rs
index 72f7e12c..9208db9d 100644
--- a/helix-dap/src/client.rs
+++ b/helix-dap/src/client.rs
@@ -31,6 +31,7 @@ pub struct Client {
     pub breakpoints: HashMap<PathBuf, Vec<SourceBreakpoint>>,
     // thread_id -> frames
     pub stack_frames: HashMap<usize, Vec<StackFrame>>,
+    pub thread_states: HashMap<usize, String>,
     pub thread_id: Option<usize>,
     /// Currently active frame for the current thread.
     pub active_frame: Option<usize>,
diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs
index 24ebbf60..eed7b914 100644
--- a/helix-term/src/application.rs
+++ b/helix-term/src/application.rs
@@ -273,10 +273,12 @@ impl Application {
                     all_threads_stopped,
                     ..
                 }) => {
-                    debugger.is_running = false;
+                    if let Some(thread_id) = thread_id {
+                        debugger.thread_states.insert(thread_id, reason); // TODO: dap uses "type" || "reason" here
+                        // whichever thread stops is made "current" (if no previously selected thread).
+                        select_thread_id(&mut self.editor, thread_id, false).await;
+                    }
 
-                    // whichever thread stops is made "current" (if no previously selected thread).
-                    select_thread_id(&mut self.editor, thread_id.unwrap(), false).await;
 
                     let scope = match thread_id {
                         Some(id) => format!("Thread {}", id),
@@ -296,6 +298,15 @@ impl Application {
 
                     self.editor.set_status(status);
                 }
+                Event::Continued(events::Continued { thread_id, .. }) => {
+                    debugger.thread_states.remove(&thread_id);
+                    if debugger.thread_id == Some(thread_id) {
+                        resume_application(debugger)
+                    }
+                }
+                Event::Thread(_) => {
+                    // TODO: update thread_states, make threads request 
+                }
                 Event::Output(events::Output {
                     category, output, ..
                 }) => {
@@ -315,12 +326,6 @@ impl Application {
                     self.editor
                         .set_status("Debugged application started".to_owned());
                 }
-                Event::Continued(events::Continued { thread_id, .. }) => {
-                    // TODO: remove thread from thread-states
-                    if debugger.thread_id == Some(thread_id) {
-                        resume_application(debugger)
-                    }
-                }
                 ev => {
                     log::warn!("Unhandled event {:?}", ev);
                     return; // return early to skip render
diff --git a/helix-term/src/commands/dap.rs b/helix-term/src/commands/dap.rs
index 7efc2c74..37f87711 100644
--- a/helix-term/src/commands/dap.rs
+++ b/helix-term/src/commands/dap.rs
@@ -19,7 +19,10 @@ pub fn dap_pos_to_pos(doc: &helix_core::Rope, line: usize, column: usize) -> Opt
 }
 
 pub fn resume_application(debugger: &mut Client) {
-    debugger.is_running = true; // TODO: set state running for debugger.thread_id
+    if let Some(thread_id) = debugger.thread_id {
+        debugger.thread_states.insert(thread_id, "running".to_string());
+        debugger.stack_frames.remove(&thread_id);
+    }
     debugger.active_frame = None;
     debugger.thread_id = None;
 }
@@ -302,7 +305,6 @@ pub fn dap_continue(cx: &mut Context) {
             return;
         }
         resume_application(debugger);
-        debugger.stack_frames.remove(&thread_id);
     } else {
         cx.editor
             .set_error("Currently active thread is not stopped. Switch the thread.".into());
@@ -315,6 +317,8 @@ pub fn dap_pause(cx: &mut Context) {
         None => return,
     };
 
+    // TODO: this should instead open a picker to pause a selected thread
+
     if !debugger.is_running {
         cx.editor.set_status("Debuggee is not running".to_owned());
         return;
@@ -340,7 +344,6 @@ pub fn dap_step_in(cx: &mut Context) {
             return;
         }
         resume_application(debugger);
-        debugger.stack_frames.remove(&thread_id);
     } else {
         cx.editor
             .set_error("Currently active thread is not stopped. Switch the thread.".into());
@@ -360,7 +363,6 @@ pub fn dap_step_out(cx: &mut Context) {
             return;
         }
         resume_application(debugger);
-        debugger.stack_frames.remove(&thread_id);
     } else {
         cx.editor
             .set_error("Currently active thread is not stopped. Switch the thread.".into());
@@ -380,7 +382,6 @@ pub fn dap_next(cx: &mut Context) {
             return;
         }
         resume_application(debugger);
-        debugger.stack_frames.remove(&thread_id);
     } else {
         cx.editor
             .set_error("Currently active thread is not stopped. Switch the thread.".into());
@@ -393,7 +394,7 @@ pub fn dap_variables(cx: &mut Context) {
         None => return,
     };
 
-    if debugger.is_running {
+    if debugger.thread_id.is_none() {
         cx.editor
             .set_status("Cannot access variables while target is running".to_owned());
         return;
-- 
cgit v1.2.3-70-g09d2