diff options
| author | blasty <blasty@local> | 2026-07-09 14:30:13 +0200 |
|---|---|---|
| committer | blasty <blasty@local> | 2026-07-09 14:30:13 +0200 |
| commit | 9aa8d8a381a2afc81ffdcfa095247ea66b019b63 (patch) | |
| tree | e006fdead8005c395eb9dd0519606e6190644e6f /tests | |
| parent | preserve cursor line+column in the jump history (diff) | |
| download | ida-tui-9aa8d8a381a2afc81ffdcfa095247ea66b019b63.tar.gz ida-tui-9aa8d8a381a2afc81ffdcfa095247ea66b019b63.tar.xz ida-tui-9aa8d8a381a2afc81ffdcfa095247ea66b019b63.zip | |
track pseudocode-view cursor position across jumps
NavEntry now also stores dec_cursor/dec_cursor_x. DecompView posts a CursorMoved
(with the line's /*0xEA*/ address) on move/click; the app keeps the top-of-history
pseudocode position current and DecompView.show restores it when returning to a
function. So Esc after a jump lands on the exact pseudocode line+column too,
independent of the disasm position.
pilot suite 38/38.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_tui.py | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/tests/test_tui.py b/tests/test_tui.py index 5567eb5..bd110c1 100644 --- a/tests/test_tui.py +++ b/tests/test_tui.py @@ -337,6 +337,53 @@ async def run(db): dis.cursor == mline and dis.word_under_cursor() == msym, f"cursor={dis.cursor} (want {mline}) word={dis.word_under_cursor()!r}") + # Pseudocode-view position is tracked independently across jumps. + prog = app.program + fi = prog.functions() + fi.ensure(500) + pick = None + for fn in fi.all_loaded()[:500]: + d = prog.decompile(fn.addr) + if d.failed or not d.code: + continue + dl = d.code.split("\n") + if len(dl) < 12: + continue + for i, txt in enumerate(dl): + if i < 8: + continue + dm2 = re.search(r"\b(sub_[0-9A-Fa-f]+)", txt) + if dm2 and dm2.group(1) != fn.name: + pick = (fn, i, dm2.start(1), dm2.group(1)) + break + if pick: + break + if pick is None: + check("found a pseudocode line to test decomp nav", False) + else: + fn, drow, dcol, dsym = pick + await pilot.press("g") + await pilot.pause(0.2) + for ch in fn.name: + await pilot.press(ch) + await pilot.press("enter") + await wait_until(pilot, lambda: dis.total > 0, timeout=20) + await pilot.press("tab") + await wait_until(pilot, lambda: dec.loaded_ea == fn.addr, timeout=20) + dec.cursor = drow + dec.cursor_x = dcol + dec._after_cursor_move() + await pilot.pause(0.1) + depth = len(app._nav) + await pilot.press("enter") # follow the sym under the pseudocode cursor + await wait_until(pilot, lambda: len(app._nav) > depth, timeout=25) + await pilot.press("escape") + await wait_until(pilot, lambda: dec.loaded_ea == fn.addr, timeout=25) + await pilot.pause(0.2) + check("pseudocode-view position restored after jump+back", + dec.cursor == drow and dec.word_under_cursor() == dsym, + f"cursor={dec.cursor} (want {drow}) word={dec.word_under_cursor()!r}") + def main(argv): db = None |
