use lsp_types::CompletionParams;
use rowan::{ast::AstNode, TextRange};
use crate::{component_db::COMPONENT_DATABASE, features::cursor::CursorContext, syntax::latex};
use super::types::{InternalCompletionItem, InternalCompletionItemData};
pub fn complete_arguments<'a>(
context: &'a CursorContext<CompletionParams>,
items: &mut Vec<InternalCompletionItem<'a>>,
) -> Option<()> {
let token = context.cursor.as_latex()?;
let range = if token.kind() == latex::WORD {
token.text_range()
} else {
TextRange::empty(context.offset)
};
let group = latex::CurlyGroup::cast(token.parent()?)
.or_else(|| {
token
.parent()
.and_then(|node| node.parent())
.and_then(latex::CurlyGroup::cast)
})
.filter(|group| context.is_inside_latex_curly(group))?;
let command = latex::GenericCommand::cast(group.syntax().parent()?)?;
let index = command
.syntax()
.children()
.filter_map(latex::CurlyGroup::cast)
.position(|g| g.syntax().text_range() == group.syntax().text_range())?;
let command_name = command.name()?;
let command_name = &command_name.text()[1..];
for component in COMPONENT_DATABASE.linked_components(&context.request.workspace) {
for component_command in component
.commands
.iter()
.filter(|command| command.name == command_name)
{
for (_, param) in component_command
.parameters
.iter()
.enumerate()
.filter(|(i, _)| *i == index)
{
for arg in ¶m.0 {
let item = InternalCompletionItem::new(
range,
InternalCompletionItemData::Argument {
name: &arg.name,
image: arg.image.as_deref(),
},
);
items.push(item);
}
}
}
}
Some(())
}