Skip to main content

Module modeline

Module modeline 

Source
Expand description

Modeline element model + descriptor registry (slice ML.0a).

The configurable modeline (see docs/dev/architecture/modeline.md) is a registry of styled, positioned, optionally-interactive elements contributed by host built-ins, modes, and (later) plugins. This module holds the mode-facing data model + the descriptor registry.

Split of concerns (mirrors lsp_progress): the descriptor (ModelineElement) is registered once and changes rarely; the content (ElementContent) churns and lives in the host content store, published as a render snapshot and updated over the event bus (ML.0b / ML.3). The renderers lay out zones (ML.1 / ML.2). Interaction (Interaction) is designed here but wired in ML.4 — shipping the field now keeps that slice additive (no model churn).

Structs§

ElementContent
The dynamic, frequently-updated value of an element. Empty (no non-empty span text) ⇒ the element is hidden this frame — the cheap way a producer hides itself without deregistering.
ElementId
Stable, namespaced element identifier — "core.mode", "lsp", "<plugin-id>.<name>". The namespace doubles as the owner key (feedback_mode_owns_its_surface): a mode/plugin owns the elements under its namespace end to end.
HoverSpec
Hover payload — a GPUI tooltip; ignored in the terminal (no hover). Realized in ML.4.
Interaction
Interaction spec — designed in ML.0, behaviour wired in ML.4. on_click is dispatched through the host action registry; the handler body lives in the registering mode/plugin crate (feedback_mode_owns_its_surface, feedback_effect_vocabulary_is_host_boundary) — the host is only a router. hover is GPUI-only.
ModelineElement
Static descriptor for a modeline element. Registered once into the ModelineRegistry; its ElementContent lives separately in the host content store and updates over the event bus (ML.3).
ModelineElementUpdate
A typed event a producer (mode / plugin) publishes on the event bus to set an element’s content (ML.3). The host forwarder fires the §12 render-wake on arrival; the actor thread drains the event into the content store in run_tick_pending (single-writer). Empty content hides the element (the drain treats it as a ModelineService::clear).
ModelineRegistry
Descriptor registry. Host-owned storage; modes register in on_activate and remove when their Guard drops (there is no on_deactivate); plugins via WIT, ML.6. Holds only descriptors — the churning content lives in the host content store, not here, so registration is rare and cheap.
ModelineRole
Theme role key for a Span. Resolved by the renderer against the ResolvedTheme (T-series). Kept as a string key so lattice-mode need not depend on the theme crate (dep-inversion, same pattern as the service registry). Unknown roles fall back to the default modeline style at render time.
ModelineService
Shared modeline service: descriptor registry + content store, each behind an [ArcSwap] for wait-free reads and lock-free updates. The host holds an Arc and reads Self::snapshot each build_render_state; modes/plugins hold the same Arc (via ctx.service::<ModelineServiceHandle>(), ML.0b-2 / ML.3) and register / remove descriptors. Content normally arrives as a ModelineElementUpdate on the event bus, which also wakes the render; calling update directly changes the store without a wake.
ModelineSnapshot
A published, wait-free snapshot of the modeline state the renderer reads: descriptors + content, each an Arc (cheap clone). The host takes one per build_render_state and stores it in RenderState (ML.0b-2).
Span
A styled run of text within an element’s content.

Enums§

ModelineKey
Content-store key discriminator (ML.3). Content is keyed by (ModelineKey, ElementId) so a single descriptor can carry distinct content per pane: Buffer(id) for a Scope::PaneLocal element (resolved against the pane’s buffer), Global for a Scope::Global element (one value, rendered only on the active pane). A producer pushes per-buffer content for each buffer it serves — e.g. each side of a split diff shows its own +N ~M. See docs/dev/architecture/modeline.md §4 (per-pane content resolution).
Scope
Whether an element renders on every pane (PaneLocal, default) or only the active pane (Global). Global carries project-wide content (clock, git branch) without per-pane duplication and without reintroducing a global chrome bar (Option A stays).
Zone
Horizontal placement zone. Left fills left→right, Right fills right→left, Center sits in the gap between them and is the default zone for custom / plugin content.

Constants§

ROLE_MODE_ITEM
The modeline role a mode tags content with when it contributes a segment to the modeline (e.g. diff-mode’s +N ~M stats) (DX.4, BC.6). Lives in lattice-mode (not host) because it is the role modes reach for — ModelineRole::new(ROLE_MODE_ITEM) — so it belongs with the mode-contribution substrate, letting lattice-diff reach it without the host. The host’s own element roles (modeline.path, modeline.position, modeline.lang, modeline.mode) stay host-side; the host re-exports this one so renderer style maps + crate::modeline call sites are unchanged.

Type Aliases§

ModelineServiceHandle
Shared handle to the ModelineService.