diff options
author | Norbert Preining <norbert@preining.info> | 2024-05-02 03:02:55 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2024-05-02 03:02:55 +0000 |
commit | 68c5442089b7c2e61ee14fc3efed490e291a244a (patch) | |
tree | 91d0e68d495b53cb52bb60a3e234da061741067d /support/texlab/crates/base-db | |
parent | 6ac3dbed4b71022bd6bb0cc25e8fc3df81198498 (diff) |
CTAN sync 202405020302
Diffstat (limited to 'support/texlab/crates/base-db')
-rw-r--r-- | support/texlab/crates/base-db/Cargo.toml | 6 | ||||
-rw-r--r-- | support/texlab/crates/base-db/src/deps.rs | 2 | ||||
-rw-r--r-- | support/texlab/crates/base-db/src/deps/discover.rs | 4 | ||||
-rw-r--r-- | support/texlab/crates/base-db/src/deps/graph.rs | 8 | ||||
-rw-r--r-- | support/texlab/crates/base-db/src/deps/root.rs | 40 | ||||
-rw-r--r-- | support/texlab/crates/base-db/src/document.rs | 7 | ||||
-rw-r--r-- | support/texlab/crates/base-db/src/semantics.rs | 9 | ||||
-rw-r--r-- | support/texlab/crates/base-db/src/semantics/tex.rs | 29 | ||||
-rw-r--r-- | support/texlab/crates/base-db/src/util.rs | 2 | ||||
-rw-r--r-- | support/texlab/crates/base-db/src/util/expand.rs | 31 | ||||
-rw-r--r-- | support/texlab/crates/base-db/src/workspace.rs | 20 |
11 files changed, 117 insertions, 41 deletions
diff --git a/support/texlab/crates/base-db/Cargo.toml b/support/texlab/crates/base-db/Cargo.toml index 010c83d0e4..ca477c496c 100644 --- a/support/texlab/crates/base-db/Cargo.toml +++ b/support/texlab/crates/base-db/Cargo.toml @@ -10,17 +10,19 @@ rust-version.workspace = true bibtex-utils = { path = "../bibtex-utils" } dirs = "5.0.1" distro = { path = "../distro" } -itertools = "0.12.0" +itertools = "0.12.1" line-index = { path = "../line-index" } log = "0.4.21" notify = "6.0.1" once_cell = "1.19.0" parser = { path = "../parser" } percent-encoding = "2.3.0" -regex = "1.10.2" +regex = "1.10.4" rowan = "0.15.15" rustc-hash = "1.1.0" +shellexpand = "3.1.0" syntax = { path = "../syntax" } +titlecase = "3.0.0" url = "2.5.0" [lib] diff --git a/support/texlab/crates/base-db/src/deps.rs b/support/texlab/crates/base-db/src/deps.rs index 06689a0df2..f501d04935 100644 --- a/support/texlab/crates/base-db/src/deps.rs +++ b/support/texlab/crates/base-db/src/deps.rs @@ -5,7 +5,7 @@ mod root; pub use self::{ discover::{discover, watch}, - graph::{DirectLinkData, Edge, EdgeData, Graph}, + graph::{DirectLinkData, Edge, EdgeData, Graph, HOME_DIR}, project::{parents, Project}, root::ProjectRoot, }; diff --git a/support/texlab/crates/base-db/src/deps/discover.rs b/support/texlab/crates/base-db/src/deps/discover.rs index 06905905a5..cbcab4d8fb 100644 --- a/support/texlab/crates/base-db/src/deps/discover.rs +++ b/support/texlab/crates/base-db/src/deps/discover.rs @@ -84,7 +84,7 @@ fn discover_parents(workspace: &mut Workspace, checked_paths: &mut FxHashSet<Pat continue; } - if workspace.lookup_path(&file).is_none() && file.exists() { + if workspace.lookup_file(&file).is_none() && file.exists() { changed |= workspace.load(&file, lang).is_ok(); checked_paths.insert(file); } @@ -107,7 +107,7 @@ fn discover_children(workspace: &mut Workspace, checked_paths: &mut FxHashSet<Pa for file in files { let language = Language::from_path(&file).unwrap_or(Language::Tex); - if workspace.lookup_path(&file).is_none() && file.exists() { + if workspace.lookup_file(&file).is_none() && file.exists() { changed |= workspace.load(&file, language).is_ok(); checked_paths.insert(file); } diff --git a/support/texlab/crates/base-db/src/deps/graph.rs b/support/texlab/crates/base-db/src/deps/graph.rs index a90d8fa204..e07368d078 100644 --- a/support/texlab/crates/base-db/src/deps/graph.rs +++ b/support/texlab/crates/base-db/src/deps/graph.rs @@ -7,11 +7,11 @@ use percent_encoding::percent_decode_str; use rustc_hash::FxHashSet; use url::Url; -use crate::{semantics, Document, Workspace}; +use crate::{semantics, util, Document, Workspace}; use super::ProjectRoot; -pub(crate) static HOME_DIR: Lazy<Option<PathBuf>> = Lazy::new(dirs::home_dir); +pub static HOME_DIR: Lazy<Option<PathBuf>> = Lazy::new(dirs::home_dir); #[derive(Debug, PartialEq, Eq, Clone, Hash)] pub struct Edge { @@ -158,7 +158,9 @@ impl Graph { for target_uri in file_names .iter() - .flat_map(|file_name| start.root.src_dir.join(file_name)) + .flat_map(|file_name| { + util::expand_relative_path(&file_name, &start.root.src_dir, workspace.folders()) + }) .chain(distro_files) { match workspace.lookup(&target_uri) { diff --git a/support/texlab/crates/base-db/src/deps/root.rs b/support/texlab/crates/base-db/src/deps/root.rs index 442d6f9e35..a8cec6604a 100644 --- a/support/texlab/crates/base-db/src/deps/root.rs +++ b/support/texlab/crates/base-db/src/deps/root.rs @@ -1,6 +1,6 @@ use url::Url; -use crate::{DocumentData, Workspace}; +use crate::{util, DocumentData, Workspace}; use super::graph::HOME_DIR; @@ -74,6 +74,7 @@ impl ProjectRoot { } pub fn from_latexmkrc(workspace: &Workspace, dir: &Url) -> Option<Self> { + let config = workspace.config(); let rcfile = workspace .iter() .filter(|document| document.dir == *dir) @@ -81,20 +82,30 @@ impl ProjectRoot { let compile_dir = dir.clone(); let src_dir = dir.clone(); - let aux_dir = rcfile + + let aux_dir_rc = rcfile .aux_dir .as_ref() - .and_then(|path| append_dir(dir, path).ok()) - .unwrap_or_else(|| dir.clone()); + .and_then(|path| append_dir(dir, path, workspace).ok()); - let out_dir = rcfile + let out_dir_rc = rcfile .out_dir .as_ref() - .and_then(|path| append_dir(dir, path).ok()) + .and_then(|path| append_dir(dir, path, workspace).ok()); + + let aux_dir = aux_dir_rc + .clone() + .or_else(|| append_dir(dir, &config.build.aux_dir, workspace).ok()) + .unwrap_or_else(|| dir.clone()); + + let log_dir = aux_dir_rc + .or_else(|| append_dir(dir, &config.build.log_dir, workspace).ok()) + .unwrap_or_else(|| dir.clone()); + + let pdf_dir = out_dir_rc + .or_else(|| append_dir(dir, &config.build.pdf_dir, workspace).ok()) .unwrap_or_else(|| dir.clone()); - let log_dir = out_dir.clone(); - let pdf_dir = out_dir; let additional_files = vec![]; Some(Self { @@ -124,9 +135,12 @@ impl ProjectRoot { let compile_dir = dir.clone(); let src_dir = dir.clone(); let config = workspace.config(); - let aux_dir = append_dir(dir, &config.build.aux_dir).unwrap_or_else(|_| dir.clone()); - let log_dir = append_dir(dir, &config.build.log_dir).unwrap_or_else(|_| dir.clone()); - let pdf_dir = append_dir(dir, &config.build.pdf_dir).unwrap_or_else(|_| dir.clone()); + let aux_dir = + append_dir(dir, &config.build.aux_dir, workspace).unwrap_or_else(|_| dir.clone()); + let log_dir = + append_dir(dir, &config.build.log_dir, workspace).unwrap_or_else(|_| dir.clone()); + let pdf_dir = + append_dir(dir, &config.build.pdf_dir, workspace).unwrap_or_else(|_| dir.clone()); let additional_files = vec![]; Self { @@ -140,13 +154,13 @@ impl ProjectRoot { } } -fn append_dir(dir: &Url, path: &str) -> Result<Url, url::ParseError> { +fn append_dir(dir: &Url, path: &str, workspace: &Workspace) -> Result<Url, url::ParseError> { let mut path = String::from(path); if !path.ends_with('/') { path.push('/'); } - dir.join(&path) + util::expand_relative_path(&path, dir, workspace.folders()) } impl std::fmt::Debug for ProjectRoot { diff --git a/support/texlab/crates/base-db/src/document.rs b/support/texlab/crates/base-db/src/document.rs index 25607a1bf5..7a388129fd 100644 --- a/support/texlab/crates/base-db/src/document.rs +++ b/support/texlab/crates/base-db/src/document.rs @@ -77,7 +77,12 @@ impl Document { } Language::Root => DocumentData::Root, Language::Latexmkrc => { - let data = parser::parse_latexmkrc(&text).unwrap_or_default(); + let data = path + .as_deref() + .and_then(|path| path.parent()) + .and_then(|dir| parser::parse_latexmkrc(&text, dir).ok()) + .unwrap_or_default(); + DocumentData::Latexmkrc(data) } Language::Tectonic => DocumentData::Tectonic, diff --git a/support/texlab/crates/base-db/src/semantics.rs b/support/texlab/crates/base-db/src/semantics.rs index f83d758cf7..a2f0de291f 100644 --- a/support/texlab/crates/base-db/src/semantics.rs +++ b/support/texlab/crates/base-db/src/semantics.rs @@ -1,3 +1,5 @@ +use rowan::{TextLen, TextRange}; + pub mod auxiliary; pub mod bib; pub mod tex; @@ -19,6 +21,13 @@ impl Span { range: rowan::TextRange::empty(offset), } } + + pub fn command<L: rowan::Language>(token: &rowan::SyntaxToken<L>) -> Self { + let range = token.text_range(); + let range = TextRange::new(range.start() + "\\".text_len(), range.end()); + let text = String::from(&token.text()[1..]); + Self::new(text, range) + } } impl std::fmt::Debug for Span { diff --git a/support/texlab/crates/base-db/src/semantics/tex.rs b/support/texlab/crates/base-db/src/semantics/tex.rs index 659ec8c166..1ad8969a80 100644 --- a/support/texlab/crates/base-db/src/semantics/tex.rs +++ b/support/texlab/crates/base-db/src/semantics/tex.rs @@ -1,6 +1,7 @@ -use rowan::{ast::AstNode, TextLen, TextRange}; +use rowan::{ast::AstNode, TextRange}; use rustc_hash::FxHashSet; use syntax::latex::{self, HasBrack, HasCurly}; +use titlecase::titlecase; use super::Span; @@ -26,10 +27,7 @@ impl Semantics { } latex::SyntaxElement::Token(token) => { if token.kind() == latex::COMMAND_NAME { - let range = token.text_range(); - let range = TextRange::new(range.start() + "\\".text_len(), range.end()); - let text = String::from(&token.text()[1..]); - self.commands.push(Span { range, text }); + self.commands.push(Span::command(&token)); } } }; @@ -257,18 +255,15 @@ impl Semantics { } fn process_theorem_definition(&mut self, theorem_def: latex::TheoremDefinition) { - let Some(name) = theorem_def.name().and_then(|name| name.key()) else { - return; - }; - - let Some(heading) = theorem_def.heading() else { - return; - }; - - self.theorem_definitions.push(TheoremDefinition { - name: Span::from(&name), - heading, - }); + for name in theorem_def.names() { + let name = Span::from(&name); + let heading = theorem_def + .heading() + .unwrap_or_else(|| titlecase(&name.text)); + + self.theorem_definitions + .push(TheoremDefinition { name, heading }); + } } fn process_graphics_path(&mut self, graphics_path: latex::GraphicsPath) { diff --git a/support/texlab/crates/base-db/src/util.rs b/support/texlab/crates/base-db/src/util.rs index 068a0c9b2a..789eee9c85 100644 --- a/support/texlab/crates/base-db/src/util.rs +++ b/support/texlab/crates/base-db/src/util.rs @@ -1,8 +1,10 @@ +mod expand; mod label; pub mod queries; mod regex_filter; pub use self::{ + expand::expand_relative_path, label::{render_label, FloatKind, RenderedLabel, RenderedObject}, regex_filter::filter_regex_patterns, }; diff --git a/support/texlab/crates/base-db/src/util/expand.rs b/support/texlab/crates/base-db/src/util/expand.rs new file mode 100644 index 0000000000..a315737115 --- /dev/null +++ b/support/texlab/crates/base-db/src/util/expand.rs @@ -0,0 +1,31 @@ +use std::{borrow::Cow, path::PathBuf}; + +use url::Url; + +use crate::deps::HOME_DIR; + +pub fn expand_relative_path( + path: &str, + current_dir: &Url, + workspace_folders: &[PathBuf], +) -> Result<Url, url::ParseError> { + let home_dir = HOME_DIR.as_ref().and_then(|dir| dir.to_str()); + + let workspace_folder = workspace_folders.iter().find_map(|folder| { + let current_dir = current_dir.to_file_path().ok()?; + if current_dir.starts_with(folder) { + Some(folder.to_str()?) + } else { + None + } + }); + + let expand_var = |variable: &str| match variable { + "userHome" => home_dir.map(Cow::Borrowed), + "workspaceFolder" => Some(Cow::Borrowed(workspace_folder.unwrap_or("."))), + _ => std::env::var(variable).ok().map(Cow::Owned), + }; + + let path = shellexpand::full_with_context_no_errors(&path, || home_dir, expand_var); + current_dir.join(&path) +} diff --git a/support/texlab/crates/base-db/src/workspace.rs b/support/texlab/crates/base-db/src/workspace.rs index 1afd4712e9..75674dcf8d 100644 --- a/support/texlab/crates/base-db/src/workspace.rs +++ b/support/texlab/crates/base-db/src/workspace.rs @@ -29,11 +29,22 @@ impl Workspace { self.documents.get(key) } - pub fn lookup_path(&self, path: &Path) -> Option<&Document> { + pub fn lookup_file(&self, path: &Path) -> Option<&Document> { self.iter() .find(|document| document.path.as_deref() == Some(path)) } + pub fn lookup_file_or_dir<'a>( + &'a self, + file_or_dir: &'a Path, + ) -> impl Iterator<Item = &'a Document> + '_ { + self.iter().filter(move |doc| { + doc.path + .as_deref() + .map_or(false, |p| p.starts_with(file_or_dir)) + }) + } + pub fn iter(&self) -> impl Iterator<Item = &Document> + '_ { self.documents.iter() } @@ -50,6 +61,10 @@ impl Workspace { &self.graphs } + pub fn folders(&self) -> &[PathBuf] { + &self.folders + } + pub fn open( &mut self, uri: Url, @@ -90,7 +105,7 @@ impl Workspace { Owner::Server }; - if let Some(document) = self.lookup_path(path) { + if let Some(document) = self.lookup_file(path) { if document.text == text { return Ok(()); } @@ -173,6 +188,7 @@ impl Workspace { } pub fn remove(&mut self, uri: &Url) { + log::info!("Removing moved or deleted document: {uri}"); self.documents.remove(uri); } |