From 82b9e4625406542a5420e667b7fed1ca01df5b63 Mon Sep 17 00:00:00 2001 From: jiaren wang <33421508+JiarenWang@users.noreply.github.com> Date: Thu, 7 May 2026 17:18:22 +0900 Subject: [PATCH] fix(help): handle Ctrl+H as delete on some systems Summary: - Treat Ctrl+H as Backspace in the help overlay filter. - Document the terminal erase behavior inline. - Add regression coverage for the help filter widening after Ctrl+H. Maintainer verification on current origin/main: - cargo test -p deepseek-tui ctrl_h_widens_match_set --locked - cargo fmt --all -- --check - git diff --check origin/main...HEAD Fixes #958 --- crates/tui/src/tui/views/help.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/crates/tui/src/tui/views/help.rs b/crates/tui/src/tui/views/help.rs index 8621d21e..d9b54d3e 100644 --- a/crates/tui/src/tui/views/help.rs +++ b/crates/tui/src/tui/views/help.rs @@ -6,7 +6,8 @@ //! keybinding list from [`crate::tui::keybindings::KEYBINDINGS`] so neither //! can drift from the wired-up handlers. //! -//! Keys: any printable character extends the filter, `Backspace` shrinks it, +//! Keys: any printable character extends the filter, `Backspace` (or `Ctrl+H`) +//! shrinks it, //! `↑`/`↓` (or `Ctrl+P`/`Ctrl+N`) move the selection, `PgUp`/`PgDn` jump by //! ten rows, `Home`/`End` jump to ends, and `Esc` closes. Pressing `?` again //! at the call-site (`tui::ui`) also toggles the overlay closed. @@ -284,6 +285,14 @@ impl ModalView for HelpView { self.refilter(); ViewAction::None } + // Terminals where stty erase == ^H send Ctrl+H instead of + // Backspace (DEL). Treat it identically so the filter input + // works across all platforms (#958). + KeyCode::Char('h') if key.modifiers.contains(KeyModifiers::CONTROL) => { + self.query.pop(); + self.refilter(); + ViewAction::None + } KeyCode::Char(c) if !c.is_control() && (key.modifiers.is_empty() || key.modifiers == KeyModifiers::SHIFT) => @@ -547,6 +556,19 @@ mod tests { ); } + #[test] + fn ctrl_h_widens_match_set() { + let mut view = HelpView::new(); + type_filter(&mut view, "yolox"); + let narrow = view.filtered.len(); + view.handle_key(KeyEvent::new(KeyCode::Char('h'), KeyModifiers::CONTROL)); + let wider = view.filtered.len(); + assert!( + wider > narrow, + "Ctrl+H must behave as Backspace, broadening the matching set (was {narrow}, now {wider})" + ); + } + #[test] fn esc_closes_overlay() { let mut view = HelpView::new();