summaryrefslogtreecommitdiff
path: root/support/texlab/src/link/latex_import.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/src/link/latex_import.rs')
-rw-r--r--support/texlab/src/link/latex_import.rs99
1 files changed, 99 insertions, 0 deletions
diff --git a/support/texlab/src/link/latex_import.rs b/support/texlab/src/link/latex_import.rs
new file mode 100644
index 0000000000..494a72b481
--- /dev/null
+++ b/support/texlab/src/link/latex_import.rs
@@ -0,0 +1,99 @@
+use crate::{
+ feature::{FeatureProvider, FeatureRequest},
+ protocol::{DocumentLink, DocumentLinkParams},
+ syntax::{latex, SyntaxNode},
+ workspace::DocumentContent,
+};
+use async_trait::async_trait;
+
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
+pub struct LatexImportLinkProvider;
+
+#[async_trait]
+impl FeatureProvider for LatexImportLinkProvider {
+ type Params = DocumentLinkParams;
+ type Output = Vec<DocumentLink>;
+
+ async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
+ if let DocumentContent::Latex(table) = &req.current().content {
+ table
+ .imports
+ .iter()
+ .flat_map(|import| Self::resolve(req, table, import))
+ .collect()
+ } else {
+ Vec::new()
+ }
+ }
+}
+
+impl LatexImportLinkProvider {
+ fn resolve(
+ req: &FeatureRequest<DocumentLinkParams>,
+ table: &latex::SymbolTable,
+ import: &latex::Import,
+ ) -> Vec<DocumentLink> {
+ let mut links = Vec::new();
+ let file = import.file(&table);
+ for target in &import.targets {
+ if let Some(link) = req.snapshot().find(target).map(|doc| DocumentLink {
+ range: file.range(),
+ target: doc.uri.clone().into(),
+ tooltip: None,
+ }) {
+ links.push(link);
+ break;
+ }
+ }
+ links
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::{
+ feature::FeatureTester,
+ protocol::{Range, RangeExt},
+ };
+
+ #[tokio::test]
+ async fn empty_latex_document_command() {
+ let actual_links = FeatureTester::new()
+ .file("main.tex", "")
+ .main("main.tex")
+ .test_link(LatexImportLinkProvider)
+ .await;
+
+ assert!(actual_links.is_empty());
+ }
+
+ #[tokio::test]
+ async fn empty_bibtex_document_command() {
+ let actual_links = FeatureTester::new()
+ .file("main.bib", "")
+ .main("main.bib")
+ .test_link(LatexImportLinkProvider)
+ .await;
+
+ assert!(actual_links.is_empty());
+ }
+
+ #[tokio::test]
+ async fn has_links() {
+ let actual_links = FeatureTester::new()
+ .file("foo.tex", r#"\import{bar/}{baz}"#)
+ .file("bar/baz.tex", r#""#)
+ .main("foo.tex")
+ .test_link(LatexImportLinkProvider)
+ .await;
+
+ let expected_links = vec![DocumentLink {
+ range: Range::new_simple(0, 14, 0, 17),
+ target: FeatureTester::uri("bar/baz.tex").into(),
+ tooltip: None,
+ }];
+
+ assert_eq!(actual_links, expected_links);
+ }
+}