<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ida-tui.git/idatui/domain.py, branch main</title>
<subtitle>tui for headless ida</subtitle>
<id>https://git.sl0p.foo/ida-tui.git/atom/idatui/domain.py?h=main</id>
<link rel='self' href='https://git.sl0p.foo/ida-tui.git/atom/idatui/domain.py?h=main'/>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/'/>
<updated>2026-07-11T20:58:52Z</updated>
<entry>
<title>disasm: render opcode bytes (toggle 'o'), padded to widest insn</title>
<updated>2026-07-11T20:58:52Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-11T20:58:52Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=17b8c95b948d4fe2d38cac4f80ffa8fb0a750d4f'/>
<id>urn:sha1:17b8c95b948d4fe2d38cac4f80ffa8fb0a750d4f</id>
<content type='text'>
Fetch per-instruction opcode bytes alongside the disasm listing and show
them in a column between the address and the mnemonic. Instruction length
comes from consecutive addresses (variable-length safe: x86 movabs shows
its full 10 bytes); the block over-fetches one instruction for the last
line's boundary, falling back to the function end for the final insn.

The column pads to the widest instruction across the whole function:
_fetch_block tracks a running max, and on load a background scan_bytes()
settles a stable width so padding doesn't jump as blocks stream in.
_op_field is shared by the rendered strip, _line_plain, and search _fmt
so cursor/match offsets stay aligned. 'o' toggles the column.
</content>
</entry>
<entry>
<title>fix: don't hang drive pc on undecompilable functions</title>
<updated>2026-07-11T08:59:48Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-07-11T08:59:48Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=2c86330705569805c5d201113a569c9e03c0214a'/>
<id>urn:sha1:2c86330705569805c5d201113a569c9e03c0214a</id>
<content type='text'>
toggle_view's settle predicate (lambda: app._active != before) never
fired when tabbing toward pseudocode on a function Hex-Rays can't
decompile: App._apply_decomp snaps the view back to disasm, so _active
returns to its prior value -&gt; full 20s settle timeout (x2 in _show_decomp,
~40s for drive pc). Recognize the decomp-failed fallback as settled.

Also harden two amplifiers surfaced by the same case:
- rpcclient: the CLI socket had no read timeout and would block forever
  on any server slowness; add a bounded settimeout (IDATUI_RPC_TIMEOUT,
  default 90s) with a clear error.
- domain.decompile: pass a bounded 15s timeout and cache failures, so a
  failing decompile can't sit at the 30s client default or be re-run by
  transport retries.
</content>
</entry>
<entry>
<title>hex view: file offsets + 'g' goto (dedicated input)</title>
<updated>2026-07-10T12:53:20Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-10T12:53:20Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=b8d0335682758ef51eab1c6dea6435b11d4e0bd2'/>
<id>urn:sha1:b8d0335682758ef51eab1c6dea6435b11d4e0bd2</id>
<content type='text'>
Add a file_regions server tool (get_fileregion_offset per segment) and
Program.file_regions/file_offset so a virtual address maps to its raw
on-disk offset without a format-specific header parser. The hex view now
shows a VA column and a file-offset column side by side, and the status
line reports file+off.

Goto moves to its own top-level #goto Input instead of overloading the
function-filter box (which is hidden with the names pane, so goto was
unreachable there). In the hex view 'g' jumps the cursor to an address
(bounds-checked against the image); elsewhere it navigates as before.
</content>
</entry>
<entry>
<title>hex view: raw image bytes (VA-addressed), synced to the code cursor</title>
<updated>2026-07-10T12:03:16Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-10T12:03:16Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=636a6cb34e83523c3c513fb62ca39e0f6c10098f'/>
<id>urn:sha1:636a6cb34e83523c3c513fb62ca39e0f6c10098f</id>
<content type='text'>
New HexView: a line-virtualized 16-bytes/row dump of the whole loaded image,
addressed by virtual address. Format-agnostic — the range/segments come from IDA
(image_range over sections()), not any file header; gaps read back as zeros.

Backslash toggles it, synced to the address under the disasm/pseudocode cursor
(see the naked bytes of some code/data). In hex: hjkl/paging navigate a byte
cursor (status shows the section), Enter jumps the code view to the byte,
Tab/Esc/backslash return to the preferred code view. A third _active state; block
-cached + prefetched like the disasm model.

domain: HexModel + Program.hex_model/read_bytes/image_range (get_bytes regions).
Fixed a self-deadlock (hex_model held _lock while sections() re-locked).
Pilot: sync, actual bytes, byte-step, return. full suite 98/98.
</content>
</entry>
<entry>
<title>retype: set variable/function types with 'y' (IDA-style), via structured tools</title>
<updated>2026-07-10T11:30:48Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-10T11:30:48Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=6d83015906f850b872261655f014ef14612a8ba5'/>
<id>urn:sha1:6d83015906f850b872261655f014ef14612a8ba5</id>
<content type='text'>
Instead of parsing pseudocode text, add structured server tools (server/
patch_server.py, alongside del_type):
 - func_types(addr): prototype + local variables (name/type/is_arg)
 - set_lvar_type(addr,var,type): retype a decompiler local, working on auto/
   register vars too (stock set_type only updates already-user-modified lvars)

