Expand description
The ui guest→host contribution seam (OC.3 / ML.6) — a plugin-owned
modeline element.
The canonical API is the WIT (ui.wit); this module is only the host
side of it. The rule it implements is modeline.md §6: whoever registers an
element owns it end to end — the descriptor, the content, and (later) the
interaction handlers. The host exposes generic primitives and branches on
nothing, so the acid test that fragment states holds: a provider adding a
modeline element needs zero Editor:: methods and zero new host Action
variants.
§Three things that are load-bearing and easy to get wrong
Content goes on the bus, not straight into the service. ModelineService
is interior-mutable, so a host function could just call apply and the
content store would be correct — and nothing would repaint until the user
next pressed a key. The repaint comes from the bus forwarder waking the actor
(editor_boot.rs’s ModelineElementUpdate subscription → async_landed),
which is the same reason lattice-lsp::modeline and lattice-ai::mcp::status
publish rather than write. Writing directly is the “it works, but only after I
hit something” bug with a plausible-looking implementation.
The descriptor goes straight into the service, not on the bus. It is not per-frame state and has no wake to earn; the renderer reads the registry through the snapshot it takes each frame.
Ids are namespaced with the plugin’s name, like config options. Without
that, register-segment("mode") would resolve to the id mode, and a plugin
could register core.mode and silently take over a built-in element —
ModelineService::register is last-write-wins by design.