diff --git a/bot.py b/bot.py index c4db334..4073a19 100644 --- a/bot.py +++ b/bot.py @@ -6,6 +6,7 @@ import traceback import yaml from discord.ext import commands +from discord.ext.commands.view import StringView from cogs.utils.settings import Settings from cogs.utils.localizer import Localizer from cogs.utils.localizer import LocalizerWrapper @@ -90,11 +91,13 @@ class Bot(commands.Bot): async def process_commands(self, message): ctx = await self.get_context(message, cls=Context) - if not ctx.command: - command = self.aliaser.get_command(ctx.locale, ctx.invoked_with) - if command is not None: - ctx.command = self.get_command(command) + # Replace aliases with commands + ctx = self.aliaser.get_command(ctx) + if ctx.command and isinstance(ctx.command, commands.GroupMixin): + ctx = self.aliaser.subcommand_from_alias(ctx, ctx.command) + + # Add the localizer if ctx.command and ctx.command.cog_name: ctx.localizer = LocalizerWrapper(self.localizer, ctx.locale, ctx.command.cog_name.lower()) else: diff --git a/cogs/utils/alias.py b/cogs/utils/alias.py index 252c011..c5cf2fe 100644 --- a/cogs/utils/alias.py +++ b/cogs/utils/alias.py @@ -1,7 +1,11 @@ +import discord import yaml + from glob import glob from os import path +from discord.ext import commands + class Aliaser: def __init__(self, localization_folder, default_lang): self.localization_folder = path.realpath(localization_folder) @@ -30,10 +34,49 @@ class Aliaser: data = yaml.load(f) self.localization_table[lang] = {'aliases': data, 'commands': self._invert(data)} - def get_command(self, locale, alias): + def cmd_from_alias(self, locale, alias, default=None): locale = self.localization_table[locale] - return locale['commands'].get(alias, None) + return locale['commands'].get(alias, default) def get_alias(self, locale, command): locale = self.localization_table[locale] - return locale['aliases'].get(command, []) \ No newline at end of file + return locale['aliases'].get(command, []) + + def get_command(self, ctx): + ctx.view.undo() + alias = ctx.view.get_word() + command = self.cmd_from_alias(ctx.locale, alias, alias) + ctx.invoked_with = command + ctx.command = ctx.bot.all_commands.get(command) + return ctx + + def subcommand_from_alias(self, ctx, group): + """ Recursicely replaces all subcommand aliases with subcommands.""" + view = ctx.view + prev = view.previous + idx = view.index + + # get the alias used + view.skip_ws() + alias = view.get_word() + subcmd = self.cmd_from_alias(ctx.locale, alias, alias) + + # Replace the alias in the command + view.buffer = view.buffer.replace(alias, subcmd) + + # Update the view to account for difference in length + strdiff = len(subcmd) - len(alias) + view.end += strdiff + view.index += strdiff + + # Get the subcommand + sub = group.all_commands.get(subcmd, None) + + # Translate any subsubcommands + if sub and isinstance(sub, commands.GroupMixin): + self.subcommand_from_alias(ctx, sub) + + # Reset the view indexes + view.index = idx + view.previous = prev + return ctx \ No newline at end of file