mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +08:00
Dictionary field completion
This commit is contained in:
parent
1e97d5c8cb
commit
d29acd2203
@ -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);
|
||||||
|
@ -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.");
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user