Dictionary field completion

This commit is contained in:
Laurenz 2023-01-28 23:55:24 +01:00
parent 1e97d5c8cb
commit d29acd2203
3 changed files with 28 additions and 21 deletions

View File

@ -23,7 +23,7 @@ pub fn analyze(world: &(dyn World + 'static), node: &LinkedNode) -> Vec<Value> {
.collect() .collect()
} }
Some(ast::Expr::Ident(_) | ast::Expr::MathIdent(_) | ast::Expr::FuncCall(_)) => { Some(_) => {
if let Some(parent) = node.parent() { if let Some(parent) = node.parent() {
if parent.kind() == SyntaxKind::FieldAccess && node.index() > 0 { if parent.kind() == SyntaxKind::FieldAccess && node.index() > 0 {
return analyze(world, parent); return analyze(world, parent);

View File

@ -307,6 +307,19 @@ fn complete_field_accesses(ctx: &mut CompletionContext) -> bool {
/// Add completions for all fields on a value. /// Add completions for all fields on a value.
fn field_access_completions(ctx: &mut CompletionContext, value: &Value) { fn field_access_completions(ctx: &mut CompletionContext, value: &Value) {
for &(method, args) in methods_on(value.type_name()) {
ctx.completions.push(Completion {
kind: CompletionKind::Func,
label: method.into(),
apply: Some(if args {
format_eco!("{method}(${{}})")
} else {
format_eco!("{method}()${{}}")
}),
detail: None,
})
}
match value { match value {
Value::Symbol(symbol) => { Value::Symbol(symbol) => {
for modifier in symbol.modifiers() { for modifier in symbol.modifiers() {
@ -320,25 +333,17 @@ fn field_access_completions(ctx: &mut CompletionContext, value: &Value) {
} }
} }
} }
Value::Dict(dict) => {
for (name, value) in dict.iter() {
ctx.value_completion(Some(name.clone().into()), value, None);
}
}
Value::Module(module) => { Value::Module(module) => {
for (name, value) in module.scope().iter() { for (name, value) in module.scope().iter() {
ctx.value_completion(Some(name.clone()), value, None); ctx.value_completion(Some(name.clone()), value, None);
} }
} }
_ => { _ => {}
for &(method, args) in methods_on(value.type_name()) {
ctx.completions.push(Completion {
kind: CompletionKind::Func,
label: method.into(),
apply: Some(if args {
format_eco!("{method}(${{}})")
} else {
format_eco!("{method}()${{}}")
}),
detail: None,
})
}
}
} }
} }
@ -835,12 +840,12 @@ impl<'a> CompletionContext<'a> {
} }
let detail = docs.map(Into::into).or_else(|| match value { let detail = docs.map(Into::into).or_else(|| match value {
Value::Symbol(_) => None,
Value::Content(_) => None,
Value::Func(func) => { Value::Func(func) => {
func.info().map(|info| plain_docs_sentence(info.docs).into()) func.info().map(|info| plain_docs_sentence(info.docs).into())
} }
Value::Color(color) => Some(format_eco!("The color {color:?}.")), v => Some(v.repr().into()),
Value::Auto => Some("A smart default.".into()),
_ => None,
}); });
self.completions.push(Completion { self.completions.push(Completion {
@ -867,9 +872,7 @@ impl<'a> CompletionContext<'a> {
CastInfo::Value(value, docs) => { CastInfo::Value(value, docs) => {
self.value_completion(None, value, Some(docs)); self.value_completion(None, value, Some(docs));
} }
CastInfo::Type("none") => { CastInfo::Type("none") => self.snippet_completion("none", "none", "Nothing."),
self.snippet_completion("none", "none", "Nonexistent.")
}
CastInfo::Type("auto") => { CastInfo::Type("auto") => {
self.snippet_completion("auto", "auto", "A smart default."); self.snippet_completion("auto", "auto", "A smart default.");
} }

View File

@ -24,6 +24,10 @@ pub fn tooltip(
/// Tooltip for a hovered expression. /// Tooltip for a hovered expression.
fn expr_tooltip(world: &(dyn World + 'static), leaf: &LinkedNode) -> Option<String> { fn expr_tooltip(world: &(dyn World + 'static), leaf: &LinkedNode) -> Option<String> {
let expr = leaf.cast::<ast::Expr>()?; let expr = leaf.cast::<ast::Expr>()?;
if !expr.hashtag() {
return None;
}
let values = analyze(world, leaf); let values = analyze(world, leaf);
if let [value] = values.as_slice() { if let [value] = values.as_slice() {