@@ -91,6 +91,7 @@ impl Serialize for Mode {
9191pub struct DocumentSaveEvent {
9292 pub revision: usize,
9393 pub doc_id: DocumentId,
94+ pub path: PathBuf,
9495}
9596
9697pub type DocumentSaveEventResult = Result<DocumentSaveEvent, anyhow::Error>;
@@ -512,41 +513,61 @@ impl Document {
512513 Some(fut.boxed())
513514 }
514515
515− pub fn save(&mut self, force: bool) -> Result<(), anyhow::Error> {
516− self.save_impl::<futures_util::future::Ready<_>>(None, force)
516+ pub fn save<P: Into<PathBuf>>(
517+ &mut self,
518+ path: Option<P>,
519+ force: bool,
520+ ) -> Result<(), anyhow::Error> {
521+ self.save_impl::<futures_util::future::Ready<_>, _>(None, path, force)
517522 }
518523
519− pub fn format_and_save(
524+ pub fn format_and_save<F, P>(
520525 &mut self,
521− formatting: Option<
522− impl Future<Output = Result<Transaction, FormatterError>> + 'static + Send,
523− >,
526+ formatting: Option<F>,
527+ path: Option<P>,
524528 force: bool,
525− ) -> anyhow::Result<()> {
526− self.save_impl(formatting, force)
529+ ) -> anyhow::Result<()>
530+ where
531+ F: Future<Output = Result<Transaction, FormatterError>> + 'static + Send,
532+ P: Into<PathBuf>,
533+ {
534+ self.save_impl(formatting, path, force)
527535 }
528536
529− // TODO: impl Drop to handle ensuring writes when closed
530537 /// The `Document`'s text is encoded according to its encoding and written to the file located
531538 /// at its `path()`.
532539 ///
533540 /// If `formatting` is present, it supplies some changes that we apply to the text before saving.
534− fn save_impl<F: Future<Output = Result<Transaction, FormatterError>> + 'static + Send>(
541+ fn save_impl<F, P>(
535542 &mut self,
536543 formatting: Option<F>,
544+ path: Option<P>,
537545 force: bool,
538− ) -> Result<(), anyhow::Error> {
546+ ) -> Result<(), anyhow::Error>
547+ where
548+ F: Future<Output = Result<Transaction, FormatterError>> + 'static + Send,
549+ P: Into<PathBuf>,
550+ {
539551 if self.save_sender.is_none() {
540552 bail!("saves are closed for this document!");
541553 }
542554
543555 // we clone and move text + path into the future so that we asynchronously save the current
544556 // state without blocking any further edits.
545−
546557 let mut text = self.text().clone();
547− let path = self.path.clone().expect("Can't save with no path set!");
548− let identifier = self.identifier();
549558
559+ let path = match path {
560+ Some(path) => helix_core::path::get_canonicalized_path(&path.into())?,
561+ None => {
562+ if self.path.is_none() {
563+ bail!("Can't save with no path set!");
564+ }
565+
566+ self.path.as_ref().unwrap().clone()
567+ }
568+ };
569+
570+ let identifier = self.identifier();
550571 let language_server = self.language_server.clone();
551572
552573 // mark changes up to now as saved
@@ -586,12 +607,13 @@ impl Document {
586607 }
587608 }
588609
589− let mut file = File::create(path).await?;
610+ let mut file = File::create(&path).await?;
590611 to_writer(&mut file, encoding, &text).await?;
591612
592613 let event = DocumentSaveEvent {
593614 revision: current_rev,
594615 doc_id,
616+ path,
595617 };
596618
597619 if let Some(language_server) = language_server {