Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion src/ui/enhanced_tui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1879,7 +1879,10 @@ impl EnhancedTuiApp {
Ok(false)
}
ChordResult::SingleKey(single_key) => {
// Not a chord, process normally
// Not a chord (or a chord that lapsed and was reset on this key).
// Clear any lingering chord hint so the indicator reflects reality.
self.key_sequence_renderer.clear_chord_mode();
// Process normally
self.handle_results_input(single_key)
}
}
Expand Down Expand Up @@ -1963,6 +1966,16 @@ impl EnhancedTuiApp {
// Ignore other events (mouse, resize, etc.) to reduce CPU
}
} else {
// No key event. If a pending chord has lapsed, cancel it and refresh
// so the "Yank mode" hint visibly disappears (chord reset indicator).
if self.key_chord_handler.clear_if_timed_out() {
self.key_sequence_renderer.clear_chord_mode();
self.state_container
.set_status_message("Chord cancelled (timeout)".to_string());
terminal.draw(|f| self.ui(f))?;
return Ok(false);
}

// No event available, but still redraw if we have pending debounced actions or table needs render
if self.search_modes_widget.is_active()
|| self.table_widget_manager.borrow().needs_render()
Expand Down
18 changes: 17 additions & 1 deletion src/ui/key_handling/chord_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ impl KeyChordHandler {
let description = if self.current_chord.len() == 1
&& self.current_chord[0].code == KeyCode::Char('y')
{
"Yank mode: y=row, c=column, a=all, ESC=cancel".to_string()
"Yank mode: y/r=row, c=column, a=all, v=cell, q=query, ESC=cancel".to_string()
} else {
format!("Waiting for: {}", possible.join(", "))
};
Expand Down Expand Up @@ -333,6 +333,22 @@ impl KeyChordHandler {
self.chord_mode_active
}

/// Cancel a pending chord if it has exceeded the timeout.
///
/// The normal timeout check only runs when the next key arrives, so a chord
/// left dangling (e.g. `y` with no follow-up key) never resets on its own.
/// Calling this from the idle loop lets the UI clear the chord hint once the
/// window lapses. Returns true if a pending chord was cleared.
pub fn clear_if_timed_out(&mut self) -> bool {
if let Some(start) = self.chord_start {
if start.elapsed() > self.chord_timeout {
self.cancel_chord();
return true;
}
}
false
}

/// Get chord mode description
#[must_use]
pub fn get_chord_mode_description(&self) -> Option<&str> {
Expand Down
Loading