Expand description
escriba-mode — modal state machine, typed as a sum so illegal mode
field combinations are unrepresentable.
Phase 1: vim-ish Normal/Insert/Visual/VisualLine/Command. The earlier
design was a product type — { mode, pending_count, pending_operator, minibuffer } — where nonsense like mode: Insert carrying a
pending_operator: Some(Delete) was constructible and only kept sane
by a runtime guard inside enter(). Per the org-level ★★
UNREPRESENTABILITY rule, the fix is structural: model the per-mode state
as a SUM so each mode carries ONLY the data that is valid in that mode.
Normalcarries the pending count (5dd) + pending operator (thedindw) — these exist NOWHERE else.Insert/VisualLinecarry nothing.Visualcarries nothing in phase 1 (a futureanchor: Positionlands here, in the one variant where a visual anchor is meaningful).Commandcarries ONLY the accumulating minibuffer line.
There is no way to construct a Command without dropping the pending
operator, or an Insert that still holds a count — the type system
refuses it. The only way to change mode is the typed transition methods
(enter_* / enter / escape), so the per-mode invariant is enforced
by construction at every transition, not re-checked by a guard.
Typestate destination: a future revision can promote this to a
phantom-typestate Modal<P> where illegal transitions (not just
illegal field combos) are E0599 compile errors. That is a larger
ripple across the keymap-dispatch and runtime borrow sites; this sum
type is the pragmatic first tier — illegal field combinations are
already truly-unrepresentable, and the transition surface is sealed
behind methods so the typestate promotion is a later, localized change.
Structs§
- Pending
Op - Pending operator-pending state — only meaningful in
ModalState::Normal.
Enums§
- Modal
State - The modal state machine — a SUM over the five editor modes, each carrying ONLY the data valid in that mode.