Skip to main content

Module keymap_normal

Module keymap_normal 

Source
Expand description

Normal-mode binding registration + lookup helper.

Audit slice 8.g (Normal mode) is sub-sliced; this module handles the 8.g.i deliverable – the simple single-key bindings that don’t depend on App-side state (counts, pending prefixes, macro recording, operator-pending). The remaining sub-slices migrate the rest:

  • 8.g.ii – g_ / z_ family.
  • 8.g.iii – operator-pending -> motion / text-object trie expansion.
  • 8.g.iv – count accumulator (stays input-side; attaches to the resolved invocation).
  • 8.g.v – mark / register / find-char wildcards.
  • 8.g.vi – <C-w> window-management sub-tree.

§What 8.g.i registers

  • Motions (with <Left> / <Down> / <Up> / <Right> / <Home> / <End> aliases): h, j, k, l, 0, $, ^, w, b, e, W, B, E, }, {, ), (, G. Each binds to CommandInvocation::of(motion.0) – the dispatcher returns Action::Invoke(command.clone()).
  • Viewport jumps: H / M / L.
  • Mode entry: i, a, o, O, :, v, V, R.
  • Paste: p, P.
  • Pseudo-operators with built-in target: D (= d$), C (= c$), S (= cc), Y (= yy), x (= delete one char right). These bind to the typed CommandInvocation directly (no operator-pending state), so they stay single-chord even though they conceptually compose an operator with a target.
  • Misc single-chord: J (line-join), ; / , (find-repeat), ~ (toggle case), K (LSP hover), / / ? (enter search), n / N / * / # (search nav), % (match bracket), u (undo), . (dot-repeat), - (oil parent dir), <Tab> (jump-list forward), <PageUp> / <PageDown> (count-10 line-down/up).

§What 8.g.i leaves in input::translate_normal

  • Pending-state resolution (AfterCtrlW, AfterG, AfterOperator, AfterFindChar, AfterTextObject, AfterZ, AfterSetMark, AfterJumpMark{Line,Exact}, AfterRegister, AfterMacroStart, AfterMacroPlay).
  • <C-...> chords (8.g.vi).
  • Numeric prefix accumulator.
  • Operator-leading single keys (d / c / y / > / <) – they set Pending::AfterOperator (8.g.iii).
  • Pending-prefix single keys (g, z, q, @, ", m, ', `, f, F, t, T).

input::translate_normal now starts with a lookup_normal call against the registry; on Some(action) it returns immediately, on None it falls through to the legacy match arm. As subsequent sub-slices migrate more bindings, the legacy match arm shrinks; 8.g.vi closes it out.

§Modifier transparency

dispatch_normal’s lookup_normal tries the chord AS PRESSED first and only falls back to a form with ALT and SUPER stripped (OS.0c, lookup_normal_chord); CTRL and SHIFT are preserved either way. It stripped unconditionally until OS.0c, which made an ALT-bearing Normal binding — legal over the modes WIT seam, and what org’s <M-CR> and meta-arrows need — impossible to fire. KeyChord::from_event already strips redundant SHIFT on bare letters, so (Char('H'), NONE) is the canonical chord for both H and <S-h> – the trie only needs one entry per uppercase letter. CTRL-bearing chords are filtered by the legacy CTRL guard above the lookup call site, so the trie never sees them in slice 8.g.i (they migrate in 8.g.vi together with the <C-w> sub-tree).

Functions§

attach_count
Slice 8.g.iv: attach the input-side count accumulator to a resolved Action::Invoke. Pure function; non-Invoke actions pass through unchanged.
binding_layer_mode
Resolve the next key of a multi-chord Normal-mode sequence via the registry. The caller supplies the prefix chord sequence already absorbed; this helper appends the normalised current chord and looks the resulting path up in the trie. Bound -> the bound action; everything else (Partial / Unbound) -> Action::None to drop the pending state, matching every legacy resolve_after_*’s catchall.
expand_grammar_rows
Derive the rows a grammar binding implies but nobody wrote: a motion’s Visual / Select / operator-pending peers, and a text object’s.
lookup_normal
Look up a single-key event in the Normal-mode catalog. Returns Some(action) when the chord is bound; None to signal the caller (input::translate_normal) to fall back to its legacy match arm for the not-yet-migrated bindings.
lookup_normal_with_prefix
operator_prefix
Map an operator id to its primary chord prefix in the Normal-mode trie. Used by the Pending::AfterOperator and Pending::AfterTextObject resolvers to compute the lookup path.
register_normal_bindings
Register the slice 8.g.i Normal-mode catalog into the supplied handle’s Builtin layer. The legacy input::translate_normal keeps its match arm for the bindings not yet in this catalog.
register_operator_bindings
Register the slice 8.g.iii operator-pending paths for one operator under op_prefix. Same shape across every operator: motion targets, the doubled-operator current-line shorthand, i_ / a_ text-object pendings + their resolutions, and the f / F / t / T find-char pendings (resolution stays in legacy resolve_after_find_char until 8.g.v).
register_operator_bindings_in
CM.2: register_operator_bindings with the layer chosen by the caller.