use base_db::semantics::Span; use rowan::ast::AstNode; use syntax::latex; use crate::{ util::{find_curly_group_word, CompletionBuilder, ProviderContext}, CompletionItem, CompletionItemData, CompletionParams, GlossaryEntryData, }; pub fn complete_acronyms<'a>( params: &'a CompletionParams<'a>, builder: &mut CompletionBuilder<'a>, ) -> Option<()> { let cursor = find_acronym(params)?; let mut proc = Processor(ProviderContext { builder, params, cursor, }); proc.add_acronyms(); Some(()) } pub fn complete_glossaries<'a>( params: &'a CompletionParams<'a>, builder: &mut CompletionBuilder<'a>, ) -> Option<()> { let cursor = find_glossary(params)?; let mut proc = Processor(ProviderContext { builder, params, cursor, }); proc.add_acronyms(); proc.add_glossaries(); Some(()) } struct Processor<'a, 'b>(ProviderContext<'a, 'b>); impl<'a, 'b> Processor<'a, 'b> { pub fn add_acronyms(&mut self) { self.add_generic(|node| latex::AcronymDefinition::cast(node)?.name()); } pub fn add_glossaries(&mut self) { self.add_generic(|node| latex::GlossaryEntryDefinition::cast(node)?.name()); } fn add_generic(&mut self, extract: F) where F: Fn(latex::SyntaxNode) -> Option, { let documents = self.0.params.feature.project.documents.iter(); for data in documents.filter_map(|document| document.data.as_tex()) { for name in data .root_node() .descendants() .filter_map(&extract) .filter_map(|name| name.key()) .map(|name| name.to_string()) { if let Some(score) = self.0.builder.matcher.score(&name, &self.0.cursor.text) { let data = CompletionItemData::GlossaryEntry(GlossaryEntryData { name }); self.0.builder.items.push(CompletionItem::new_simple( score, self.0.cursor.range, data, )); } } } } } fn find_acronym(params: &CompletionParams) -> Option { let (cursor, group) = find_curly_group_word(params)?; latex::AcronymReference::cast(group.syntax().parent()?)?; Some(cursor) } fn find_glossary(params: &CompletionParams) -> Option { let (cursor, group) = find_curly_group_word(params)?; latex::GlossaryEntryReference::cast(group.syntax().parent()?)?; Some(cursor) }