on master help sign in
dap: Extract a thread_states map
27c1b3fBlaž Hrastnik
helix-dap/src/client.rs+1
@@ -31,6 +31,7 @@ pub struct Client {
31 pub breakpoints: HashMap<PathBuf, Vec<SourceBreakpoint>>,
31 pub breakpoints: HashMap<PathBuf, Vec<SourceBreakpoint>>,
32 // thread_id -> frames
32 // thread_id -> frames
33 pub stack_frames: HashMap<usize, Vec<StackFrame>>,
33 pub stack_frames: HashMap<usize, Vec<StackFrame>>,
34+ pub thread_states: HashMap<usize, String>,
34 pub thread_id: Option<usize>,
35 pub thread_id: Option<usize>,
35 /// Currently active frame for the current thread.
36 /// Currently active frame for the current thread.
36 pub active_frame: Option<usize>,
37 pub active_frame: Option<usize>,
helix-term/src/application.rs+14−9
@@ -273,10 +273,12 @@ impl Application {
273 all_threads_stopped,
273 all_threads_stopped,
274 ..
274 ..
275 }) => {
275 }) => {
276− debugger.is_running = false;
276+ if let Some(thread_id) = thread_id {
277+ debugger.thread_states.insert(thread_id, reason); // TODO: dap uses "type" || "reason" here
278+ // whichever thread stops is made "current" (if no previously selected thread).
279+ select_thread_id(&mut self.editor, thread_id, false).await;
280+ }
277
281
278− // whichever thread stops is made "current" (if no previously selected thread).
279− select_thread_id(&mut self.editor, thread_id.unwrap(), false).await;
280
282
281 let scope = match thread_id {
283 let scope = match thread_id {
282 Some(id) => format!("Thread {}", id),
284 Some(id) => format!("Thread {}", id),
@@ -296,6 +298,15 @@ impl Application {
296
298
297 self.editor.set_status(status);
299 self.editor.set_status(status);
298 }
300 }
301+ Event::Continued(events::Continued { thread_id, .. }) => {
302+ debugger.thread_states.remove(&thread_id);
303+ if debugger.thread_id == Some(thread_id) {
304+ resume_application(debugger)
305+ }
306+ }
307+ Event::Thread(_) => {
308+ // TODO: update thread_states, make threads request
309+ }
299 Event::Output(events::Output {
310 Event::Output(events::Output {
300 category, output, ..
311 category, output, ..
301 }) => {
312 }) => {
@@ -315,12 +326,6 @@ impl Application {
315 self.editor
326 self.editor
316 .set_status("Debugged application started".to_owned());
327 .set_status("Debugged application started".to_owned());
317 }
328 }
318− Event::Continued(events::Continued { thread_id, .. }) => {
319− // TODO: remove thread from thread-states
320− if debugger.thread_id == Some(thread_id) {
321− resume_application(debugger)
322− }
323− }
324 ev => {
329 ev => {
325 log::warn!("Unhandled event {:?}", ev);
330 log::warn!("Unhandled event {:?}", ev);
326 return; // return early to skip render
331 return; // return early to skip render
helix-term/src/commands/dap.rs+7−6
@@ -19,7 +19,10 @@ pub fn dap_pos_to_pos(doc: &helix_core::Rope, line: usize, column: usize) -> Opt
19}
19}
20
20
21pub fn resume_application(debugger: &mut Client) {
21pub fn resume_application(debugger: &mut Client) {
22− debugger.is_running = true; // TODO: set state running for debugger.thread_id
22+ if let Some(thread_id) = debugger.thread_id {
23+ debugger.thread_states.insert(thread_id, "running".to_string());
24+ debugger.stack_frames.remove(&thread_id);
25+ }
23 debugger.active_frame = None;
26 debugger.active_frame = None;
24 debugger.thread_id = None;
27 debugger.thread_id = None;
25}
28}
@@ -302,7 +305,6 @@ pub fn dap_continue(cx: &mut Context) {
302 return;
305 return;
303 }
306 }
304 resume_application(debugger);
307 resume_application(debugger);
305− debugger.stack_frames.remove(&thread_id);
306 } else {
308 } else {
307 cx.editor
309 cx.editor
308 .set_error("Currently active thread is not stopped. Switch the thread.".into());
310 .set_error("Currently active thread is not stopped. Switch the thread.".into());
@@ -315,6 +317,8 @@ pub fn dap_pause(cx: &mut Context) {
315 None => return,
317 None => return,
316 };
318 };
317
319
320+ // TODO: this should instead open a picker to pause a selected thread
321+
318 if !debugger.is_running {
322 if !debugger.is_running {
319 cx.editor.set_status("Debuggee is not running".to_owned());
323 cx.editor.set_status("Debuggee is not running".to_owned());
320 return;
324 return;
@@ -340,7 +344,6 @@ pub fn dap_step_in(cx: &mut Context) {
340 return;
344 return;
341 }
345 }
342 resume_application(debugger);
346 resume_application(debugger);
343− debugger.stack_frames.remove(&thread_id);
344 } else {
347 } else {
345 cx.editor
348 cx.editor
346 .set_error("Currently active thread is not stopped. Switch the thread.".into());
349 .set_error("Currently active thread is not stopped. Switch the thread.".into());
@@ -360,7 +363,6 @@ pub fn dap_step_out(cx: &mut Context) {
360 return;
363 return;
361 }
364 }
362 resume_application(debugger);
365 resume_application(debugger);
363− debugger.stack_frames.remove(&thread_id);
364 } else {
366 } else {
365 cx.editor
367 cx.editor
366 .set_error("Currently active thread is not stopped. Switch the thread.".into());
368 .set_error("Currently active thread is not stopped. Switch the thread.".into());
@@ -380,7 +382,6 @@ pub fn dap_next(cx: &mut Context) {
380 return;
382 return;
381 }
383 }
382 resume_application(debugger);
384 resume_application(debugger);
383− debugger.stack_frames.remove(&thread_id);
384 } else {
385 } else {
385 cx.editor
386 cx.editor
386 .set_error("Currently active thread is not stopped. Switch the thread.".into());
387 .set_error("Currently active thread is not stopped. Switch the thread.".into());
@@ -393,7 +394,7 @@ pub fn dap_variables(cx: &mut Context) {
393 None => return,
394 None => return,
394 };
395 };
395
396
396− if debugger.is_running {
397+ if debugger.thread_id.is_none() {
397 cx.editor
398 cx.editor
398 .set_status("Cannot access variables while target is running".to_owned());
399 .set_status("Cannot access variables while target is running".to_owned());
399 return;
400 return;