mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-22 01:16:18 +04:00
fix(command): write-quit: do not quit if write fails
During write-quit, if the file fails to be written for any reason, helix will still quit without saving the changes. This fixes this behavior by introducing fallibility to the asynchronous job queues. This will also benefit all contexts which may depend on these job queues. Fixes #1575
This commit is contained in:
parent
fac36bc5ea
commit
41bf1d5811
@ -814,7 +814,7 @@ pub async fn run<S>(&mut self, input_stream: &mut S) -> Result<i32, Error>
|
||||
}
|
||||
|
||||
pub async fn close(&mut self) -> anyhow::Result<()> {
|
||||
self.jobs.finish().await;
|
||||
self.jobs.finish().await?;
|
||||
|
||||
if self.editor.close_language_servers(None).await.is_err() {
|
||||
log::error!("Timed out waiting for language servers to shutdown");
|
||||
|
@ -233,6 +233,7 @@ fn write_impl(
|
||||
doc.detect_language(cx.editor.syn_loader.clone());
|
||||
let _ = cx.editor.refresh_language_server(id);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -422,6 +423,7 @@ fn write_quit(
|
||||
event: PromptEvent,
|
||||
) -> anyhow::Result<()> {
|
||||
write_impl(cx, args.first(), false)?;
|
||||
helix_lsp::block_on(cx.jobs.finish())?;
|
||||
quit(cx, &[], event)
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use crate::compositor::Compositor;
|
||||
|
||||
use futures_util::future::{self, BoxFuture, Future, FutureExt};
|
||||
use futures_util::future::{BoxFuture, Future, FutureExt};
|
||||
use futures_util::stream::{FuturesUnordered, StreamExt};
|
||||
|
||||
pub type Callback = Box<dyn FnOnce(&mut Editor, &mut Compositor) + Send>;
|
||||
@ -93,9 +93,21 @@ pub fn add(&self, j: Job) {
|
||||
}
|
||||
|
||||
/// Blocks until all the jobs that need to be waited on are done.
|
||||
pub async fn finish(&mut self) {
|
||||
let wait_futures = std::mem::take(&mut self.wait_futures);
|
||||
pub async fn finish(&mut self) -> anyhow::Result<()> {
|
||||
log::debug!("waiting on jobs...");
|
||||
wait_futures.for_each(|_| future::ready(())).await
|
||||
let mut wait_futures = std::mem::take(&mut self.wait_futures);
|
||||
while let (Some(job), tail) = wait_futures.into_future().await {
|
||||
match job {
|
||||
Ok(_) => {
|
||||
wait_futures = tail;
|
||||
}
|
||||
Err(e) => {
|
||||
self.wait_futures = tail;
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore]
|
||||
async fn test_write_quit_fail() -> anyhow::Result<()> {
|
||||
let file = helpers::new_readonly_tempfile()?;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user