From 7c58501232d493bc8f132d2d745f62a96ea27d82 Mon Sep 17 00:00:00 2001 From: blasty Date: Thu, 9 Jul 2026 23:00:32 +0200 Subject: names: command-palette fuzzy finder (Ctrl+N), overlay-first Replace the docked names pane as the primary way to jump to symbols with a command-palette overlay: Ctrl+N opens SymbolPalette, type to fuzzy-find (scored subsequence match with matched-char highlighting), up/down to select, Enter to open, Esc to close. Mouse-clickable too. The docked FunctionsPanel now starts hidden and is still reachable/toggleable with Ctrl+B (classic table view, sort, filter, goto all unchanged); a code view takes focus on startup. Status hints 'Ctrl+N: find symbol'. Pilot checks for open/fuzzy/subsequence/select/close. Tests reveal the docked pane (Ctrl+B) for the existing table-driven checks. full suite 74/74. --- tests/test_tui.py | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/test_tui.py b/tests/test_tui.py index 8874c54..afa995e 100644 --- a/tests/test_tui.py +++ b/tests/test_tui.py @@ -19,7 +19,7 @@ import sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from idatui.app import ( # noqa: E402 - DecompView, DisasmView, FunctionsPanel, IdaTui, XrefsScreen, + DecompView, DisasmView, FunctionsPanel, IdaTui, SymbolPalette, XrefsScreen, ) from textual.widgets import DataTable, Input, OptionList, Static # noqa: E402 from rich.text import Text # noqa: E402 @@ -66,7 +66,13 @@ async def run(db): loaded = await wait_until(pilot, lambda: table.row_count > 0) check("function list populated", loaded, f"rows={table.row_count}") + # The names pane is an overlay now (Ctrl+N) and starts hidden; reveal the + # classic docked pane (Ctrl+B) for the table-driven checks below. left = app.query_one("#left") + check("names pane starts hidden (overlay-first)", not left.display, + f"display={left.display}") + await pilot.press("ctrl+b") + await wait_until(pilot, lambda: left.display, timeout=5) check("function pane width is capped (doesn't eat the screen)", left.size.width <= 44, f"width={left.size.width}") @@ -78,6 +84,39 @@ async def run(db): nfuncs = table.row_count print(f" loaded {nfuncs} functions") + # Symbol palette (Ctrl+N): fuzzy find + open, overlay-style. + await pilot.press("ctrl+n") + pal_open = await wait_until(pilot, lambda: isinstance(app.screen, SymbolPalette), 10) + check("Ctrl+N opens the symbol palette", pal_open, + f"screen={type(app.screen).__name__}") + if pal_open: + pal = app.screen + pinp = pal.query_one(Input) + pinp.value = "main" + await wait_until(pilot, lambda: pal._results and pal._results[0].name == "main", 10) + check("palette fuzzy-finds (top result matches the query)", + bool(pal._results) and pal._results[0].name == "main", + f"top={pal._results[0].name if pal._results else None}") + pinp.value = "eror" # scattered subsequence of 'error' + await wait_until(pilot, lambda: any(f.name == "error" for f in pal._results), 10) + check("palette matches a fuzzy subsequence", + any(f.name == "error" for f in pal._results), + f"results={[f.name for f in pal._results[:4]]}") + pinp.value = "main" + await wait_until(pilot, lambda: pal._results and pal._results[0].name == "main", 10) + want = pal._results[0].addr + await pilot.press("enter") + await wait_until(pilot, lambda: not isinstance(app.screen, SymbolPalette), 10) + await wait_until(pilot, lambda: app._cur and app._cur.ea == want, 20) + check("selecting a palette entry opens that function", + bool(app._cur) and app._cur.ea == want, + f"cur={app._cur.ea if app._cur else None}") + await pilot.press("ctrl+n") + await wait_until(pilot, lambda: isinstance(app.screen, SymbolPalette), 10) + await pilot.press("escape") + await wait_until(pilot, lambda: not isinstance(app.screen, SymbolPalette), 10) + check("Esc closes the palette", not isinstance(app.screen, SymbolPalette)) + # Open the biggest function we can find (scan a sample of rows for size). # Simpler: select the row whose Size column is largest among first N. biggest_i, biggest_sz = 0, -1 -- cgit v1.3.1-sl0p