pub struct BootContext { /* private fields */ }Expand description
The host’s generic-primitive surface, handed to per-subsystem wiring.
Holds shared handles by Arc (cheap to clone) plus the boot-lifetime
tick-callback registration tokens, so drains registered via
inbound / tick_callback
outlive the construction phase. The tokens move into the Editor (program
lifetime) via into_registrations; dropping the
BootContext without taking them drops the drains.
§BC.3a — registry ownership (decision 2-b)
BootContext owns the three registries during the build phase. A
subsystem registers its modes / commands / services through boot — the
SubsystemBoot surface (modes_mut /
commands_mut /
register_service); host-native
builtins (the native vim grammar, ex-commands, foundation / language /
oil / file-tree / snippet / tutor / buffer-kind modes, host actions,
mode-toggle commands, syntax text objects) register through the SAME seam.
BC.final finding (2026-06-25): the *_mut accessors are NOT transitional
— those builtins are host-native (not subsystems, never installed), so the
accessors are the permanent builtin-registration seam, kept by design. The
mode-ownership acid test (“a new SUBSYSTEM touches boot in one place”)
governs the Phase-B install list, not the host’s own builtins. The
registries are held
behind Option and taken on freeze_command_registry
/ freeze_mode_registry /
freeze_service_registry. The freeze order
editor_boot uses: the ModeRegistry first (right after the mode-
registration block — its Arc is needed by register_mode_toggle_commands,
which borrows &mut CommandRegistry + &ModeRegistry at once and so cannot
hold both through boot; freezing modes first hands back an
Arc<ModeRegistry> that derefs to &ModeRegistry), then the
CommandRegistry mid-boot (its Arc feeds the picker registry + document
handles), then the ServiceRegistry last. Freezing only wraps + takes the
registry; the populated data is unchanged, so the order is behaviour-neutral.
Registering into an already-frozen registry is a boot-sequencing bug and
panics with a clear message.
Implementations§
Source§impl BootContext
impl BootContext
Sourcepub fn new(
event_bus: Arc<EventBus>,
tick_callbacks: TickCallbackRegistryHandle,
async_landed: Arc<Notify>,
runtime_handle: Handle,
buffer_store: BufferStoreHandle,
idle_gates: IdleGateRegistryHandle,
command_registry: CommandRegistry,
mode_registry: ModeRegistry,
service_registry: ServiceRegistry,
) -> Self
pub fn new( event_bus: Arc<EventBus>, tick_callbacks: TickCallbackRegistryHandle, async_landed: Arc<Notify>, runtime_handle: Handle, buffer_store: BufferStoreHandle, idle_gates: IdleGateRegistryHandle, command_registry: CommandRegistry, mode_registry: ModeRegistry, service_registry: ServiceRegistry, ) -> Self
Bundle the host primitives + the registries editor_boot will populate
through this context. The three registries are passed in empty (fresh
*::new()); editor_boot and the per-subsystem installs register into
them via boot and freeze_* them at the right points.
Sourcepub fn async_landed(&self) -> &Arc<Notify> ⓘ
pub fn async_landed(&self) -> &Arc<Notify> ⓘ
The editor’s off-keystroke wake handle (host-only lifecycle accessor;
the subsystem install surface is the SubsystemBoot impl below).
Sourcepub fn inbound_raw<T>(&self) -> (InboundBus<T>, UnboundedReceiver<T>)where
T: Send + 'static,
pub fn inbound_raw<T>(&self) -> (InboundBus<T>, UnboundedReceiver<T>)where
T: Send + 'static,
BC.8d: a host-drained inbound bus — the wake-baked sender PLUS the raw
receiver, with no per-tick handler. For server-initiated work whose apply
is irreducibly &mut Editor (LSP workspace/applyEdit): the host seats
the receiver on the Editor and drains it from run_tick_pending, while
send still wakes the editor off-keystroke (the wake lives in the sender
— can’t be forgotten). Keeps the irreducible apply host-side without an
internal-pump Effect. Inherent (not on SubsystemBoot): only the
host’s own Phase-A wiring uses it; no subsystem install does.
Sourcepub fn tick_callbacks(&self) -> &TickCallbackRegistryHandle
pub fn tick_callbacks(&self) -> &TickCallbackRegistryHandle
The shared tick-callback registry (run once per tick by the host).
Sourcepub fn idle_gates(&self) -> &IdleGateRegistryHandle
pub fn idle_gates(&self) -> &IdleGateRegistryHandle
WK.3: the shared idle-gate registry. The host seats this on the
Editor so the actor loop can point its pinned sleep at
earliest() and fire the due gates when it elapses.
Sourcepub fn freeze_command_registry(&mut self) -> CommandRegistryHandle
pub fn freeze_command_registry(&mut self) -> CommandRegistryHandle
Freeze the command registry into its shared runtime-mutable handle
(ArcSwap) and take it out of the context. Called mid-boot, after all
command registration, before the handle is consumed (picker registry,
document handles). Subsequent commands_mut panics.
PL8.B / B3b: ArcSwap (not a bare Arc) so the plugin loader can
RCU-register a runtime grammar contribution; the dispatch path — the
per-buffer actor and every host-side ex-command / completion read —
snapshots it wait-free. Mirrors Self::freeze_mode_registry.
Sourcepub fn freeze_mode_registry(&mut self) -> ModeRegistryHandle
pub fn freeze_mode_registry(&mut self) -> ModeRegistryHandle
Freeze the mode registry into its shared runtime-mutable handle
(ArcSwap) and take it out. Called after register_mode_toggle_commands.
Subsequent modes_mut panics. ArcSwap (not a bare Arc) so the plugin
loader can RCU-register a runtime mode; reads snapshot it wait-free.
Sourcepub fn freeze_service_registry(&mut self) -> Arc<ServiceRegistry> ⓘ
pub fn freeze_service_registry(&mut self) -> Arc<ServiceRegistry> ⓘ
Freeze the service registry into its shared Arc and take it out.
Called last, after the services block. Subsequent services_mut panics.
Sourcepub fn into_registrations(self) -> Vec<TickCallbackRegistration>
pub fn into_registrations(self) -> Vec<TickCallbackRegistration>
Take the boot-lifetime tick-callback registration tokens. BC.3 calls
this to move them into the Editor so the drains live for the program
rather than being dropped when the BootContext is dropped.
Trait Implementations§
Source§impl SubsystemBoot for BootContext
BC.3b: the subsystem install surface. Subsystems wire against this trait
(defined in lattice-mode, below them) instead of the concrete
BootContext (in lattice-host, above them — which would cycle). Host-only
lifecycle (new, freeze_*, into_registrations, the
async_landed/tick_callbacks accessors) stays inherent above; only the
generic install operations live here. The LSP diagnostics handle is reached
via service, so this surface names no
lattice-lsp type.
impl SubsystemBoot for BootContext
BC.3b: the subsystem install surface. Subsystems wire against this trait
(defined in lattice-mode, below them) instead of the concrete
BootContext (in lattice-host, above them — which would cycle). Host-only
lifecycle (new, freeze_*, into_registrations, the
async_landed/tick_callbacks accessors) stays inherent above; only the
generic install operations live here. The LSP diagnostics handle is reached
via service, so this surface names no
lattice-lsp type.
Source§fn commands_mut(&mut self) -> &mut CommandRegistry
fn commands_mut(&mut self) -> &mut CommandRegistry
Source§fn modes_mut(&mut self) -> &mut ModeRegistry
fn modes_mut(&mut self) -> &mut ModeRegistry
Source§fn services_mut(&mut self) -> &mut ServiceRegistry
fn services_mut(&mut self) -> &mut ServiceRegistry
register_service.Source§fn register_service<T: Any + Send + Sync>(&mut self, service: T)
fn register_service<T: Any + Send + Sync>(&mut self, service: T)
TypeId. Per the
ServiceRegistry Arc/TypeId rule, register and look up with the same
T (register Arc<X> ⇒ look up Arc<X>).Source§fn service<T: Any + Send + Sync>(&self) -> Option<Arc<T>>
fn service<T: Any + Send + Sync>(&self) -> Option<Arc<T>>
DiagnosticsQueryHandle
the host registered in Phase A) without this trait naming that type.
Returns Arc<T>; for an Arc<X> registration this is Arc<Arc<X>>,
so unwrap one layer ((*h).clone()).Source§fn inbound<T, H>(&mut self, handler: H) -> InboundBus<T>
fn inbound<T, H>(&mut self, handler: H) -> InboundBus<T>
send wakes the
editor off-keystroke (the wake is inside the sender — structurally
impossible to forget) and whose items are drained per-tick, each run
through handler (validate → map to an Effect → resolve any
oneshot). Returns the sender for the off-thread producer; the drain’s
registration is retained for the editor’s lifetime by the host.Source§fn wake_on_event<E>(&self)where
E: TypedEvent + Clone,
fn wake_on_event<E>(&self)where
E: TypedEvent + Clone,
Source§fn tick_callback(&mut self, callback: TickCallback)
fn tick_callback(&mut self, callback: TickCallback)
Source§fn idle_gate(
&mut self,
name: &'static str,
handler: IdleGateHandler,
) -> IdleGateHandle
fn idle_gate( &mut self, name: &'static str, handler: IdleGateHandler, ) -> IdleGateHandle
Effects it returns and
repainting. The subsystem arms it from its own event handler
(handle.arm(Instant::now() + delay)) and disarms when the reason
evaporates (WK.3). Read moreSource§fn runtime_handle(&self) -> &Handle
fn runtime_handle(&self) -> &Handle
Source§fn buffer_store(&self) -> &BufferStoreHandle
fn buffer_store(&self) -> &BufferStoreHandle
BufferId).Auto Trait Implementations§
impl !RefUnwindSafe for BootContext
impl !UnwindSafe for BootContext
impl Freeze for BootContext
impl Send for BootContext
impl Sync for BootContext
impl Unpin for BootContext
impl UnsafeUnpin for BootContext
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§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