aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorblasty <blasty@local>2026-07-09 23:00:32 +0200
committerblasty <blasty@local>2026-07-09 23:00:32 +0200
commit7c58501232d493bc8f132d2d745f62a96ea27d82 (patch)
tree4d5ed2ac07cb813115e58380a936486f9ddb175f /tests
parentxrefs: pre-select the site the dialog was invoked from (diff)
downloadida-tui-7c58501232d493bc8f132d2d745f62a96ea27d82.tar.gz
ida-tui-7c58501232d493bc8f132d2d745f62a96ea27d82.tar.xz
ida-tui-7c58501232d493bc8f132d2d745f62a96ea27d82.zip
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.
Diffstat (limited to 'tests')
-rw-r--r--tests/test_tui.py41
1 files changed, 40 insertions, 1 deletions
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