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()
}
Some(ast::Expr::Ident(_) | ast::Expr::MathIdent(_) | ast::Expr::FuncCall(_)) => {
Some(_) => {
if let Some(parent) = node.parent() {
if parent.kind() == SyntaxKind::FieldAccess && node.index() > 0 {
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.
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 {
Value::Symbol(symbol) => {
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) => {
for (name, value) in module.scope().iter() {
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 {
Value::Symbol(_) => None,
Value::Content(_) => None,
Value::Func(func) => {
func.info().map(|info| plain_docs_sentence(info.docs).into())
}
Value::Color(color) => Some(format_eco!("The color {color:?}.")),
Value::Auto => Some("A smart default.".into()),
_ => None,
v => Some(v.repr().into()),
});
self.completions.push(Completion {
@ -867,9 +872,7 @@ impl<'a> CompletionContext<'a> {
CastInfo::Value(value, docs) => {
self.value_completion(None, value, Some(docs));
}
CastInfo::Type("none") => {
self.snippet_completion("none", "none", "Nonexistent.")
}
CastInfo::Type("none") => self.snippet_completion("none", "none", "Nothing."),
CastInfo::Type("auto") => {
self.snippet_completion("auto", "auto", "A smart default.");
}

View File

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