diff options
| author | blasty <blasty@local> | 2026-07-09 14:07:22 +0200 |
|---|---|---|
| committer | blasty <blasty@local> | 2026-07-09 14:07:22 +0200 |
| commit | b441f2d89bd9273dad9253914a09765e52679666 (patch) | |
| tree | fe756d0c415b4c513916e65d758957e9546dd4b2 /tests | |
| parent | xrefs + follow-under-cursor (disasm & pseudocode) (diff) | |
| download | ida-tui-b441f2d89bd9273dad9253914a09765e52679666.tar.gz ida-tui-b441f2d89bd9273dad9253914a09765e52679666.tar.xz ida-tui-b441f2d89bd9273dad9253914a09765e52679666.zip | |
column cursor: real left/right movement + follow the ref UNDER the cursor
- ColumnCursor mixin for both views: h/l/left/right, w/b word-hops, 0/$ line
ends; block cursor cell + word-under-cursor highlight rendered on the cursor
line (region-refresh so it stays cheap). vertical moves clamp the column.
- follow/xrefs now use the token under the cursor, so a line with multiple refs
follows the one you're pointing at (proven: 'return sub_A(sub_B,..)' -> cursor
on sub_B follows sub_B). decomp matches a decompiler ref by exact name; disasm
resolves the symbol, falling back to the line's from-xref (address column /
hex operands are excluded so the default position still follows the target).
- horizontal scroll follows the cursor in the pseudocode view.
- dropped the f/b paging aliases (b is now word-back).
- pilot suite 34/34.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_tui.py | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/tests/test_tui.py b/tests/test_tui.py index 999d341..22d50b1 100644 --- a/tests/test_tui.py +++ b/tests/test_tui.py @@ -9,6 +9,7 @@ status update. Uses ~/ida-venv python (has textual). """ import asyncio import os +import re import sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) @@ -265,6 +266,33 @@ async def run(db): check("Esc closes the xrefs popup", not isinstance(app.screen, XrefsScreen)) + # Column cursor: h/l move it; following the symbol under the cursor. + dis.focus() + dis.cursor = call_idx + dis.cursor_x = 5 + dis.refresh() + await pilot.press("h") + check("h moves the column cursor left", dis.cursor_x == 4, f"x={dis.cursor_x}") + await pilot.press("l") + await pilot.press("l") + check("l moves the column cursor right", dis.cursor_x == 6, f"x={dis.cursor_x}") + plain = dis._line_plain(call_idx) or "" + m = re.search(r"\b(sub_[0-9A-Fa-f]+)", plain) + if m: + dis.cursor = call_idx + dis.cursor_x = m.start(1) + 1 + dis.refresh() + await pilot.pause(0.1) + check("word-under-cursor is the operand symbol", + dis.word_under_cursor() == m.group(1), + f"{dis.word_under_cursor()!r} vs {m.group(1)!r}") + depth = len(app._nav) + want = app.program.resolve(m.group(1)) + await pilot.press("enter") + await wait_until(pilot, lambda: len(app._nav) > depth, timeout=25) + check("follows the symbol under the cursor", + app._cur.ea == want, f"cur={app._cur.ea:#x} want={want:#x}") + def main(argv): db = None |
