@@ -1,7 +1,7 @@
1use super::{align_view, Align, Context, Editor};
1use super::{align_view, Align, Context, Editor};
2use crate::ui::Picker;
2use crate::ui::Picker;
3use helix_core::Selection;
3use helix_core::Selection;
4−use helix_dap::Client;
4+use helix_dap::{self as dap, Client};
5use helix_lsp::block_on;
5use helix_lsp::block_on;
7use serde_json::{to_value, Value};
7use serde_json::{to_value, Value};
@@ -20,7 +20,9 @@ pub fn dap_pos_to_pos(doc: &helix_core::Rope, line: usize, column: usize) -> Opt
21pub fn resume_application(debugger: &mut Client) {
21pub fn resume_application(debugger: &mut Client) {
22 if let Some(thread_id) = debugger.thread_id {
22 if let Some(thread_id) = debugger.thread_id {
23− debugger.thread_states.insert(thread_id, "running".to_string());
25+ .insert(thread_id, "running".to_string());
24 debugger.stack_frames.remove(&thread_id);
26 debugger.stack_frames.remove(&thread_id);
26 debugger.active_frame = None;
28 debugger.active_frame = None;
@@ -80,7 +82,32 @@ pub fn jump_to_stack_frame(editor: &mut Editor, frame: &helix_dap::StackFrame) {
80 align_view(doc, view, Align::Center);
82 align_view(doc, view, Align::Center);
85+fn thread_picker(cx: &mut Context, callback_fn: impl Fn(&mut Editor, &dap::Thread) + 'static) {
86+ let debugger = match &mut cx.editor.debugger {
87+ Some(debugger) => debugger,
91+ let threads = match block_on(debugger.threads()) {
92+ Ok(threads) => threads,
95+ .set_error(format!("Failed to retrieve threads: {:?}", e));
100+ let picker = Picker::new(
103+ |thread| thread.name.clone().into(),
104+ move |editor, thread, _action| callback_fn(editor, thread),
106+ cx.push_layer(Box::new(picker))
84pub fn dap_start_impl(
111pub fn dap_start_impl(
85 editor: &mut Editor,
112 editor: &mut Editor,
86 name: Option<&str>,
113 name: Option<&str>,
@@ -312,23 +339,17 @@ pub fn dap_continue(cx: &mut Context) {
314pub fn dap_pause(cx: &mut Context) {
341pub fn dap_pause(cx: &mut Context) {
342+ thread_picker(cx, |editor, thread| {
315− let debugger = match &mut cx.editor.debugger {
343+ let debugger = match &mut editor.debugger {
316 Some(debugger) => debugger,
344 Some(debugger) => debugger,
317 None => return,
345 None => return,
319−
347+ let request = debugger.pause(thread.id);
320− // TODO: this should instead open a picker to pause a selected thread
348+ // NOTE: we don't need to set active thread id here because DAP will emit a "stopped" event
322− if !debugger.is_running {
323− cx.editor.set_status("Debuggee is not running".to_owned());
327− // FIXME: correct number here
328− let request = debugger.pause(0);
329− if let Err(e) = block_on(request) {
349+ if let Err(e) = block_on(request) {
330− cx.editor.set_error(format!("Failed to pause: {:?}", e));
350+ editor.set_error(format!("Failed to pause: {:?}", e));
334pub fn dap_step_in(cx: &mut Context) {
355pub fn dap_step_in(cx: &mut Context) {
@@ -456,28 +477,7 @@ pub fn dap_terminate(cx: &mut Context) {
458pub fn dap_switch_thread(cx: &mut Context) {
479pub fn dap_switch_thread(cx: &mut Context) {
459− let debugger = match &mut cx.editor.debugger {
460− Some(debugger) => debugger,
464− let request = debugger.threads();
465− let threads = match block_on(request) {
466− Ok(threads) => threads,
469− .set_error(format!("Failed to retrieve threads: {:?}", e));
474− let picker = Picker::new(
477− |thread| thread.name.clone().into(),
478− |editor, thread, _action| {
480+ thread_picker(cx, |editor, thread| {
479− block_on(select_thread_id(editor, thread.id, true));
481+ block_on(select_thread_id(editor, thread.id, true));
482− cx.push_layer(Box::new(picker))