Expand description
Buffer-local mode-internal state — Shape A from
mode-architecture.md §9.4 (M.3.2.a).
A typed analogue of emacs’s buffer-local-variables. Each
piece of mode-internal data declares an OptionDecl-style
type identity via the BufferLocal trait; the typed-map
BufferLocals stores them keyed by TypeId for O(1)
type-keyed reads. Each entry carries metadata (display name,
doc, owner mode) so :describe-buffer can enumerate every
local a buffer carries grouped by its owning mode.
§Distinction from options
Buffer-locals are runtime data the mode owns, not user-
configurable values. They store opaque Rust structs
(SyntaxHandle, Vec<FileTreeEntry>, Vec<Link>, …)
that don’t have string-parseable forms and shouldn’t appear
in :set autocomplete. The user can inspect them via
:describe-buffer but never edit them via :set /
:customize.
§Ownership and the OWNER_MODE rule
Each local declares the mode that owns it
(BufferLocal::OWNER_MODE). The design (M.3.2.a) has
crate::ModeContext check at write time that the currently
activating mode matches the local’s owner, rejecting cross-mode
mutation with
ModeActivationError::WrongOwnerMode.
That checked write surface is not implemented: ModeContext has
no local accessors today, writes happen host-side through
BufferLocals::insert (unchecked), and OWNER_MODE is attribution
metadata for :describe-buffer. Treat the rule as a convention — write
only the locals your mode owns.
Reads are unrestricted: any mode can read any local. This
lets, e.g., lsp-completion-mode read file-tree-mode’s
entries to populate path completion without a special-case
handshake.
§What does NOT live here
- Universal buffer state (rope, cursor, scroll, version) – direct fields on whatever struct holds them. Buffer-locals are for mode-specific runtime data.
- User-facing options – those are
OptionDeclinlattice-config. Seemode-architecture.md§6.4. - Declarative contributions (option overrides, keymap
layers, decoration providers) – modes return these from
Mode::options()etc.; the registry applies them. The mode never writes to them directly.
§Storage shape
BufferLocals is a HashMap<TypeId, Box<dyn LocalDyn>>.
LocalDyn is a sealed inner trait that lets us:
- Read metadata (
name,doc,owner_mode,describe) without knowing the concrete type — for:describe-buffer. - Downcast back to the concrete
Tfor typed reads / removes — for the typed accessors.
Structs§
- Buffer
Locals - Typed-map of buffer-local mode-internal state.
- Buffer
Scope Dir - The directory a buffer is about, when that is not its own path.
- Buffer
Scope Source Registry - Registered
BufferScopeSources. AVecrather than a single handle because two providers naming buffers is normal and a single slot would let the second registration silently displace the first. - Local
Descriptor - Read-only descriptor for one buffer-local, returned by
BufferLocals::iter_descriptorsfor:describe-buffer.
Traits§
- Buffer
Local - Compile-time declaration of a mode-owned per-buffer local.
- Buffer
Scope Source - A provider’s answer to “which directory is the buffer called this about?”, asked by the host the moment it creates a synthetic buffer.
Type Aliases§
- Buffer
Scope Source Registry Handle - Register and look up with this exact alias (the
ServiceRegistryTypeIdrule).