From c64a8e73f1286c5e27258f46316e5e5e2a930a3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20F=C3=B6rster?= Date: Wed, 23 Oct 2024 19:20:56 +0200 Subject: [PATCH] Fix opening untitled documents (#1243) --- CHANGELOG.md | 6 ++++++ crates/base-db/src/deps/discover.rs | 2 +- crates/base-db/src/deps/graph.rs | 8 ++++++-- crates/base-db/src/deps/root.rs | 6 +++--- crates/base-db/src/document.rs | 4 ++-- crates/commands/src/build.rs | 6 +++++- crates/commands/src/clean.rs | 6 +++++- crates/commands/src/fwd_search.rs | 6 +++++- crates/completion/src/providers/include.rs | 2 +- crates/diagnostics/src/chktex.rs | 2 +- crates/texlab/src/features/formatting/latexindent.rs | 2 +- 11 files changed, 36 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6af6af218..2c7ec19a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Fixed + +- Fix opening `untitled` documents ([#1242](https://github.com/latex-lsp/texlab/issues/1242)) + ## [5.20.0] - 2024-10-08 ### Added diff --git a/crates/base-db/src/deps/discover.rs b/crates/base-db/src/deps/discover.rs index cbcab4d8f..3039d7b0f 100644 --- a/crates/base-db/src/deps/discover.rs +++ b/crates/base-db/src/deps/discover.rs @@ -15,7 +15,7 @@ pub fn watch( ) { let roots = workspace .iter() - .map(|document| &document.dir) + .filter_map(|document| document.dir.as_ref()) .filter(|dir| dir.scheme() == "file") .unique() .map(|dir| ProjectRoot::walk_and_find(workspace, dir)); diff --git a/crates/base-db/src/deps/graph.rs b/crates/base-db/src/deps/graph.rs index 0d8252688..aec5cea92 100644 --- a/crates/base-db/src/deps/graph.rs +++ b/crates/base-db/src/deps/graph.rs @@ -55,7 +55,11 @@ impl Graph { start: start.uri.clone(), }; - let root = ProjectRoot::walk_and_find(workspace, &start.dir); + let Some(start_dir) = &start.dir else { + return graph; + }; + + let root = ProjectRoot::walk_and_find(workspace, start_dir); let mut stack = vec![(start, Rc::new(root))]; let mut visited = FxHashSet::default(); @@ -135,7 +139,7 @@ impl Graph { .as_deref() .and_then(|dir| Url::from_directory_path(dir).ok()); - let working_dir = working_dir.as_ref().unwrap_or(&start.source.dir); + let working_dir = working_dir.as_ref().or(start.source.dir.as_ref())?; let new_root = Arc::new(ProjectRoot::from_config(workspace, working_dir)); for target_uri in file_list diff --git a/crates/base-db/src/deps/root.rs b/crates/base-db/src/deps/root.rs index 03fd41a9a..aa3969353 100644 --- a/crates/base-db/src/deps/root.rs +++ b/crates/base-db/src/deps/root.rs @@ -45,7 +45,7 @@ impl ProjectRoot { pub fn from_tectonic(workspace: &Workspace, dir: &Url) -> Option { let exists = workspace .iter() - .filter(|document| document.dir == *dir) + .filter(|document| document.dir.as_ref() == Some(dir)) .any(|document| matches!(document.data, DocumentData::Tectonic)); if !exists { @@ -77,7 +77,7 @@ impl ProjectRoot { let config = workspace.config(); let rcfile = workspace .iter() - .filter(|document| document.dir == *dir) + .filter(|document| document.dir.as_ref() == Some(dir)) .find_map(|document| document.data.as_latexmkrc())?; let compile_dir = dir.clone(); @@ -121,7 +121,7 @@ impl ProjectRoot { pub fn from_rootfile(workspace: &Workspace, dir: &Url) -> Option { let exists = workspace .iter() - .filter(|document| document.dir == *dir) + .filter(|document| document.dir.as_ref() == Some(dir)) .any(|document| matches!(document.data, DocumentData::Root)); if !exists { diff --git a/crates/base-db/src/document.rs b/crates/base-db/src/document.rs index 6fdcf30c1..0b81fa287 100644 --- a/crates/base-db/src/document.rs +++ b/crates/base-db/src/document.rs @@ -28,7 +28,7 @@ pub struct DocumentParams<'a> { #[derive(Clone)] pub struct Document { pub uri: Url, - pub dir: Url, + pub dir: Option, pub path: Option, pub text: String, pub line_index: LineIndex, @@ -42,7 +42,7 @@ impl Document { pub fn parse(params: DocumentParams) -> Self { let DocumentParams { uri, text, .. } = params; - let dir = uri.join(".").unwrap(); + let dir = uri.join(".").ok(); let path = if uri.scheme() == "file" { uri.to_file_path().ok() diff --git a/crates/commands/src/build.rs b/crates/commands/src/build.rs index 34d39f26e..23a6e16b7 100644 --- a/crates/commands/src/build.rs +++ b/crates/commands/src/build.rs @@ -47,6 +47,10 @@ impl BuildCommand { .next() .unwrap_or(document); + let Some(document_dir) = &document.dir else { + return Err(BuildError::NotLocal(document.uri.clone())); + }; + let Some(path) = document.path.as_deref().and_then(Path::to_str) else { return Err(BuildError::NotLocal(document.uri.clone())); }; @@ -55,7 +59,7 @@ impl BuildCommand { let program = config.program.clone(); let args = replace_placeholders(&config.args, &[('f', path)]); - let root = ProjectRoot::walk_and_find(workspace, &document.dir); + let root = ProjectRoot::walk_and_find(workspace, document_dir); let Ok(working_dir) = root.compile_dir.to_file_path() else { return Err(BuildError::NotLocal(document.uri.clone())); diff --git a/crates/commands/src/clean.rs b/crates/commands/src/clean.rs index d4ec6b24f..e429d1afa 100644 --- a/crates/commands/src/clean.rs +++ b/crates/commands/src/clean.rs @@ -21,7 +21,11 @@ impl CleanCommand { anyhow::bail!("document '{}' is not a local file", document.uri) }; - let root = ProjectRoot::walk_and_find(workspace, &document.dir); + let Some(document_dir) = &document.dir else { + anyhow::bail!("document '{}' is not a local file", document.uri) + }; + + let root = ProjectRoot::walk_and_find(workspace, document_dir); let flag = match target { CleanTarget::Auxiliary => "-c", diff --git a/crates/commands/src/fwd_search.rs b/crates/commands/src/fwd_search.rs index f3480ef3e..8b6227d8c 100644 --- a/crates/commands/src/fwd_search.rs +++ b/crates/commands/src/fwd_search.rs @@ -84,7 +84,11 @@ impl ForwardSearch { } fn find_pdf(workspace: &Workspace, document: &Document) -> Result { - let root = ProjectRoot::walk_and_find(workspace, &document.dir); + let Some(document_dir) = &document.dir else { + return Err(ForwardSearchError::NotLocal(document.uri.clone())); + }; + + let root = ProjectRoot::walk_and_find(workspace, document_dir); log::debug!("[FwdSearch] root={root:#?}"); diff --git a/crates/completion/src/providers/include.rs b/crates/completion/src/providers/include.rs index d0a042252..f3deb3a10 100644 --- a/crates/completion/src/providers/include.rs +++ b/crates/completion/src/providers/include.rs @@ -118,7 +118,7 @@ fn current_dir( .next() .map_or(params.document, Clone::clone); - let root = ProjectRoot::walk_and_find(workspace, &parent.dir); + let root = ProjectRoot::walk_and_find(workspace, parent.dir.as_ref()?); let mut path = PathBuf::new(); if let Some(graphics_path) = graphics_path { diff --git a/crates/diagnostics/src/chktex.rs b/crates/diagnostics/src/chktex.rs index a3f539440..b7cd80d67 100644 --- a/crates/diagnostics/src/chktex.rs +++ b/crates/diagnostics/src/chktex.rs @@ -36,7 +36,7 @@ impl Command { return None; } - let root = ProjectRoot::walk_and_find(workspace, &parent.dir); + let root = ProjectRoot::walk_and_find(workspace, parent.dir.as_ref()?); let working_dir = root.src_dir.to_file_path().ok()?; log::debug!("Calling ChkTeX from directory: {}", working_dir.display()); diff --git a/crates/texlab/src/features/formatting/latexindent.rs b/crates/texlab/src/features/formatting/latexindent.rs index e1a277c0c..b956378ed 100644 --- a/crates/texlab/src/features/formatting/latexindent.rs +++ b/crates/texlab/src/features/formatting/latexindent.rs @@ -16,7 +16,7 @@ pub fn format_with_latexindent( ) -> Option> { let config = workspace.config(); let target_dir = tempdir().ok()?; - let root = ProjectRoot::walk_and_find(workspace, &document.dir); + let root = ProjectRoot::walk_and_find(workspace, document.dir.as_ref()?); let source_dir = root.src_dir.to_file_path().ok()?; let target_file = target_dir