feat(rawcli): render page-argument completion in the active entry mode
The memory-map completion for a page/block argument now follows the entry mode instead of always emitting hex: hex mode READ( -> 0x04 user memory binary mode READ( -> 0b00000100 user memory (full 8 bits — each bit visible) Matching narrows in the same base (a binary partial filters bit-prefix-wise), and a 0x/0b prefix on the argument overrides the session mode. Binary matters here because for the config pages each bit carries its own meaning (CFG0 AUTH0, CFG1 PROT/CFGLCK/AUTHLIM), so seeing the whole pattern is the point. Hardware-verified against a real NTAG216 in binary mode (0b00000000..0b11100110 with roles). Tests for binary rendering, bit-prefix filtering, and prefix-override. 1271 green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -65,23 +65,39 @@ class RawCompleter(Completer):
|
||||
yield from self._catalog_names(word)
|
||||
|
||||
def _page_arg(self, cmd_name: str, partial: str):
|
||||
"""Complete a page/block argument with the identified tag's memory landmarks, so
|
||||
``READ(`` lists ``0x00 → UID``, ``0x03 → CC``, ``0xE3 → CFG0`` … as suggestions."""
|
||||
"""Complete a page/block argument with the identified tag's memory landmarks, rendered in
|
||||
the active entry mode — ``0x04`` in hex, ``0b00000100`` in binary (every bit visible,
|
||||
since for config pages each bit carries its own meaning). ``READ(`` lists the whole map;
|
||||
typing narrows it. A ``0x``/``0b`` prefix on the argument overrides the session mode."""
|
||||
catalog = catalog_for(self._session)
|
||||
if catalog is None:
|
||||
return
|
||||
tc = catalog.get(cmd_name)
|
||||
if tc is None or not tc.params or tc.params[0] not in ("page", "block"):
|
||||
return
|
||||
low = partial.lower()
|
||||
mode = self._arg_mode(partial)
|
||||
body = partial.lower()
|
||||
if body.startswith(("0x", "0b")):
|
||||
body = body[2:]
|
||||
for page, role in landmark_pages(self._session.transponder):
|
||||
val = f"0x{page:02X}"
|
||||
forms = (val.lower(), f"{page:x}", f"{page:02x}", str(page)) # 0x-, bare-hex, decimal
|
||||
if low and not any(f.startswith(low) for f in forms):
|
||||
if mode == "bin":
|
||||
val, forms = f"0b{page:08b}", (f"{page:08b}", f"{page:b}")
|
||||
else:
|
||||
val, forms = f"0x{page:02X}", (f"{page:02x}", f"{page:x}", str(page))
|
||||
if body and not any(f.startswith(body) for f in forms):
|
||||
continue
|
||||
yield Completion(val, start_position=-len(partial),
|
||||
display=f"{val} {role}", display_meta=role)
|
||||
|
||||
def _arg_mode(self, partial: str) -> str:
|
||||
"""hex/bin for an argument token — a 0x/0b prefix wins, else the session entry mode."""
|
||||
low = partial.lower()
|
||||
if low.startswith("0x"):
|
||||
return "hex"
|
||||
if low.startswith("0b"):
|
||||
return "bin"
|
||||
return "bin" if getattr(self._session, "entry_mode", "hex") == "bin" else "hex"
|
||||
|
||||
def _first_token(self, word: str):
|
||||
low = word.lower()
|
||||
for verb in sorted(CONTROL_VERBS):
|
||||
|
||||
Reference in New Issue
Block a user