use super::*;
impl CompletionPair<'_, '_, '_> {
pub fn complete_comments(&mut self) -> bool {
let text = self.cursor.leaf.get().text();
if (text == "///" || text == "/// ")
&& let Some(hash_node) = self.cursor.leaf.next_leaf()
&& let Some(let_node) = hash_node.next_leaf()
&& let Some(let_closure) = let_node.next_leaf()
&& matches!(let_closure.parent_kind(), Some(SyntaxKind::Closure))
&& let Some(closure) = let_closure.parent()
&& let Some(closure) = closure.cast::<ast::Expr>()
&& let ast::Expr::Closure(c) = closure
{
let rng = self.cursor.leaf.offset()..hash_node.offset();
let text_between = &self.cursor.source.text()[rng];
let mut line_count = 0;
for ch in text_between.chars() {
if ch == '\n' {
line_count += 1;
}
if line_count > 1 {
return false;
}
}
let mut doc_snippet: String = if text == "///" {
" $0\n///".to_string()
} else {
"$0\n///".to_string()
};
let mut i = 0;
for param in c.params().children() {
let param: &EcoString = match param {
Param::Pos(p) => match p {
ast::Pattern::Normal(ast::Expr::Ident(ident)) => ident.get(),
_ => &"_".into(),
},
Param::Named(n) => n.name().get(),
Param::Spread(s) => {
if let Some(ident) = s.sink_ident() {
&eco_format!("{}", ident.get())
} else {
&EcoString::new()
}
}
};
log::info!("param: {param}, index: {i}");
doc_snippet += &format!("\n/// - {param} (${}): ${}", i + 1, i + 2);
i += 2;
}
doc_snippet += &format!("\n/// -> ${}", i + 1);
self.push_completion(Completion {
label: "Document function".into(),
apply: Some(doc_snippet.into()),
..Completion::default()
});
}
true
}
pub fn complete_markup(&mut self) -> bool {
let parent_raw =
node_ancestors(&self.cursor.leaf).find(|node| matches!(node.kind(), SyntaxKind::Raw));
if let Some(prev) = self.cursor.leaf.prev_leaf()
&& matches!(prev.kind(), SyntaxKind::Eq | SyntaxKind::Arrow)
&& matches!(
prev.parent_kind(),
Some(SyntaxKind::LetBinding | SyntaxKind::Closure)
)
{
self.cursor.from = self.cursor.cursor;
self.code_completions(false);
return true;
}
if let Some(prev) = self.cursor.leaf.prev_leaf()
&& prev.kind() == SyntaxKind::Context
{
self.cursor.from = self.cursor.cursor;
self.code_completions(false);
return true;
}
if let Some(parent_raw) = parent_raw {
let mut s = Scanner::new(self.cursor.text);
s.jump(parent_raw.offset());
if s.eat_if("```") {
s.eat_while('`');
let start = s.cursor();
if s.eat_if(is_id_start) {
s.eat_while(is_id_continue);
}
if s.cursor() == self.cursor.cursor {
self.cursor.from = start;
self.raw_completions();
}
return true;
}
}
if !is_triggered_by_punc(self.worker.trigger_character) && self.worker.explicit {
self.cursor.from = self.cursor.cursor;
self.snippet_completions(Some(InterpretMode::Markup), None);
return true;
}
false
}
pub fn complete_math(&mut self) -> bool {
if !is_triggered_by_punc(self.worker.trigger_character)
&& matches!(
self.cursor.leaf.kind(),
SyntaxKind::Text | SyntaxKind::MathIdent | SyntaxKind::MathText
)
{
self.cursor.from = self.cursor.leaf.offset();
self.scope_completions(true);
self.snippet_completions(Some(InterpretMode::Math), None);
return true;
}
if !is_triggered_by_punc(self.worker.trigger_character) && self.worker.explicit {
self.cursor.from = self.cursor.cursor;
self.scope_completions(true);
self.snippet_completions(Some(InterpretMode::Math), None);
return true;
}
false
}
pub fn complete_code(&mut self) -> bool {
if self.cursor.leaf.kind() == SyntaxKind::Hash {
self.cursor.from = self.cursor.cursor;
self.code_completions(true);
return true;
}
if self.cursor.leaf.kind() == SyntaxKind::Ident {
self.cursor.from = self.cursor.leaf.offset();
self.code_completions(is_hash_expr(&self.cursor.leaf));
return true;
}
if let Some(prev) = self.cursor.leaf.prev_leaf()
&& prev.kind() == SyntaxKind::Context
{
self.cursor.from = self.cursor.cursor;
self.code_completions(false);
return true;
}
if self.cursor.leaf.kind() == SyntaxKind::Ident
&& !matches!(
self.cursor.leaf.parent_kind(),
Some(SyntaxKind::FieldAccess)
)
{
self.cursor.from = self.cursor.leaf.offset();
self.code_completions(false);
return true;
}
if self.cursor.leaf.kind().is_trivia()
|| (matches!(
self.cursor.leaf.kind(),
SyntaxKind::LeftParen | SyntaxKind::LeftBrace
) || (matches!(self.cursor.leaf.kind(), SyntaxKind::Colon)
&& self.cursor.leaf.parent_kind() == Some(SyntaxKind::ShowRule)))
{
self.cursor.from = self.cursor.cursor;
self.code_completions(false);
return true;
}
false
}
fn code_completions(&mut self, hash: bool) {
self.scope_completions(true);
self.snippet_completions(Some(InterpretMode::Code), None);
if !hash {
self.snippet_completion(
"function",
"(${params}) => ${output}",
"Creates an unnamed function.",
);
}
}
}