mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-07-24 05:05:00 +00:00
feat: complete parameter values on user functions (#149)
* feat: complete parameter values on user functions * dev: separate type/value repr in parameter analysis
This commit is contained in:
parent
d708bdfe2d
commit
d71dd38b98
6 changed files with 63 additions and 35 deletions
|
@ -220,7 +220,9 @@ pub struct ParamSpec {
|
|||
pub docs: Cow<'static, str>,
|
||||
/// Describe what values this parameter accepts.
|
||||
pub input: CastInfo,
|
||||
/// The parameter's default name.
|
||||
/// The parameter's default name as type.
|
||||
pub type_repr: Option<EcoString>,
|
||||
/// The parameter's default name as value.
|
||||
pub expr: Option<EcoString>,
|
||||
/// Creates an instance of the parameter's default value.
|
||||
pub default: Option<fn() -> Value>,
|
||||
|
@ -243,7 +245,8 @@ impl ParamSpec {
|
|||
name: Cow::Borrowed(s.name),
|
||||
docs: Cow::Borrowed(s.docs),
|
||||
input: s.input.clone(),
|
||||
expr: Some(eco_format!("{}", TypeExpr(&s.input))),
|
||||
type_repr: Some(eco_format!("{}", TypeExpr(&s.input))),
|
||||
expr: None,
|
||||
default: s.default,
|
||||
positional: s.positional,
|
||||
named: s.named,
|
||||
|
@ -343,6 +346,7 @@ fn analyze_closure_signature(c: Arc<LazyHash<Closure>>) -> Vec<Arc<ParamSpec>> {
|
|||
params.push(Arc::new(ParamSpec {
|
||||
name: Cow::Borrowed("_"),
|
||||
input: CastInfo::Any,
|
||||
type_repr: None,
|
||||
expr: None,
|
||||
default: None,
|
||||
positional: true,
|
||||
|
@ -363,6 +367,7 @@ fn analyze_closure_signature(c: Arc<LazyHash<Closure>>) -> Vec<Arc<ParamSpec>> {
|
|||
params.push(Arc::new(ParamSpec {
|
||||
name: Cow::Owned(name.to_owned()),
|
||||
input: CastInfo::Any,
|
||||
type_repr: None,
|
||||
expr: None,
|
||||
default: None,
|
||||
positional: true,
|
||||
|
@ -378,6 +383,7 @@ fn analyze_closure_signature(c: Arc<LazyHash<Closure>>) -> Vec<Arc<ParamSpec>> {
|
|||
params.push(Arc::new(ParamSpec {
|
||||
name: Cow::Owned(n.name().as_str().to_owned()),
|
||||
input: CastInfo::Any,
|
||||
type_repr: Some(expr.clone()),
|
||||
expr: Some(expr.clone()),
|
||||
default: None,
|
||||
positional: false,
|
||||
|
@ -392,11 +398,12 @@ fn analyze_closure_signature(c: Arc<LazyHash<Closure>>) -> Vec<Arc<ParamSpec>> {
|
|||
params.push(Arc::new(ParamSpec {
|
||||
name: Cow::Owned(ident.unwrap_or_default().to_owned()),
|
||||
input: CastInfo::Any,
|
||||
type_repr: None,
|
||||
expr: None,
|
||||
default: None,
|
||||
positional: false,
|
||||
named: true,
|
||||
variadic: false,
|
||||
named: false,
|
||||
variadic: true,
|
||||
settable: false,
|
||||
docs: Cow::Borrowed(""),
|
||||
}));
|
||||
|
|
|
@ -155,7 +155,7 @@ impl<'a> fmt::Display for ParamTooltip<'a> {
|
|||
if !sig.named.is_empty() {
|
||||
let mut name_prints = vec![];
|
||||
for v in sig.named.values() {
|
||||
name_prints.push((v.name.clone(), v.expr.clone()))
|
||||
name_prints.push((v.name.clone(), v.type_repr.clone()))
|
||||
}
|
||||
name_prints.sort();
|
||||
for (k, v) in name_prints {
|
||||
|
|
|
@ -720,32 +720,6 @@ fn complete_params(ctx: &mut CompletionContext) -> bool {
|
|||
false
|
||||
}
|
||||
|
||||
/// Add completions for the values of a named function parameter.
|
||||
fn named_param_value_completions<'a>(
|
||||
ctx: &mut CompletionContext<'a, '_>,
|
||||
callee: ast::Expr<'a>,
|
||||
name: &str,
|
||||
) {
|
||||
let Some(func) = resolve_global_callee(ctx, callee) else {
|
||||
return;
|
||||
};
|
||||
let Some(param) = func.param(name) else {
|
||||
return;
|
||||
};
|
||||
if !param.named {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.cast_completions(¶m.input);
|
||||
if name == "font" {
|
||||
ctx.font_completions();
|
||||
}
|
||||
|
||||
if ctx.before.ends_with(':') {
|
||||
ctx.enrich(" ", "");
|
||||
}
|
||||
}
|
||||
|
||||
/// Complete in code mode.
|
||||
fn complete_code(ctx: &mut CompletionContext) -> bool {
|
||||
if matches!(
|
||||
|
|
|
@ -152,7 +152,7 @@ pub fn param_completions<'a>(
|
|||
set: bool,
|
||||
args: ast::Args<'a>,
|
||||
) {
|
||||
let Some(func) = resolve_global_callee(ctx, callee) else {
|
||||
let Some(func) = resolve_callee(ctx, callee) else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
@ -203,9 +203,55 @@ pub fn param_completions<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
/// Add completions for the values of a named function parameter.
|
||||
pub fn named_param_value_completions<'a>(
|
||||
ctx: &mut CompletionContext<'a, '_>,
|
||||
callee: ast::Expr<'a>,
|
||||
name: &str,
|
||||
) {
|
||||
let Some(func) = resolve_callee(ctx, callee) else {
|
||||
return;
|
||||
};
|
||||
|
||||
use typst::foundations::func::Repr;
|
||||
let mut func = func;
|
||||
while let Repr::With(f) = func.inner() {
|
||||
// todo: complete with positional arguments
|
||||
// with_args.push(ArgValue::Instance(f.1.clone()));
|
||||
func = f.0.clone();
|
||||
}
|
||||
|
||||
let signature = analyze_signature(func.clone());
|
||||
|
||||
let Some(param) = signature.named.get(name) else {
|
||||
return;
|
||||
};
|
||||
if !param.named {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(expr) = ¶m.type_repr {
|
||||
ctx.completions.push(Completion {
|
||||
kind: CompletionKind::Constant,
|
||||
label: expr.clone(),
|
||||
apply: None,
|
||||
detail: Some(plain_docs_sentence(¶m.docs)),
|
||||
});
|
||||
}
|
||||
|
||||
ctx.cast_completions(¶m.input);
|
||||
if name == "font" {
|
||||
ctx.font_completions();
|
||||
}
|
||||
|
||||
if ctx.before.ends_with(':') {
|
||||
ctx.enrich(" ", "");
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolve a callee expression to a function.
|
||||
// todo: fallback to static analysis if we can't resolve the callee
|
||||
pub fn resolve_global_callee<'a>(
|
||||
pub fn resolve_callee<'a>(
|
||||
ctx: &mut CompletionContext<'a, '_>,
|
||||
callee: ast::Expr<'a>,
|
||||
) -> Option<Func> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue