From 1eed36ec1cdd573ef5a095dcafff12a6dd4daab2 Mon Sep 17 00:00:00 2001 From: blasty Date: Thu, 6 Aug 2026 16:36:53 +0200 Subject: help: reach the cheatsheet with H as well as F1 F1 is swallowed before it ever reaches us on at least one setup here -- the app's own binding fires when the key is injected directly, zellij has no F1 binding of its own, and every common F1 encoding written straight into the pane (SS3 ESC O P, CSI ESC [11~, CSI-u ESC [1;1P) opens it. So the key is being eaten by something upstream, which is not ours to fix, and a cheatsheet reachable only through a function key is fragile anyway: terminals and multiplexers claim them routinely. H opens and closes it too. '?' stays with the incremental search, which is what it has always done in the code views. --- idatui/app.py | 14 +++++++++----- tests/test_scenarios.py | 10 ++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/idatui/app.py b/idatui/app.py index 0779b93..b3367c4 100644 --- a/idatui/app.py +++ b/idatui/app.py @@ -3147,7 +3147,7 @@ _HELP = ( ("?", "search backward"), ("N", "previous match"), ("Ctrl+Y", "copy the current line"), - ("F1", "this cheatsheet"), + ("F1 / H", "this cheatsheet"), ("q", "quit"), )), ("Graph (Space)", ( @@ -3205,7 +3205,7 @@ class QuitScreen(ModalScreen): class HelpScreen(ModalScreen): """F1: the keyboard cheatsheet, replacing the permanent footer.""" - BINDINGS = [Binding("escape,f1,q,question_mark", "close", "Close")] + BINDINGS = [Binding("escape,f1,H,q,question_mark", "close", "Close")] #: widest cell content, +2 for the card's border, +2 for its padding _CARD_PAD = 4 @@ -3233,7 +3233,7 @@ class HelpScreen(ModalScreen): classes="help-card", markup=False) card.border_title = title yield card - yield Static("Esc / F1 to close", id="help-foot") + yield Static("Esc · F1 · H to close", id="help-foot") @staticmethod def _section_widths() -> list[int]: @@ -4185,7 +4185,8 @@ class IdaCommands(Provider): app.action_strings), ("Switch binary…", "another binary in the project (Ctrl+O)", app.action_switch_binary), - ("Keyboard shortcuts", "the key cheatsheet (F1)", app.action_help), + ("Keyboard shortcuts", "the key cheatsheet (F1 or H)", + app.action_help), ("Follow symbol under cursor", "jump to the referenced symbol (Enter)", lambda: va("follow")), ("Show xrefs to symbol", "cross-references to the cursor symbol (x)", @@ -4396,7 +4397,10 @@ class IdaTui(App): Binding("left_square_bracket", "step_back", "Step back", show=False), Binding("right_curly_bracket", "step_over_fwd", "Step over", show=False), Binding("left_curly_bracket", "step_over_back", "Step over back", show=False), - Binding("f1", "help", "Keys", show=False), + # H as well as F1: terminals and multiplexers swallow function keys all + # the time (and the one that does it is upstream of us, so there is + # nothing to fix on this side), which left the cheatsheet unreachable. + Binding("f1,H", "help", "Keys", show=False), Binding("g", "goto", "Goto"), Binding("slash", "filter", "Filter", show=False), Binding("ctrl+b", "toggle_functions", "Names", show=False), diff --git a/tests/test_scenarios.py b/tests/test_scenarios.py index b4d5990..e138946 100644 --- a/tests/test_scenarios.py +++ b/tests/test_scenarios.py @@ -554,6 +554,16 @@ async def s_help(c: Ctx): await c.press("escape") await c.wait(lambda: not isinstance(app.screen, HelpScreen), 10) c.check("Esc closes it", not isinstance(app.screen, HelpScreen)) + # F-keys get eaten by terminals/multiplexers upstream of us, so the + # cheatsheet must not be reachable ONLY through F1. + await c.press("H") + opened_h = await c.wait(lambda: isinstance(app.screen, HelpScreen), 10) + c.check("H opens the cheatsheet too", opened_h, + f"screen={type(app.screen).__name__}") + if opened_h: + await c.press("H") + await c.wait(lambda: not isinstance(app.screen, HelpScreen), 10) + c.check("H closes it again", not isinstance(app.screen, HelpScreen)) @scenario("strings") -- cgit v1.3.1-sl0p