on master help sign in
Make dap_start non-blocking
commit43fbb6d965ad5a1a6cd07c0646a0e6b278ff5397 authorBlaž Hrastnik <blaz@mxxn.io> dateFri 3 Dec 2021, 13:27 (5 years ago) parent032aaff
3 files changed+59−51
helix-dap/src/client.rs+4−8 helix-term/src/commands.rs+2−5 helix-term/src/commands/dap.rs+53−38
helix-dap/src/client.rs+4−8
@@ -288,16 +288,12 @@ impl Client {
288288 self.request::<requests::Disconnect>(()).await
289289 }
290290
291− pub async fn launch(&mut self, args: serde_json::Value) -> Result<Value> {
292− let response = self.request::<requests::Launch>(args).await?;
293− log::error!("launch response {}", response);
294− Ok(response)
291+ pub fn launch(&self, args: serde_json::Value) -> impl Future<Output = Result<Value>> {
292+ self.call::<requests::Launch>(args)
295293 }
296294
297− pub async fn attach(&mut self, args: serde_json::Value) -> Result<Value> {
298− let response = self.request::<requests::Attach>(args).await?;
299− log::error!("attach response {}", response);
300− Ok(response)
295+ pub fn attach(&self, args: serde_json::Value) -> impl Future<Output = Result<Value>> {
296+ self.call::<requests::Attach>(args)
301297 }
302298
303299 pub async fn set_breakpoints(
helix-term/src/commands.rs+2−5
@@ -2571,8 +2571,7 @@ mod cmd {
25712571 0 => None,
25722572 _ => Some(args.remove(0)),
25732573 };
2574− dap_start_impl(&mut cx.editor, name, None, Some(args));
2575− Ok(())
2574+ dap_start_impl(cx, name, None, Some(args))
25762575 }
25772576
25782577 fn debug_remote(
@@ -2589,9 +2588,7 @@ mod cmd {
25892588 0 => None,
25902589 _ => Some(args.remove(0)),
25912590 };
2592− dap_start_impl(&mut cx.editor, name, address, Some(args));
2593−
2594− Ok(())
2591+ dap_start_impl(cx, name, address, Some(args))
25952592 }
25962593
25972594 fn tutor(
helix-term/src/commands/dap.rs+53−38
@@ -1,7 +1,7 @@
11use super::{align_view, Align, Context, Editor};
22use crate::{
3− compositor::Compositor,
4− job::Callback,
3+ compositor::{self, Compositor},
4+ job::{Callback, Jobs},
55 ui::{self, FilePicker, Picker, Popup, Prompt, PromptEvent, Text},
66};
77use helix_core::{
@@ -16,8 +16,11 @@ use serde_json::{to_value, Value};
1616use tokio_stream::wrappers::UnboundedReceiverStream;
1717
1818use std::collections::HashMap;
19+use std::future::Future;
1920use std::path::PathBuf;
2021
22+use anyhow::bail;
23+
2124// general utils:
2225pub fn dap_pos_to_pos(doc: &helix_core::Rope, line: usize, column: usize) -> Option<usize> {
2326 // 1-indexing to 0 indexing
@@ -174,23 +177,39 @@ fn get_breakpoint_at_current_line(editor: &mut Editor) -> Option<(usize, Breakpo
174177
175178// -- DAP
176179
180+fn dap_callback<T, F>(
181+ jobs: &mut Jobs,
182+ call: impl Future<Output = helix_dap::Result<serde_json::Value>> + 'static + Send,
183+ callback: F,
184+) where
185+ T: for<'de> serde::Deserialize<'de> + Send + 'static,
186+ F: FnOnce(&mut Editor, &mut Compositor, T) + Send + 'static,
187+{
188+ let callback = Box::pin(async move {
189+ let json = call.await?;
190+ let response = serde_json::from_value(json)?;
191+ let call: Callback = Box::new(move |editor: &mut Editor, compositor: &mut Compositor| {
192+ callback(editor, compositor, response)
193+ });
194+ Ok(call)
195+ });
196+ jobs.callback(callback);
197+}
198+
177199pub fn dap_start_impl(
178− editor: &mut Editor,
200+ cx: &mut compositor::Context,
179201 name: Option<&str>,
180202 socket: Option<std::net::SocketAddr>,
181203 params: Option<Vec<&str>>,
182−) {
183− let doc = doc!(editor);
204+) -> Result<(), anyhow::Error> {
205+ let doc = doc!(cx.editor);
184206
185207 let config = match doc
186208 .language_config()
187209 .and_then(|config| config.debugger.as_ref())
188210 {
189211 Some(c) => c,
190− None => {
191− editor.set_error("No debug adapter available for language".to_string());
192− return;
193− }
212+ None => bail!("No debug adapter available for language"),
194213 };
195214
196215 let result = match socket {
@@ -206,16 +225,12 @@ pub fn dap_start_impl(
206225
207226 let (mut debugger, events) = match result {
208227 Ok(r) => r,
209− Err(e) => {
210− editor.set_error(format!("Failed to start debug session: {}", e));
211− return;
212− }
228+ Err(e) => bail!("Failed to start debug session: {}", e),
213229 };
214230
215231 let request = debugger.initialize(config.name.clone());
216232 if let Err(e) = block_on(request) {
217− editor.set_error(format!("Failed to initialize debug adapter: {}", e));
218− return;
233+ bail!("Failed to initialize debug adapter: {}", e);
219234 }
220235
221236 debugger.quirks = config.quirks.clone();
@@ -227,10 +242,7 @@ pub fn dap_start_impl(
227242 };
228243 let template = match template {
229244 Some(template) => template,
230− None => {
231− editor.set_error("No debug config with given name".to_string());
232− return;
233− }
245+ None => bail!("No debug config with given name"),
234246 };
235247
236248 let mut args: HashMap<&str, Value> = HashMap::new();
@@ -282,28 +294,29 @@ pub fn dap_start_impl(
282294
283295 let args = to_value(args).unwrap();
284296
285− // problem: this blocks for too long while we get back the startInTerminal REQ
297+ let callback = |_editor: &mut Editor, _compositor: &mut Compositor, _response: Value| {
298+ // if let Err(e) = result {
299+ // editor.set_error(format!("Failed {} target: {}", template.request, e));
300+ // }
301+ };
286302
287− log::error!("pre start");
288− let result = match &template.request[..] {
289− "launch" => block_on(debugger.launch(args)),
290− "attach" => block_on(debugger.attach(args)),
291− _ => {
292− editor.set_error("Unsupported request".to_string());
293− return;
303+ match &template.request[..] {
304+ "launch" => {
305+ let call = debugger.launch(args);
306+ dap_callback(cx.jobs, call, callback);
307+ }
308+ "attach" => {
309+ let call = debugger.attach(args);
310+ dap_callback(cx.jobs, call, callback);
294311 }
312+ request => bail!("Unsupported request '{}'", request),
295313 };
296− log::error!("post start");
297− if let Err(e) = result {
298− let msg = format!("Failed {} target: {}", template.request, e);
299− editor.set_error(msg);
300− return;
301− }
302314
303315 // TODO: either await "initialized" or buffer commands until event is received
304− editor.debugger = Some(debugger);
316+ cx.editor.debugger = Some(debugger);
305317 let stream = UnboundedReceiverStream::new(events);
306− editor.debugger_events.push(stream);
318+ cx.editor.debugger_events.push(stream);
319+ Ok(())
307320}
308321
309322pub fn dap_launch(cx: &mut Context) {
@@ -404,12 +417,14 @@ fn debug_parameter_prompt(
404417 });
405418 cx.jobs.callback(callback);
406419 } else {
407− dap_start_impl(
408− cx.editor,
420+ if let Err(e) = dap_start_impl(
421+ cx,
409422 Some(&config_name),
410423 None,
411424 Some(params.iter().map(|x| x.as_str()).collect()),
412− );
425+ ) {
426+ cx.editor.set_error(e.to_string());
427+ }
413428 }
414429 },
415430 )