'y' in a code view retypes what's under the cursor: a local variable (prompt
prefilled with its current type) or a function (prompt prefilled with its full
prototype). Applies via set_lvar_type / set_type, then recompiles + refreshes.
Copy-line moved off 'y' to Ctrl+Y.

domain: Program.func_types / set_function_type / set_lvar_type (LVar/FuncTypes).
Pilot: function-prototype retype (prefill + apply). full suite 94/94.
</content>
</entry>
<entry>
<title>struct editor: C-style CRUD for local types (Ctrl+T)</title>
<updated>2026-07-10T07:53:56Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-10T07:53:56Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=29f8a238d0e316c4a0fe4081c5412a18f5bb3c64'/>
<id>urn:sha1:29f8a238d0e316c4a0fe4081c5412a18f5bb3c64</id>
<content type='text'>
New StructEditor overlay: left is the list of local structs/unions, right is an
editable C definition. Enter loads a struct (reconstructed as C from its member
layout via type_inspect), Ctrl+S declares it (create or update via declare_type),
Ctrl+N starts a new one, Del deletes, Esc returns to the list then closes.

Domain: Struct model + Program.list_structs / struct_source / declare_type /
delete_type (anonymous $-types filtered).

Delete needs a 'del_type' tool the ida-pro-mcp server doesn't currently expose;
delete_type detects its absence and reports a clear message instead of failing.
Create/read/update work fully.

Pilot checks: open, list, view C, create, update-in-place, delete(-or-report),
close. full suite 84/84.
</content>
</entry>
<entry>
<title>xrefs: informative labels — function+offset, and section instead of '?'</title>
<updated>2026-07-09T20:28:53Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-09T20:28:53Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=6a761c222a6f08cb2fd825a15f3d3f44390a716d'/>
<id>urn:sha1:6a761c222a6f08cb2fd825a15f3d3f44390a716d</id>
<content type='text'>
The xref list showed just the containing function name, so multiple sites in the
same function were indistinguishable ('sub_2300' repeated), and references not in
any function collapsed to a bare '?'.

- In-function sites now show fn_name+offset (e.g. main+0xb08), so each site is
  distinct and you can see where in the function it is.
- Non-function sites (GOT/reloc data slots, loose thunks) show the section they
  live in (.got, .data.rel.ro, .text, LOAD, ...) instead of '?'. Add
  Program.sections()/section_of() over survey_binary's segment map (fetched once,
  cached lazily).

Pilot checks for both. full suite 67/67.
</content>
</entry>
<entry>
<title>comments: ';' sets a comment on the current line (disasm + pseudocode)</title>
<updated>2026-07-09T18:56:08Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-09T18:56:08Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=c5499b4e69c969e1c8dcc0f98f7df023c8b8407f'/>
<id>urn:sha1:c5499b4e69c969e1c8dcc0f98f7df023c8b8407f</id>
<content type='text'>
Bind ';' (NavMixin, so both code views) to a comment prompt for the line under
the cursor. Resolve the line's address (_cursor_ea in disasm, the /*0xEA*/ marker
in pseudocode), prefill any existing comment (parsed from the rendered '//' text),
and apply via the set_comments tool; an empty value clears it.

After setting, reuse the name-generation invalidation (bump_names) so Hex-Rays is
force_recompiled lazily and the pseudocode/disasm refresh in place at the saved
position -- the new '// comment' shows on the line. Marks the IDB dirty (Ctrl+S).

Pilot checks for the pseudocode round-trip. full suite 63/63.
</content>
</entry>
<entry>
<title>fix: pseudocode names not refreshing across history after rename</title>
<updated>2026-07-09T13:44:11Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-09T13:44:11Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=986abcaf21ee2ebf4f5b48f7fc5b05833fa55d34'/>
<id>urn:sha1:986abcaf21ee2ebf4f5b48f7fc5b05833fa55d34</id>
<content type='text'>
force_recompile takes 'items=[{addr}]', not 'addr' — my call raised and was
swallowed, so the Hex-Rays cache was never cleared and a caller's cached
pseudocode kept showing the old callee name on 'back' (disasm refreshed because
its names are live). Use the correct params. History test now also caches and
verifies the caller's pseudocode. pilot suite 52/52.
</content>
</entry>
<entry>
<title>fix input visibility (search/rename) + refresh stale names across history</title>
<updated>2026-07-09T13:36:12Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-07-09T13:36:12Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=6a8e022441c973bbdfb1c4ee0f55373ebf1d1456'/>
<id>urn:sha1:6a8e022441c973bbdfb1c4ee0f55373ebf1d1456</id>
<content type='text'>
- Visibility: #search/#rename/#status were dock:bottom like the Footer and got
  placed on the SAME row (y=39) as the Footer, which drew over them, so the
  typed text was invisible. Drop the docking; they now sit in normal flow just
  above the Footer (y=38). Verified: input region is above the footer.
- Stale names on 'back': a rename only invalidated the current function, so
  popping back to a caller (cached earlier) showed the old name. Add
  Program.bump_names(): a rename bumps a name-generation, clears all disasm block
  caches (disasm names are live), and decompilation is generation-checked and
  force-recompiled lazily on next view. _after_rename now invalidates globally.
- verified: rename a callee, 'back' to the caller shows the new name.
- pilot suite 51/51.
</content>
</entry>
</feed>
