diff --git a/src/niobot/client.py b/src/niobot/client.py index 7e40f0a..c74e88c 100644 --- a/src/niobot/client.py +++ b/src/niobot/client.py @@ -262,7 +262,7 @@ async def process_message(self, room: nio.MatrixRoom, event: nio.RoomMessageText else: content = event.body - def get_prefix(c) -> typing.Union[str, None]: + def get_prefix(c: str) -> typing.Union[str, None]: if isinstance(self.command_prefix, re.Pattern): _m = re.match(self.command_prefix, c) if _m: @@ -271,10 +271,10 @@ def get_prefix(c) -> typing.Union[str, None]: if c.startswith(self.command_prefix): return self.command_prefix - _p = get_prefix(content) - if get_prefix(content): + matched_prefix = get_prefix(content) + if matched_prefix: try: - command = original_command = content[len(_p) :].splitlines()[0].split(" ")[0] + command = original_command = content[len(matched_prefix) :].splitlines()[0].split(" ")[0] except IndexError: self.log.info( "Failed to parse message %r - message terminated early (was the content *just* the prefix?)", @@ -288,7 +288,13 @@ def get_prefix(c) -> typing.Union[str, None]: self.dispatch("command_error", command, error) return - context = command.construct_context(self, room, event, self.command_prefix + original_command) + context = command.construct_context( + self, + room=room, + src_event=event, + invoking_prefix=matched_prefix, + meta=matched_prefix + original_command, + ) self.dispatch("command", context) def _task_callback(t: asyncio.Task): diff --git a/src/niobot/commands.py b/src/niobot/commands.py index f3051d8..886ba8c 100644 --- a/src/niobot/commands.py +++ b/src/niobot/commands.py @@ -306,7 +306,13 @@ async def invoke(self, ctx: Context) -> typing.Coroutine: return self.callback(*parsed_args) def construct_context( - self, client: "NioBot", room: nio.MatrixRoom, src_event: nio.RoomMessageText, meta: str, cls: type = Context + self, + client: "NioBot", + room: nio.MatrixRoom, + src_event: nio.RoomMessageText, + invoking_prefix: str, + meta: str, + cls: type = Context, ) -> Context: """ Constructs the context for the current command. @@ -316,13 +322,14 @@ def construct_context( :param client: The current instance of the client. :param room: The room the command was invoked in. :param src_event: The source event that triggered the command. Must be `nio.RoomMessageText`. + :param invoking_prefix: The prefix that triggered the command. :param meta: The invoking string (usually the command name, however may be an alias instead) :param cls: The class to construct the context with. Defaults to `Context`. :return: The constructed Context. """ if not isinstance(src_event, (nio.RoomMessageText, nio.RoomMessageNotice)): raise TypeError("src_event must be a textual event (i.e. m.text or m.notice).") - return cls(client, room, src_event, self, invoking_string=meta) + return cls(client, room, src_event, self, invoking_prefix=invoking_prefix, invoking_string=meta) def command(name: str = None, **kwargs) -> callable: diff --git a/src/niobot/context.py b/src/niobot/context.py index 8ff377f..148957b 100644 --- a/src/niobot/context.py +++ b/src/niobot/context.py @@ -83,6 +83,7 @@ def __init__( event: nio.RoomMessageText, command: "Command", *, + invoking_prefix: typing.Optional[str] = None, invoking_string: str = None, ): self._init_ts = time.time() @@ -90,8 +91,10 @@ def __init__( self._room = room self._event = event self._command = command + self.invoking_prefix = invoking_prefix self._invoking_string = invoking_string to_parse = event.body + if invoking_string: try: to_parse = event.body[len(invoking_string) :] diff --git a/src/niobot/utils/help_command.py b/src/niobot/utils/help_command.py index 37be398..d58dc14 100644 --- a/src/niobot/utils/help_command.py +++ b/src/niobot/utils/help_command.py @@ -116,6 +116,7 @@ def get_long_description(command: "Command") -> str: async def default_help_command(ctx: "Context"): """Displays help text""" lines = [] + prefix = ctx.invoking_prefix or "[p]" if not ctx.args: added = [] # Display global help. @@ -123,7 +124,7 @@ async def default_help_command(ctx: "Context"): for command in ctx.client._commands.values(): if command in added or command.disabled is True: continue - display = format_command_line(ctx.client.command_prefix, command) + display = format_command_line(prefix, command) description = get_short_description(command) lines.append("* `{}`: {}".format(display, description)) added.append(command) @@ -133,7 +134,7 @@ async def default_help_command(ctx: "Context"): if not command: return await ctx.respond("No command with that name found!") - display = format_command_line(ctx.client.command_prefix, command) + display = format_command_line(prefix, command) description = get_long_description(command) lines = ["* {}:".format(display), *description.splitlines()] await ctx.respond(clean_output("\n".join(lines)))