Skip to main content

Module keybinding

Module keybinding 

Source
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§

ActionConfig
Configuration for action mapping behavior.
ActionMapper
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.
BindingId
Identifier of one binding inside a KeyMap.
Chord
One to Chord::MAX_LEN combos pressed in sequence (g g, Ctrl+x Ctrl+s).
ConflictReport
Every conflict in a map, with a one-line warning per item.
ContextId
An interned context name (see KeyMap::context).
DispatchStats
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 Clone type (usually an app enum).
KeyMapConfig
Timing configuration of a KeyMap.
Lookup
Result of KeyMap::lookup.
SequenceConfig
Configuration for the sequence detector.
SequenceDetector
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.
CtrlCIdleAction
Behavior when Ctrl+C is pressed with empty input and no running task.
Dispatch
What the dispatcher decided for one key event or tick.
KeyParseError
Why a key, combo, or chord string could not be parsed.
Priority
Binding priority level; higher wins for the same chord.
SequenceOutput
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.