aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSkyler Hawthorne2022-07-10 02:39:40 +0000
committerSkyler Hawthorne2022-10-19 02:31:38 +0000
commitcb23399dee723cec67f1a04dbe6514dfddfd7f5f (patch)
tree46bffb665bf15a71c05632b8c3afba1bcd14103f
parentb8a07f7d15a10186fa2b481a3423c23f32d7d561 (diff)
improve reliability of shutdown
-rw-r--r--helix-term/src/application.rs72
-rw-r--r--helix-term/src/commands/typed.rs8
-rw-r--r--helix-view/src/document.rs17
-rw-r--r--helix-view/src/editor.rs8
4 files changed, 80 insertions, 25 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(()))?;
diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs
index b6e42065..1743fac2 100644
--- a/helix-view/src/document.rs
+++ b/helix-view/src/document.rs
@@ -551,6 +551,11 @@ impl Document {
bail!("saves are closed for this document!");
}
+ log::debug!(
+ "submitting save of doc '{:?}'",
+ self.path().map(|path| path.to_string_lossy())
+ );
+
// we clone and move text + path into the future so that we asynchronously save the current
// state without blocking any further edits.
let mut text = self.text().clone();
@@ -695,7 +700,14 @@ impl Document {
self.set_last_saved_revision(event.revision);
false
}
- Err(_) => true,
+ Err(err) => {
+ log::error!(
+ "error saving document {:?}: {}",
+ self.path().map(|path| path.to_string_lossy()),
+ err
+ );
+ true
+ }
};
final_result = Some(save_event);
@@ -1072,7 +1084,8 @@ impl Document {
let current_revision = history.current_revision();
self.history.set(history);
log::debug!(
- "modified - last saved: {}, current: {}",
+ "id {} modified - last saved: {}, current: {}",
+ self.id,
self.last_saved_revision,
current_revision
);
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index e54aa7fa..58fcf238 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -816,12 +816,16 @@ impl Editor {
#[inline]
pub fn set_status<T: Into<Cow<'static, str>>>(&mut self, status: T) {
- self.status_msg = Some((status.into(), Severity::Info));
+ let status = status.into();
+ log::debug!("editor status: {}", status);
+ self.status_msg = Some((status, Severity::Info));
}
#[inline]
pub fn set_error<T: Into<Cow<'static, str>>>(&mut self, error: T) {
- self.status_msg = Some((error.into(), Severity::Error));
+ let error = error.into();
+ log::error!("editor error: {}", error);
+ self.status_msg = Some((error, Severity::Error));
}
#[inline]