summaryrefslogtreecommitdiff
path: root/support/texlab/src/workspace.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/src/workspace.rs')
-rw-r--r--support/texlab/src/workspace.rs225
1 files changed, 0 insertions, 225 deletions
diff --git a/support/texlab/src/workspace.rs b/support/texlab/src/workspace.rs
deleted file mode 100644
index e01a2fede4..0000000000
--- a/support/texlab/src/workspace.rs
+++ /dev/null
@@ -1,225 +0,0 @@
-use std::{
- fs::{self, FileType},
- path::PathBuf,
- sync::Arc,
-};
-
-use anyhow::Result;
-use crossbeam_channel::Sender;
-use lsp_types::Url;
-use petgraph::{graphmap::UnGraphMap, visit::Dfs};
-use rustc_hash::{FxHashMap, FxHashSet};
-
-use crate::{
- component_db::COMPONENT_DATABASE, syntax::latex::ExplicitLink, Document, DocumentLanguage,
- Environment,
-};
-
-#[derive(Debug, Clone)]
-pub enum WorkspaceEvent {
- Changed(Workspace, Document),
-}
-
-#[derive(Debug, Clone, Default)]
-pub struct Workspace {
- pub documents_by_uri: FxHashMap<Arc<Url>, Document>,
- pub viewport: FxHashSet<Arc<Url>>,
- pub listeners: Vec<Sender<WorkspaceEvent>>,
- pub environment: Environment,
-}
-
-impl Workspace {
- #[must_use]
- pub fn new(environment: Environment) -> Self {
- Self {
- environment,
- ..Self::default()
- }
- }
-
- pub fn open(
- &mut self,
- uri: Arc<Url>,
- text: Arc<String>,
- language: DocumentLanguage,
- ) -> Result<Document> {
- log::debug!("(Re)Loading document: {}", uri);
- let document = Document::parse(&self.environment, Arc::clone(&uri), text, language);
-
- self.documents_by_uri
- .insert(Arc::clone(&uri), document.clone());
-
- for listener in &self.listeners {
- listener.send(WorkspaceEvent::Changed(self.clone(), document.clone()))?;
- }
-
- self.expand_parent(&document);
- self.expand_children(&document);
- Ok(document)
- }
-
- pub fn reload(&mut self, path: PathBuf) -> Result<Option<Document>> {
- let uri = Arc::new(Url::from_file_path(path.clone()).unwrap());
-
- if self.is_open(&uri) && !uri.as_str().ends_with(".log") {
- return Ok(self.documents_by_uri.get(&uri).cloned());
- }
-
- if let Some(language) = DocumentLanguage::by_path(&path) {
- let data = fs::read(&path)?;
- let text = Arc::new(String::from_utf8_lossy(&data).into_owned());
- Ok(Some(self.open(uri, text, language)?))
- } else {
- Ok(None)
- }
- }
-
- pub fn load(&mut self, path: PathBuf) -> Result<Option<Document>> {
- let uri = Arc::new(Url::from_file_path(path.clone()).unwrap());
-
- if let Some(document) = self.documents_by_uri.get(&uri).cloned() {
- return Ok(Some(document));
- }
-
- let data = fs::read(&path)?;
- let text = Arc::new(String::from_utf8_lossy(&data).into_owned());
- if let Some(language) = DocumentLanguage::by_path(&path) {
- Ok(Some(self.open(uri, text, language)?))
- } else {
- Ok(None)
- }
- }
-
- pub fn close(&mut self, uri: &Url) {
- self.viewport.remove(uri);
- }
-
- pub fn is_open(&self, uri: &Url) -> bool {
- self.viewport.contains(uri)
- }
-
- pub fn slice(&self, uri: &Url) -> Self {
- let all_uris: Vec<_> = self.documents_by_uri.keys().cloned().collect();
-
- all_uris
- .iter()
- .position(|u| u.as_ref() == uri)
- .map(|start| {
- let mut edges = Vec::new();
- for (i, uri) in all_uris.iter().enumerate() {
- let document = self.documents_by_uri.get(uri);
- if let Some(data) = document
- .as_ref()
- .and_then(|document| 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 {
- all_targets.push(&link.targets);
- }
-
- for targets in all_targets {
- for target in targets {
- if let Some(j) = all_uris.iter().position(|uri| uri == target) {
- edges.push((i, j, ()));
- break;
- }
- }
- }
- }
- }
-
- let mut slice = self.clone();
- slice.documents_by_uri = FxHashMap::default();
- let graph = UnGraphMap::from_edges(edges);
- let mut dfs = Dfs::new(&graph, start);
- while let Some(i) = dfs.next(&graph) {
- let uri = &all_uris[i];
- let doc = self.documents_by_uri[uri].clone();
- slice.documents_by_uri.insert(Arc::clone(uri), doc);
- }
-
- slice
- })
- .unwrap_or_default()
- }
-
- #[must_use]
- pub fn find_parent(&self, uri: &Url) -> Option<Document> {
- self.slice(uri)
- .documents_by_uri
- .values()
- .find(|document| {
- document.data.as_latex().map_or(false, |data| {
- data.extras.has_document_environment
- && !data
- .extras
- .explicit_links
- .iter()
- .filter_map(ExplicitLink::as_component_name)
- .any(|name| name == "subfiles.cls")
- })
- })
- .cloned()
- }
-
- fn expand_parent(&mut self, document: &Document) {
- let all_current_paths = self
- .documents_by_uri
- .values()
- .filter_map(|doc| doc.uri.to_file_path().ok())
- .collect::<FxHashSet<_>>();
-
- if document.uri.scheme() == "file" {
- if let Ok(mut path) = document.uri.to_file_path() {
- while path.pop() && self.find_parent(&document.uri).is_none() {
- std::fs::read_dir(&path)
- .into_iter()
- .flatten()
- .filter_map(Result::ok)
- .filter(|entry| entry.file_type().ok().filter(FileType::is_file).is_some())
- .map(|entry| entry.path())
- .filter(|path| {
- matches!(
- DocumentLanguage::by_path(path),
- Some(DocumentLanguage::Latex)
- )
- })
- .filter(|path| !all_current_paths.contains(path))
- .for_each(|path| {
- let _ = self.load(path);
- });
- }
- }
- }
- }
-
- fn expand_children(&mut self, 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);
- }
- }
-
- for targets in all_targets {
- for path in targets
- .iter()
- .filter(|uri| uri.scheme() == "file" && uri.fragment().is_none())
- .filter_map(|uri| uri.to_file_path().ok())
- {
- if self.load(path).is_ok() {
- break;
- }
- }
- }
- }
- }
-}