pub struct PluginTeardown {Show 17 fields
pub plugin_id: PluginId,
pub seam_ids: Vec<PluginId>,
pub picker_sources: Vec<String>,
pub provider_views: Vec<String>,
pub modes: Vec<ModeId>,
pub config_options: Vec<String>,
pub events_defined: Vec<String>,
pub subscriptions: Vec<SubscriptionId>,
pub keymap_bindings: Vec<KeymapBindingToken>,
pub decoration_sources: Vec<u64>,
pub media_sources: Vec<u64>,
pub agenda_sources: Vec<u64>,
pub context_sources: Vec<u64>,
pub transient_sources: Vec<String>,
pub theme_elements: Vec<String>,
pub signs: Vec<String>,
pub modeline_namespace: Option<String>,
}Expand description
The union of teardown tokens a plugin’s contributions produce, aggregated at
spawn time and consumed by unload. A given plugin populates
only the surfaces it exercised; the rest stay empty and their reversal is a
no-op. Every field is pub so the spawning caller fills it from the tokens
the spawn_* fns already return (Vec<SubscriptionId>, Vec<ModeId>,
Vec<String> option names, …).
Fields§
§plugin_id: PluginIdThe host-issued identity — drives CommandRegistry::unregister_plugin,
which unconditionally removes every SourceLayer::Plugin(plugin_id)
command (grammar contributions + the modes seam’s :<mode> toggles) by
provenance. No per-command token or “did I register grammar?” flag: the
provenance IS the token.
seam_ids: Vec<PluginId>Every host id this plugin’s seams were issued, plugin_id
included.
Each spawn_* issues its own id — deliberately, because a provenance
id must never be derived from guest-controlled input, so it cannot be
keyed on the manifest’s string id. A plugin providing N seams therefore
has N provenances, and reversing only one of them leaves the rest
registered: bundled auto-pair (grammar, modes, config, help) leaked
its :help pages on unload exactly that way.
Token-based reversals below are unaffected — the drains capture their tokens on the record. This is only for the provenance-keyed ones.
picker_sources: Vec<String>Picker source ids the plugin registered (PickerRegistry::unregister).
provider_views: Vec<String>MV.1: multibuffer view ids the plugin registered openers under
(ProviderViewRegistry::unregister). Without reversing these, a
reloaded plugin’s register returns false against its OWN stale
opener and its views come back dead.
modes: Vec<ModeId>Modes the plugin registered — each reversed via ModeRegistry::unregister
and KeymapHandle::remove_layer(MinorMode(id)) (both halves of the mode
surface, PH7.11).
config_options: Vec<String>Config option names the plugin registered (ConfigRegistry::unregister);
mirrors PluginState::config_contributions.
events_defined: Vec<String>Plugin-defined event names (unregister_runtime_event, process-wide).
subscriptions: Vec<SubscriptionId>Event-bus subscription ids the plugin’s subscribe calls produced
(EventBus::unsubscribe); the Vec spawn_event_plugin returns.
keymap_bindings: Vec<KeymapBindingToken>User keybindings the plugin bound via the keymap seam (PL8.D) — each
reversed by KeymapHandle::try_unbind_chord_string from KeymapLayer::User.
The Vec spawn_keymap_plugin returns.
decoration_sources: Vec<u64>PL8.E: decoration producer ids the plugin registered into the
GutterDecorationSourceRegistry — each reversed via
GutterDecorationSourceRegistry::unregister. Mirrors picker_sources.
media_sources: Vec<u64>IM.6b: media producers to unregister, by plugin id. Mirrors
decoration_sources — without this a :plugin-reload would leave the
old producer registered and every image would be requested twice.
agenda_sources: Vec<u64>OM.A1: agenda producers to unregister, by plugin id. Mirrors
media_sources — without this a :plugin-reload would leave the old
producer registered and every agenda row would appear twice.
context_sources: Vec<u64>TC.2: context producer ids the plugin registered into the
ContextSourceRegistry — each reversed via
ContextSourceRegistry::unregister. Mirrors decoration_sources.
transient_sources: Vec<String>TR.2b: transient-menu names the plugin registered. Reversed by the
LOADER, not by unload — the registry is
Arc-shared rather than one of the &mut snapshots
TeardownRegistries carries, and it is the same placement
help_topics / dashboard_sections use for the same reason.
Leaving a name registered after unload is not cosmetic: the entry holds
a TransientClient whose actor has ended, so the chord would report a
host error instead of “unknown source”.
theme_elements: Vec<String>TC.4: namespaced theme-element names the plugin registered. Reversed by
ThemeRegistry::unregister_element so an unloaded plugin’s elements stop
appearing in :customize and stop resolving.
signs: Vec<String>SG.3a: namespaced sign names the plugin declared. Reversed by
SignRegistry::undefine so an unloaded plugin’s signs stop painting.
A NAME list rather than the namespace prefix, even though
undefine_prefix exists for the latter — because the seam’s store is
dropped when register-signs returns, so a plugin cannot declare a
sign later in its life the way a modeline segment can. The list is
therefore complete by construction, and it gives the report an exact
count instead of a boolean. undefine_prefix is what to switch to if
that ever stops being true.
modeline_namespace: Option<String>OC.3 / ML.6: the plugin’s element namespace — its manifest id — not a list of the ids it registered.
Reversal is by prefix on purpose. A plugin may register a segment at any point in its life (org’s clock could arm one the first time you clock in), so a token list collected at load would miss a later one and leave its descriptor behind — and that matters because the renderer iterates DESCRIPTORS, so an orphan renders the plugin’s last segment forever with nobody left to update or clear it. A prefix has nothing to forget. Same reasoning as the compilation parser factories, reversed by provenance.
Implementations§
Source§impl PluginTeardown
impl PluginTeardown
Sourcepub fn new(plugin_id: PluginId) -> Self
pub fn new(plugin_id: PluginId) -> Self
A bundle for plugin_id with no contributions recorded yet.
Sourcepub fn provenances(&self) -> Vec<PluginId>
pub fn provenances(&self) -> Vec<PluginId>
Reverse every recorded contribution against the host registries, returning
a TeardownReport of what was removed. Idempotent — each underlying
unregister_* is a no-op on an already-removed entry, so a double-unload
(or an unload after a partial crash) is safe and simply reports zeros the
second time. Order is irrelevant: the surfaces are independent (grammar
commands, picker sources, modes+their keymap layer, options, events, and
subscriptions never share an entry).
Every provenance this plugin stamped contributions with.
Falls back to plugin_id alone when seam_ids was never populated, so
a hand-built PluginTeardown (tests, and any caller predating
seam_ids) still reverses its one id rather than silently reversing
nothing.
pub fn unload(&self, reg: &mut TeardownRegistries<'_>) -> TeardownReport
Trait Implementations§
Source§impl Clone for PluginTeardown
impl Clone for PluginTeardown
Source§fn clone(&self) -> PluginTeardown
fn clone(&self) -> PluginTeardown
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for PluginTeardown
impl RefUnwindSafe for PluginTeardown
impl Send for PluginTeardown
impl Sync for PluginTeardown
impl Unpin for PluginTeardown
impl UnsafeUnpin for PluginTeardown
impl UnwindSafe for PluginTeardown
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<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