@@ -35,8 +35,8 @@ use crate::{
35 ui::{self, Completion, Picker, Popup, Prompt, PromptEvent},
35 ui::{self, Completion, Picker, Popup, Prompt, PromptEvent},
38−use crate::application::{LspCallback, LspCallbackWrapper, LspCallbacks};
38+use crate::job::{self, Job, JobFuture, Jobs};
39−use futures_util::FutureExt;
39+use futures_util::{FutureExt, TryFutureExt};
40use std::{fmt, future::Future, path::Display, str::FromStr};
40use std::{fmt, future::Future, path::Display, str::FromStr};
@@ -54,7 +54,7 @@ pub struct Context<'a> {
55 pub callback: Option<crate::compositor::Callback>,
55 pub callback: Option<crate::compositor::Callback>,
56 pub on_next_key_callback: Option<Box<dyn FnOnce(&mut Context, KeyEvent)>>,
56 pub on_next_key_callback: Option<Box<dyn FnOnce(&mut Context, KeyEvent)>>,
57− pub callbacks: &'a mut LspCallbacks,
57+ pub jobs: &'a mut Jobs,
60impl<'a> Context<'a> {
60impl<'a> Context<'a> {
@@ -85,13 +85,13 @@ impl<'a> Context<'a> {
85 let callback = Box::pin(async move {
85 let callback = Box::pin(async move {
86 let json = call.await?;
86 let json = call.await?;
87 let response = serde_json::from_value(json)?;
87 let response = serde_json::from_value(json)?;
88− let call: LspCallbackWrapper =
88+ let call: job::Callback =
89 Box::new(move |editor: &mut Editor, compositor: &mut Compositor| {
89 Box::new(move |editor: &mut Editor, compositor: &mut Compositor| {
90 callback(editor, compositor, response)
90 callback(editor, compositor, response)
94− self.callbacks.push(callback);
94+ self.jobs.callback(callback);
97 /// Returns 1 if no explicit count was provided
97 /// Returns 1 if no explicit count was provided
@@ -1149,7 +1149,7 @@ mod cmd {
1149 path: Option<P>,
1149 path: Option<P>,
1150 ) -> Result<tokio::task::JoinHandle<Result<(), anyhow::Error>>, anyhow::Error> {
1150 ) -> Result<tokio::task::JoinHandle<Result<(), anyhow::Error>>, anyhow::Error> {
1151 use anyhow::anyhow;
1151 use anyhow::anyhow;
1152− let callbacks = &mut cx.callbacks;
1152+ let jobs = &mut cx.jobs;
1153 let (view, doc) = current!(cx.editor);
1153 let (view, doc) = current!(cx.editor);
1155 if let Some(path) = path {
1155 if let Some(path) = path {
@@ -1168,7 +1168,7 @@ mod cmd {
1168 doc.format().map(|fmt| {
1168 doc.format().map(|fmt| {
1169 let shared = fmt.shared();
1169 let shared = fmt.shared();
1170 let callback = make_format_callback(doc.id(), doc.version(), true, shared.clone());
1170 let callback = make_format_callback(doc.id(), doc.version(), true, shared.clone());
1171− callbacks.push(callback);
1171+ jobs.callback(callback);
1174 } else {
1174 } else {
@@ -1178,8 +1178,12 @@ mod cmd {
1180 fn write(cx: &mut compositor::Context, args: &[&str], event: PromptEvent) {
1180 fn write(cx: &mut compositor::Context, args: &[&str], event: PromptEvent) {
1181− if let Err(e) = write_impl(cx, args.first()) {
1181+ match write_impl(cx, args.first()) {
1182− cx.editor.set_error(e.to_string());
1182+ Err(e) => cx.editor.set_error(e.to_string()),
1185+ .add(Job::new(handle.unwrap_or_else(|e| Err(e.into()))).wait_before_exiting());
@@ -1192,7 +1196,7 @@ mod cmd {
1193 if let Some(format) = doc.format() {
1197 if let Some(format) = doc.format() {
1194 let callback = make_format_callback(doc.id(), doc.version(), false, format);
1198 let callback = make_format_callback(doc.id(), doc.version(), false, format);
1195− cx.callbacks.push(callback);
1199+ cx.jobs.callback(callback);
@@ -1918,10 +1922,10 @@ fn make_format_callback(
1918 doc_version: i32,
1922 doc_version: i32,
1919 set_unmodified: bool,
1923 set_unmodified: bool,
1920 format: impl Future<Output = helix_lsp::util::LspFormatting> + Send + 'static,
1924 format: impl Future<Output = helix_lsp::util::LspFormatting> + Send + 'static,
1921−) -> LspCallback {
1925+) -> impl Future<Output = anyhow::Result<job::Callback>> {
1922− Box::pin(async move {
1926+ async move {
1923 let format = format.await;
1927 let format = format.await;
1924− let call: LspCallbackWrapper =
1928+ let call: job::Callback =
1925 Box::new(move |editor: &mut Editor, compositor: &mut Compositor| {
1929 Box::new(move |editor: &mut Editor, compositor: &mut Compositor| {
1926 let view_id = view!(editor).id;
1930 let view_id = view!(editor).id;
1927 if let Some(doc) = editor.document_mut(doc_id) {
1931 if let Some(doc) = editor.document_mut(doc_id) {
@@ -1937,7 +1941,7 @@ fn make_format_callback(
1939 Ok(call)
1943 Ok(call)
1943enum Open {
1947enum Open {