dap: Remap keys, match current thread behavior from dap-mode, switch-thread

pull/574/head
Blaž Hrastnik 3 years ago
parent 03b2d81406
commit 986828e75c

@ -31,7 +31,7 @@ pub struct Client {
pub breakpoints: HashMap<PathBuf, Vec<SourceBreakpoint>>, pub breakpoints: HashMap<PathBuf, Vec<SourceBreakpoint>>,
// TODO: multiple threads support // TODO: multiple threads support
pub stack_pointer: Option<StackFrame>, pub stack_pointer: Option<StackFrame>,
pub stopped_thread: Option<usize>, pub thread_id: Option<usize>,
pub is_running: bool, pub is_running: bool,
} }
@ -77,7 +77,7 @@ impl Client {
// //
breakpoints: HashMap::new(), breakpoints: HashMap::new(),
stack_pointer: None, stack_pointer: None,
stopped_thread: None, thread_id: None,
is_running: false, is_running: false,
}; };

@ -1,4 +1,4 @@
use helix_core::{merge_toml_values, syntax, Range, Selection}; use helix_core::{merge_toml_values, syntax, Selection};
use helix_dap::Payload; use helix_dap::Payload;
use helix_lsp::{lsp, util::lsp_pos_to_pos, LspProgressMap}; use helix_lsp::{lsp, util::lsp_pos_to_pos, LspProgressMap};
use helix_view::{theme, Editor}; use helix_view::{theme, Editor};
@ -280,19 +280,13 @@ impl Application {
.. ..
}) => { }) => {
debugger.is_running = false; debugger.is_running = false;
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
});
if let Some(main) = main { // whichever thread stops is made "current".
let (bt, _) = debugger.stack_trace(main.id).await.unwrap(); debugger.thread_id = thread_id;
if let Some(thread_id) = thread_id {
let (bt, _) = debugger.stack_trace(thread_id).await.unwrap();
debugger.stack_pointer = bt.get(0).cloned(); debugger.stack_pointer = bt.get(0).cloned();
debugger.stopped_thread = Some(main.id);
} }
let scope = match thread_id { let scope = match thread_id {
@ -379,7 +373,6 @@ impl Application {
.set_status("Debugged application started".to_owned()); .set_status("Debugged application started".to_owned());
} }
Event::Continued(_) => { Event::Continued(_) => {
debugger.stopped_thread = None;
debugger.stack_pointer = None; debugger.stack_pointer = None;
debugger.is_running = true; debugger.is_running = true;
} }

@ -316,6 +316,7 @@ impl Command {
dap_next, "Step to next", dap_next, "Step to next",
dap_variables, "List variables", dap_variables, "List variables",
dap_terminate, "End debug session", dap_terminate, "End debug session",
dap_switch_thread, "Switch current thread",
suspend, "Suspend" suspend, "Suspend"
); );
} }

@ -1,4 +1,5 @@
use super::{Context, Editor}; use super::{Context, Editor};
use crate::ui::Picker;
use helix_dap::Client; use helix_dap::Client;
use helix_lsp::block_on; use helix_lsp::block_on;
@ -221,7 +222,7 @@ pub fn dap_continue(cx: &mut Context) {
return; return;
} }
let request = debugger.continue_thread(debugger.stopped_thread.unwrap()); let request = debugger.continue_thread(debugger.thread_id.unwrap());
if let Err(e) = block_on(request) { if let Err(e) = block_on(request) {
cx.editor.set_error(format!("Failed to continue: {:?}", e)); cx.editor.set_error(format!("Failed to continue: {:?}", e));
return; return;
@ -254,7 +255,7 @@ pub fn dap_step_in(cx: &mut Context) {
return; return;
} }
let request = debugger.step_in(debugger.stopped_thread.unwrap()); let request = debugger.step_in(debugger.thread_id.unwrap());
if let Err(e) = block_on(request) { if let Err(e) = block_on(request) {
cx.editor.set_error(format!("Failed to step: {:?}", e)); cx.editor.set_error(format!("Failed to step: {:?}", e));
} }
@ -269,7 +270,7 @@ pub fn dap_step_out(cx: &mut Context) {
return; return;
} }
let request = debugger.step_out(debugger.stopped_thread.unwrap()); let request = debugger.step_out(debugger.thread_id.unwrap());
if let Err(e) = block_on(request) { if let Err(e) = block_on(request) {
cx.editor.set_error(format!("Failed to step: {:?}", e)); cx.editor.set_error(format!("Failed to step: {:?}", e));
} }
@ -284,7 +285,7 @@ pub fn dap_next(cx: &mut Context) {
return; return;
} }
let request = debugger.next(debugger.stopped_thread.unwrap()); let request = debugger.next(debugger.thread_id.unwrap());
if let Err(e) = block_on(request) { if let Err(e) = block_on(request) {
cx.editor.set_error(format!("Failed to step: {:?}", e)); cx.editor.set_error(format!("Failed to step: {:?}", e));
} }
@ -347,3 +348,30 @@ pub fn dap_terminate(cx: &mut Context) {
cx.editor.debugger = None; cx.editor.debugger = None;
} }
} }
pub fn dap_switch_thread(cx: &mut Context) {
if let Some(debugger) = &mut cx.editor.debugger {
let request = debugger.threads();
let threads = match block_on(request) {
Ok(threads) => threads,
Err(e) => {
cx.editor
.set_error(format!("Failed to retrieve threads: {:?}", e));
return;
}
};
let picker = Picker::new(
true,
threads,
|thread| thread.name.clone().into(),
|editor, thread, _action| {
if let Some(debugger) = &mut editor.debugger {
debugger.thread_id = Some(thread.id);
// TODO: probably need to refetch stack frames?
}
},
);
cx.push_layer(Box::new(picker))
}
}

@ -486,16 +486,21 @@ impl Default for Keymaps {
"a" => code_action, "a" => code_action,
"'" => last_picker, "'" => last_picker,
"d" => { "Debug" "d" => { "Debug"
"s" => dap_launch, "l" => dap_launch,
"b" => dap_toggle_breakpoint, "b" => dap_toggle_breakpoint,
"r" => dap_run, "r" => dap_run,
"c" => dap_continue, "c" => dap_continue,
"h" => dap_pause, "h" => dap_pause,
"j" => dap_step_in, "i" => dap_step_in,
"k" => dap_step_out, "o" => dap_step_out,
"l" => dap_next, "n" => dap_next,
"v" => dap_variables, "v" => dap_variables,
"t" => dap_terminate, "t" => dap_terminate,
"s" => { "Switch"
"t" => dap_switch_thread,
// f = stack frame
// sl, sb
},
}, },
"w" => { "Window" "w" => { "Window"
"C-w" | "w" => rotate_view, "C-w" | "w" => rotate_view,

Loading…
Cancel
Save