Expand description
Mode-driven completion sources (insert-completion.md §12).
The trait surface every minor mode uses to contribute one or
more completion sources via Mode::completion_sources(). The
v1 architecture (§3 – §11) hardcodes the source set inside
lattice-ui-tui::app::completion::populate_insert_completion_sync
and the bespoke do_async_insert_completion_requests host code;
§12 of the design doc lays out the migration to a uniform
mode-contribution shape that:
- lets WASM plugins register a completion source the same way they register any other mode contribution (options, keymap, subscriptions, decorations);
- relocates each source impl into the crate that owns its
feature (LSP source ->
lattice-lsp, snippet source ->lattice-snippet, etc.); - keeps the per-keystroke hot path identical by caching the
active source set per buffer in an
ActiveCompletionSourcesbuffer-local (§12.4).
CSM.1 lands the type surface only – nothing in the editor references these types yet. CSM.2 – CSM.8 wire production code through them one source at a time.
§Two source shapes
SyncCompletionSource: cheap, blocking. The aggregator callsproduce()directly on the popup-open / refilter path. Buffer-words, snippets, tree-sitter symbols, path completion all fit here – microsecond-scale walks.AsyncCompletionSource: produces candidates via a future that pushes into a host-suppliedCandidateSink. LSP (multi-server fan-out + isIncomplete refresh) is the driving case; plugin sources that round-trip to a backend use the same shape.
The crate stays runtime-agnostic – the async trait hands
back a Pin<Box<dyn Future + Send>> and the host (TUI today,
plugin host later) runs it on whatever executor it owns. No
tokio dependency in lattice-completion.
Structs§
- Completion
Source Contribution - One source’s contribution to the active completion set for a
buffer. Returned from
lattice_mode::Mode::completion_sources(the new declarative contribution method onMode– seelattice-mode). The aggregator’s per-buffer cache holds a list of these; the active-source resolver in the host recomputes the cache only on mode-activation / -deactivation transitions, so the keystroke-frequency refilter pays an O(1) buffer-local lookup. - Insert
Context Snapshot - Owned snapshot of
InsertContextfor crossing the spawn / future boundary. The borrowedcrate::insert::InsertContextcan’t cross the spawn (it holds&Buffer/&str); the snapshot copies the fields the source actually needs.
Enums§
- Async
Completion Outcome - OR.7: drain payload for the async completion fan-out — every
AsyncCompletionSourcethe active modes contribute, not only LSP’s. - Completion
Source Kind - Discriminator for
CompletionSourceContribution::kind. The aggregator dispatches on this:Syncsources are called inline during refilter;Asyncsources are spawned at popup- open + onisIncompleterefresh, with the host running the returned future on its executor.
Traits§
- Async
Completion Source - Asynchronous completion source. Used for sources that must
round-trip (LSP), watch a long-running task, or otherwise
can’t deliver candidates synchronously. The aggregator calls
Self::produce_asyncat popup-open and on everyisIncompletere-fire; the returned future pushes candidates into a host-suppliedCandidateSinkas they arrive. - Candidate
Sink - Host-supplied mailbox an
AsyncCompletionSourcepushes candidates into. The host’slattice-ui-tuiimpl wraps atokio::sync::mpsc::UnboundedSender<SinkEvent>so the per-frame drain merges async-source pushes intoInsertCompletionState::raw; a WASM-plugin host wraps whatever its runtime provides. - Sync
Completion Source - Cheap, blocking completion source. Implementations walk the
buffer / a small registry / a cached symbol table and return
the matching
RawCandidates in a single call. The aggregator invokesSelf::produceonce per refilter (once per popup- query change). Sources strictly more expensive than ~100 us per call should beAsyncCompletionSources instead.
Functions§
- line_
before_ cursor - The text from the start of
cursor’s line up tocursor.