feat(rawcli): ipython-style completion (Phase 6)
- completer.py: RawCompleter completes the leading command token — control verbs + the identified transponder's catalog commands — with each command's help as the completion meta (tooltip). `help <cmd>` completes catalog command names. - app: wire the completer with complete_while_typing (live menu) + AutoSuggestFromHistory (inline hints) for the ipython feel. Completes the 6-phase rawcli plan. 4 new tests (verb/catalog completion, tooltips, help-arg completion). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,7 @@ from pm3py.cli.rawcli.entry import byte_space
|
||||
from pm3py.cli.rawcli.identify import identify, clear, name_14a
|
||||
from pm3py.cli.rawcli.catalog import TYPE2, ISO15, catalog_for, catalog_for as _cf
|
||||
from pm3py.cli.rawcli.tlv import parse_tlv, format_tlv
|
||||
from pm3py.cli.rawcli.completer import RawCompleter
|
||||
from pm3py.cli.rawcli.app import dispatch
|
||||
|
||||
_ANSI = re.compile(r"\x1b\[[0-9;]*m")
|
||||
@@ -296,3 +297,32 @@ class TestTLV:
|
||||
def test_tlv_command(self, capsys):
|
||||
dispatch(RawSession(), "tlv " + self.BLOCK.hex())
|
||||
assert "NDEF MESSAGE" in capsys.readouterr().out
|
||||
|
||||
|
||||
class TestCompleter:
|
||||
def _complete(self, session, text):
|
||||
from prompt_toolkit.document import Document
|
||||
return list(RawCompleter(session).get_completions(Document(text), None))
|
||||
|
||||
def test_completes_control_verbs(self):
|
||||
cs = self._complete(RawSession(), "ide")
|
||||
assert any(c.text == "identify" for c in cs)
|
||||
|
||||
def test_completes_catalog_commands_with_meta(self):
|
||||
s = RawSession()
|
||||
s.protocol, s.transponder = "hf14a", "NTAG215" # -> Type 2 catalog
|
||||
cs = self._complete(s, "REA")
|
||||
texts = [c.text for c in cs]
|
||||
assert "READ(" in texts
|
||||
read = next(c for c in cs if c.text == "READ(")
|
||||
assert "0x30" in read.display_meta_text # tooltip = help
|
||||
|
||||
def test_no_catalog_before_identify(self):
|
||||
cs = self._complete(RawSession(), "REA")
|
||||
assert all(c.text != "READ(" for c in cs) # no tag => no catalog commands
|
||||
|
||||
def test_help_argument_completes_command_names(self):
|
||||
s = RawSession()
|
||||
s.protocol, s.transponder = "hf14a", "NTAG215"
|
||||
cs = self._complete(s, "help GET")
|
||||
assert any(c.text == "GET_VERSION" for c in cs)
|
||||
|
||||
Reference in New Issue
Block a user