Repository: typst/typst
File: crates/typst-ide/src/complete.rs (Rust)

Code before:
            | Some(SyntaxKind::Math)
            | Some(SyntaxKind::MathFrac)
            | Some(SyntaxKind::MathAttach)
            | Some(SyntaxKind::MathRoot)
    ) {
        return false;
    }

    // An existing identifier (which is not the key of a named pair): "{ pa| }".
    if ctx.leaf.kind() == SyntaxKind::Ident
        && (ctx.leaf.index() > 0 || ctx.leaf.parent_kind() != Some(SyntaxKind::Named))
    {
        ctx.from = ctx.leaf.offset();
        code_completions(ctx, false);
        return true;
    }

    // A potential label (only at the start of an argument list): "(<|".
    if ctx.before.ends_with("(<") {
        ctx.from = ctx.cursor;
        ctx.label_completions();
        return true;
    }

    // Anywhere: "{ | }".
    // But not within or after an expression, and not a dictionary key
    if ctx.explicit
        && ctx.leaf.parent_kind() != Some(SyntaxKind::Dict)
        && (ctx.leaf.kind().is_trivia()
            || matches!(
                ctx.leaf.kind(),
                SyntaxKind::LeftParen
                    | SyntaxKind::LeftBrace
                    | SyntaxKind::Comma
                    | SyntaxKind::Colon
            ))
    {
        ctx.from = ctx.cursor;
        code_completions(ctx, false);
        return true;
    }

    false
}

/// Add completions for expression snippets.
#[rustfmt::skip]
fn code_completions(ctx: &mut CompletionContext, hash: bool) {
    if hash {
        ctx.scope_completions(true, |value| {
            // If we are in markup, ignore colors, directions, and alignments.

Review comment (suggestion):
```suggestion
    // But not within or after an expression.
    // Also not as part of a dictionary key (e.g. `(alig|: 30)`).
```

Code after:
    }

    // A potential label (only at the start of an argument list): "(<|".
    if ctx.before.ends_with("(<") {
        ctx.from = ctx.cursor;
        ctx.label_completions();
        return true;
    }

    // Anywhere: "{ | }", "(|)", "(1,|)", "(a:|)".
    // But not within or after an expression, and also not part of a dictionary
    // key (as in "(pa: |,)")
    if ctx.explicit
        && ctx.leaf.parent_kind() != Some(SyntaxKind::Dict)
        && (ctx.leaf.kind().is_trivia()
            || matches!(
                ctx.leaf.kind(),
                SyntaxKind::LeftParen
                    | SyntaxKind::LeftBrace
                    | SyntaxKind::Comma
                    | SyntaxKind::Colon
            ))
    {
        ctx.from = ctx.cursor;
        code_completions(ctx, false);
        return true;
    }

    false
}

/// Add completions for expression snippets.
#[rustfmt::skip]
fn code_completions(ctx: &mut CompletionContext, hash: bool) {
    if hash {
        ctx.scope_completions(true, |value| {
            // If we are in markup, ignore colors, directions, and alignments.
            // They are useless and bloat the autocomplete results.
            let ty = value.ty();
            ty != Type::of::<Color>()
                && ty != Type::of::<Dir>()
                && ty != Type::of::<Alignment>()
        });
    } else {
        ctx.scope_completions(true, |_| true);
    }

    ctx.snippet_completion(
        "function call",
        "${function}(${arguments})[${body}]",
        "Evaluates a function.",