Make dap_start non-blocking
This commit is contained in:
parent
032aaffa15
commit
43fbb6d965
3 changed files with 61 additions and 53 deletions
|
@ -288,16 +288,12 @@ impl Client {
|
||||||
self.request::<requests::Disconnect>(()).await
|
self.request::<requests::Disconnect>(()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn launch(&mut self, args: serde_json::Value) -> Result<Value> {
|
pub fn launch(&self, args: serde_json::Value) -> impl Future<Output = Result<Value>> {
|
||||||
let response = self.request::<requests::Launch>(args).await?;
|
self.call::<requests::Launch>(args)
|
||||||
log::error!("launch response {}", response);
|
|
||||||
Ok(response)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn attach(&mut self, args: serde_json::Value) -> Result<Value> {
|
pub fn attach(&self, args: serde_json::Value) -> impl Future<Output = Result<Value>> {
|
||||||
let response = self.request::<requests::Attach>(args).await?;
|
self.call::<requests::Attach>(args)
|
||||||
log::error!("attach response {}", response);
|
|
||||||
Ok(response)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_breakpoints(
|
pub async fn set_breakpoints(
|
||||||
|
|
|
@ -2571,8 +2571,7 @@ mod cmd {
|
||||||
0 => None,
|
0 => None,
|
||||||
_ => Some(args.remove(0)),
|
_ => Some(args.remove(0)),
|
||||||
};
|
};
|
||||||
dap_start_impl(&mut cx.editor, name, None, Some(args));
|
dap_start_impl(cx, name, None, Some(args))
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_remote(
|
fn debug_remote(
|
||||||
|
@ -2589,9 +2588,7 @@ mod cmd {
|
||||||
0 => None,
|
0 => None,
|
||||||
_ => Some(args.remove(0)),
|
_ => Some(args.remove(0)),
|
||||||
};
|
};
|
||||||
dap_start_impl(&mut cx.editor, name, address, Some(args));
|
dap_start_impl(cx, name, address, Some(args))
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tutor(
|
fn tutor(
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use super::{align_view, Align, Context, Editor};
|
use super::{align_view, Align, Context, Editor};
|
||||||
use crate::{
|
use crate::{
|
||||||
compositor::Compositor,
|
compositor::{self, Compositor},
|
||||||
job::Callback,
|
job::{Callback, Jobs},
|
||||||
ui::{self, FilePicker, Picker, Popup, Prompt, PromptEvent, Text},
|
ui::{self, FilePicker, Picker, Popup, Prompt, PromptEvent, Text},
|
||||||
};
|
};
|
||||||
use helix_core::{
|
use helix_core::{
|
||||||
|
@ -16,8 +16,11 @@ use serde_json::{to_value, Value};
|
||||||
use tokio_stream::wrappers::UnboundedReceiverStream;
|
use tokio_stream::wrappers::UnboundedReceiverStream;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::future::Future;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use anyhow::bail;
|
||||||
|
|
||||||
// general utils:
|
// general utils:
|
||||||
pub fn dap_pos_to_pos(doc: &helix_core::Rope, line: usize, column: usize) -> Option<usize> {
|
pub fn dap_pos_to_pos(doc: &helix_core::Rope, line: usize, column: usize) -> Option<usize> {
|
||||||
// 1-indexing to 0 indexing
|
// 1-indexing to 0 indexing
|
||||||
|
@ -174,23 +177,39 @@ fn get_breakpoint_at_current_line(editor: &mut Editor) -> Option<(usize, Breakpo
|
||||||
|
|
||||||
// -- DAP
|
// -- DAP
|
||||||
|
|
||||||
|
fn dap_callback<T, F>(
|
||||||
|
jobs: &mut Jobs,
|
||||||
|
call: impl Future<Output = helix_dap::Result<serde_json::Value>> + 'static + Send,
|
||||||
|
callback: F,
|
||||||
|
) where
|
||||||
|
T: for<'de> serde::Deserialize<'de> + Send + 'static,
|
||||||
|
F: FnOnce(&mut Editor, &mut Compositor, T) + Send + 'static,
|
||||||
|
{
|
||||||
|
let callback = Box::pin(async move {
|
||||||
|
let json = call.await?;
|
||||||
|
let response = serde_json::from_value(json)?;
|
||||||
|
let call: Callback = Box::new(move |editor: &mut Editor, compositor: &mut Compositor| {
|
||||||
|
callback(editor, compositor, response)
|
||||||
|
});
|
||||||
|
Ok(call)
|
||||||
|
});
|
||||||
|
jobs.callback(callback);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn dap_start_impl(
|
pub fn dap_start_impl(
|
||||||
editor: &mut Editor,
|
cx: &mut compositor::Context,
|
||||||
name: Option<&str>,
|
name: Option<&str>,
|
||||||
socket: Option<std::net::SocketAddr>,
|
socket: Option<std::net::SocketAddr>,
|
||||||
params: Option<Vec<&str>>,
|
params: Option<Vec<&str>>,
|
||||||
) {
|
) -> Result<(), anyhow::Error> {
|
||||||
let doc = doc!(editor);
|
let doc = doc!(cx.editor);
|
||||||
|
|
||||||
let config = match doc
|
let config = match doc
|
||||||
.language_config()
|
.language_config()
|
||||||
.and_then(|config| config.debugger.as_ref())
|
.and_then(|config| config.debugger.as_ref())
|
||||||
{
|
{
|
||||||
Some(c) => c,
|
Some(c) => c,
|
||||||
None => {
|
None => bail!("No debug adapter available for language"),
|
||||||
editor.set_error("No debug adapter available for language".to_string());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = match socket {
|
let result = match socket {
|
||||||
|
@ -206,16 +225,12 @@ pub fn dap_start_impl(
|
||||||
|
|
||||||
let (mut debugger, events) = match result {
|
let (mut debugger, events) = match result {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
Err(e) => {
|
Err(e) => bail!("Failed to start debug session: {}", e),
|
||||||
editor.set_error(format!("Failed to start debug session: {}", e));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let request = debugger.initialize(config.name.clone());
|
let request = debugger.initialize(config.name.clone());
|
||||||
if let Err(e) = block_on(request) {
|
if let Err(e) = block_on(request) {
|
||||||
editor.set_error(format!("Failed to initialize debug adapter: {}", e));
|
bail!("Failed to initialize debug adapter: {}", e);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
debugger.quirks = config.quirks.clone();
|
debugger.quirks = config.quirks.clone();
|
||||||
|
@ -227,10 +242,7 @@ pub fn dap_start_impl(
|
||||||
};
|
};
|
||||||
let template = match template {
|
let template = match template {
|
||||||
Some(template) => template,
|
Some(template) => template,
|
||||||
None => {
|
None => bail!("No debug config with given name"),
|
||||||
editor.set_error("No debug config with given name".to_string());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut args: HashMap<&str, Value> = HashMap::new();
|
let mut args: HashMap<&str, Value> = HashMap::new();
|
||||||
|
@ -282,28 +294,29 @@ pub fn dap_start_impl(
|
||||||
|
|
||||||
let args = to_value(args).unwrap();
|
let args = to_value(args).unwrap();
|
||||||
|
|
||||||
// problem: this blocks for too long while we get back the startInTerminal REQ
|
let callback = |_editor: &mut Editor, _compositor: &mut Compositor, _response: Value| {
|
||||||
|
// if let Err(e) = result {
|
||||||
log::error!("pre start");
|
// editor.set_error(format!("Failed {} target: {}", template.request, e));
|
||||||
let result = match &template.request[..] {
|
// }
|
||||||
"launch" => block_on(debugger.launch(args)),
|
|
||||||
"attach" => block_on(debugger.attach(args)),
|
|
||||||
_ => {
|
|
||||||
editor.set_error("Unsupported request".to_string());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
log::error!("post start");
|
|
||||||
if let Err(e) = result {
|
match &template.request[..] {
|
||||||
let msg = format!("Failed {} target: {}", template.request, e);
|
"launch" => {
|
||||||
editor.set_error(msg);
|
let call = debugger.launch(args);
|
||||||
return;
|
dap_callback(cx.jobs, call, callback);
|
||||||
}
|
}
|
||||||
|
"attach" => {
|
||||||
|
let call = debugger.attach(args);
|
||||||
|
dap_callback(cx.jobs, call, callback);
|
||||||
|
}
|
||||||
|
request => bail!("Unsupported request '{}'", request),
|
||||||
|
};
|
||||||
|
|
||||||
// TODO: either await "initialized" or buffer commands until event is received
|
// TODO: either await "initialized" or buffer commands until event is received
|
||||||
editor.debugger = Some(debugger);
|
cx.editor.debugger = Some(debugger);
|
||||||
let stream = UnboundedReceiverStream::new(events);
|
let stream = UnboundedReceiverStream::new(events);
|
||||||
editor.debugger_events.push(stream);
|
cx.editor.debugger_events.push(stream);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dap_launch(cx: &mut Context) {
|
pub fn dap_launch(cx: &mut Context) {
|
||||||
|
@ -404,12 +417,14 @@ fn debug_parameter_prompt(
|
||||||
});
|
});
|
||||||
cx.jobs.callback(callback);
|
cx.jobs.callback(callback);
|
||||||
} else {
|
} else {
|
||||||
dap_start_impl(
|
if let Err(e) = dap_start_impl(
|
||||||
cx.editor,
|
cx,
|
||||||
Some(&config_name),
|
Some(&config_name),
|
||||||
None,
|
None,
|
||||||
Some(params.iter().map(|x| x.as_str()).collect()),
|
Some(params.iter().map(|x| x.as_str()).collect()),
|
||||||
);
|
) {
|
||||||
|
cx.editor.set_error(e.to_string());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Reference in a new issue