diff options
Diffstat (limited to 'support/texlab/src/completion/latex/glossary.rs')
-rw-r--r-- | support/texlab/src/completion/latex/glossary.rs | 149 |
1 files changed, 105 insertions, 44 deletions
diff --git a/support/texlab/src/completion/latex/glossary.rs b/support/texlab/src/completion/latex/glossary.rs index ca6600b690..417152dd21 100644 --- a/support/texlab/src/completion/latex/glossary.rs +++ b/support/texlab/src/completion/latex/glossary.rs @@ -1,53 +1,114 @@ use super::combinators::{self, Parameter}; -use crate::completion::factory; -use crate::syntax::LatexGlossaryEntryKind::*; -use crate::syntax::*; -use crate::workspace::*; -use futures_boxed::boxed; -use lsp_types::{CompletionItem, CompletionParams, TextEdit}; - -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub struct LatexGlossaryCompletionProvider; - -impl FeatureProvider for LatexGlossaryCompletionProvider { - type Params = CompletionParams; - type Output = Vec<CompletionItem>; - - #[boxed] - async fn execute<'a>(&'a self, request: &'a FeatureRequest<Self::Params>) -> Self::Output { - let parameters = LANGUAGE_DATA +use crate::{ + completion::types::{Item, ItemData}, + feature::FeatureRequest, + protocol::CompletionParams, + syntax::{ + LatexGlossaryEntryKind::{Acronym, General}, + LANGUAGE_DATA, + }, + workspace::DocumentContent, +}; + +pub async fn complete_latex_glossary_entries<'a>( + req: &'a FeatureRequest<CompletionParams>, + items: &mut Vec<Item<'a>>, +) { + let parameters = LANGUAGE_DATA + .glossary_entry_reference_commands + .iter() + .map(|cmd| Parameter { + name: &cmd.name[1..], + index: cmd.index, + }); + + combinators::argument(req, parameters, |ctx| async move { + let cmd_kind = LANGUAGE_DATA .glossary_entry_reference_commands .iter() - .map(|cmd| Parameter::new(&cmd.name, cmd.index)); - - combinators::argument(request, parameters, |context| { - async move { - let cmd_kind = LANGUAGE_DATA - .glossary_entry_reference_commands - .iter() - .find(|cmd| cmd.name == context.parameter.name) - .unwrap() - .kind; - - let mut items = Vec::new(); - for document in request.related_documents() { - if let SyntaxTree::Latex(tree) = &document.tree { - for entry in &tree.glossary.entries { - match (cmd_kind, entry.kind) { - (Acronym, Acronym) | (General, General) | (General, Acronym) => { - let label = entry.label().text().to_owned(); - let text_edit = TextEdit::new(context.range, label.clone()); - let item = factory::glossary_entry(request, label, text_edit); - items.push(item); - } - (Acronym, General) => {} - } + .find(|cmd| &cmd.name[1..] == ctx.parameter.name) + .unwrap() + .kind; + + for doc in req.related() { + if let DocumentContent::Latex(table) = &doc.content { + for entry in &table.glossary_entries { + match (cmd_kind, entry.kind) { + (Acronym, Acronym) | (General, General) | (General, Acronym) => { + let name = entry.label(&table).text(); + let item = Item::new(ctx.range, ItemData::GlossaryEntry { name }); + items.push(item); } + (Acronym, General) => {} } } - items } - }) - .await + } + }) + .await +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + feature::FeatureTester, + protocol::{Range, RangeExt}, + }; + use indoc::indoc; + + #[tokio::test] + async fn empty_latex_document() { + let req = FeatureTester::new() + .file("main.tex", "") + .main("main.tex") + .position(0, 0) + .test_completion_request() + .await; + let mut actual_items = Vec::new(); + + complete_latex_glossary_entries(&req, &mut actual_items).await; + + assert!(actual_items.is_empty()); + } + + #[tokio::test] + async fn empty_bibtex_document() { + let req = FeatureTester::new() + .file("main.bib", "") + .main("main.bib") + .position(0, 0) + .test_completion_request() + .await; + let mut actual_items = Vec::new(); + + complete_latex_glossary_entries(&req, &mut actual_items).await; + + assert!(actual_items.is_empty()); + } + + #[tokio::test] + async fn acronym() { + let req = FeatureTester::new() + .file( + "main.tex", + indoc!( + r#" + \newacronym{lvm}{LVM}{Logical Volume Manager} + \acrfull{foo} + "# + ), + ) + .main("main.tex") + .position(1, 9) + .test_completion_request() + .await; + let mut actual_items = Vec::new(); + + complete_latex_glossary_entries(&req, &mut actual_items).await; + + assert_eq!(actual_items.len(), 1); + assert_eq!(actual_items[0].data.label(), "lvm"); + assert_eq!(actual_items[0].range, Range::new_simple(1, 9, 1, 12)); } } |