aboutsummaryrefslogtreecommitdiff
path: root/helix-term
diff options
context:
space:
mode:
authorSkyler Hawthorne2022-07-10 02:39:40 +0000
committerSkyler Hawthorne2022-10-19 02:31:38 +0000
commitcb23399dee723cec67f1a04dbe6514dfddfd7f5f (patch)
tree46bffb665bf15a71c05632b8c3afba1bcd14103f /helix-term
parentb8a07f7d15a10186fa2b481a3423c23f32d7d561 (diff)
improve reliability of shutdown
Diffstat (limited to 'helix-term')
-rw-r--r--helix-term/src/application.rs72
-rw-r--r--helix-term/src/commands/typed.rs8
2 files changed, 59 insertions, 21 deletions
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<str>], 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(()))?;