summaryrefslogtreecommitdiff
path: root/support/texlab/crates/base-db/src/workspace.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/crates/base-db/src/workspace.rs')
-rw-r--r--support/texlab/crates/base-db/src/workspace.rs212
1 files changed, 12 insertions, 200 deletions
diff --git a/support/texlab/crates/base-db/src/workspace.rs b/support/texlab/crates/base-db/src/workspace.rs
index 0fe347f1b3..1afd4712e9 100644
--- a/support/texlab/crates/base-db/src/workspace.rs
+++ b/support/texlab/crates/base-db/src/workspace.rs
@@ -4,14 +4,12 @@ use std::{
};
use distro::{Distro, Language};
-use itertools::Itertools;
use line_index::LineCol;
use rowan::{TextLen, TextRange};
-use rustc_hash::FxHashSet;
-use syntax::latexmkrc::LatexmkrcData;
+use rustc_hash::{FxHashMap, FxHashSet};
use url::Url;
-use crate::{graph, Config, Document, DocumentData, DocumentParams, Owner};
+use crate::{deps, Config, Document, DocumentParams, Owner};
#[derive(Debug, Default)]
pub struct Workspace {
@@ -19,6 +17,7 @@ pub struct Workspace {
config: Config,
distro: Distro,
folders: Vec<PathBuf>,
+ graphs: FxHashMap<Url, deps::Graph>,
}
impl Workspace {
@@ -47,6 +46,10 @@ impl Workspace {
&self.distro
}
+ pub fn graphs(&self) -> &FxHashMap<Url, deps::Graph> {
+ &self.graphs
+ }
+
pub fn open(
&mut self,
uri: Url,
@@ -65,6 +68,11 @@ impl Workspace {
cursor,
config: &self.config,
}));
+
+ self.graphs = self
+ .iter()
+ .map(|start| (start.uri.clone(), deps::Graph::new(self, start)))
+ .collect();
}
pub fn load(&mut self, path: &Path, language: Language) -> std::io::Result<()> {
@@ -114,83 +122,6 @@ impl Workspace {
Some(())
}
- pub fn watch(
- &mut self,
- watcher: &mut dyn notify::Watcher,
- watched_dirs: &mut FxHashSet<PathBuf>,
- ) {
- self.iter()
- .filter(|document| document.uri.scheme() == "file")
- .flat_map(|document| {
- let current_dir = &self.current_dir(&document.dir);
- let doc_dir = document.dir.to_file_path();
- let aux_dir = self.aux_dir(current_dir).to_file_path();
- let log_dir = self.log_dir(current_dir).to_file_path();
- [aux_dir, log_dir, doc_dir]
- })
- .flatten()
- .for_each(|path| {
- if !watched_dirs.contains(&path) {
- let _ = watcher.watch(&path, notify::RecursiveMode::NonRecursive);
- watched_dirs.insert(path);
- }
- });
- }
-
- pub fn current_dir(&self, base_dir: &Url) -> Url {
- let root_dir = self.config.root_dir.as_deref();
- if let Some(dir) = root_dir.and_then(|path| base_dir.join(path).ok()) {
- return dir;
- }
-
- self.iter()
- .filter(|document| matches!(document.data, DocumentData::Root | DocumentData::Tectonic))
- .flat_map(|document| document.uri.join("."))
- .find(|root_dir| base_dir.as_str().starts_with(root_dir.as_str()))
- .unwrap_or_else(|| base_dir.clone())
- }
-
- pub fn aux_dir(&self, base_dir: &Url) -> Url {
- self.output_dir(base_dir, &self.config.build.aux_dir, |data| {
- data.aux_dir.as_deref()
- })
- }
-
- pub fn log_dir(&self, base_dir: &Url) -> Url {
- self.output_dir(base_dir, &self.config.build.log_dir, |_| None)
- }
-
- pub fn pdf_dir(&self, base_dir: &Url) -> Url {
- self.output_dir(base_dir, &self.config.build.pdf_dir, |_| None)
- }
-
- fn current_latexmkrc(&self, base_dir: &Url) -> Option<&LatexmkrcData> {
- self.documents
- .iter()
- .filter(|document| document.language == Language::Latexmkrc)
- .find(|document| document.uri.join(".").as_ref() == Ok(base_dir))
- .and_then(|document| document.data.as_latexmkrc())
- }
-
- fn output_dir(
- &self,
- base_dir: &Url,
- config: &str,
- extract_latexmkrc: impl FnOnce(&LatexmkrcData) -> Option<&str>,
- ) -> Url {
- let mut dir: String = self
- .current_latexmkrc(base_dir)
- .and_then(|data| extract_latexmkrc(data).or_else(|| data.out_dir.as_deref()))
- .unwrap_or(config)
- .into();
-
- if !dir.ends_with('/') {
- dir.push('/');
- }
-
- base_dir.join(&dir).unwrap_or_else(|_| base_dir.clone())
- }
-
pub fn contains(&self, path: &Path) -> bool {
if self.folders.is_empty() {
return true;
@@ -199,35 +130,6 @@ impl Workspace {
self.folders.iter().any(|dir| path.starts_with(dir))
}
- pub fn project(&self, child: &Document) -> Project {
- let mut documents = FxHashSet::default();
- for graph in self
- .iter()
- .map(|start| graph::Graph::new(self, start))
- .filter(|graph| graph.preorder().contains(&child))
- {
- documents.extend(graph.preorder());
- }
-
- Project { documents }
- }
-
- pub fn parents(&self, child: &Document) -> FxHashSet<&Document> {
- self.iter()
- .filter(|document| {
- let DocumentData::Tex(data) = &document.data else {
- return false;
- };
- data.semantics.can_be_root
- })
- .filter(|parent| {
- let graph = graph::Graph::new(self, parent);
- let mut nodes = graph.preorder();
- nodes.contains(&child)
- })
- .collect()
- }
-
pub fn set_config(&mut self, config: Config) {
self.config = config;
self.reload();
@@ -280,94 +182,4 @@ impl Workspace {
self.documents.insert(document);
Some(())
}
-
- pub fn discover(&mut self, checked_paths: &mut FxHashSet<PathBuf>) {
- loop {
- let mut changed = false;
- changed |= self.discover_parents(checked_paths);
- changed |= self.discover_children(checked_paths);
- if !changed {
- break;
- }
- }
- }
-
- fn discover_parents(&mut self, checked_paths: &mut FxHashSet<PathBuf>) -> bool {
- let dirs = self
- .iter()
- .filter(|document| document.language != Language::Bib)
- .filter_map(|document| document.path.as_deref())
- .flat_map(|path| path.ancestors().skip(1))
- .filter(|path| self.contains(path))
- .map(|path| path.to_path_buf())
- .collect::<FxHashSet<_>>();
-
- let mut changed = false;
- for dir in dirs {
- if self
- .iter()
- .filter(|document| matches!(document.language, Language::Root | Language::Tectonic))
- .filter_map(|document| document.path.as_deref())
- .filter_map(|path| path.parent())
- .any(|marker| dir.starts_with(marker))
- {
- continue;
- }
-
- let Ok(entries) = std::fs::read_dir(dir) else {
- continue;
- };
-
- for file in entries
- .flatten()
- .filter(|entry| entry.file_type().map_or(false, |type_| type_.is_file()))
- .map(|entry| entry.path())
- {
- let Some(lang) = Language::from_path(&file) else {
- continue;
- };
-
- if !matches!(
- lang,
- Language::Tex | Language::Root | Language::Tectonic | Language::Latexmkrc
- ) {
- continue;
- }
-
- if self.lookup_path(&file).is_none() && file.exists() {
- changed |= self.load(&file, lang).is_ok();
- checked_paths.insert(file);
- }
- }
- }
-
- changed
- }
-
- fn discover_children(&mut self, checked_paths: &mut FxHashSet<PathBuf>) -> bool {
- let files = self
- .iter()
- .map(|start| graph::Graph::new(self, start))
- .flat_map(|graph| graph.missing)
- .filter(|uri| uri.scheme() == "file")
- .flat_map(|uri| uri.to_file_path())
- .collect::<FxHashSet<_>>();
-
- let mut changed = false;
- for file in files {
- let language = Language::from_path(&file).unwrap_or(Language::Tex);
-
- if self.lookup_path(&file).is_none() && file.exists() {
- changed |= self.load(&file, language).is_ok();
- checked_paths.insert(file);
- }
- }
-
- changed
- }
-}
-
-#[derive(Debug)]
-pub struct Project<'a> {
- pub documents: FxHashSet<&'a Document>,
}