From b6d797e53f6553eca4b015b3d2d8cf998f2d169a Mon Sep 17 00:00:00 2001 From: Florent Date: Thu, 30 Oct 2025 23:32:32 +0100 Subject: [PATCH] completion for slash commands --- pyproject.toml | 2 +- src/meshcore_cli/meshcore_cli.py | 58 +++++++++++++++++++++++++------- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 7e1ab5c..76d6358 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "meshcore-cli" -version = "1.1.41" +version = "1.2.0" authors = [ { name="Florent de Lamotte", email="florent@frizoncorrea.fr" }, ] diff --git a/src/meshcore_cli/meshcore_cli.py b/src/meshcore_cli/meshcore_cli.py index 2942453..cc97a4d 100644 --- a/src/meshcore_cli/meshcore_cli.py +++ b/src/meshcore_cli/meshcore_cli.py @@ -33,7 +33,7 @@ import re from meshcore import MeshCore, EventType, logger # Version -VERSION = "v1.1.41" +VERSION = "v1.2.0" # default ble address is stored in a config file MCCLI_CONFIG_DIR = str(Path.home()) + "/.config/meshcore/" @@ -307,11 +307,22 @@ async def subscribe_to_msgs(mc, json_output=False, above=False): await mc.start_auto_message_fetching() # redefine get_completion to let user put symbols in first item +# and handle navigating in path ... class MyNestedCompleter(NestedCompleter): def get_completions( self, document, complete_event): - if not " " in document.text_before_cursor.lstrip(): + txt = document.text_before_cursor.lstrip() + if not " " in txt: + if txt != "" and txt[0] == "/" and txt.count("/") == 1: + opts = [] + for k in self.options.keys(): + if k[0] == "/" : + v = "/" + k.split("/")[1] + ("/" if k.count("/") == 2 else "") + if v not in opts: + opts.append(v) + else: + opts = self.options.keys() completer = WordCompleter( - list(self.options.keys()), ignore_case=self.ignore_case, + opts, ignore_case=self.ignore_case, pattern=re.compile(r"([a-zA-Z0-9_\\/]+|[^a-zA-Z0-9_\s]+)")) yield from completer.get_completions(document, complete_event) else: # normal behavior for remainder @@ -566,16 +577,36 @@ def make_completion_dict(contacts, pending={}, to=None, channels=None): completion_list.update({ "send" : None, }) - if to['type'] == 1 : completion_list.update(client_completion_list) - - if to['type'] > 1 : # repeaters and room servers + if to['type'] == 2 or to['type'] == 3 : # repeaters and room servers completion_list.update(repeater_completion_list) - if (to['type'] == 4) : #specific to sensors completion_list.update(sensor_completion_list) + slash_root_completion_list = {} + for k,v in root_completion_list.items(): + slash_root_completion_list["/"+k]=v + + completion_list.update(slash_root_completion_list) + + slash_contacts_completion_list = {} + for k,v in contacts.items(): + d={} + if v["type"] == 1: + l = client_completion_list + elif v["type"] == 2 or v["type"] == 3: + l = repeater_completion_list + elif v["type"] == 4: + l = sensor_completion_list + + for kk, vv in l.items(): + d["/" + v["adv_name"] + "/" + kk] = vv + + slash_contacts_completion_list.update(d) + + completion_list.update(slash_contacts_completion_list) + completion_list.update({ "script" : None, "quit" : None @@ -700,6 +731,10 @@ Line starting with \"$\" or \".\" will issue a meshcli command. pass # raw meshcli command as on command line + elif line.startswith("$") : + args = shlex.split(line[1:]) + await process_cmds(mc, args) + elif line.startswith("/") : path = line.split(" ", 1)[0] if path.count("/") == 1: @@ -713,11 +748,10 @@ Line starting with \"$\" or \".\" will issue a meshcli command. print(f"{contact_name} is not a contact") else: if not await process_contact_chat_line(mc, tct, cmdline): - print(f"{cmdline} not found for {contact_name}") - - elif line.startswith("$") : - args = shlex.split(line[1:]) - await process_cmds(mc, args) + if tct["type"] == 1: + last_ack = await msg_ack(mc, tct, cmdline) + else : + await process_cmds(mc, ["cmd", tct["adv_name"], cmdline]) elif line.startswith("to ") : # dest dest = line[3:]