summaryrefslogtreecommitdiff
path: root/support/texlab/src/workspace/children_expand.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/src/workspace/children_expand.rs')
-rw-r--r--support/texlab/src/workspace/children_expand.rs92
1 files changed, 92 insertions, 0 deletions
diff --git a/support/texlab/src/workspace/children_expand.rs b/support/texlab/src/workspace/children_expand.rs
new file mode 100644
index 0000000000..006e7b17e2
--- /dev/null
+++ b/support/texlab/src/workspace/children_expand.rs
@@ -0,0 +1,92 @@
+use std::sync::Arc;
+
+use rayon::iter::{IntoParallelIterator, ParallelIterator};
+
+use crate::{
+ component_db::COMPONENT_DATABASE, Document, DocumentLanguage, OpenHandler, Uri, Workspace,
+ WorkspaceSource, WorkspaceSubset,
+};
+
+pub struct ChildrenExpander<W> {
+ workspace: Arc<W>,
+}
+
+impl<W> ChildrenExpander<W>
+where
+ W: Workspace + Send + Sync + 'static,
+{
+ pub fn new(workspace: Arc<W>) -> Self {
+ workspace.register_open_handler(Arc::new(move |workspace, document| {
+ Self::expand(workspace.as_ref(), document.as_ref());
+ }));
+ Self { workspace }
+ }
+
+ fn expand(workspace: &dyn Workspace, document: &Document) {
+ if let Some(data) = document.data.as_latex() {
+ let extras = &data.extras;
+ let mut all_targets = vec![&extras.implicit_links.aux, &extras.implicit_links.log];
+ for link in &extras.explicit_links {
+ if link
+ .as_component_name()
+ .and_then(|name| COMPONENT_DATABASE.find(&name))
+ .is_none()
+ {
+ all_targets.push(&link.targets);
+ }
+ }
+
+ all_targets.into_par_iter().for_each(|targets| {
+ for path in targets
+ .iter()
+ .filter(|uri| uri.scheme() == "file" && uri.fragment().is_none())
+ .filter_map(|uri| uri.to_file_path().ok())
+ {
+ if workspace.load(path).is_ok() {
+ break;
+ }
+ }
+ });
+ }
+ }
+}
+
+impl<W: Workspace> Workspace for ChildrenExpander<W> {
+ fn open(
+ &self,
+ uri: Arc<Uri>,
+ text: String,
+ language: DocumentLanguage,
+ source: WorkspaceSource,
+ ) -> Arc<Document> {
+ self.workspace.open(uri, text, language, source)
+ }
+
+ fn register_open_handler(&self, handler: OpenHandler) {
+ self.workspace.register_open_handler(handler)
+ }
+
+ fn documents(&self) -> Vec<Arc<Document>> {
+ self.workspace.documents()
+ }
+
+ fn has(&self, uri: &Uri) -> bool {
+ self.workspace.has(uri)
+ }
+
+ fn get(&self, uri: &Uri) -> Option<Arc<Document>> {
+ self.workspace.get(uri)
+ }
+
+ fn close(&self, uri: &Uri) {
+ self.workspace.close(uri)
+ }
+
+ fn is_open(&self, uri: &Uri) -> bool {
+ self.workspace.is_open(uri)
+ }
+
+ fn subset(&self, uri: Arc<Uri>) -> Option<WorkspaceSubset> {
+ self.workspace.subset(uri)
+ }
+}