mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-22 09:26:19 +04:00
Make dap_start non-blocking
This commit is contained in:
parent
032aaffa15
commit
43fbb6d965
@ -288,16 +288,12 @@ pub async fn disconnect(&mut self) -> Result<()> {
|
||||
self.request::<requests::Disconnect>(()).await
|
||||
}
|
||||
|
||||
pub async fn launch(&mut self, args: serde_json::Value) -> Result<Value> {
|
||||
let response = self.request::<requests::Launch>(args).await?;
|
||||
log::error!("launch response {}", response);
|
||||
Ok(response)
|
||||
pub fn launch(&self, args: serde_json::Value) -> impl Future<Output = Result<Value>> {
|
||||
self.call::<requests::Launch>(args)
|
||||
}
|
||||
|
||||
pub async fn attach(&mut self, args: serde_json::Value) -> Result<Value> {
|
||||
let response = self.request::<requests::Attach>(args).await?;
|
||||
log::error!("attach response {}", response);
|
||||
Ok(response)
|
||||
pub fn attach(&self, args: serde_json::Value) -> impl Future<Output = Result<Value>> {
|
||||
self.call::<requests::Attach>(args)
|
||||
}
|
||||
|
||||
pub async fn set_breakpoints(
|
||||
|
@ -2571,8 +2571,7 @@ fn debug_start(
|
||||
0 => None,
|
||||
_ => Some(args.remove(0)),
|
||||
};
|
||||
dap_start_impl(&mut cx.editor, name, None, Some(args));
|
||||
Ok(())
|
||||
dap_start_impl(cx, name, None, Some(args))
|
||||
}
|
||||
|
||||
fn debug_remote(
|
||||
@ -2589,9 +2588,7 @@ fn debug_remote(
|
||||
0 => None,
|
||||
_ => Some(args.remove(0)),
|
||||
};
|
||||
dap_start_impl(&mut cx.editor, name, address, Some(args));
|
||||
|
||||
Ok(())
|
||||
dap_start_impl(cx, name, address, Some(args))
|
||||
}
|
||||
|
||||
fn tutor(
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::{align_view, Align, Context, Editor};
|
||||
use crate::{
|
||||
compositor::Compositor,
|
||||
job::Callback,
|
||||
compositor::{self, Compositor},
|
||||
job::{Callback, Jobs},
|
||||
ui::{self, FilePicker, Picker, Popup, Prompt, PromptEvent, Text},
|
||||
};
|
||||
use helix_core::{
|
||||
@ -16,8 +16,11 @@
|
||||
use tokio_stream::wrappers::UnboundedReceiverStream;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::future::Future;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::bail;
|
||||
|
||||
// general utils:
|
||||
pub fn dap_pos_to_pos(doc: &helix_core::Rope, line: usize, column: usize) -> Option<usize> {
|
||||
// 1-indexing to 0 indexing
|
||||
@ -174,23 +177,39 @@ fn get_breakpoint_at_current_line(editor: &mut Editor) -> Option<(usize, Breakpo
|
||||
|
||||
// -- 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(
|
||||
editor: &mut Editor,
|
||||
cx: &mut compositor::Context,
|
||||
name: Option<&str>,
|
||||
socket: Option<std::net::SocketAddr>,
|
||||
params: Option<Vec<&str>>,
|
||||
) {
|
||||
let doc = doc!(editor);
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let doc = doc!(cx.editor);
|
||||
|
||||
let config = match doc
|
||||
.language_config()
|
||||
.and_then(|config| config.debugger.as_ref())
|
||||
{
|
||||
Some(c) => c,
|
||||
None => {
|
||||
editor.set_error("No debug adapter available for language".to_string());
|
||||
return;
|
||||
}
|
||||
None => bail!("No debug adapter available for language"),
|
||||
};
|
||||
|
||||
let result = match socket {
|
||||
@ -206,16 +225,12 @@ pub fn dap_start_impl(
|
||||
|
||||
let (mut debugger, events) = match result {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
editor.set_error(format!("Failed to start debug session: {}", e));
|
||||
return;
|
||||
}
|
||||
Err(e) => bail!("Failed to start debug session: {}", e),
|
||||
};
|
||||
|
||||
let request = debugger.initialize(config.name.clone());
|
||||
if let Err(e) = block_on(request) {
|
||||
editor.set_error(format!("Failed to initialize debug adapter: {}", e));
|
||||
return;
|
||||
bail!("Failed to initialize debug adapter: {}", e);
|
||||
}
|
||||
|
||||
debugger.quirks = config.quirks.clone();
|
||||
@ -227,10 +242,7 @@ pub fn dap_start_impl(
|
||||
};
|
||||
let template = match template {
|
||||
Some(template) => template,
|
||||
None => {
|
||||
editor.set_error("No debug config with given name".to_string());
|
||||
return;
|
||||
}
|
||||
None => bail!("No debug config with given name"),
|
||||
};
|
||||
|
||||
let mut args: HashMap<&str, Value> = HashMap::new();
|
||||
@ -282,28 +294,29 @@ pub fn dap_start_impl(
|
||||
|
||||
let args = to_value(args).unwrap();
|
||||
|
||||
// problem: this blocks for too long while we get back the startInTerminal REQ
|
||||
|
||||
log::error!("pre start");
|
||||
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;
|
||||
}
|
||||
let callback = |_editor: &mut Editor, _compositor: &mut Compositor, _response: Value| {
|
||||
// if let Err(e) = result {
|
||||
// editor.set_error(format!("Failed {} target: {}", template.request, e));
|
||||
// }
|
||||
};
|
||||
|
||||
match &template.request[..] {
|
||||
"launch" => {
|
||||
let call = debugger.launch(args);
|
||||
dap_callback(cx.jobs, call, callback);
|
||||
}
|
||||
"attach" => {
|
||||
let call = debugger.attach(args);
|
||||
dap_callback(cx.jobs, call, callback);
|
||||
}
|
||||
request => bail!("Unsupported request '{}'", request),
|
||||
};
|
||||
log::error!("post start");
|
||||
if let Err(e) = result {
|
||||
let msg = format!("Failed {} target: {}", template.request, e);
|
||||
editor.set_error(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
// 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);
|
||||
editor.debugger_events.push(stream);
|
||||
cx.editor.debugger_events.push(stream);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn dap_launch(cx: &mut Context) {
|
||||
@ -404,12 +417,14 @@ fn debug_parameter_prompt(
|
||||
});
|
||||
cx.jobs.callback(callback);
|
||||
} else {
|
||||
dap_start_impl(
|
||||
cx.editor,
|
||||
if let Err(e) = dap_start_impl(
|
||||
cx,
|
||||
Some(&config_name),
|
||||
None,
|
||||
Some(params.iter().map(|x| x.as_str()).collect()),
|
||||
);
|
||||
) {
|
||||
cx.editor.set_error(e.to_string());
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user