Skip to main content

Module registry

Module registry 

Source
Expand description

The CommandRegistry holds every registered operator, motion, text object, and ex-command. The dispatcher (super::dispatcher::execute) looks up commands here.

Built-in commands are registered at editor startup via populate_builtins (see super::builtins). Plugins register their own through the same register_* methods. v1 keeps these as native Rust closures; the WASM plugin host (Phase 7) wraps the same shape.

Structs§

ActionContext
Context passed to a free-form action’s evaluator. Mirrors ExCommandContext’s shape (no document mutation; the App applies the returned crate::effect::Effect) but omits the bang bit – chord-bound actions never carry one. The register / count slots flow the count and register prefixes the user typed before the chord (vim’s 3"+yy-style); most actions ignore them.
ActionSpec
A registered free-form action: a command with no grammar role, usually bound to a chord.
CommandRegistry
The one registry of every command: motions, operators, text objects, ex-commands and actions, built-in and plugin alike (DESIGN.md §5.2.1).
CommentSyntax
N.1.6 (2026-06-10): per-buffer comment-leader descriptor for the comment text objects (aC / iC). Commentstring-driven (NOT tree-sitter) so it works for any language with a known leader, even without a parse tree. The host populates it from the active buffer’s language (Lang::comment_syntax); None (or line: None) means the comment objects resolve nothing (graceful operator no-op).
ExCommandContext
Context handed to an ex-command’s evaluator. Mirrors the shape passed to motion / operator / text-object specs but adds the bang bit and drops direct document mutation: ex-commands describe their work by returning an crate::effect::Effect, which the host applies.
ExCommandId
Strongly-typed handle to an ex-command in the registry.
ExCommandSpec
A registered ex-command: how the : line parses it and what it returns.
GrammarEnv
The per-dispatch environment: everything the host knows that a command’s apply may need but the grammar layer cannot derive for itself. Bundled into ONE value so the dispatch seam carries a single env rather than a widening parameter list (the long-term-fit choice over parallel params). Copy; default() is the no-input case, and commands that read nothing from the env (iw, ap, i{) are unaffected by what it carries.
LastFind
The last f / F / t / T the user ran, which is all ; and , need to repeat it.
LastSearch
VM.3d-2: the last completed / / ? / * / # search, which is all n and N need to repeat it. Moved here from the host (which re-exports the name, so no call site moved) for the reason LastFind was: n is a motion now, and the state it repeats has to reach the grammar.
MotionContext
Context passed to a motion’s evaluator.
MotionId
Strongly-typed handle to a motion command in the registry.
MotionResult
What a motion’s evaluator returned.
MotionSpec
A registered motion: its evaluator plus the vim properties the dispatcher and host need without running it.
NativeFormatIntents
RF.5b: which formatting intents the buffer handles natively.
OperatorContext
Context passed to an operator’s evaluator.
OperatorId
Strongly-typed handle to an operator command in the registry.
OperatorSpec
A registered operator: its evaluator plus how the dispatcher should feed it spans.
RangeId
Strongly-typed handle to a custom range source (plugin-registered) used by Range::Custom(RangeId).
ShownLines
VM.3f: the window’s lines, top to bottom, each with its height in line-heights (1.0 for an ordinary row). The host builds it from the walk it paints with; this type owns vim’s rule for which of them H / M / L mean, so the keyboard motion and the host’s JumpViewport action answer from one place. Checked in vim 9.2: a count past the window clamps to the far edge, and M is top + (lines shown − 1) / 2 — half the lines SHOWN, so a short buffer’s middle, not the window’s.
TextObjectContext
Context passed to a text-object’s evaluator.
TextObjectId
Strongly-typed handle to a text-object command in the registry.
TextObjectSpec
A registered text object: an evaluator that returns the span around a position.

Enums§

CommandRegistration
What a registered command holds in the registry, beyond its metadata.
Curswant
VM.3g-1: vim’s curswant — the column a vertical motion aims for, which survives passing through a SHORT line. jj from column 9 over a 2-column line lands back on 9, not on 2 (vim 9.2, vimcheck_curswant2.vim).
CurswantEffect
VM.3g-1: what a motion does to the goal column. A property of the MOTION (vim’s j always keeps it, $ always pins it), so it lives on the spec rather than the result — and Self::SetFromTarget is the default, so every motion that has never heard of curswant, plugin motions included, behaves as vim’s ordinary motions do.
FindKind
f / F / t / T — which direction, and whether the target character is included.
MotionNotice
VM.3d-2: something a motion wants the user told, alongside where it moved. Copy, so MotionResult stays Copy; the dispatcher renders the text.
NavBoundary
Which boundary of the target node the motion lands on.
NavDir
Direction of travel for a structural motion. Forward scans toward EOF, Backward toward BOF.
SurfaceForm
How the user types this command on the : line. The default (Keyword) covers most commands – :write, :quit, :set number. Delimiter is for the small family of commands whose arguments are interleaved with delimiters: :s/pat/repl/, :g/pat/body, :v/pat/body. The keyword form (:ex:substitute, :ex:global) for these is intentionally a hard error – the front-end parser routes them via try_parse_substitute / try_parse_global. UI surfaces (completion, command palette) hide Delimiter commands because there’s no useful keyword-form completion for them; the user types the delimiter directly.

Constants§

MODE_TOGGLE_COMMAND_DOC
Doc string for an auto-generated :<mode-name> mode-toggle ex-command — shared so native and plugin modes read identically in :describe-command.

Traits§

DisplayResolver
VM.3g-2: what the DISPLAY looks like, for gj / gk / g0 / g$. Soft wrap is a rendering decision — the wrap width, and how many rows a line takes once tabs and wide characters are measured — so the grammar asks rather than computes, exactly as it does for folds and the viewport.
FoldResolver
VM.3i: where zj / zk find the next fold edge.
IndentResolver
IN.7: how deep should this line sit?
MarkResolver
VM.3e: the mark table 'x / `x read, so they can be motions. The host owns the marks (m writes them); the grammar only asks where one is. None means the mark isn’t set, which fails the motion with E20.
ScopeResolver
Resolves a tree-sitter scope near the cursor, for the structural text objects (af / ac / aa / …) and structural motions (]f / [c / …).
ViewportResolver
VM.3f: which line of the window H / M / L mean. The layout — folds, row heights, window size — stays on the host; the grammar only asks.

Functions§

mode_toggle_ex_command_spec
Build the auto-generated :<mode-name> mode-toggle ex-command spec. The apply returns crate::effect::Effect::ToggleMode; the host routes that to toggle_mode_by_name, flipping the mode on the active buffer. Shared by boot (native modes, register_mode_toggle_commands) AND the plugin modes-seam drain, so a plugin-registered mode gets an IDENTICAL :<mode> toggle surface. The caller registers it under the right provenance: Builtin for native modes; SourceLayer::Plugin(id) for plugin modes, so unload reverses it. Takes no arguments.