aboutsummaryrefslogtreecommitdiff
path: root/helix-view/src
diff options
context:
space:
mode:
authorSkyler Hawthorne2022-04-24 19:33:43 +0000
committerSkyler Hawthorne2022-10-19 02:31:38 +0000
commit83b6042b97d13fca751e3d5d0c32f04e3ad04c9a (patch)
tree42fb0367fcd09868371687e3ccbe27abf2de4762 /helix-view/src
parenta5a93182cd5ccf88bc95b68044aa05d746ded35e (diff)
fix(write): do not set new path on document until write succeeds
If a document is written with a new path, currently, in the event that the write fails, the document still gets its path changed. This fixes it so that the path is not updated unless the write succeeds.
Diffstat (limited to 'helix-view/src')
-rw-r--r--helix-view/src/document.rs52
1 files changed, 37 insertions, 15 deletions
diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs
index 3045e3b7..82d526a9 100644
--- a/helix-view/src/document.rs
+++ b/helix-view/src/document.rs
@@ -91,6 +91,7 @@ impl Serialize for Mode {
pub struct DocumentSaveEvent {
pub revision: usize,
pub doc_id: DocumentId,
+ pub path: PathBuf,
}
pub type DocumentSaveEventResult = Result<DocumentSaveEvent, anyhow::Error>;
@@ -512,41 +513,61 @@ impl Document {
Some(fut.boxed())
}
- pub fn save(&mut self, force: bool) -> Result<(), anyhow::Error> {
- self.save_impl::<futures_util::future::Ready<_>>(None, force)
+ pub fn save<P: Into<PathBuf>>(
+ &mut self,
+ path: Option<P>,
+ force: bool,
+ ) -> Result<(), anyhow::Error> {
+ self.save_impl::<futures_util::future::Ready<_>, _>(None, path, force)
}
- pub fn format_and_save(
+ pub fn format_and_save<F, P>(
&mut self,
- formatting: Option<
- impl Future<Output = Result<Transaction, FormatterError>> + 'static + Send,
- >,
+ formatting: Option<F>,
+ path: Option<P>,
force: bool,
- ) -> anyhow::Result<()> {
- self.save_impl(formatting, force)
+ ) -> anyhow::Result<()>
+ where
+ F: Future<Output = Result<Transaction, FormatterError>> + 'static + Send,
+ P: Into<PathBuf>,
+ {
+ self.save_impl(formatting, path, force)
}
- // TODO: impl Drop to handle ensuring writes when closed
/// The `Document`'s text is encoded according to its encoding and written to the file located
/// at its `path()`.
///
/// If `formatting` is present, it supplies some changes that we apply to the text before saving.
- fn save_impl<F: Future<Output = Result<Transaction, FormatterError>> + 'static + Send>(
+ fn save_impl<F, P>(
&mut self,
formatting: Option<F>,
+ path: Option<P>,
force: bool,
- ) -> Result<(), anyhow::Error> {
+ ) -> Result<(), anyhow::Error>
+ where
+ F: Future<Output = Result<Transaction, FormatterError>> + 'static + Send,
+ P: Into<PathBuf>,
+ {
if self.save_sender.is_none() {
bail!("saves are closed for this document!");
}
// 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();
- let path = self.path.clone().expect("Can't save with no path set!");
- let identifier = self.identifier();
+ let path = match path {
+ Some(path) => helix_core::path::get_canonicalized_path(&path.into())?,
+ None => {
+ if self.path.is_none() {
+ bail!("Can't save with no path set!");
+ }
+
+ self.path.as_ref().unwrap().clone()
+ }
+ };
+
+ let identifier = self.identifier();
let language_server = self.language_server.clone();
// mark changes up to now as saved
@@ -586,12 +607,13 @@ impl Document {
}
}
- let mut file = File::create(path).await?;
+ let mut file = File::create(&path).await?;
to_writer(&mut file, encoding, &text).await?;
let event = DocumentSaveEvent {
revision: current_rev,
doc_id,
+ path,
};
if let Some(language_server) = language_server {