@@ -1,5 +1,5 @@
1use super::{align_view, Align, Context, Editor};
1use super::{align_view, Align, Context, Editor};
2−use crate::ui::Picker;
2+use crate::ui::{FilePicker, Picker};
3use helix_core::Selection;
3use helix_core::Selection;
4use helix_dap::{self as dap, Client};
4use helix_dap::{self as dap, Client};
5use helix_lsp::block_on;
5use helix_lsp::block_on;
@@ -461,3 +461,52 @@ pub fn dap_switch_thread(cx: &mut Context) {
461 block_on(select_thread_id(editor, thread.id, true));
461 block_on(select_thread_id(editor, thread.id, true));
464+pub fn dap_switch_stack_frame(cx: &mut Context) {
465+ let debugger = match &mut cx.editor.debugger {
466+ Some(debugger) => debugger,
470+ let thread_id = match debugger.thread_id {
471+ Some(thread_id) => thread_id,
474+ .set_error(format!("No thread is currently active"));
479+ let frames = debugger.stack_frames[&thread_id].clone();
481+ let picker = FilePicker::new(
483+ |frame| frame.name.clone().into(), // TODO: include thread_states in the label
484+ move |editor, frame, _action| {
485+ let debugger = match &mut editor.debugger {
486+ Some(debugger) => debugger,
489+ // TODO: this should be simpler to find
490+ let pos = debugger.stack_frames[&thread_id]
492+ .position(|f| f.id == frame.id);
493+ debugger.active_frame = pos;
495+ move |_editor, frame| {
499+ .and_then(|source| source.path.clone())
504+ frame.line.saturating_sub(1),
505+ frame.end_line.unwrap_or(frame.line).saturating_sub(1),
511+ cx.push_layer(Box::new(picker))