summaryrefslogtreecommitdiff
path: root/support/texlab/src/symbol/latex_section/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/src/symbol/latex_section/mod.rs')
-rw-r--r--support/texlab/src/symbol/latex_section/mod.rs781
1 files changed, 409 insertions, 372 deletions
diff --git a/support/texlab/src/symbol/latex_section/mod.rs b/support/texlab/src/symbol/latex_section/mod.rs
index f6fe2aede9..fc81695b50 100644
--- a/support/texlab/src/symbol/latex_section/mod.rs
+++ b/support/texlab/src/symbol/latex_section/mod.rs
@@ -3,38 +3,57 @@ mod equation;
mod float;
mod theorem;
-use super::{LatexSymbol, LatexSymbolKind};
-use crate::range::RangeExt;
-use crate::syntax::*;
-use crate::workspace::*;
-use futures_boxed::boxed;
-use lsp_types::*;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
+use super::types::{LatexSymbol, LatexSymbolKind};
+use crate::{
+ feature::{DocumentView, FeatureProvider, FeatureRequest},
+ outline::{Outline, OutlineContext, OutlineContextItem},
+ protocol::{DocumentSymbolParams, Options, Position, Range, RangeExt},
+ syntax::{latex, CharStream, LatexLabelKind, SyntaxNode},
+ workspace::DocumentContent,
+};
+use async_trait::async_trait;
+use std::path::Path;
+
+fn label_name(table: &latex::SymbolTable, label: Option<&latex::Label>) -> Option<String> {
+ label.map(|label| label.names(&table)[0].text().to_owned())
+}
+
+fn selection_range(
+ table: &latex::SymbolTable,
+ full_range: Range,
+ label: Option<&latex::Label>,
+) -> Range {
+ label
+ .map(|label| table[label.parent].range())
+ .unwrap_or(full_range)
+}
+
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
pub struct LatexSectionSymbolProvider;
+#[async_trait]
impl FeatureProvider for LatexSectionSymbolProvider {
type Params = DocumentSymbolParams;
type Output = Vec<LatexSymbol>;
- #[boxed]
- async fn execute<'a>(&'a self, request: &'a FeatureRequest<Self::Params>) -> Self::Output {
+ async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
let mut symbols = Vec::new();
- if let SyntaxTree::Latex(tree) = &request.document().tree {
- let mut section_tree = build_section_tree(&request.view, tree);
- for symbol in enumeration::symbols(&request.view, tree) {
+ if let DocumentContent::Latex(table) = &req.current().content {
+ let mut section_tree =
+ build_section_tree(&req.view, table, &req.options, &req.current_dir);
+ for symbol in enumeration::symbols(&req.view, table) {
section_tree.insert_symbol(&symbol);
}
- for symbol in equation::symbols(&request.view, tree) {
+ for symbol in equation::symbols(&req.view, table) {
section_tree.insert_symbol(&symbol);
}
- for symbol in float::symbols(&request.view, tree) {
+ for symbol in float::symbols(&req.view, table) {
section_tree.insert_symbol(&symbol);
}
- for symbol in theorem::symbols(&request.view, tree) {
+ for symbol in theorem::symbols(&req.view, table) {
section_tree.insert_symbol(&symbol);
}
@@ -52,33 +71,36 @@ impl FeatureProvider for LatexSectionSymbolProvider {
pub fn build_section_tree<'a>(
view: &'a DocumentView,
- tree: &'a LatexSyntaxTree,
+ table: &'a latex::SymbolTable,
+ options: &'a Options,
+ current_dir: &'a Path,
) -> LatexSectionTree<'a> {
- let mut section_tree = LatexSectionTree::from(tree);
- section_tree.set_full_text(&view.document.text);
- let end_position = compute_end_position(tree, &view.document.text);
- LatexSectionNode::set_full_range(&mut section_tree.children, end_position);
- let outline = Outline::from(view);
+ let mut section_tree = LatexSectionTree::from(table);
+ section_tree.set_full_text(&view.current.text);
+ let end_position = compute_end_position(table, &view.current.text);
+ LatexSectionNode::set_full_range(&mut section_tree.children, table, end_position);
+ let outline = Outline::analyze(view, options, current_dir);
for child in &mut section_tree.children {
- child.set_label(tree, view, &outline);
+ child.set_label(view, &outline);
}
section_tree
}
-fn compute_end_position(tree: &LatexSyntaxTree, text: &str) -> Position {
+fn compute_end_position(table: &latex::SymbolTable, text: &str) -> Position {
let mut stream = CharStream::new(text);
while stream.next().is_some() {}
- tree.env
+ table
.environments
.iter()
- .find(|env| env.left.name().map(LatexToken::text) == Some("document"))
- .map(|env| env.right.start())
+ .find(|env| env.left.name(&table).map(latex::Token::text) == Some("document"))
+ .map(|env| table[env.right.parent].start())
.unwrap_or(stream.current_position)
}
-#[derive(Debug, PartialEq, Eq, Clone)]
+#[derive(Debug, Clone)]
pub struct LatexSectionNode<'a> {
- pub section: &'a LatexSection,
+ pub table: &'a latex::SymbolTable,
+ pub section: &'a latex::Section,
pub full_range: Range,
full_text: &'a str,
label: Option<String>,
@@ -88,8 +110,9 @@ pub struct LatexSectionNode<'a> {
}
impl<'a> LatexSectionNode<'a> {
- fn new(section: &'a LatexSection) -> Self {
+ fn new(table: &'a latex::SymbolTable, section: &'a latex::Section) -> Self {
Self {
+ table,
section,
full_range: Range::default(),
full_text: "",
@@ -108,37 +131,45 @@ impl<'a> LatexSectionNode<'a> {
}
fn name(&self) -> String {
- self.section
- .extract_text(self.full_text)
- .unwrap_or_else(|| "Unknown".to_owned())
+ self.table
+ .print_group_content(
+ self.section.parent,
+ latex::GroupKind::Group,
+ self.section.arg_index,
+ )
+ .unwrap_or_else(|| "Unknown".into())
}
- fn set_full_range(children: &mut Vec<Self>, end_position: Position) {
+ fn set_full_range(
+ children: &mut Vec<Self>,
+ table: &latex::SymbolTable,
+ end_position: Position,
+ ) {
for i in 0..children.len() {
let current_end = children
.get(i + 1)
- .map(|next| next.section.start())
+ .map(|next| table[next.section.parent].start())
.unwrap_or(end_position);
let mut current = &mut children[i];
- current.full_range = Range::new(current.section.start(), current_end);
- Self::set_full_range(&mut current.children, current_end);
+ current.full_range = Range::new(table[current.section.parent].start(), current_end);
+ Self::set_full_range(&mut current.children, table, current_end);
}
}
- fn set_label(&mut self, tree: &LatexSyntaxTree, view: &DocumentView, outline: &Outline) {
- if let Some(label) = tree
- .structure
+ fn set_label(&mut self, view: &DocumentView, outline: &Outline) {
+ if let Some(label) = self
+ .table
.labels
.iter()
.filter(|label| label.kind == LatexLabelKind::Definition)
- .find(|label| self.full_range.contains(label.start()))
+ .find(|label| self.full_range.contains(self.table[label.parent].start()))
{
- if let Some(ctx) = OutlineContext::parse(view, label, outline) {
+ if let Some(ctx) = OutlineContext::parse(view, outline, *label) {
let mut is_section = false;
if let OutlineContextItem::Section { text, .. } = &ctx.item {
if self.name() == *text {
- for name in label.names() {
+ for name in label.names(&self.table) {
self.label = Some(name.text().to_owned());
}
@@ -153,21 +184,25 @@ impl<'a> LatexSectionNode<'a> {
}
for child in &mut self.children {
- child.set_label(tree, view, outline);
+ child.set_label(view, outline);
}
}
- fn insert_section(nodes: &mut Vec<Self>, section: &'a LatexSection) {
+ fn insert_section(
+ nodes: &mut Vec<Self>,
+ table: &'a latex::SymbolTable,
+ section: &'a latex::Section,
+ ) {
match nodes.last_mut() {
Some(parent) => {
if parent.section.level < section.level {
- Self::insert_section(&mut parent.children, section);
+ Self::insert_section(&mut parent.children, table, section);
} else {
- nodes.push(LatexSectionNode::new(section));
+ nodes.push(LatexSectionNode::new(table, section));
}
}
None => {
- nodes.push(LatexSectionNode::new(section));
+ nodes.push(LatexSectionNode::new(table, section));
}
}
}
@@ -223,13 +258,13 @@ impl<'a> Into<LatexSymbol> for LatexSectionNode<'a> {
kind: LatexSymbolKind::Section,
deprecated: false,
full_range: self.full_range,
- selection_range: self.section.range(),
+ selection_range: self.table[self.section.parent].range(),
children,
}
}
}
-#[derive(Debug, PartialEq, Eq, Clone)]
+#[derive(Debug, Clone)]
pub struct LatexSectionTree<'a> {
symbols: Vec<LatexSymbol>,
children: Vec<LatexSectionNode<'a>>,
@@ -269,366 +304,368 @@ impl<'a> LatexSectionTree<'a> {
}
}
-impl<'a> From<&'a LatexSyntaxTree> for LatexSectionTree<'a> {
- fn from(tree: &'a LatexSyntaxTree) -> Self {
+impl<'a> From<&'a latex::SymbolTable> for LatexSectionTree<'a> {
+ fn from(table: &'a latex::SymbolTable) -> Self {
let mut root = Self::new();
- for section in &tree.structure.sections {
- LatexSectionNode::insert_section(&mut root.children, section);
+ for section in &table.sections {
+ LatexSectionNode::insert_section(&mut root.children, table, section);
}
root
}
}
-pub fn label_name(label: Option<&LatexLabel>) -> Option<String> {
- label.map(|label| label.names()[0].text().to_owned())
-}
-
-pub fn selection_range(full_range: Range, label: Option<&LatexLabel>) -> Range {
- label.map(|label| label.range()).unwrap_or(full_range)
-}
-
#[cfg(test)]
mod tests {
use super::*;
- use crate::range::RangeExt;
-
- #[test]
- fn test_subsection() {
- let symbols = test_feature(
- LatexSectionSymbolProvider,
- FeatureSpec {
- files: vec![
- FeatureSpec::file(
- "foo.tex",
- "\\section{Foo}\n\\subsection{Bar}\\label{sec:bar}\n\\subsection{Baz}\n\\section{Qux}",
- ),
- FeatureSpec::file(
- "foo.aux",
- "\\newlabel{sec:bar}{{\\relax 2.1}{4}{Bar\\relax }{figure.caption.4}{}}"
- ),
- ],
- main_file: "foo.tex",
- ..FeatureSpec::default()
- },
- );
- assert_eq!(
- symbols,
- vec![
- LatexSymbol {
- name: "Foo".into(),
- label: None,
- kind: LatexSymbolKind::Section,
- deprecated: false,
- full_range: Range::new_simple(0, 0, 3, 0),
- selection_range: Range::new_simple(0, 0, 0, 13),
- children: vec![
- LatexSymbol {
- name: "2.1 Bar".into(),
- label: Some("sec:bar".into()),
- kind: LatexSymbolKind::Section,
- deprecated: false,
- full_range: Range::new_simple(1, 0, 2, 0),
- selection_range: Range::new_simple(1, 0, 1, 16),
- children: Vec::new(),
- },
- LatexSymbol {
- name: "Baz".into(),
- label: None,
- kind: LatexSymbolKind::Section,
- deprecated: false,
- full_range: Range::new_simple(2, 0, 3, 0),
- selection_range: Range::new_simple(2, 0, 2, 16),
- children: Vec::new(),
- },
- ],
- },
- LatexSymbol {
- name: "Qux".into(),
- label: None,
- kind: LatexSymbolKind::Section,
- deprecated: false,
- full_range: Range::new_simple(3, 0, 3, 13),
- selection_range: Range::new_simple(3, 0, 3, 13),
- children: Vec::new(),
- }
- ]
- );
+ use crate::feature::FeatureTester;
+ use indoc::indoc;
+
+ #[tokio::test]
+ async fn empty_latex_document() {
+ let actual_symbols = FeatureTester::new()
+ .file("main.tex", "")
+ .main("main.tex")
+ .test_symbol(LatexSectionSymbolProvider)
+ .await;
+
+ assert!(actual_symbols.is_empty());
}
- #[test]
- fn test_section_inside_document_environment() {
- let symbols = test_feature(
- LatexSectionSymbolProvider,
- FeatureSpec {
- files: vec![FeatureSpec::file(
- "foo.tex",
- "\\begin{document}\\section{Foo}\\relax\n\\end{document}",
- )],
- main_file: "foo.tex",
- ..FeatureSpec::default()
- },
- );
- assert_eq!(
- symbols,
- vec![LatexSymbol {
+ #[tokio::test]
+ async fn empty_bibtex_document() {
+ let actual_symbols = FeatureTester::new()
+ .file("main.bib", "")
+ .main("main.bib")
+ .test_symbol(LatexSectionSymbolProvider)
+ .await;
+
+ assert!(actual_symbols.is_empty());
+ }
+
+ #[tokio::test]
+ async fn subsection() {
+ let actual_symbols = FeatureTester::new()
+ .file(
+ "main.tex",
+ indoc!(
+ r#"
+ \section{Foo}
+ \subsection{Bar}\label{sec:bar}
+ \subsection{Baz}
+ \section{Qux}
+ "#
+ ),
+ )
+ .file(
+ "main.aux",
+ r#"\newlabel{sec:bar}{{\relax 2.1}{4}{Bar\relax }{figure.caption.4}{}}"#,
+ )
+ .main("main.tex")
+ .test_symbol(LatexSectionSymbolProvider)
+ .await;
+
+ let expected_symbols = vec![
+ LatexSymbol {
name: "Foo".into(),
label: None,
kind: LatexSymbolKind::Section,
deprecated: false,
- full_range: Range::new_simple(0, 16, 1, 0),
- selection_range: Range::new_simple(0, 16, 0, 29),
- children: Vec::new()
- }]
- );
- }
-
- #[test]
- fn test_enumeration() {
- let symbols = test_feature(
- LatexSectionSymbolProvider,
- FeatureSpec {
- files: vec![FeatureSpec::file(
- "foo.tex",
- "\\section{Foo}\n\\begin{enumerate}\n\\end{enumerate}",
- )],
- main_file: "foo.tex",
- ..FeatureSpec::default()
+ full_range: Range::new_simple(0, 0, 3, 0),
+ selection_range: Range::new_simple(0, 0, 0, 13),
+ children: vec![
+ LatexSymbol {
+ name: "2.1 Bar".into(),
+ label: Some("sec:bar".into()),
+ kind: LatexSymbolKind::Section,
+ deprecated: false,
+ full_range: Range::new_simple(1, 0, 2, 0),
+ selection_range: Range::new_simple(1, 0, 1, 16),
+ children: Vec::new(),
+ },
+ LatexSymbol {
+ name: "Baz".into(),
+ label: None,
+ kind: LatexSymbolKind::Section,
+ deprecated: false,
+ full_range: Range::new_simple(2, 0, 3, 0),
+ selection_range: Range::new_simple(2, 0, 2, 16),
+ children: Vec::new(),
+ },
+ ],
},
- );
- assert_eq!(
- symbols,
- vec![LatexSymbol {
- name: "Foo".into(),
+ LatexSymbol {
+ name: "Qux".into(),
label: None,
kind: LatexSymbolKind::Section,
deprecated: false,
- full_range: Range::new_simple(0, 0, 2, 15),
- selection_range: Range::new_simple(0, 0, 0, 13),
- children: vec![LatexSymbol {
- name: "Enumerate".into(),
- label: None,
- kind: LatexSymbolKind::Enumeration,
- deprecated: false,
- full_range: Range::new_simple(1, 0, 2, 15),
- selection_range: Range::new_simple(1, 0, 2, 15),
- children: Vec::new(),
- },],
- },]
- );
+ full_range: Range::new_simple(3, 0, 3, 13),
+ selection_range: Range::new_simple(3, 0, 3, 13),
+ children: Vec::new(),
+ },
+ ];
+
+ assert_eq!(actual_symbols, expected_symbols);
}
- #[test]
- fn test_equation() {
- let symbols = test_feature(
- LatexSectionSymbolProvider,
- FeatureSpec {
- files: vec![FeatureSpec::file(
- "foo.tex",
- "\\[Foo\\]\n\\begin{equation}\\label{eq:foo}\\end{equation}",
- )],
- main_file: "foo.tex",
- ..FeatureSpec::default()
- },
- );
- assert_eq!(
- symbols,
- vec![
- LatexSymbol {
- name: "Equation".into(),
- label: None,
- kind: LatexSymbolKind::Equation,
- deprecated: false,
- full_range: Range::new_simple(0, 0, 0, 7),
- selection_range: Range::new_simple(0, 0, 0, 7),
- children: Vec::new(),
- },
- LatexSymbol {
- name: "Equation".into(),
- label: Some("eq:foo".into()),
- kind: LatexSymbolKind::Equation,
- deprecated: false,
- full_range: Range::new_simple(1, 0, 1, 44),
- selection_range: Range::new_simple(1, 16, 1, 30),
- children: Vec::new(),
- },
- ]
- );
+ #[tokio::test]
+ async fn section_inside_document_environment() {
+ let actual_symbols = FeatureTester::new()
+ .file(
+ "main.tex",
+ indoc!(
+ r#"
+ \begin{document}\section{Foo}\relax
+ \end{document}
+ "#
+ ),
+ )
+ .main("main.tex")
+ .test_symbol(LatexSectionSymbolProvider)
+ .await;
+
+ let expected_symbols = vec![LatexSymbol {
+ name: "Foo".into(),
+ label: None,
+ kind: LatexSymbolKind::Section,
+ deprecated: false,
+ full_range: Range::new_simple(0, 16, 1, 0),
+ selection_range: Range::new_simple(0, 16, 0, 29),
+ children: Vec::new(),
+ }];
+
+ assert_eq!(actual_symbols, expected_symbols);
}
- #[test]
- fn test_equation_number() {
- let symbols = test_feature(
- LatexSectionSymbolProvider,
- FeatureSpec {
- files: vec![
- FeatureSpec::file("foo.tex", "\\[\\label{eq:foo}\\]"),
- FeatureSpec::file(
- "foo.aux",
- "\\newlabel{eq:foo}{{\\relax 2.1}{4}{Bar\\relax }{figure.caption.4}{}}",
- ),
- ],
- main_file: "foo.tex",
- ..FeatureSpec::default()
- },
- );
- assert_eq!(
- symbols,
- vec![LatexSymbol {
- name: "Equation (2.1)".into(),
- label: Some("eq:foo".into()),
- kind: LatexSymbolKind::Equation,
+ #[tokio::test]
+ async fn enumeration() {
+ let actual_symbols = FeatureTester::new()
+ .file(
+ "main.tex",
+ indoc!(
+ r#"
+ \section{Foo}
+ \begin{enumerate}
+ \end{enumerate}
+ "#
+ ),
+ )
+ .main("main.tex")
+ .test_symbol(LatexSectionSymbolProvider)
+ .await;
+
+ let expected_symbols = vec![LatexSymbol {
+ name: "Foo".into(),
+ label: None,
+ kind: LatexSymbolKind::Section,
+ deprecated: false,
+ full_range: Range::new_simple(0, 0, 2, 15),
+ selection_range: Range::new_simple(0, 0, 0, 13),
+ children: vec![LatexSymbol {
+ name: "Enumerate".into(),
+ label: None,
+ kind: LatexSymbolKind::Enumeration,
deprecated: false,
- full_range: Range::new_simple(0, 0, 0, 18),
- selection_range: Range::new_simple(0, 2, 0, 16),
+ full_range: Range::new_simple(1, 0, 2, 15),
+ selection_range: Range::new_simple(1, 0, 2, 15),
children: Vec::new(),
- },]
- );
+ }],
+ }];
+
+ assert_eq!(actual_symbols, expected_symbols);
}
- #[test]
- fn test_table() {
- let symbols = test_feature(
- LatexSectionSymbolProvider,
- FeatureSpec {
- files: vec![FeatureSpec::file(
- "foo.tex",
- "\\begin{table}\\caption{Foo}\\end{table}",
- )],
- main_file: "foo.tex",
- ..FeatureSpec::default()
- },
- );
- assert_eq!(
- symbols,
- vec![LatexSymbol {
- name: "Table: Foo".into(),
+ #[tokio::test]
+ async fn equation() {
+ let actual_symbols = FeatureTester::new()
+ .file(
+ "main.tex",
+ indoc!(
+ r#"
+ \[Foo\]
+ \begin{equation}\label{eq:foo}\end{equation}
+ "#
+ ),
+ )
+ .main("main.tex")
+ .test_symbol(LatexSectionSymbolProvider)
+ .await;
+
+ let expected_symbols = vec![
+ LatexSymbol {
+ name: "Equation".into(),
label: None,
- kind: LatexSymbolKind::Table,
+ kind: LatexSymbolKind::Equation,
deprecated: false,
- full_range: Range::new_simple(0, 0, 0, 37),
- selection_range: Range::new_simple(0, 0, 0, 37),
+ full_range: Range::new_simple(0, 0, 0, 7),
+ selection_range: Range::new_simple(0, 0, 0, 7),
children: Vec::new(),
- },]
- );
- }
-
- #[test]
- fn test_figure_number() {
- let symbols = test_feature(
- LatexSectionSymbolProvider,
- FeatureSpec {
- files: vec![
- FeatureSpec::file(
- "foo.tex",
- "\\begin{figure}\\caption{Foo}\\label{fig:foo}\\end{figure}",
- ),
- FeatureSpec::file(
- "foo.aux",
- "\\newlabel{fig:foo}{{\\relax 2.1}{4}{Bar\\relax }{figure.caption.4}{}}",
- ),
- ],
- main_file: "foo.tex",
- ..FeatureSpec::default()
},
- );
- assert_eq!(
- symbols,
- vec![LatexSymbol {
- name: "Figure 2.1: Foo".into(),
- label: Some("fig:foo".into()),
- kind: LatexSymbolKind::Figure,
+ LatexSymbol {
+ name: "Equation".into(),
+ label: Some("eq:foo".into()),
+ kind: LatexSymbolKind::Equation,
deprecated: false,
- full_range: Range::new_simple(0, 0, 0, 54),
- selection_range: Range::new_simple(0, 27, 0, 42),
+ full_range: Range::new_simple(1, 0, 1, 44),
+ selection_range: Range::new_simple(1, 16, 1, 30),
children: Vec::new(),
- },]
- );
+ },
+ ];
+
+ assert_eq!(actual_symbols, expected_symbols);
}
- #[test]
- fn test_lemma() {
- let symbols = test_feature(
- LatexSectionSymbolProvider,
- FeatureSpec {
- files: vec![FeatureSpec::file(
- "foo.tex",
- "\\newtheorem{lemma}{Lemma}\\begin{lemma}\\end{lemma}",
- )],
- main_file: "foo.tex",
- ..FeatureSpec::default()
- },
- );
- assert_eq!(
- symbols,
- vec![LatexSymbol {
- name: "Lemma".into(),
- label: None,
- kind: LatexSymbolKind::Theorem,
- deprecated: false,
- full_range: Range::new_simple(0, 25, 0, 49),
- selection_range: Range::new_simple(0, 25, 0, 49),
- children: Vec::new(),
- },]
- );
+ #[tokio::test]
+ async fn equation_number() {
+ let actual_symbols = FeatureTester::new()
+ .file("main.tex", r#"\[\label{eq:foo}\]"#)
+ .file(
+ "main.aux",
+ r#"\newlabel{eq:foo}{{\relax 2.1}{4}{Bar\relax }{figure.caption.4}{}}"#,
+ )
+ .main("main.tex")
+ .test_symbol(LatexSectionSymbolProvider)
+ .await;
+
+ let expected_symbols = vec![LatexSymbol {
+ name: "Equation (2.1)".into(),
+ label: Some("eq:foo".into()),
+ kind: LatexSymbolKind::Equation,
+ deprecated: false,
+ full_range: Range::new_simple(0, 0, 0, 18),
+ selection_range: Range::new_simple(0, 2, 0, 16),
+ children: Vec::new(),
+ }];
+
+ assert_eq!(actual_symbols, expected_symbols);
}
- #[test]
- fn test_lemma_number() {
- let symbols = test_feature(
- LatexSectionSymbolProvider,
- FeatureSpec {
- files: vec![
- FeatureSpec::file(
- "foo.tex",
- "\\newtheorem{lemma}{Lemma}\n\\begin{lemma}\\label{thm:foo}\\end{lemma}",
- ),
- FeatureSpec::file(
- "foo.aux",
- "\\newlabel{thm:foo}{{\\relax 2.1}{4}{Bar\\relax }{figure.caption.4}{}}",
- ),
- ],
- main_file: "foo.tex",
- ..FeatureSpec::default()
- },
- );
- assert_eq!(
- symbols,
- vec![LatexSymbol {
- name: "Lemma 2.1".into(),
- label: Some("thm:foo".into()),
- kind: LatexSymbolKind::Theorem,
- deprecated: false,
- full_range: Range::new_simple(1, 0, 1, 39),
- selection_range: Range::new_simple(1, 13, 1, 28),
- children: Vec::new(),
- },]
- );
+ #[tokio::test]
+ async fn table() {
+ let actual_symbols = FeatureTester::new()
+ .file("main.tex", r#"\begin{table}\caption{Foo}\end{table}"#)
+ .main("main.tex")
+ .test_symbol(LatexSectionSymbolProvider)
+ .await;
+
+ let expected_symbols = vec![LatexSymbol {
+ name: "Table: Foo".into(),
+ label: None,
+ kind: LatexSymbolKind::Table,
+ deprecated: false,
+ full_range: Range::new_simple(0, 0, 0, 37),
+ selection_range: Range::new_simple(0, 0, 0, 37),
+ children: Vec::new(),
+ }];
+
+ assert_eq!(actual_symbols, expected_symbols);
}
- #[test]
- fn test_lemma_description() {
- let symbols = test_feature(
- LatexSectionSymbolProvider,
- FeatureSpec {
- files: vec![FeatureSpec::file(
- "foo.tex",
- "\\newtheorem{lemma}{Lemma}\\begin{lemma}[Foo]\\end{lemma}",
- )],
- main_file: "foo.tex",
- ..FeatureSpec::default()
- },
- );
- assert_eq!(
- symbols,
- vec![LatexSymbol {
- name: "Lemma (Foo)".into(),
- label: None,
- kind: LatexSymbolKind::Theorem,
- deprecated: false,
- full_range: Range::new_simple(0, 25, 0, 54),
- selection_range: Range::new_simple(0, 25, 0, 54),
- children: Vec::new(),
- },]
- );
+ #[tokio::test]
+ async fn figure_number() {
+ let actual_symbols = FeatureTester::new()
+ .file(
+ "main.tex",
+ r#"\begin{figure}\caption{Foo}\label{fig:foo}\end{figure}"#,
+ )
+ .file(
+ "main.aux",
+ r#"\newlabel{fig:foo}{{\relax 2.1}{4}{Bar\relax }{figure.caption.4}{}}"#,
+ )
+ .main("main.tex")
+ .test_symbol(LatexSectionSymbolProvider)
+ .await;
+
+ let expected_symbols = vec![LatexSymbol {
+ name: "Figure 2.1: Foo".into(),
+ label: Some("fig:foo".into()),
+ kind: LatexSymbolKind::Figure,
+ deprecated: false,
+ full_range: Range::new_simple(0, 0, 0, 54),
+ selection_range: Range::new_simple(0, 27, 0, 42),
+ children: Vec::new(),
+ }];
+
+ assert_eq!(actual_symbols, expected_symbols);
+ }
+
+ #[tokio::test]
+ async fn lemma() {
+ let actual_symbols = FeatureTester::new()
+ .file(
+ "main.tex",
+ r#"\newtheorem{lemma}{Lemma}\begin{lemma}\end{lemma}"#,
+ )
+ .main("main.tex")
+ .test_symbol(LatexSectionSymbolProvider)
+ .await;
+
+ let expected_symbols = vec![LatexSymbol {
+ name: "Lemma".into(),
+ label: None,
+ kind: LatexSymbolKind::Theorem,
+ deprecated: false,
+ full_range: Range::new_simple(0, 25, 0, 49),
+ selection_range: Range::new_simple(0, 25, 0, 49),
+ children: Vec::new(),
+ }];
+
+ assert_eq!(actual_symbols, expected_symbols);
+ }
+
+ #[tokio::test]
+ async fn lemma_number() {
+ let actual_symbols = FeatureTester::new()
+ .file(
+ "main.tex",
+ indoc!(
+ r#"
+ \newtheorem{lemma}{Lemma}
+ \begin{lemma}\label{thm:foo}\end{lemma}
+ "#
+ ),
+ )
+ .file(
+ "main.aux",
+ r#"\newlabel{thm:foo}{{\relax 2.1}{4}{Bar\relax }{figure.caption.4}{}}"#,
+ )
+ .main("main.tex")
+ .test_symbol(LatexSectionSymbolProvider)
+ .await;
+
+ let expected_symbols = vec![LatexSymbol {
+ name: "Lemma 2.1".into(),
+ label: Some("thm:foo".into()),
+ kind: LatexSymbolKind::Theorem,
+ deprecated: false,
+ full_range: Range::new_simple(1, 0, 1, 39),
+ selection_range: Range::new_simple(1, 13, 1, 28),
+ children: Vec::new(),
+ }];
+
+ assert_eq!(actual_symbols, expected_symbols);
+ }
+
+ #[tokio::test]
+ async fn lemma_description() {
+ let actual_symbols = FeatureTester::new()
+ .file(
+ "main.tex",
+ r#"\newtheorem{lemma}{Lemma}\begin{lemma}[Foo]\end{lemma}"#,
+ )
+ .main("main.tex")
+ .test_symbol(LatexSectionSymbolProvider)
+ .await;
+
+ let expected_symbols = vec![LatexSymbol {
+ name: "Lemma (Foo)".into(),
+ label: None,
+ kind: LatexSymbolKind::Theorem,
+ deprecated: false,
+ full_range: Range::new_simple(0, 25, 0, 54),
+ selection_range: Range::new_simple(0, 25, 0, 54),
+ children: Vec::new(),
+ }];
+
+ assert_eq!(actual_symbols, expected_symbols);
}
}