aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorblasty <blasty@local>2026-07-23 22:52:54 +0200
committerblasty <blasty@local>2026-07-23 22:52:54 +0200
commit1540b3904dbf605a881121f9571a1b021168af00 (patch)
tree038b40ec04978c7feaf3039a274226a5bd81d86f
parentfix: Tab back from a decomp jump returns to the listing cleanly (diff)
downloadida-tui-1540b3904dbf605a881121f9571a1b021168af00.tar.gz
ida-tui-1540b3904dbf605a881121f9571a1b021168af00.tar.xz
ida-tui-1540b3904dbf605a881121f9571a1b021168af00.zip
fix: Tab decomp->listing reuses the nav entry so edits stay put
The previous fix reopened the listing via _goto_ea(push=False), which made _cur a DETACHED entry (not _nav[-1]). Cursor moves update _nav[-1], so _cur.cursor went stale: after moving to a label and renaming it, _reload_active_code -> _open_entry(cur) restored the stale cursor and scrolled the just-renamed label off-screen. The rename actually applied (model showed the new name) but the view jumped away, so it looked like it "didn't propagate". Now Tab from a jumped-to pseudocode view converts the CURRENT entry (which is _nav[-1]) to a listing view in place (_toggle_to_listing): set view="listing", position at the current line's address, and reopen. Cursor moves keep updating the same entry, so a subsequent rename reloads at the cursor and the renamed label stays on screen. Verified: decomp jump -> Tab -> move to loc_ label -> rename: cursor stays on the label, which now shows the new name (00002040 ZZLABEL:) in the viewport. view_toggle/decomp_nav/decomp_follow_self/follow_xrefs/xref_labels/rename/ rename_history/disasm_nav/search/mouse/listing_view/continuous_view/func_banners/ scroll_restore 70/0.
-rw-r--r--idatui/app.py30
1 files changed, 25 insertions, 5 deletions
diff --git a/idatui/app.py b/idatui/app.py
index e06d2c8..c4cae93 100644
--- a/idatui/app.py
+++ b/idatui/app.py
@@ -2611,18 +2611,38 @@ class IdaTui(App):
self._active = "listing"
self._open_entry(ret, push=False)
elif self._cur is not None:
- # No F5 snapshot (we arrived via a decomp navigation): open the
- # listing at the current pseudocode line's address, as a real listing
- # view — otherwise we'd show a stale widget with _cur.view still
- # "decomp", and the next edit would bounce back to the decompiler.
+ # No F5 snapshot (we arrived via a decomp navigation): show THIS entry
+ # in the listing at the current pseudocode line's address. Reuse the
+ # entry (it is _nav[-1]) rather than spawning a detached one, so cursor
+ # moves keep updating it and a later edit reloads at the right spot.
dec = self.query_one(DecompView)
ea = dec._line_ea(dec.cursor)
- self._goto_ea(ea if ea is not None else self._cur.ea, push=False)
+ self._toggle_to_listing(ea if ea is not None else self._cur.ea)
else:
self._active = "listing"
self._show_active()
@work(thread=True, group="nav")
+ def _toggle_to_listing(self, ea: int) -> None:
+ assert self.program is not None
+ lm = self.program.listing(ea)
+ idx = max(lm.ensure_ea(ea), 0) if lm is not None else 0
+ self.app.call_from_thread(self._apply_toggle_listing, idx)
+
+ def _apply_toggle_listing(self, idx: int) -> None:
+ cur = self._cur
+ if cur is None:
+ self._active = "listing"
+ self._show_active()
+ return
+ cur.view = "listing"
+ cur.cursor = idx
+ cur.cursor_x = 0
+ cur.scroll_y = -1 # derive a viewport (keeps the target in context)
+ self._active = "listing"
+ self._open_entry(cur, push=False)
+
+ @work(thread=True, group="nav")
def _decomp_from_listing(self, ea: int) -> None:
assert self.program is not None
fn = self.program.function_of(ea)