diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 8f74adb6299c5..55da328c3fc9d 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -193,6 +193,7 @@ fn buffer_previous( fn write_impl(cx: &mut compositor::Context, path: Option<&Cow>) -> anyhow::Result<()> { let jobs = &mut cx.jobs; let doc = doc_mut!(cx.editor); + let doc_was_scratch = doc.path().is_none(); if let Some(ref path) = path { doc.set_path(Some(path.as_ref().as_ref())) @@ -217,6 +218,9 @@ fn write_impl(cx: &mut compositor::Context, path: Option<&Cow>) -> anyhow:: if path.is_some() { let id = doc.id(); + if doc_was_scratch { + let _ = doc.no_longer_scratch(); + } doc.detect_language(cx.editor.syn_loader.clone()); let _ = cx.editor.refresh_language_server(id); } diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index 5d739af586988..a754987e91b5a 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -506,6 +506,17 @@ impl Document { } } + // TODO: better name + pub fn no_longer_scratch(&mut self) -> Option<()> { + if let Some(language_server) = self.language_server() { + let scratch_url = Document::scratch_url(self.id()).ok()?; + let identifier = lsp::TextDocumentIdentifier::new(scratch_url); + tokio::spawn(language_server.text_document_did_close(identifier)); + self.language_server = None; + } + Some(()) + } + /// Detect the programming language based on the file type. pub fn detect_language(&mut self, config_loader: Arc) { if let Some(path) = &self.path { @@ -902,7 +913,17 @@ impl Document { /// File path as a URL. pub fn url(&self) -> Option { - Url::from_file_path(self.path()?).ok() + if let Some(ref path) = self.path { + Url::from_file_path(path).ok() + } else { + Document::scratch_url(self.id()).ok() + } + } + + fn scratch_url(doc_id: DocumentId) -> Result { + let cwd = std::env::current_dir().map_err(|_| ())?; + let path = cwd.join(format!("scratch{}", doc_id)); + Url::from_file_path(path) } #[inline]