Expand description
The modes guest→host mode-declaration seam (PH7.11a).
A mode plugin implements the modes-plugin world: it imports the modes
API (register-mode) and exports register-modes (the host calls it once
to drive declaration). This module holds the bindgen! for that world plus
the host-side registration logic — building a marker Mode impl
([PluginMode], the EmacsKeysMode template) from the declaration and
registering it into the SAME ModeRegistry
builtins use, so :describe-mode / mode introspection treat it uniformly.
The canonical API is the WIT (modes.wit) — any component-model language
calls register-mode directly. The mapping + register logic live here so they
are unit-testable without a Store (the config_host / host_services
precedent).
Registration flow (the register-grammar drain precedent): register-mode
records the declaration into the Store’s [ModeContributions]; after the
guest’s register-modes export returns, PluginHost::spawn_mode_plugin
drains them and registers each into a &mut ModeRegistry (registration needs
&mut, not a live handle — unlike config’s Arc<ConfigRegistry>).
PH7.11a lands mode declaration + registration; PH7.11b the keymap bindings.
OM.2 adds major modes, because a plugin-contributed language can get a
major no other way: major_mode_id_for_lang is a hand-written match over the
Lang enum and has no arm for Lang::Plugin(_). A declared major claims its
language through target-language, the registry indexes it
(ModeRegistry::find_major_for_lang), and a document of that language
activates it through the same resolver a built-in major uses.
Lifecycle callbacks, decorations and typed option-overrides remain deferred (fragment / Phase 8).