mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Fix autocomplete for functions in modules
This commit is contained in:
parent
07c80e9a81
commit
b61eee4306
@ -8,7 +8,9 @@ use unscanny::Scanner;
|
|||||||
use super::analyze::analyze_labels;
|
use super::analyze::analyze_labels;
|
||||||
use super::{analyze_expr, analyze_import, plain_docs_sentence, summarize_font_family};
|
use super::{analyze_expr, analyze_import, plain_docs_sentence, summarize_font_family};
|
||||||
use crate::doc::Frame;
|
use crate::doc::Frame;
|
||||||
use crate::eval::{fields_on, format_str, methods_on, CastInfo, Library, Scope, Value};
|
use crate::eval::{
|
||||||
|
fields_on, format_str, methods_on, CastInfo, Func, Library, Scope, Value,
|
||||||
|
};
|
||||||
use crate::syntax::{
|
use crate::syntax::{
|
||||||
ast, is_id_continue, is_id_start, is_ident, LinkedNode, Source, SyntaxKind,
|
ast, is_id_continue, is_id_start, is_ident, LinkedNode, Source, SyntaxKind,
|
||||||
};
|
};
|
||||||
@ -606,7 +608,7 @@ fn complete_params(ctx: &mut CompletionContext) -> bool {
|
|||||||
if let Some(grand) = parent.parent();
|
if let Some(grand) = parent.parent();
|
||||||
if let Some(expr) = grand.cast::<ast::Expr>();
|
if let Some(expr) = grand.cast::<ast::Expr>();
|
||||||
let set = matches!(expr, ast::Expr::Set(_));
|
let set = matches!(expr, ast::Expr::Set(_));
|
||||||
if let Some(ast::Expr::Ident(callee)) = match expr {
|
if let Some(callee) = match expr {
|
||||||
ast::Expr::FuncCall(call) => Some(call.callee()),
|
ast::Expr::FuncCall(call) => Some(call.callee()),
|
||||||
ast::Expr::Set(set) => Some(set.target()),
|
ast::Expr::Set(set) => Some(set.target()),
|
||||||
_ => None,
|
_ => None,
|
||||||
@ -669,16 +671,12 @@ fn complete_params(ctx: &mut CompletionContext) -> bool {
|
|||||||
/// Add completions for the parameters of a function.
|
/// Add completions for the parameters of a function.
|
||||||
fn param_completions(
|
fn param_completions(
|
||||||
ctx: &mut CompletionContext,
|
ctx: &mut CompletionContext,
|
||||||
callee: &ast::Ident,
|
callee: &ast::Expr,
|
||||||
set: bool,
|
set: bool,
|
||||||
exclude: &[ast::Ident],
|
exclude: &[ast::Ident],
|
||||||
) {
|
) {
|
||||||
let info = if_chain! {
|
let Some(func) = resolve_global_callee(ctx, callee) else { return };
|
||||||
if let Some(Value::Func(func)) = ctx.global.get(callee);
|
let Some(info) = func.info() else { return };
|
||||||
if let Some(info) = func.info();
|
|
||||||
then { info }
|
|
||||||
else { return; }
|
|
||||||
};
|
|
||||||
|
|
||||||
for param in &info.params {
|
for param in &info.params {
|
||||||
if exclude.iter().any(|ident| ident.as_str() == param.name) {
|
if exclude.iter().any(|ident| ident.as_str() == param.name) {
|
||||||
@ -711,21 +709,18 @@ fn param_completions(
|
|||||||
/// Add completions for the values of a named function parameter.
|
/// Add completions for the values of a named function parameter.
|
||||||
fn named_param_value_completions(
|
fn named_param_value_completions(
|
||||||
ctx: &mut CompletionContext,
|
ctx: &mut CompletionContext,
|
||||||
callee: &ast::Ident,
|
callee: &ast::Expr,
|
||||||
name: &str,
|
name: &str,
|
||||||
) {
|
) {
|
||||||
let param = if_chain! {
|
let Some(func) = resolve_global_callee(ctx, callee) else { return };
|
||||||
if let Some(Value::Func(func)) = ctx.global.get(callee);
|
let Some(info) = func.info() else { return };
|
||||||
if let Some(info) = func.info();
|
let Some(param) = info.param(name) else { return };
|
||||||
if let Some(param) = info.param(name);
|
if !param.named {
|
||||||
if param.named;
|
return;
|
||||||
then { param }
|
}
|
||||||
else { return; }
|
|
||||||
};
|
|
||||||
|
|
||||||
ctx.cast_completions(¶m.cast);
|
ctx.cast_completions(¶m.cast);
|
||||||
|
if name == "font" {
|
||||||
if callee.as_str() == "text" && name == "font" {
|
|
||||||
ctx.font_completions();
|
ctx.font_completions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -734,6 +729,30 @@ fn named_param_value_completions(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resolve a callee expression to a global function.
|
||||||
|
fn resolve_global_callee<'a>(
|
||||||
|
ctx: &CompletionContext<'a>,
|
||||||
|
callee: &ast::Expr,
|
||||||
|
) -> Option<&'a Func> {
|
||||||
|
let value = match callee {
|
||||||
|
ast::Expr::Ident(ident) => ctx.global.get(ident)?,
|
||||||
|
ast::Expr::FieldAccess(access) => match access.target() {
|
||||||
|
ast::Expr::Ident(target) => match ctx.global.get(&target)? {
|
||||||
|
Value::Module(module) => module.get(&access.field()).ok()?,
|
||||||
|
Value::Func(func) => func.get(&access.field()).ok()?,
|
||||||
|
_ => return None,
|
||||||
|
},
|
||||||
|
_ => return None,
|
||||||
|
},
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
match value {
|
||||||
|
Value::Func(func) => Some(func),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Complete in code mode.
|
/// Complete in code mode.
|
||||||
fn complete_code(ctx: &mut CompletionContext) -> bool {
|
fn complete_code(ctx: &mut CompletionContext) -> bool {
|
||||||
if matches!(
|
if matches!(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user