pub enum PluginSeam {
Show 21 variants
PickerSource,
MultibufferViewSource,
CompletionSource,
Grammar,
Events,
Modes,
Config,
Decorations,
Media,
Context,
Theme,
Signs,
Keymap,
Logging,
PluginManager,
ErrorParser,
Help,
Dashboard,
ScannedExcerptSource,
TransientSource,
Language,
}Expand description
Which extension seam a plugin’s component implements — the WIT world it
exports. Each seam is its own world (picker-source, events-plugin, …); a
component implements one, and the manifest declares which so the plugin
loader (lattice-plugin-loader) knows which spawn_* path to drive. An
empty provides list is a lifecycle-only plugin (the base plugin
world — init.rs, the no-op fixture), driven through instantiate_plugin +
activate rather than a seam actor.
Wire form (manifest provides = [...] + [Display]) is the dashed WIT
interface name: picker-source, completion-source, grammar, events,
modes, config, decorations, context.
Variants§
PickerSource
MultibufferViewSource
MV.1 — a plugin-contributed multibuffer VIEW: the guest owns the view’s
identity, contents, order and status, and the host owns the buffer and
the excerpt machinery. Distinct from ScannedExcerptSource, which
supplies rows to a view someone else owns.
CompletionSource
Grammar
Events
Modes
Config
Decorations
Media
IM.6: inline media blocks (inline-media.md §7). A producer, like
Decorations — the guest names files and lines, the host resolves
sizes and builds the virtual rows.
Context
TC.2 — the sticky-context producer (context-plugin world). Async,
host-cached per parse version; see treesitter-context.md.
Theme
TC.4 — theme-element declaration (theme-plugin world). The plugin’s
elements land in the SAME registry builtins use.
Signs
SG.3a — sign declaration (sign-plugin world). The plugin’s signs land
in the SAME registry native producers use, styled through the ordinary
theme registry.
Keymap
Logging
The wasi:logging-shaped guest→host logging import (PO.5, Layer 2). Not a
native trait seam — the guest’s own narrative, host-captured into the same
tracer as the boundary trace.
PluginManager
PM.7 — the require seam (plugin-manager-plugin world). A config
guest (the user’s init.rs) declares the plugins it wants; the host
records the specs and the loader resolves/builds/loads them off-thread.
Deliberately its own seam rather than folded into config: declaring
software to install is a strictly larger authority than setting an
option, and provides is where that difference is visible to a user
reading the manifest.
ErrorParser
CM.6 — a compilation-output parser (error-parser-plugin world). Sync,
fed one captured line at a time by the compilation reader.
Help
CR.3 — plugin-contributed :help pages (help-plugin world). The
markdown ships inside the component and crosses once, at load; the
topic then lives in the same registry the builtin docs do.
Dashboard
CR.4 — plugin-contributed launch-page sections (dashboard-plugin
world). Sync, and unlike help the guest stays instantiated: a
section is a function of a live DashboardCtx, not data.
ScannedExcerptSource
OM.A1 — a plugin-contributed producer of scanned excerpts: rows
found by reading many files, globally ordered and grouped
(scanned-excerpt-source-plugin world). Async, driven once per file of
a project walk. The guest declares the file extensions it wants
offered, which is what keeps a filetype out of the host’s walk.
OR.9 renamed this from AgendaSource. Its record — line, end-line,
group, label, sort-key — is an excerpt plus an ordering plus a group
header, and contains nothing about org, dates or TODOs. The agenda is
its first consumer, not its definition; a project-TODO view or a tags
view is the same shape and should not have to register as an “agenda
source”. Renamed while org was still the only consumer, because a seam
name is API and third-party plugins would have bound to it.
TransientSource
TR.2b — a plugin-contributed transient menu (transient-source-plugin
world). Async and live: id() is called once at load to key the
registry entry, build(ctx) per menu open, because a builder’s rows
depend on where the user opened it from.
Language
LG.3c — a plugin-contributed language (language-plugin world). Data,
like help: the grammar bytes and query sources cross once at load and
the guest is dropped. The host compiles the grammar (~100 ms) and owns
the parse loop forever after, so there is no guest call on any hot
path.
Implementations§
Source§impl PluginSeam
impl PluginSeam
Sourcepub fn drain_rank(self) -> u8
pub fn drain_rank(self) -> u8
Where this seam sits in the loader’s drain order (OM.0). Lower drains
first; the loader stable-sorts a plugin’s provides by this before
draining, so the order a manifest happens to list its seams in cannot
change what registers.
The ordering exists because seams have real registration dependencies,
and the one that bites is modes on grammar: a
mode-keymap-binding resolves its command against the
CommandRegistry at registration, so a mode binding a chord to the
plugin’s OWN grammar action needs that action already registered. Drain
the other way round and the binding is skipped with a log — the plugin
loads “successfully” and the user’s chord silently does nothing.
This used to be the plugin author’s problem. Both bundled multi-seam
manifests carried a hand-written comment telling the next author to put
grammar before modes, which made a load-bearing invariant depend on
prose inside a guest-authored file. Sorting here makes it a property
of the seam set instead.
The ranks, and why each is where it is:
| rank | seams | reason |
|---|---|---|
| 0 | config, logging | the option surface: every value any later seam reads exists after this |
| 1 | theme | theme elements later seams may name — and org derives its per-keyword elements from an OPTION, so it must follow rank 0 |
| 2 | language | a major mode may declare target-language; the language should exist first |
| 3 | grammar | registers commands into the CommandRegistry |
| 4 | modes | keymap bindings resolve command names — needs rank 3 |
| 5 | keymap | user-layer bindings, same name resolution |
| 6 | everything else | producers and data seams with no registration dependency |
Ties keep manifest order (the sort is stable), so an author’s intent is respected everywhere it cannot break anything.
OA.14d split config from theme. They shared rank 0, so org’s
register-theme-elements reading org.todo-keywords worked only
because org’s provides happened to list config first — a
load-bearing invariant living in a guest-authored file again, which is
the exact thing this function exists to end. It is also the seam
boundary the awaited pre-plugin-loaded fires on: the loader publishes
it once every rank-0 seam has drained, so a handler can set an option
that rank 1 and up will read.
Trait Implementations§
Source§impl Clone for PluginSeam
impl Clone for PluginSeam
Source§fn clone(&self) -> PluginSeam
fn clone(&self) -> PluginSeam
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for PluginSeam
Source§impl Debug for PluginSeam
impl Debug for PluginSeam
Source§impl Display for PluginSeam
impl Display for PluginSeam
impl Eq for PluginSeam
Source§impl FromStr for PluginSeam
impl FromStr for PluginSeam
Source§impl PartialEq for PluginSeam
impl PartialEq for PluginSeam
impl StructuralPartialEq for PluginSeam
Auto Trait Implementations§
impl Freeze for PluginSeam
impl RefUnwindSafe for PluginSeam
impl Send for PluginSeam
impl Sync for PluginSeam
impl Unpin for PluginSeam
impl UnsafeUnpin for PluginSeam
impl UnwindSafe for PluginSeam
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more