aboutsummaryrefslogtreecommitdiffstats
path: root/idatui
diff options
context:
space:
mode:
authorblasty <blasty@local>2026-07-23 15:26:42 +0200
committerblasty <blasty@local>2026-07-23 15:26:42 +0200
commit73305a513b929838f04f53d88dea2b1483cc485f (patch)
tree089588a172346c854789436f6444dc3a2ee0f155 /idatui
parentunify: back the function disasm view on the heads listing walker (M4 item 4) (diff)
downloadida-tui-73305a513b929838f04f53d88dea2b1483cc485f.tar.gz
ida-tui-73305a513b929838f04f53d88dea2b1483cc485f.tar.xz
ida-tui-73305a513b929838f04f53d88dea2b1483cc485f.zip
app: 'L' opens the continuous segment listing (functions+data interleaved)
Function views are bounded to one function; 'L' from any code view opens the whole-segment ListingView at the cursor instead -- one long flat listing where functions/data/undefined interleave and you scroll straight from one function into the next. Reuses the region listing path (_goto_continuous). New continuous_view scenario: open a function, press L, assert continuous listing opens, cursor at the origin function, listing spans past the function bounds, code interleaves with data. 22/0 with disasm_nav/view_toggle/ region_define (L is additive).
Diffstat (limited to 'idatui')
-rw-r--r--idatui/app.py38
1 files changed, 38 insertions, 0 deletions
diff --git a/idatui/app.py b/idatui/app.py
index 234b720..415d00a 100644
--- a/idatui/app.py
+++ b/idatui/app.py
@@ -607,6 +607,7 @@ class DisasmView(SearchMixin, NavMixin, ColumnCursor, ScrollView, can_focus=True
Binding("p", "define_func", "Func", show=False),
Binding("u", "undefine", "Undef", show=False),
Binding("tab,shift+tab", "app.toggle_view", "Pseudocode", priority=True),
+ Binding("L", "app.continuous_here", "Listing"),
*SearchMixin.SEARCH_BINDINGS,
*NavMixin.NAV_BINDINGS,
*ColumnCursor.COL_BINDINGS,
@@ -1165,6 +1166,7 @@ class DecompView(SearchMixin, NavMixin, ColumnCursor, ScrollView, can_focus=True
BINDINGS = [
Binding("tab,shift+tab", "app.toggle_view", "Disasm", priority=True),
+ Binding("L", "app.continuous_here", "Listing"),
Binding("j,down", "cursor_down", "Down", show=False),
Binding("k,up", "cursor_up", "Up", show=False),
Binding("ctrl+d", "half_page(1)", "½↓", show=False),
@@ -3393,6 +3395,42 @@ class IdaTui(App):
def _code_view(self): # type: ignore[no-untyped-def]
return self.query_one(DecompView if self._pref == "decomp" else DisasmView)
+ def _active_code_view(self): # type: ignore[no-untyped-def]
+ """The currently-shown code widget (for reading the cursor address)."""
+ if self._active == "listing":
+ return self.query_one(ListingView)
+ if self._active == "disasm":
+ return self.query_one(DisasmView)
+ if self._active == "decomp":
+ return self.query_one(DecompView)
+ return None
+
+ def action_continuous_here(self) -> None:
+ """'L': open the continuous segment listing at the cursor — one long
+ flat view where functions, data and undefined bytes are interleaved,
+ instead of the function-bounded disassembly."""
+ if self.program is None:
+ return
+ view = self._active_code_view()
+ ea = self._line_ea_for(view) if view is not None else None
+ if ea is None and self._cur is not None:
+ ea = self._cur.ea
+ if ea is None:
+ self._status("no address here to open the continuous listing")
+ return
+ if self._cur is not None and self._cur.is_region:
+ self._status("already in the continuous listing")
+ return
+ self._goto_continuous(ea)
+
+ @work(thread=True, group="nav")
+ def _goto_continuous(self, ea: int, push: bool = True) -> None:
+ assert self.program is not None
+ name = self.program.region_label(ea)
+ 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._open_at, ea, name, idx, push, -1, 0, True)
+
@work(thread=True, exclusive=True, group="goto")
def _goto(self, target: str) -> None:
assert self.program is not None