Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-term/src/commands/dap.rs')
-rw-r--r--helix-term/src/commands/dap.rs81
1 files changed, 37 insertions, 44 deletions
diff --git a/helix-term/src/commands/dap.rs b/helix-term/src/commands/dap.rs
index 074bef6d..0b754bc2 100644
--- a/helix-term/src/commands/dap.rs
+++ b/helix-term/src/commands/dap.rs
@@ -5,12 +5,13 @@ use crate::{
ui::{self, overlay::overlaid, Picker, Popup, Prompt, PromptEvent, Text},
};
use dap::{StackFrame, Thread, ThreadStates};
-use helix_core::syntax::config::{DebugArgumentValue, DebugConfigCompletion, DebugTemplate};
-use helix_dap::{self as dap, requests::TerminateArguments};
+use helix_core::syntax::{DebugArgumentValue, DebugConfigCompletion, DebugTemplate};
+use helix_dap::{self as dap, Client};
use helix_lsp::block_on;
use helix_view::editor::Breakpoint;
use serde_json::{to_value, Value};
+use tokio_stream::wrappers::UnboundedReceiverStream;
use tui::text::Spans;
use std::collections::HashMap;
@@ -58,12 +59,7 @@ fn thread_picker(
move |cx, thread, _action| callback_fn(cx.editor, thread),
)
.with_preview(move |editor, thread| {
- let frames = editor
- .debug_adapters
- .get_active_client()
- .as_ref()?
- .stack_frames
- .get(&thread.id)?;
+ let frames = editor.debugger.as_ref()?.stack_frames.get(&thread.id)?;
let frame = frames.first()?;
let path = frame.source.as_ref()?.path.as_ref()?.as_path();
let pos = Some((
@@ -120,16 +116,34 @@ pub fn dap_start_impl(
params: Option<Vec<std::borrow::Cow<str>>>,
) -> Result<(), anyhow::Error> {
let doc = doc!(cx.editor);
+
let config = doc
.language_config()
.and_then(|config| config.debugger.as_ref())
.ok_or_else(|| anyhow!("No debug adapter available for language"))?;
- let id = cx
- .editor
- .debug_adapters
- .start_client(socket, config)
- .map_err(|e| anyhow!("Failed to start debug client: {}", e))?;
+ let result = match socket {
+ Some(socket) => block_on(Client::tcp(socket, 0)),
+ None => block_on(Client::process(
+ &config.transport,
+ &config.command,
+ config.args.iter().map(|arg| arg.as_str()).collect(),
+ config.port_arg.as_deref(),
+ 0,
+ )),
+ };
+
+ let (mut debugger, events) = match result {
+ Ok(r) => r,
+ Err(e) => bail!("Failed to start debug session: {}", e),
+ };
+
+ let request = debugger.initialize(config.name.clone());
+ if let Err(e) = block_on(request) {
+ bail!("Failed to initialize debug adapter: {}", e);
+ }
+
+ debugger.quirks = config.quirks.clone();
// TODO: avoid refetching all of this... pass a config in
let template = match name {
@@ -164,13 +178,6 @@ pub fn dap_start_impl(
arr.iter().map(|v| v.replace(&pattern, &param)).collect(),
),
DebugArgumentValue::Boolean(_) => value,
- DebugArgumentValue::Table(map) => DebugArgumentValue::Table(
- map.into_iter()
- .map(|(mk, mv)| {
- (mk.replace(&pattern, &param), mv.replace(&pattern, &param))
- })
- .collect(),
- ),
};
}
}
@@ -189,9 +196,6 @@ pub fn dap_start_impl(
DebugArgumentValue::Boolean(bool) => {
args.insert(k, to_value(bool).unwrap());
}
- DebugArgumentValue::Table(map) => {
- args.insert(k, to_value(map).unwrap());
- }
}
}
@@ -205,13 +209,6 @@ pub fn dap_start_impl(
// }
};
- let debugger = match cx.editor.debug_adapters.get_client_mut(id) {
- Some(child) => child,
- None => {
- bail!("Failed to get child debugger.");
- }
- };
-
match &template.request[..] {
"launch" => {
let call = debugger.launch(args);
@@ -225,12 +222,14 @@ pub fn dap_start_impl(
};
// TODO: either await "initialized" or buffer commands until event is received
+ cx.editor.debugger = Some(debugger);
+ let stream = UnboundedReceiverStream::new(events);
+ cx.editor.debugger_events.push(stream);
Ok(())
}
pub fn dap_launch(cx: &mut Context) {
- // TODO: Now that we support multiple Clients, we could run multiple debuggers at once but for now keep this as is
- if cx.editor.debug_adapters.get_active_client().is_some() {
+ if cx.editor.debugger.is_some() {
cx.editor.set_error("Debugger is already running");
return;
}
@@ -284,7 +283,7 @@ pub fn dap_launch(cx: &mut Context) {
}
pub fn dap_restart(cx: &mut Context) {
- let debugger = match cx.editor.debug_adapters.get_active_client() {
+ let debugger = match &cx.editor.debugger {
Some(debugger) => debugger,
None => {
cx.editor.set_error("Debugger is not running");
@@ -519,16 +518,15 @@ pub fn dap_variables(cx: &mut Context) {
Some(thread_frame) => thread_frame,
None => {
cx.editor
- .set_error(format!("Failed to get stack frame for thread: {thread_id}"));
+ .set_error("Failed to get stack frame for thread: {thread_id}");
return;
}
};
let stack_frame = match thread_frame.get(frame) {
Some(stack_frame) => stack_frame,
None => {
- cx.editor.set_error(format!(
- "Failed to get stack frame for thread {thread_id} and frame {frame}."
- ));
+ cx.editor
+ .set_error("Failed to get stack frame for thread {thread_id} and frame {frame}.");
return;
}
};
@@ -583,17 +581,12 @@ pub fn dap_variables(cx: &mut Context) {
}
pub fn dap_terminate(cx: &mut Context) {
- cx.editor.set_status("Terminating debug session...");
let debugger = debugger!(cx.editor);
- let terminate_arguments = Some(TerminateArguments {
- restart: Some(false),
- });
-
- let request = debugger.terminate(terminate_arguments);
+ let request = debugger.disconnect(None);
dap_callback(cx.jobs, request, |editor, _compositor, _response: ()| {
// editor.set_error(format!("Failed to disconnect: {}", e));
- editor.debug_adapters.unset_active_client();
+ editor.debugger = None;
});
}