summaryrefslogtreecommitdiff
path: root/support/texlab/src/workspace/outline.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/src/workspace/outline.rs')
-rw-r--r--support/texlab/src/workspace/outline.rs438
1 files changed, 0 insertions, 438 deletions
diff --git a/support/texlab/src/workspace/outline.rs b/support/texlab/src/workspace/outline.rs
deleted file mode 100644
index 818eed1a53..0000000000
--- a/support/texlab/src/workspace/outline.rs
+++ /dev/null
@@ -1,438 +0,0 @@
-use super::{Document, DocumentView};
-use crate::range::RangeExt;
-use crate::syntax::*;
-use crate::workspace::Uri;
-use lsp_types::*;
-use std::collections::HashSet;
-
-#[derive(Debug, PartialEq, Eq, Clone, Default)]
-pub struct Outline<'a> {
- sections: Vec<OutlineSection<'a>>,
-}
-
-impl<'a> Outline<'a> {
- fn new(sections: Vec<OutlineSection<'a>>) -> Self {
- Self { sections }
- }
-
- pub fn find(&self, uri: &Uri, position: Position) -> Option<&'a LatexSection> {
- self.sections
- .iter()
- .filter(|sec| sec.document.uri == *uri)
- .rev()
- .find(|sec| sec.item.end() <= position)
- .map(|sec| sec.item)
- }
-}
-
-impl<'a> From<&'a DocumentView> for Outline<'a> {
- fn from(view: &'a DocumentView) -> Self {
- let mut finder = OutlineSectionFinder::default();
- let document = if let Some(parent) = view.workspace.find_parent(&view.document.uri) {
- view.related_documents
- .iter()
- .find(|doc| doc.uri == parent.uri)
- .unwrap()
- } else {
- &view.document
- };
- finder.analyze(view, &document);
- Outline::new(finder.sections)
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone)]
-struct OutlineSection<'a> {
- pub document: &'a Document,
- pub item: &'a LatexSection,
-}
-
-impl<'a> OutlineSection<'a> {
- fn new(document: &'a Document, item: &'a LatexSection) -> Self {
- Self { document, item }
- }
-}
-
-#[derive(Debug, Default)]
-struct OutlineSectionFinder<'a> {
- visited: HashSet<&'a Uri>,
- sections: Vec<OutlineSection<'a>>,
-}
-
-impl<'a> OutlineSectionFinder<'a> {
- fn analyze(&mut self, view: &'a DocumentView, document: &'a Document) {
- if !self.visited.insert(&document.uri) {
- return;
- }
-
- if let SyntaxTree::Latex(tree) = &document.tree {
- let mut items = Vec::new();
- for section in &tree.structure.sections {
- items.push(OutlineItem::Section(section));
- }
- for include in &tree.includes {
- items.push(OutlineItem::Include(include));
- }
- items.sort_by_key(SyntaxNode::start);
-
- for item in items {
- match item {
- OutlineItem::Section(item) => {
- let section = OutlineSection::new(document, item);
- self.sections.push(section);
- }
- OutlineItem::Include(item) => {
- for document in &view.related_documents {
- for targets in &item.all_targets {
- if targets.contains(&document.uri) {
- self.analyze(view, document);
- break;
- }
- }
- }
- }
- }
- }
- }
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-enum OutlineItem<'a> {
- Section(&'a LatexSection),
- Include(&'a LatexInclude),
-}
-
-impl<'a> SyntaxNode for OutlineItem<'a> {
- fn range(&self) -> Range {
- match self {
- OutlineItem::Section(section) => section.range(),
- OutlineItem::Include(include) => include.range(),
- }
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub enum OutlineCaptionKind {
- Figure,
- Table,
- Listing,
- Algorithm,
-}
-
-impl OutlineCaptionKind {
- pub fn as_str(self) -> &'static str {
- match self {
- Self::Figure => "Figure",
- Self::Table => "Table",
- Self::Listing => "Listing",
- Self::Algorithm => "Algorithm",
- }
- }
-
- pub fn parse(environment_name: &str) -> Option<Self> {
- match environment_name {
- "figure" | "subfigure" => Some(Self::Figure),
- "table" | "subtable" => Some(Self::Table),
- "listing" | "lstlisting" => Some(Self::Listing),
- "algorithm" => Some(Self::Algorithm),
- _ => None,
- }
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone)]
-pub enum OutlineContextItem {
- Section {
- prefix: &'static str,
- text: String,
- },
- Caption {
- kind: Option<OutlineCaptionKind>,
- text: String,
- },
- Theorem {
- kind: String,
- description: Option<String>,
- },
- Equation,
- Item,
-}
-
-#[derive(Debug, PartialEq, Eq, Clone)]
-pub struct OutlineContext {
- pub range: Range,
- pub number: Option<String>,
- pub item: OutlineContextItem,
-}
-
-impl OutlineContext {
- pub fn reference(&self) -> String {
- match (&self.number, &self.item) {
- (Some(number), OutlineContextItem::Section { prefix, text }) => {
- format!("{} {} ({})", prefix, number, text)
- }
- (Some(number), OutlineContextItem::Caption { kind: None, text }) => {
- format!("{} {}", number, text)
- }
- (
- Some(number),
- OutlineContextItem::Caption {
- kind: Some(kind),
- text,
- },
- ) => format!("{} {}: {}", kind.as_str(), number, text),
- (
- Some(number),
- OutlineContextItem::Theorem {
- kind,
- description: None,
- },
- ) => format!("{} {}", kind, number),
- (
- Some(number),
- OutlineContextItem::Theorem {
- kind,
- description: Some(description),
- },
- ) => format!("{} {} ({})", kind, number, description),
- (Some(number), OutlineContextItem::Equation) => format!("Equation ({})", number),
- (Some(number), OutlineContextItem::Item) => format!("Item {}", number),
- (None, OutlineContextItem::Section { prefix, text }) => {
- format!("{} ({})", prefix, text)
- }
- (None, OutlineContextItem::Caption { kind: None, text }) => text.clone(),
- (
- None,
- OutlineContextItem::Caption {
- kind: Some(kind),
- text,
- },
- ) => format!("{}: {}", kind.as_str(), text),
- (
- None,
- OutlineContextItem::Theorem {
- kind,
- description: None,
- },
- ) => kind.to_owned(),
- (
- None,
- OutlineContextItem::Theorem {
- kind,
- description: Some(description),
- },
- ) => format!("{} ({})", kind, description),
- (None, OutlineContextItem::Equation) => "Equation".to_owned(),
- (None, OutlineContextItem::Item) => "Item".to_owned(),
- }
- }
-
- pub fn detail(&self) -> Option<String> {
- match &self.item {
- OutlineContextItem::Section { .. }
- | OutlineContextItem::Theorem { .. }
- | OutlineContextItem::Equation
- | OutlineContextItem::Item => Some(self.reference()),
- OutlineContextItem::Caption {
- kind: Some(kind), ..
- } => Some(match &self.number {
- Some(number) => format!("{} {}", kind.as_str(), number),
- None => kind.as_str().to_owned(),
- }),
- OutlineContextItem::Caption { .. } => None,
- }
- }
-
- pub fn documentation(&self) -> MarkupContent {
- MarkupContent {
- kind: MarkupKind::PlainText,
- value: self.reference(),
- }
- }
-
- pub fn parse(view: &DocumentView, label: &LatexLabel, outline: &Outline) -> Option<Self> {
- if let SyntaxTree::Latex(tree) = &view.document.tree {
- Self::find_caption(view, label, tree)
- .or_else(|| Self::find_theorem(view, label, tree))
- .or_else(|| Self::find_equation(view, label, tree))
- .or_else(|| Self::find_item(view, label, tree))
- .or_else(|| Self::find_section(view, label, outline))
- } else {
- None
- }
- }
-
- fn find_caption(
- view: &DocumentView,
- label: &LatexLabel,
- tree: &LatexSyntaxTree,
- ) -> Option<Self> {
- let caption_env = tree
- .env
- .environments
- .iter()
- .filter(|env| env.left.name().map(LatexToken::text) != Some("document"))
- .find(|env| env.range().contains(label.start()))?;
-
- let caption = tree
- .structure
- .captions
- .iter()
- .find(|cap| tree.is_direct_child(caption_env, cap.start()))?;
-
- let caption_content = &caption.command.args[caption.index];
- let caption_text = extract_group(caption_content);
- let caption_kind = caption_env
- .left
- .name()
- .map(LatexToken::text)
- .and_then(OutlineCaptionKind::parse);
-
- Some(Self {
- range: caption_env.range(),
- number: Self::find_number(view, label),
- item: OutlineContextItem::Caption {
- kind: caption_kind,
- text: caption_text,
- },
- })
- }
-
- fn find_theorem(
- view: &DocumentView,
- label: &LatexLabel,
- tree: &LatexSyntaxTree,
- ) -> Option<Self> {
- let env = tree
- .env
- .environments
- .iter()
- .find(|env| env.range().contains(label.start()))?;
-
- let env_name = env.left.name().map(LatexToken::text)?;
-
- for document in &view.related_documents {
- if let SyntaxTree::Latex(tree) = &document.tree {
- for definition in &tree.math.theorem_definitions {
- if env_name == definition.name().text() {
- let kind = definition
- .command
- .args
- .get(definition.index + 1)
- .map(|content| extract_group(&content))
- .unwrap_or_else(|| titlelize(env_name));
-
- let description = env
- .left
- .command
- .options
- .get(0)
- .map(|content| extract_group(&content));
-
- return Some(Self {
- range: env.range(),
- number: Self::find_number(view, label),
- item: OutlineContextItem::Theorem { kind, description },
- });
- }
- }
- }
- }
- None
- }
-
- fn find_equation(
- view: &DocumentView,
- label: &LatexLabel,
- tree: &LatexSyntaxTree,
- ) -> Option<Self> {
- tree.env
- .environments
- .iter()
- .filter(|env| env.left.is_math())
- .map(|env| env.range())
- .find(|range| range.contains(label.start()))
- .map(|range| Self {
- range,
- number: Self::find_number(view, label),
- item: OutlineContextItem::Equation,
- })
- }
-
- fn find_item(view: &DocumentView, label: &LatexLabel, tree: &LatexSyntaxTree) -> Option<Self> {
- struct LatexItemNode<'a> {
- item: &'a LatexItem,
- range: Range,
- }
-
- let enumeration = tree
- .env
- .environments
- .iter()
- .find(|env| env.left.is_enum() && env.range().contains(label.start()))?;
-
- let mut item_nodes: Vec<_> = tree
- .structure
- .items
- .iter()
- .filter(|item| tree.is_enumeration_item(enumeration, item))
- .map(|item| LatexItemNode {
- item,
- range: Range::default(),
- })
- .collect();
-
- for i in 0..item_nodes.len() {
- let start = item_nodes[i].item.start();
- let end = item_nodes
- .get(i + 1)
- .map(|node| node.item.start())
- .unwrap_or_else(|| enumeration.right.start());
- item_nodes[i].range = Range::new(start, end);
- }
-
- let node = item_nodes
- .iter()
- .find(|node| node.range.contains(label.start()))?;
-
- let number = node.item.name().or_else(|| Self::find_number(view, label));
-
- Some(Self {
- range: enumeration.range(),
- number,
- item: OutlineContextItem::Item,
- })
- }
-
- fn find_section(view: &DocumentView, label: &LatexLabel, outline: &Outline) -> Option<Self> {
- let section = outline.find(&view.document.uri, label.start())?;
- let content = &section.command.args[section.index];
- Some(Self {
- range: section.range(),
- number: Self::find_number(view, label),
- item: OutlineContextItem::Section {
- prefix: section.prefix,
- text: extract_group(content),
- },
- })
- }
-
- pub fn find_number(view: &DocumentView, label: &LatexLabel) -> Option<String> {
- let label_names = label.names();
- if label_names.len() != 1 {
- return None;
- }
-
- for document in &view.related_documents {
- if let SyntaxTree::Latex(tree) = &document.tree {
- for numbering in &tree.structure.label_numberings {
- if numbering.name().text() == label_names[0].text() {
- return Some(numbering.number.clone());
- }
- }
- }
- }
- None
- }
-}