mirror of https://github.com/helix-editor/helix
dap: Remap keys, match current thread behavior from dap-mode, switch-thread
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…
Reference in New Issue