pub struct DetachDetector { /* private fields */ }Expand description
Deterministic detach-chord detector.
feed and tick accept caller-supplied timestamps so unit tests can
drive every state transition without sleeping. The detector is purely
a state machine: it never spawns threads, never reads from a terminal,
and never owns a clock of its own.
§Contract
The detector’s behaviour is fully specified by the following rules:
- Strict code+modifier equality. A key matches the chord’s
prefix(ordetach) slot only when bothKeyCodeand the fullKeyModifiersbitfield are byte-for-byte equal to the configured event.Ctrl+Bdoes not matchCtrl+Shift+B. - Prefix swallowing. While idle, observing the prefix transitions
the detector to
PrefixHeldand returnsDetachOutcome::Armed; the prefix is consumed and is not forwarded to the pane until the timeout lapses or a mismatch is seen. - Chord completion. While
PrefixHeld, observing the detach follow-up returnsDetachOutcome::DetachRequestedand the detector returns to idle without forwarding anything. - Mismatch forwarding. While
PrefixHeld, observing any other event (including the prefix again) returnsDetachOutcome::Forward(vec![prefix, event])in that order, and the detector returns to idle. - Timeout flushing. A
feedortickcall wherenow.saturating_duration_since(prefix_arrival) >= timeoutflushes the held prefix asForward(vec![prefix])and returns the detector to idle. Forfeed, the new event is then processed against the now-idle detector and any extra forwarded events are appended after the flushed prefix. - Zero-timeout edge case. A
Duration::ZEROtimeout means any observation strictly after the prefix is treated as expired (>=is the comparison): the detector flushes the prefix and forwards the new event without ever firing the chord. Hosts that want chord behaviour must configure a non-zero timeout. - Equal prefix/detach edge case. If a chord is configured with
prefix == detach, the detach branch is checked first whilePrefixHeld, so pressing the shared key twice quickly enough returnsDetachRequested. - Reusability. The detector is fully reusable after every
terminal outcome: hosts may keep a single detector across
sessions or runs. After
DetachRequested, the detector is idle and a subsequenttickreturnsForward(vec![]).
Implementations§
Source§impl DetachDetector
impl DetachDetector
Sourcepub const DEFAULT_TIMEOUT: Duration
pub const DEFAULT_TIMEOUT: Duration
Default chord-completion window matching tmux’s interactive feel.
Sourcepub const fn new(chord: DetachChord) -> Self
pub const fn new(chord: DetachChord) -> Self
Constructs a detector for the given chord with Self::DEFAULT_TIMEOUT.
Sourcepub const fn with_timeout(chord: DetachChord, timeout: Duration) -> Self
pub const fn with_timeout(chord: DetachChord, timeout: Duration) -> Self
Constructs a detector with an explicit timeout window.
Sourcepub const fn chord(&self) -> &DetachChord
pub const fn chord(&self) -> &DetachChord
Returns the chord this detector matches.
Sourcepub const fn is_prefix_armed(&self) -> bool
pub const fn is_prefix_armed(&self) -> bool
Returns true while the detector has consumed the prefix and is
waiting for the follow-up key.
Sourcepub fn feed(&mut self, event: KeyEvent, now: Instant) -> DetachOutcome
pub fn feed(&mut self, event: KeyEvent, now: Instant) -> DetachOutcome
Feeds an event into the detector and returns the outcome.
now is the timestamp at which the event is observed. Tests pass
a deterministic Instant so timeout edges can be exercised
precisely. The detector never blocks and never reads Instant::now()
internally.
Sourcepub fn tick(&mut self, now: Instant) -> DetachOutcome
pub fn tick(&mut self, now: Instant) -> DetachOutcome
Advances the detector’s clock without consuming an input event.
Hosts call this when they receive a non-key wakeup (poll loop tick,
resize event, etc.) so the detector can release a held prefix once
the timeout has lapsed. Returns Forward(vec![prefix]) when the
timeout has elapsed; otherwise returns the current state.
Trait Implementations§
Source§impl Clone for DetachDetector
impl Clone for DetachDetector
Source§fn clone(&self) -> DetachDetector
fn clone(&self) -> DetachDetector
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more