mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 11:18:54 -05:00
[V3 Alias] Customize Parameters (#2455)
* [alias] custom parameters Signed-off-by: zephyrkul <zephyrkul@users.noreply.github.com> * [alias] quoted words remain quoted Signed-off-by: zephyrkul <zephyrkul@users.noreply.github.com> * [alias] fix no-parameter aliases Signed-off-by: zephyrkul <zephyrkul@users.noreply.github.com> * [alias] remove unneeded error dispatch it was expensive and did nothing anyway from my own testing
This commit is contained in:
parent
82cda4b57a
commit
d6d6d14977
@ -1,8 +1,10 @@
|
||||
from copy import copy
|
||||
from re import search
|
||||
from re import findall, search
|
||||
from string import Formatter
|
||||
from typing import Generator, Tuple, Iterable, Optional
|
||||
|
||||
import discord
|
||||
from discord.ext.commands.view import StringView, quoted_word
|
||||
from redbot.core import Config, commands, checks
|
||||
from redbot.core.i18n import Translator, cog_i18n
|
||||
from redbot.core.utils.chat_formatting import box
|
||||
@ -13,6 +15,21 @@ from .alias_entry import AliasEntry
|
||||
_ = Translator("Alias", __file__)
|
||||
|
||||
|
||||
class _TrackingFormatter(Formatter):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.max = -1
|
||||
|
||||
def get_value(self, key, args, kwargs):
|
||||
if isinstance(key, int):
|
||||
self.max = max((key, self.max))
|
||||
return super().get_value(key, args, kwargs)
|
||||
|
||||
|
||||
class ArgParseError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@cog_i18n(_)
|
||||
class Alias(commands.Cog):
|
||||
"""Create aliases for commands.
|
||||
@ -80,8 +97,25 @@ class Alias(commands.Cog):
|
||||
return not bool(search(r"\s", alias_name)) and alias_name.isprintable()
|
||||
|
||||
async def add_alias(
|
||||
self, ctx: commands.Context, alias_name: str, command: Tuple[str], global_: bool = False
|
||||
self, ctx: commands.Context, alias_name: str, command: str, global_: bool = False
|
||||
) -> AliasEntry:
|
||||
indices = findall(r"{(\d*)}", command)
|
||||
if indices:
|
||||
try:
|
||||
indices = [int(a[0]) for a in indices]
|
||||
except IndexError:
|
||||
raise ArgParseError(_("Arguments must be specified with a number."))
|
||||
low = min(indices)
|
||||
indices = [a - low for a in indices]
|
||||
high = max(indices)
|
||||
gaps = set(indices).symmetric_difference(range(high + 1))
|
||||
if gaps:
|
||||
raise ArgParseError(
|
||||
_("Arguments must be sequential. Missing arguments: ")
|
||||
+ ", ".join(str(i + low) for i in gaps)
|
||||
)
|
||||
command = command.format(*(f"{{{i}}}" for i in range(-low, high + low + 1)))
|
||||
|
||||
alias = AliasEntry(alias_name, command, ctx.author, global_=global_)
|
||||
|
||||
if global_:
|
||||
@ -142,7 +176,17 @@ class Alias(commands.Cog):
|
||||
:return:
|
||||
"""
|
||||
known_content_length = len(prefix) + len(alias.name)
|
||||
extra = message.content[known_content_length:].strip()
|
||||
extra = message.content[known_content_length:]
|
||||
view = StringView(extra)
|
||||
view.skip_ws()
|
||||
extra = []
|
||||
while not view.eof:
|
||||
prev = view.index
|
||||
word = quoted_word(view)
|
||||
if len(word) < view.index - prev:
|
||||
word = "".join((view.buffer[prev], word, view.buffer[view.index - 1]))
|
||||
extra.append(word)
|
||||
view.skip_ws()
|
||||
return extra
|
||||
|
||||
async def maybe_call_alias(
|
||||
@ -167,10 +211,18 @@ class Alias(commands.Cog):
|
||||
|
||||
async def call_alias(self, message: discord.Message, prefix: str, alias: AliasEntry):
|
||||
new_message = copy(message)
|
||||
try:
|
||||
args = self.get_extra_args_from_alias(message, prefix, alias)
|
||||
except commands.BadArgument as bae:
|
||||
return
|
||||
|
||||
trackform = _TrackingFormatter()
|
||||
command = trackform.format(alias.command, *args)
|
||||
|
||||
# noinspection PyDunderSlots
|
||||
new_message.content = "{}{} {}".format(prefix, alias.command, args)
|
||||
new_message.content = "{}{} {}".format(
|
||||
prefix, command, " ".join(args[trackform.max + 1 :])
|
||||
)
|
||||
await self.bot.process_commands(new_message)
|
||||
|
||||
@commands.group()
|
||||
@ -228,7 +280,10 @@ class Alias(commands.Cog):
|
||||
# At this point we know we need to make a new alias
|
||||
# and that the alias name is valid.
|
||||
|
||||
try:
|
||||
await self.add_alias(ctx, alias_name, command)
|
||||
except ArgParseError as e:
|
||||
return await ctx.send(" ".join(e.args))
|
||||
|
||||
await ctx.send(
|
||||
_("A new alias with the trigger `{name}` has been created.").format(name=alias_name)
|
||||
@ -274,7 +329,10 @@ class Alias(commands.Cog):
|
||||
return
|
||||
# endregion
|
||||
|
||||
try:
|
||||
await self.add_alias(ctx, alias_name, command, global_=True)
|
||||
except ArgParseError as e:
|
||||
return await ctx.send(" ".join(e.args))
|
||||
|
||||
await ctx.send(
|
||||
_("A new global alias with the trigger `{name}` has been created.").format(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user