Expand description
KeymapTrie – the lookup data structure the keymap registry
consults on the keystroke path. Audit slice 8.b of the M3
refactor; see docs/dev/architecture/keymap-architecture.md for the design.
§Shape
Each TrieNode carries:
children: HashMap<KeyChord, TrieNode>– exact-match descents indexed by chord.gd’s second descent comes fromchildren[KeyChord::char('d')].char_wildcard: Option<Box<TrieNode>>– “any single printable char” descent. Used for marks ('a), registers ("a), find-char (fX/FX/tX/TX), macro names (@a/qa). Subsumes today’sBindingMode::AfterMark/AfterRegister/AfterFindCharspecial-case states.binding: Option<Arc<BoundCommand>>– terminal binding at this depth, if any. Internal nodes holdNone.
Lookup walks chord-by-chord. Exact children match wins; if
absent, fall back to char_wildcard (capturing the matched
char). Returns:
Boundwhen the walk ends at a node with a terminal binding (and the input is exhausted).Partialwhen the walk ends at an internal node with no terminal but with children – caller waits for the next chord.Unboundwhen no descent matches at some point.
§Performance
Lookup is O(prefix_length) HashMap lookups. With ~500
bindings per layer and chord depths of 1-3, the inner cost
is two HashMap::get calls plus a few branches; bench
keymap_trie_lookup_* rows in BENCHMARKS.md measure it.
Allocation-free on the hot path – the Vec<char> of
captured wildcards is built only when the path actually
crosses a wildcard, which is rare.
§Mutation
insert / remove / merge_over are off the hot path
(registry construction, layer push/pop, :bind invocations).
They take &mut self; the registry handle (slice 8.c) wraps
the trie in Arc<ArcSwap<KeymapTrie>> so wait-free reads
coexist with these &mut-bound mutations – the registry
builds a new trie, swaps the cell, and the old trie drops
once readers release their Arc.
Structs§
- Bound
Command - What the trie returns at a terminal node.
- Child
View - WK.1: one immediate child of a trie node, as which-key sees it.
- Keymap
Trie - One layer’s worth of bindings, indexed for
O(prefix_length)lookup. - Node
View - WK.1: the immediate children of the node a prefix names — which-key’s
view of the trie, as distinct from
:describe-key’sKeymapTrie::walk_continuations, which wants the whole subtree with provenance. Same trie, different questions.
Enums§
- Chord
Pattern - One element of a keymap registration path.
- Keymap
Layer - Where in the five-layer model (DESIGN.md §5.2.3) a binding originated. Higher value wins on cross-layer conflict; the trie itself doesn’t enforce this, the registry does at merge time.
- Lookup
Result - Lookup outcome.