diff options
| author | blasty <blasty@local> | 2026-07-09 14:44:31 +0200 |
|---|---|---|
| committer | blasty <blasty@local> | 2026-07-09 14:44:31 +0200 |
| commit | 5f6014514edf65dcf249a8ff457bb42409336eef (patch) | |
| tree | 6afe367fa931cb6977ee22f802ed8b9d13453944 /tests/test_tui.py | |
| parent | sortable function list: click column headers (addr/name/size) (diff) | |
| download | ida-tui-5f6014514edf65dcf249a8ff457bb42409336eef.tar.gz ida-tui-5f6014514edf65dcf249a8ff457bb42409336eef.tar.xz ida-tui-5f6014514edf65dcf249a8ff457bb42409336eef.zip | |
rename symbol under cursor ('n') + save ('Ctrl+S')
- 'n' on the token under the cursor opens a rename prompt prefilled with the
current name. The symbol is classified and routed to the right rename batch:
* resolves to a function start -> func
* decompiler ref (global/string) -> data
* pseudocode token, not a ref -> local (Hex-Rays lvar)
* disasm var_/arg_ -> stack
tool errors (e.g. name collisions) are surfaced in the status line.
- after a rename: force_recompile + cache invalidation, reload the current views
(preserving cursor), update the renamed function's row in place (avoids racing
the initial stream), and update nav history names.
- 'Ctrl+S' persists the IDB (idb_save); edits mark the session dirty.
- 'n'/'N' search-repeat dropped for 'n'=rename (repeat stays on '/'+Enter / '?').
- verified live: func rename (list + disasm update), local var rename (pseudocode
update), save. pilot suite 44/44; domain 17/17.
Diffstat (limited to 'tests/test_tui.py')
| -rw-r--r-- | tests/test_tui.py | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/tests/test_tui.py b/tests/test_tui.py index f7cbc81..422476a 100644 --- a/tests/test_tui.py +++ b/tests/test_tui.py @@ -405,6 +405,46 @@ async def run(db): check("click Address header sorts by address", app._sort_col == 0 and saddrs == sorted(saddrs), f"sort_col={app._sort_col}") + # Rename via 'n' (reuse the pseudocode sub_ ref found above). + if pick is not None: + fn, drow, dcol, dsym = pick + dtarget = app.program.resolve(dsym) + 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) + if app._active != "decomp": + await pilot.press("tab") + await wait_until(pilot, lambda: dec.loaded_ea == fn.addr, timeout=20) + dec.focus() + dec.cursor, dec.cursor_x = drow, dcol + 1 + dec.refresh() + await pilot.pause(0.1) + newname = f"ren_{os.getpid()}" + await pilot.press("n") + await pilot.pause(0.2) + ri = app.query_one("#rename", Input) + check("'n' opens the rename prompt prefilled with the symbol", + ri.display and ri.value == dsym, f"val={ri.value!r}") + ri.value = newname + await pilot.press("enter") + await wait_until( + pilot, + lambda: app._func_index.by_addr(dtarget) + and app._func_index.by_addr(dtarget).name == newname, + timeout=25, + ) + check("rename updates the function name", + app._func_index.by_addr(dtarget).name == newname, + app._func_index.by_addr(dtarget).name) + # revert via the API for reliable, race-free cleanup + rr = app.program.client.call( + "rename", batch={"func": {"addr": hex(dtarget), "name": dsym}}) + check("rename reverted cleanly", + rr.get("summary", {}).get("ok", 0) == 1, str(rr.get("summary"))) + def main(argv): db = None |
