From cb23399dee723cec67f1a04dbe6514dfddfd7f5f Mon Sep 17 00:00:00 2001 From: Skyler Hawthorne Date: Sat, 9 Jul 2022 22:39:40 -0400 Subject: improve reliability of shutdown --- helix-term/src/application.rs | 72 +++++++++++++++++++++++++++++----------- helix-term/src/commands/typed.rs | 8 ++++- 2 files changed, 59 insertions(+), 21 deletions(-) (limited to 'helix-term') diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index fd9b7c3e..e84739cd 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -937,26 +937,26 @@ impl Application { self.event_loop(input_stream).await; - let mut save_errs = Vec::new(); - - for doc in self.editor.documents_mut() { - if let Some(Err(err)) = doc.close().await { - save_errs.push(( - doc.path() - .map(|path| path.to_string_lossy().into_owned()) - .unwrap_or_else(|| "".into()), - err, - )); - } - } + // let mut save_errs = Vec::new(); + + // for doc in self.editor.documents_mut() { + // if let Some(Err(err)) = doc.close().await { + // save_errs.push(( + // doc.path() + // .map(|path| path.to_string_lossy().into_owned()) + // .unwrap_or_else(|| "".into()), + // err, + // )); + // } + // } let close_err = self.close().await.err(); restore_term()?; - for (path, err) in save_errs { - self.editor.exit_code = 1; - eprintln!("Error closing '{}': {}", path, err); - } + // for (path, err) in save_errs { + // self.editor.exit_code = 1; + // eprintln!("Error closing '{}': {}", path, err); + // } if let Some(err) = close_err { self.editor.exit_code = 1; @@ -967,12 +967,44 @@ impl Application { } pub async fn close(&mut self) -> anyhow::Result<()> { - self.jobs.finish().await?; + // [NOTE] we intentionally do not return early for errors because we + // want to try to run as much cleanup as we can, regardless of + // errors along the way - if self.editor.close_language_servers(None).await.is_err() { - log::error!("Timed out waiting for language servers to shutdown"); + let mut result = match self.jobs.finish().await { + Ok(_) => Ok(()), + Err(err) => { + log::error!("Error executing job: {}", err); + Err(err) + } }; - Ok(()) + for doc in self.editor.documents_mut() { + if let Some(save_result) = doc.close().await { + result = match save_result { + Ok(_) => result, + Err(err) => { + if let Some(path) = doc.path() { + log::error!( + "Error saving document '{}': {}", + path.to_string_lossy(), + err + ); + } + Err(err) + } + }; + } + } + + match self.editor.close_language_servers(None).await { + Ok(_) => result, + Err(_) => { + log::error!("Timed out waiting for language servers to shutdown"); + Err(anyhow::format_err!( + "Timed out waiting for language servers to shutdown" + )) + } + } } } diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 14b23f2a..650ff75d 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -1,5 +1,7 @@ use std::ops::Deref; +use crate::job::Job; + use super::*; use helix_view::{ @@ -19,6 +21,8 @@ pub struct TypableCommand { } fn quit(cx: &mut compositor::Context, args: &[Cow], event: PromptEvent) -> anyhow::Result<()> { + log::info!("quitting..."); + if event != PromptEvent::Validate { return Ok(()); } @@ -274,7 +278,7 @@ fn write_impl( doc.auto_format().map(|fmt| { let shared = fmt.shared(); let callback = make_format_callback(doc.id(), doc.version(), shared.clone()); - jobs.callback(callback); + jobs.add(Job::with_callback(callback).wait_before_exiting()); shared }) } else { @@ -512,8 +516,10 @@ fn write_quit( } write_impl(cx, args.first(), false)?; + let doc = doc_mut!(cx.editor); + tokio::task::block_in_place(|| helix_lsp::block_on(cx.jobs.finish()))?; tokio::task::block_in_place(|| helix_lsp::block_on(doc.try_flush_saves())) .map(|result| result.map(|_| ())) .unwrap_or(Ok(()))?; -- cgit v1.2.3-70-g09d2