From 51b7cc5a1e4fbb861909946b2feb842294d412e8 Mon Sep 17 00:00:00 2001 From: blasty Date: Thu, 9 Jul 2026 12:25:49 +0200 Subject: decompiler view: Tab/Shift+Tab toggle disasm<->pseudocode, full bodies - domain.decompile now fetches the FULL body: server caps responses at 50KB and clips strings to 1KB, but caches the full output and exposes it at _meta.ida_mcp.download_url -> we GET that so pseudocode is complete (main: 43257 chars, not a 1KB stub). include_addresses gives per-line /*0xEA*/. - DecompView (read-only TextArea, cpp highlighting best-effort, line numbers) - Tab and Shift+Tab toggle the code pane; lazy decompile in a worker, cached; hard-failures ('decompilation failed') shown gracefully with disasm fallback - pilot suite 14/14 (adds tab->pseudocode, full-body, shift+tab->disasm) --- tests/test_tui.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/test_tui.py b/tests/test_tui.py index 8769321..683f896 100644 --- a/tests/test_tui.py +++ b/tests/test_tui.py @@ -12,7 +12,7 @@ import os import sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -from idatui.app import DisasmView, FunctionsPanel, IdaTui # noqa: E402 +from idatui.app import DecompView, DisasmView, FunctionsPanel, IdaTui # noqa: E402 from textual.widgets import DataTable, Static # noqa: E402 PASS = FAIL = 0 @@ -124,6 +124,25 @@ async def run(db): left.display and isinstance(app.focused, DataTable), f"display={left.display} focus={type(app.focused).__name__}") + # Decompiler toggle: open a function, Tab -> pseudocode, Shift+Tab -> back. + table.focus() + table.move_cursor(row=biggest_i) + await pilot.press("enter") + dis = app.query_one(DisasmView) + dec = app.query_one(DecompView) + await wait_until(pilot, lambda: dis.total > 0, timeout=20) + await pilot.press("tab") + pc = await wait_until(pilot, lambda: dec.display and dec.loaded_ea is not None, 25) + check("tab shows pseudocode", pc and app._active == "decomp", + f"active={app._active} disp={dec.display}") + check("pseudocode has real body (not 1KB stub)", len(dec.text) > 1200, + f"len={len(dec.text)}") + await pilot.press("shift+tab") + await pilot.pause(0.2) + check("shift+tab returns to disassembly", + app._active == "disasm" and dis.display and not dec.display, + f"active={app._active}") + def main(argv): db = None -- cgit v1.3.1-sl0p