aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBlaž Hrastnik2021-12-05 05:52:56 +0000
committerBlaž Hrastnik2021-12-06 00:35:59 +0000
commitdc8df7ba219d9a403ee77027dd5a698f08a1dcce (patch)
tree57802ebae4f4068fe5e3917542ec21f1e8f51d94
parent2b4de41bf0e0fc7d276e99f6359c9062df65473d (diff)
Make thread_picker non-blocking
-rw-r--r--helix-dap/src/client.rs9
-rw-r--r--helix-term/src/application.rs4
-rw-r--r--helix-term/src/commands/dap.rs88
3 files changed, 54 insertions, 47 deletions
diff --git a/helix-dap/src/client.rs b/helix-dap/src/client.rs
index 9598e24e..651bf4d6 100644
--- a/helix-dap/src/client.rs
+++ b/helix-dap/src/client.rs
@@ -209,7 +209,7 @@ impl Client {
}
/// Execute a RPC request on the debugger.
- fn call<R: crate::types::Request>(
+ pub fn call<R: crate::types::Request>(
&self,
arguments: R::Arguments,
) -> impl Future<Output = Result<Value>>
@@ -248,7 +248,7 @@ impl Client {
}
}
- async fn request<R: crate::types::Request>(&self, params: R::Arguments) -> Result<R::Result>
+ pub async fn request<R: crate::types::Request>(&self, params: R::Arguments) -> Result<R::Result>
where
R::Arguments: serde::Serialize,
R::Result: core::fmt::Debug, // TODO: temporary
@@ -384,9 +384,8 @@ impl Client {
Ok((response.stack_frames, response.total_frames))
}
- pub async fn threads(&self) -> Result<Vec<Thread>> {
- let response = self.request::<requests::Threads>(()).await?;
- Ok(response.threads)
+ pub fn threads(&self) -> impl Future<Output = Result<Value>> {
+ self.call::<requests::Threads>(())
}
pub async fn scopes(&self, frame_id: usize) -> Result<Vec<Scope>> {
diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs
index c2daaa6b..55e4bb03 100644
--- a/helix-term/src/application.rs
+++ b/helix-term/src/application.rs
@@ -340,8 +340,8 @@ impl Application {
let all_threads_stopped = all_threads_stopped.unwrap_or_default();
if all_threads_stopped {
- if let Ok(threads) = debugger.threads().await {
- for thread in threads {
+ if let Ok(response) = debugger.request::<dap::requests::Threads>(()).await {
+ for thread in response.threads {
fetch_stack_trace(debugger, thread.id).await;
}
select_thread_id(
diff --git a/helix-term/src/commands/dap.rs b/helix-term/src/commands/dap.rs
index d256e5c4..336ccf1a 100644
--- a/helix-term/src/commands/dap.rs
+++ b/helix-term/src/commands/dap.rs
@@ -19,7 +19,7 @@ use std::collections::HashMap;
use std::future::Future;
use std::path::PathBuf;
-use anyhow::bail;
+use anyhow::{anyhow, bail};
// general utils:
pub fn dap_pos_to_pos(doc: &helix_core::Rope, line: usize, column: usize) -> Option<usize> {
@@ -99,53 +99,61 @@ pub fn jump_to_stack_frame(editor: &mut Editor, frame: &helix_dap::StackFrame) {
align_view(doc, view, Align::Center);
}
-fn thread_picker(cx: &mut Context, callback_fn: impl Fn(&mut Editor, &dap::Thread) + 'static) {
+fn thread_picker(
+ cx: &mut Context,
+ callback_fn: impl Fn(&mut Editor, &dap::Thread) + Send + 'static,
+) {
let debugger = match &mut cx.editor.debugger {
Some(debugger) => debugger,
None => return,
};
- let threads = match block_on(debugger.threads()) {
- Ok(threads) => threads,
- Err(e) => {
- cx.editor
- .set_error(format!("Failed to retrieve threads: {}", e));
- return;
- }
- };
-
- if threads.len() == 1 {
- callback_fn(cx.editor, &threads[0]);
- return;
- }
+ let future = debugger.threads();
+ dap_callback(
+ cx.jobs,
+ future,
+ move |editor: &mut Editor,
+ compositor: &mut Compositor,
+ response: dap::requests::ThreadsResponse| {
+ let threads = response.threads;
+ if threads.len() == 1 {
+ callback_fn(editor, &threads[0]);
+ return;
+ }
+ let debugger = match &mut editor.debugger {
+ Some(debugger) => debugger,
+ None => return,
+ };
- let thread_states = debugger.thread_states.clone();
- let picker = FilePicker::new(
- threads,
- move |thread| {
- format!(
- "{} ({})",
- thread.name,
- thread_states
- .get(&thread.id)
- .map(|state| state.as_str())
- .unwrap_or("unknown")
- )
- .into()
- },
- move |cx, thread, _action| callback_fn(cx.editor, thread),
- move |editor, thread| {
- let frames = editor.debugger.as_ref()?.stack_frames.get(&thread.id)?;
- let frame = frames.get(0)?;
- let path = frame.source.as_ref()?.path.clone()?;
- let pos = Some((
- frame.line.saturating_sub(1),
- frame.end_line.unwrap_or(frame.line).saturating_sub(1),
- ));
- Some((path, pos))
+ let thread_states = debugger.thread_states.clone();
+ let picker = FilePicker::new(
+ threads,
+ move |thread| {
+ format!(
+ "{} ({})",
+ thread.name,
+ thread_states
+ .get(&thread.id)
+ .map(|state| state.as_str())
+ .unwrap_or("unknown")
+ )
+ .into()
+ },
+ move |cx, thread, _action| callback_fn(cx.editor, thread),
+ move |editor, thread| {
+ let frames = editor.debugger.as_ref()?.stack_frames.get(&thread.id)?;
+ let frame = frames.get(0)?;
+ let path = frame.source.as_ref()?.path.clone()?;
+ let pos = Some((
+ frame.line.saturating_sub(1),
+ frame.end_line.unwrap_or(frame.line).saturating_sub(1),
+ ));
+ Some((path, pos))
+ },
+ );
+ compositor.push(Box::new(picker));
},
);
- cx.push_layer(Box::new(picker))
}
fn get_breakpoint_at_current_line(editor: &mut Editor) -> Option<(usize, Breakpoint)> {