Expand description
Keybinding sequence detection and action mapping.
This module implements the keybinding policy specification (bd-2vne.1) for detecting multi-key sequences like Esc Esc and mapping keys to actions based on application state.
§Key Concepts
-
SequenceDetector: State machine that detects Esc Esc sequences with configurable timeout. Single Esc is emitted after timeout or when another key is pressed.
-
SequenceConfig: Configuration for sequence detection including timeout windows and debounce settings.
-
ActionMapper: Maps key events to high-level actions based on application state (input buffer, running tasks, modals, overlays). Integrates with SequenceDetector to handle Esc sequences.
-
AppState: Runtime state flags that affect action resolution.
-
Action: High-level commands like ClearInput, CancelTask, ToggleTreeView.
§State Machine
┌─────────────────────────────────────┐
│ │
▼ │
┌──────────┐ Esc ┌────────────────────┐ timeout ┌─────────┐ │
│ Idle │───────▶│ AwaitingSecondEsc │────────────▶│ Emit(Esc)│ │
└──────────┘ └────────────────────┘ └─────────┘ │
▲ │ │
│ │ Esc (within timeout) │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Emit(EscEsc) │──────────────────────────────────┘
│ └─────────────────┘
│
│ other key
└───────────────────────────────────────────────────────────────────§Example
use std::time::{Duration, Instant};
use ftui_core::keybinding::{SequenceDetector, SequenceConfig, SequenceOutput};
use ftui_core::event::{KeyCode, KeyEvent, Modifiers, KeyEventKind};
let mut detector = SequenceDetector::new(SequenceConfig::default());
let now = Instant::now();
// First Esc: starts the sequence
let esc = KeyEvent::new(KeyCode::Escape);
let output = detector.feed(&esc, now);
assert!(matches!(output, SequenceOutput::Pending));
// Second Esc within timeout: emits EscEsc
let later = now + Duration::from_millis(100);
let output = detector.feed(&esc, later);
assert!(matches!(output, SequenceOutput::EscEsc));§Action Mapping Example
use std::time::Instant;
use ftui_core::keybinding::{ActionMapper, ActionConfig, AppState, Action};
use ftui_core::event::{KeyCode, KeyEvent, Modifiers};
let mut mapper = ActionMapper::new(ActionConfig::default());
let now = Instant::now();
// Ctrl+C with non-empty input: clears input
let state = AppState { input_nonempty: true, ..Default::default() };
let ctrl_c = KeyEvent::new(KeyCode::Char('c')).with_modifiers(Modifiers::CTRL);
let action = mapper.map(&ctrl_c, &state, now);
assert!(matches!(action, Some(Action::ClearInput)));
// Ctrl+C with empty input and no task: quits (by default)
let idle_state = AppState::default();
let action = mapper.map(&ctrl_c, &idle_state, now);
assert!(matches!(action, Some(Action::Quit)));Structs§
- Action
Config - Configuration for action mapping behavior.
- Action
Mapper - Maps key events to high-level actions based on application state.
- AppState
- Runtime state flags that affect keybinding resolution.
- Binding
- One chord bound to an action.
- Binding
Id - Identifier of one binding inside a
KeyMap. - Chord
- One to
Chord::MAX_LENcombos pressed in sequence (g g,Ctrl+x Ctrl+s). - Conflict
Report - Every conflict in a map, with a one-line warning per item.
- Context
Id - An interned context name (see
KeyMap::context). - Dispatch
Stats - Counters for evidence rows and hint-usage feedback.
- KeyCombo
- A single key press with its modifiers (
Ctrl+x,Shift+Tab,F12,g). - KeyDispatcher
- Chord-aware dispatcher over a
KeyMap. - KeyMap
- A declarative binding map: chords to actions with priorities and
contexts. Actions are any
Clonetype (usually an app enum). - KeyMap
Config - Timing configuration of a
KeyMap. - Lookup
- Result of
KeyMap::lookup. - Sequence
Config - Configuration for the sequence detector.
- Sequence
Detector - Stateful detector for multi-key sequences (currently Esc Esc).
Enums§
- Action
- High-level actions that can result from keybinding resolution.
- Conflict
- A binding conflict found by
KeyMap::conflicts. - CtrlC
Idle Action - Behavior when Ctrl+C is pressed with empty input and no running task.
- Dispatch
- What the dispatcher decided for one key event or tick.
- KeyParse
Error - Why a key, combo, or chord string could not be parsed.
- Priority
- Binding priority level; higher wins for the same chord.
- Sequence
Output - Output from the sequence detector after processing a key event.
Constants§
- DEFAULT_
CHORD_ TIMEOUT_ MS - Default chord timeout (ms).
- DEFAULT_
ESC_ DEBOUNCE_ MS - Default debounce before emitting single Esc.
- DEFAULT_
ESC_ SEQ_ TIMEOUT_ MS - Default timeout for detecting Esc Esc sequence.
- MAX_
CHORD_ TIMEOUT_ MS - Upper bound of the chord timeout (ms).
- MAX_
ESC_ DEBOUNCE_ MS - Maximum allowed value for Esc debounce.
- MAX_
ESC_ SEQ_ TIMEOUT_ MS - Maximum allowed value for Esc sequence timeout.
- MIN_
CHORD_ TIMEOUT_ MS - Lower bound of the chord timeout (ms).
- MIN_
ESC_ DEBOUNCE_ MS - Minimum allowed value for Esc debounce.
- MIN_
ESC_ SEQ_ TIMEOUT_ MS - Minimum allowed value for Esc sequence timeout.