- parser.py: classify a line into control / function-call / raw payload; parse loose hex/binary with intermixed 0x/0b tokens (whitespace- insensitive, defaulting to the session entry mode) - entry.py: byte_space() byte-group formatting + key bindings — Ctrl-/ toggles hex/binary entry mode (breadcrumb updates), digits auto-space into byte groups as you type - app.py: dispatch() drives the loop via parse_line (testable without a live prompt); identify/call are stubbed for Phases 3/4 14 new tests (parser tokens/intermix/errors, byte_space, dispatch). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
53 lines
1.9 KiB
Python
53 lines
1.9 KiB
Python
"""Numeric entry helpers: byte-group spacing for hex/binary input and the prompt_toolkit key
|
|
bindings that toggle entry mode (Ctrl-/) and auto-space digits as you type.
|
|
|
|
The pure ``byte_space`` / ``group_size`` functions carry the logic and are unit-tested; the key
|
|
bindings are thin wiring exercised in the live REPL.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
HEX = "hex"
|
|
BIN = "bin"
|
|
_DIGITS = {HEX: set("0123456789abcdefABCDEF"), BIN: set("01")}
|
|
|
|
|
|
def group_size(mode: str) -> int:
|
|
"""Characters per byte group: 2 for hex, 8 for binary."""
|
|
return 2 if mode == HEX else 8
|
|
|
|
|
|
def byte_space(text: str, mode: str = HEX) -> str:
|
|
"""Re-group a run of hex/binary digits into space-separated byte groups.
|
|
|
|
Leaves a token that carries an explicit ``0x``/``0b`` prefix untouched (so intermixed input
|
|
isn't mangled); only a bare digit run is regrouped."""
|
|
if "x" in text.lower() or "b" in text.lower():
|
|
return text
|
|
n = group_size(mode)
|
|
compact = text.replace(" ", "")
|
|
return " ".join(compact[i:i + n] for i in range(0, len(compact), n))
|
|
|
|
|
|
def install_key_bindings(kb, session) -> None:
|
|
"""Wire Ctrl-/ (toggle entry mode) and live auto-byte-spacing of digit input onto ``kb``.
|
|
|
|
``session`` is the :class:`~pm3py.cli.rawcli.session.RawSession` whose ``entry_mode`` is
|
|
toggled and read."""
|
|
from prompt_toolkit.document import Document
|
|
|
|
@kb.add("c-/")
|
|
def _toggle(event):
|
|
session.toggle_entry_mode()
|
|
event.app.invalidate() # redraw the breadcrumb
|
|
|
|
def _regroup_after(event):
|
|
buf = event.current_buffer
|
|
buf.insert_text(event.data)
|
|
# only auto-space a bare digit run (no prefix), matching byte_space's guard
|
|
grouped = byte_space(buf.text, session.entry_mode)
|
|
if grouped != buf.text:
|
|
buf.document = Document(grouped, len(grouped))
|
|
|
|
for ch in sorted(_DIGITS[HEX] | _DIGITS[BIN]):
|
|
kb.add(ch)(_regroup_after)
|