tinymist_query/analysis/completion/
param.rs1use typst_shim::eval::CapturesVisitor;
7
8use super::*;
9impl CompletionPair<'_, '_, '_> {
10 pub fn complete_params(&mut self) -> Option<()> {
12 self.cursor.from = self.cursor.leaf.offset();
13
14 let leaf = self.cursor.leaf.clone();
15 let closure_node = node_ancestors(&leaf).find(|node| node.kind() == SyntaxKind::Closure)?;
16
17 let mut bindings = HashSet::<EcoString>::default();
18
19 let closure_node = closure_node.cast::<ast::Closure>()?;
20
21 let name = closure_node.name();
23 if let Some(name) = name {
24 bindings.insert(name.get().clone());
25 }
26
27 let param_list = closure_node.params();
29 for param in param_list.children() {
30 match param {
31 ast::Param::Pos(pos) => {
32 for name in pos.bindings() {
33 bindings.insert(name.get().clone());
34 }
35 }
36 ast::Param::Named(named) => {
37 bindings.insert(named.name().get().clone());
38 }
39 ast::Param::Spread(spread) => {
40 if let Some(ident) = spread.sink_ident() {
41 bindings.insert(ident.get().clone());
42 }
43 }
44 }
45 }
46
47 let mut visitor = CapturesVisitor::new(None, typst::foundations::Capturer::Function);
48 visitor.visit(closure_node.body().to_untyped());
49 let captures = visitor.finish();
50
51 for (name, bind) in captures.iter() {
53 if !bindings.contains(name) {
54 let docs = "Parametrizes the captured variable.";
55 self.value_completion(Some(name.clone()), bind.read(), false, Some(docs));
56 }
57 }
58
59 Some(())
60 }
61}