Skip to main content

Module completion

Module completion 

Source
Expand description

Completion for the cursor, keyed off the line up to it.

The surface is the canonical cursor context × candidate-kind matrix fixed by ADR 0093 (design/decisions/0093-completion-surface-contract.md), spec’d at design/bynk-lsp-spec.md §3.15. complete dispatches the six contexts it can serve purely (no analysis cache):

  • consumes <prefix> / consumes U { … } / given … — consumable units and in-scope capabilities (v0.17);
  • type position (: T, -> T, inside [ … ] type args) — built-in types, the bynk-surface transparent types, and project type decls;
  • keyword position (a bare word at a declaration/statement start) — the reserved keywords (with registry docs) and declaration snippets;
  • name-receiver UpperIdent. — sum variants (project + built-in HttpResult/QueueResult), refined/opaque of/unsafe, capability ops, and built-in type statics (Int.parse/List.empty/Effect.pure/…);
  • expression position (after =/(/,/=>/an operator) — the value constructors (Ok/Some/true/…), in-scope type names, and in-scope free functions (the current unit’s own fns + uses-imported stdlib/project combinators, gated on the uses set) (ADR 0093 D3).

Two further contexts need the analysis overlay and so live handler-side (main.rs): value-receiver lower. members (kernel methods + record fields) and in-scope locals/params. They depend on the analysis overlay (the boundary is ADR 0093 D4), but since slice 4 (ADR 0094) it is error-tolerant: best-effort partial types are recorded even on a broken buffer, so they no longer go silent on an unrelated error. Items also carry a one-line detail eagerly; the richer documentation is filled in lazily by completionItem/resolve, handler-side (slice 5).

Context detection is lexical (it must work mid-edit, when the buffer rarely parses); candidates are semantic. Unit/type/capability/member enumeration parses the project’s .bynk files (and the embedded bynk surface) with recovery, so it works even while the file the cursor sits in is mid-edit. Built-ins, keywords, and constructors come from the static bynkc registries (keywords/builtin_names/firstparty/ast), never the index — first-party symbols aren’t indexed (the v0.28 finding); the project parse supplies only project symbols.

Structs§

Completion

Enums§

CompletionKind
What a candidate refers to — maps to an LSP CompletionItemKind.

Constants§

BUILTIN_STATICS 🔒
Built-in type statics — real language statics that are not user-declared, so they come from this small table rather than the project parse. Covers the numeric parse statics and the JSON codec (v0.22, ADRs 0048/0049), the collection empty constructors (v0.20b), and Effect.pure (v0.5). The full real set per ADR 0093 D2 — kept complete and drift-tested (builtin_statics_are_reachable).
BUILTIN_TYPES 🔒
Built-in type names not declared in any parseable source. Base and generic types from the language core; collection types from builtin_names. Docs are drawn from the keywords registry where present (one source of truth).
CONSTRUCTORS 🔒
The value constructors offered at expression position (ADR 0093 D3) — the closed set of Result/Option variant constructors and the boolean literals. A value expression can begin with any of these; their docs reuse the keywords registry (one source of truth).
SNIPPETS 🔒
Declaration snippets (CompletionItemKind::SNIPPET), as LSP snippet bodies.

Statics§

EMPTY_CONSUMES 🔒

Functions§

builtin_sum_variants 🔒
Variants of a built-in sum type (HttpResult/QueueResult), sourced from the AST variant registries so a new variant surfaces in completion for free (ADR 0093 D2/G3). Empty for any other receiver.
capabilities_of_unit 🔒
The capability names a unit exports capability.
complete
Produce completions for the cursor, given the text of the line up to the cursor, the current document text, and the project source root (if any).
consumable_units 🔒
Consumable unit names: contexts and adapters (plus bynk), deduplicated.
consumes_brace_unit 🔒
consumes U { … with the brace still open at the cursor → Some(U).
current_unit_name 🔒
The qualified name of the unit the cursor’s document declares, via a recovery parse (the header survives a mid-edit body). None for a headerless fragment that names no unit.
expression_candidates 🔒
Expression-position candidates: the value constructors plus in-scope type names (the entry to a static call like Int.parse or a record construction like Order { … }). In-scope values — locals/params, and from slice 3 free functions — are appended by the handler, which owns the analysis cache, so they are not produced here (ADR 0093 D3).
for_each_unit 🔒
Parse every project unit, plus the embedded first-party adapters (the bynk surface and the bynk.cloudflare platform adapter), and call f for each. Recovery parsing tolerates the in-progress edit at the cursor.
free_fn_signature 🔒
Render a free function’s signature for the completion detail, the same way hover and signature help do (symbols::type_ref_str) — one format, never divergent. Mirrors signature help: no generic-parameter list.
free_function_candidates 🔒
Free-function candidates at expression position: the current unit’s own top-level fns plus the free fns of every uses-imported module (project commons and the embedded stdlib). Gated on the uses set so a combinator is offered only where it is actually in scope (ADR 0093 D3 / G5).
in_scope_capabilities 🔒
Capabilities in scope for a given clause in the current document: locally declared capabilities, bare names flattened by a braced consumes, and U.Cap for each whole-unit consumes U.
in_type_arg_list 🔒
head ends inside an unclosed [ … whose opening bracket immediately follows an identifier (a type constructor, e.g. Option[, Result[Int, ) — as opposed to a bare list-literal [.
is_consumes_target 🔒
consumes <partial> with no brace or as yet → completing the target name.
is_expression_position
The cursor sits where a value expression is expected — after =/(/,, a => lambda arrow, or a binary operator — so in-scope locals are offered (v0.31, ADR 0064). Conservative: covers the common positions, excludes the type arrow ->. (The handler also offers locals at keyword position.)
is_given_position 🔒
The cursor is inside a given list (after given, before the { body).
is_keyword_position
A bare word at a declaration/statement start: the line up to the cursor is only leading whitespace plus an optional partial identifier (no operators, colons, or brackets). Fires on an empty line too. Disjoint from is_type_position, whose triggers (:/->/[) make this false.
is_qualified_name 🔒
is_type_position 🔒
The cursor sits in a type position: a return type (-> T), a type annotation/field type (: T), or inside a [ … ] type-argument list. The partial type name being typed is stripped before inspecting the preceding token, so : Optio and -> Eff both qualify.
keyword_and_snippet_candidates 🔒
Keyword-position candidates: the lowercase-initial reserved keywords (the declaration/statement words — uppercase type/value names like Int/Some belong to type/expression position) with their registry docs, plus the declaration snippets.
keyword_doc 🔒
The one-line doc for a name in the keywords registry, if present.
member_candidates 🔒
Members of a name receiver: built-in type statics, then built-in sum-type variants, then — from the project and embedded-surface parse — project sum variants, refined/opaque of/unsafe, or capability operations. Yields [] when the receiver resolves to none of these (e.g. a plain type X = Int alias or a record).
member_receiver 🔒
UpperIdent.<partial> at the cursor → Some("UpperIdent") — a name receiver whose members are statically enumerable (a sum/refined/opaque type or a capability). Conservative: the receiver is a single uppercase-initial identifier, not itself a .-qualified segment (so bynk.cloudflare. and a.B. are excluded) and not a number (so the decimal 1. is excluded). A lowercase x. is a value receiver — deferred to slice 3 — and yields None.
type_candidates 🔒
Type-position candidates: built-in types (with registry docs), then every type declaration found in the project sources and the embedded bynk surface (so the transparent surface types Uuid/Method/… come for free).
unit_items_and_uses 🔒
A unit’s top-level items and its uses clauses, for the kinds that carry free functions. Service/other units contribute neither.
value_member_candidates
The members of a typed value receiver: the built-in kernel methods of its type (from the enumerable registry) plus, for a record, its fields.
value_receiver_rewrite
If the cursor (byte offset into text) sits just after a lowercase receiver.(partial) — a value receiver — return the buffer rewritten so the receiver is a complete expression (the trailing .partial dropped, so the file parses) and the byte offset of the receiver to type. Returns None for an uppercase name receiver (slice 2), a decimal 1., or a .-qualified segment.