From d37f4a693f64bebcc5614e085ab80be5eeede2a5 Mon Sep 17 00:00:00 2001 From: blasty Date: Thu, 9 Jul 2026 21:58:51 +0200 Subject: decompiler: xref jump lands the cursor on the reference token's column Previously an xref jump only positioned the pseudocode line; the cursor sat at column 0. Thread the referenced symbol's name (the token xrefs was invoked on, or the callee's name) from the xref dialog through _on_xref_chosen -> _do_navigate, and place the column at that token's whole-word start on the target line (_decomp_col_for, computed on the marker-stripped line so it matches the display). Works for both cross-function (via _apply_decomp cursor_x) and same-function (via DecompView.goto) jumps. Add a column assertion to the xref pilot test (asserts token-start when the token is on the line, line-start otherwise -- robust to a stale server Hex-Rays cache). full suite 65/65. --- tests/test_tui.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'tests') diff --git a/tests/test_tui.py b/tests/test_tui.py index 1641368..60ba2c5 100644 --- a/tests/test_tui.py +++ b/tests/test_tui.py @@ -378,11 +378,24 @@ async def run(db): app._active = "decomp" app._show_active() await wait_until(pilot, lambda: dec.loaded_ea == xfn.addr, 25) + # xfn is the referenced function; its name is the token that + # appears at the call site the xref points to. + app._xref_focus_name = xfn.name app._on_xref_chosen(xref.frm) # pick the caller from the dialog await wait_until(pilot, lambda: dec.loaded_ea == xref.fn_addr, 25) await pilot.pause(0.1) check("xref-select lands on the reference LINE in pseudocode", dec.cursor == dexp, f"dec.cursor={dec.cursor} want={dexp}") + # Cursor lands on the reference token's column (or the line + # start if that token isn't literally on the line, e.g. a + # stale Hex-Rays cache renders a different name). + landed = dec._texts[dec.cursor] if dec.cursor < len(dec._texts) else "" + tokm = re.search(rf"\b{re.escape(xfn.name)}\b", landed) + want_col = tokm.start() if tokm else 0 + check("xref-select lands the column on the reference token", + dec.cursor_x == want_col, + f"cursor_x={dec.cursor_x} want={want_col} " + f"token={xfn.name!r} line={landed.strip()!r}") # And a jump whose target is INSIDE the already-displayed # function must still move the cursor (the decompiler pane -- cgit v1.3.1-sl0p