on master help sign in
editor: support stepIn, stepOut, next and pause commands
d93cd2aDmitry Sharshakov
helix-dap/src/client.rs+3−3
@@ -30,6 +30,7 @@ pub struct Client {
30 pub breakpoints: HashMap<PathBuf, Vec<SourceBreakpoint>>,
30 pub breakpoints: HashMap<PathBuf, Vec<SourceBreakpoint>>,
31 // TODO: multiple threads support
31 // TODO: multiple threads support
32 pub stack_pointer: Option<StackFrame>,
32 pub stack_pointer: Option<StackFrame>,
33+ pub stopped_thread: Option<usize>,
33 pub is_running: bool,
34 pub is_running: bool,
34}
35}
35
36
@@ -52,6 +53,7 @@ impl Client {
52 //
53 //
53 breakpoints: HashMap::new(),
54 breakpoints: HashMap::new(),
54 stack_pointer: None,
55 stack_pointer: None,
56+ stopped_thread: None,
55 is_running: false,
57 is_running: false,
56 };
58 };
57
59
@@ -346,9 +348,7 @@ impl Client {
346 }
348 }
347
349
348 pub async fn pause(&mut self, thread_id: usize) -> Result<()> {
350 pub async fn pause(&mut self, thread_id: usize) -> Result<()> {
349− let args = requests::PauseArguments {
351+ let args = requests::PauseArguments { thread_id };
350− thread_id,
351− };
352
352
353 self.request::<requests::Pause>(args).await
353 self.request::<requests::Pause>(args).await
354 }
354 }
helix-term/src/application.rs+1
@@ -276,6 +276,7 @@ impl Application {
276 if let Some(main) = main {
276 if let Some(main) = main {
277 let (bt, _) = debugger.stack_trace(main.id).await.unwrap();
277 let (bt, _) = debugger.stack_trace(main.id).await.unwrap();
278 debugger.stack_pointer = bt.get(0).cloned();
278 debugger.stack_pointer = bt.get(0).cloned();
279+ debugger.stopped_thread = Some(main.id);
279 }
280 }
280
281
281 let scope = match thread_id {
282 let scope = match thread_id {
helix-term/src/commands.rs+65−3
@@ -307,6 +307,10 @@ impl Command {
307 dap_start, "Start debug session",
307 dap_start, "Start debug session",
308 dap_run, "Begin program execution",
308 dap_run, "Begin program execution",
309 dap_continue, "Continue program execution",
309 dap_continue, "Continue program execution",
310+ dap_pause, "Pause program execution",
311+ dap_in, "Step in",
312+ dap_out, "Step out",
313+ dap_next, "Step to next",
310 dap_variable_scopes, "List variable scopes",
314 dap_variable_scopes, "List variable scopes",
311 dap_terminate, "End debug session",
315 dap_terminate, "End debug session",
312 suspend, "Suspend"
316 suspend, "Suspend"
@@ -4394,15 +4398,73 @@ fn dap_continue(cx: &mut Context) {
4394 .set_status("Debuggee is already running".to_owned());
4398 .set_status("Debuggee is already running".to_owned());
4395 return;
4399 return;
4396 }
4400 }
4397− // assume 0 to continue all threads for now
4401+
4398− // FIXME: spec conformant behavior here
4399− let request = debugger.continue_thread(0);
4402+ let request = debugger.continue_thread(debugger.stopped_thread.unwrap());
4400 let _ = block_on(request).unwrap();
4403 let _ = block_on(request).unwrap();
4401 debugger.is_running = true;
4404 debugger.is_running = true;
4402 debugger.stack_pointer = None;
4405 debugger.stack_pointer = None;
4403 }
4406 }
4404}
4407}
4405
4408
4409+fn dap_pause(cx: &mut Context) {
4410+ use helix_lsp::block_on;
4411+
4412+ if let Some(debugger) = &mut cx.editor.debugger {
4413+ if !debugger.is_running {
4414+ cx.editor.set_status("Debuggee is not running".to_owned());
4415+ return;
4416+ }
4417+
4418+ let request = debugger.pause(debugger.stopped_thread.unwrap());
4419+ let _ = block_on(request).unwrap();
4420+ }
4421+}
4422+
4423+fn dap_in(cx: &mut Context) {
4424+ use helix_lsp::block_on;
4425+
4426+ if let Some(debugger) = &mut cx.editor.debugger {
4427+ if debugger.is_running {
4428+ cx.editor
4429+ .set_status("Debuggee is already running".to_owned());
4430+ return;
4431+ }
4432+
4433+ let request = debugger.step_in(debugger.stopped_thread.unwrap());
4434+ let _ = block_on(request).unwrap();
4435+ }
4436+}
4437+
4438+fn dap_out(cx: &mut Context) {
4439+ use helix_lsp::block_on;
4440+
4441+ if let Some(debugger) = &mut cx.editor.debugger {
4442+ if debugger.is_running {
4443+ cx.editor
4444+ .set_status("Debuggee is already running".to_owned());
4445+ return;
4446+ }
4447+
4448+ let request = debugger.step_out(debugger.stopped_thread.unwrap());
4449+ let _ = block_on(request).unwrap();
4450+ }
4451+}
4452+
4453+fn dap_next(cx: &mut Context) {
4454+ use helix_lsp::block_on;
4455+
4456+ if let Some(debugger) = &mut cx.editor.debugger {
4457+ if debugger.is_running {
4458+ cx.editor
4459+ .set_status("Debuggee is already running".to_owned());
4460+ return;
4461+ }
4462+
4463+ let request = debugger.next(debugger.stopped_thread.unwrap());
4464+ let _ = block_on(request).unwrap();
4465+ }
4466+}
4467+
4406fn dap_variable_scopes(cx: &mut Context) {
4468fn dap_variable_scopes(cx: &mut Context) {
4407 use helix_lsp::block_on;
4469 use helix_lsp::block_on;
4408
4470
helix-term/src/keymap.rs+4
@@ -490,6 +490,10 @@ impl Default for Keymaps {
490 "b" => dap_toggle_breakpoint,
490 "b" => dap_toggle_breakpoint,
491 "r" => dap_run,
491 "r" => dap_run,
492 "c" => dap_continue,
492 "c" => dap_continue,
493+ "h" => dap_pause,
494+ "j" => dap_in,
495+ "k" => dap_out,
496+ "l" => dap_next,
493 "z" => dap_variable_scopes,
497 "z" => dap_variable_scopes,
494 "t" => dap_terminate,
498 "t" => dap_terminate,
495 },
499 },