aboutsummaryrefslogtreecommitdiffstats
path: root/bot/exts/core/help.py
diff options
context:
space:
mode:
authorGravatar ChrisJL <[email protected]>2022-08-18 17:52:36 +0100
committerGravatar GitHub <[email protected]>2022-08-18 17:52:36 +0100
commit96f84a147c5e862d6153f48b2de83613aa3bd654 (patch)
tree6962c76ff7b9a9b8b732e5663b807e4a3d70f2de /bot/exts/core/help.py
parentadd more packages to .latex (diff)
parentHelp command fix, normalize suggestions for unknown commands (#1064) (diff)
Merge branch 'main' into feat/latex-enhancement
Diffstat (limited to 'bot/exts/core/help.py')
-rw-r--r--bot/exts/core/help.py40
1 files changed, 28 insertions, 12 deletions
diff --git a/bot/exts/core/help.py b/bot/exts/core/help.py
index f9b3513f..b5df70ca 100644
--- a/bot/exts/core/help.py
+++ b/bot/exts/core/help.py
@@ -3,16 +3,16 @@ import asyncio
import itertools
import logging
from contextlib import suppress
-from typing import NamedTuple, Union
+from typing import NamedTuple, Optional, Union
from discord import Colour, Embed, HTTPException, Message, Reaction, User
from discord.ext import commands
from discord.ext.commands import CheckFailure, Cog as DiscordCog, Command, Context
-from rapidfuzz import process
from bot import constants
from bot.bot import Bot
from bot.constants import Emojis
+from bot.utils.commands import get_command_suggestions
from bot.utils.pagination import FIRST_EMOJI, LAST_EMOJI, LEFT_EMOJI, LinePaginator, RIGHT_EMOJI
DELETE_EMOJI = Emojis.trashcan
@@ -41,14 +41,18 @@ class HelpQueryNotFound(ValueError):
"""
Raised when a HelpSession Query doesn't match a command or cog.
- Contains the custom attribute of ``possible_matches``.
- Instances of this object contain a dictionary of any command(s) that were close to matching the
- query, where keys are the possible matched command names and values are the likeness match scores.
+ Params:
+ possible_matches: list of similar command names.
+ parent_command: parent command of an invalid subcommand. Only available when an invalid subcommand
+ has been passed.
"""
- def __init__(self, arg: str, possible_matches: dict = None):
+ def __init__(
+ self, arg: str, possible_matches: Optional[list[str]] = None, *, parent_command: Optional[Command] = None
+ ) -> None:
super().__init__(arg)
self.possible_matches = possible_matches
+ self.parent_command = parent_command
class HelpSession:
@@ -153,12 +157,17 @@ class HelpSession:
Will pass on possible close matches along with the `HelpQueryNotFound` exception.
"""
- # Combine command and cog names
- choices = list(self._bot.all_commands) + list(self._bot.cogs)
+ # Check if parent command is valid in case subcommand is invalid.
+ if " " in query:
+ parent, *_ = query.split()
+ parent_command = self._bot.get_command(parent)
+
+ if parent_command:
+ raise HelpQueryNotFound('Invalid Subcommand.', parent_command=parent_command)
- result = process.extract(query, choices, score_cutoff=90)
+ similar_commands = get_command_suggestions(list(self._bot.all_commands.keys()), query)
- raise HelpQueryNotFound(f'Query "{query}" not found.', dict(result))
+ raise HelpQueryNotFound(f'Query "{query}" not found.', similar_commands)
async def timeout(self, seconds: int = 30) -> None:
"""Waits for a set number of seconds, then stops the help session."""
@@ -507,13 +516,20 @@ class Help(DiscordCog):
try:
await HelpSession.start(ctx, *commands)
except HelpQueryNotFound as error:
+
+ # Send help message of parent command if subcommand is invalid.
+ if cmd := error.parent_command:
+ await ctx.send(str(error))
+ await self.new_help(ctx, cmd.qualified_name)
+ return
+
embed = Embed()
embed.colour = Colour.red()
embed.title = str(error)
if error.possible_matches:
- matches = "\n".join(error.possible_matches.keys())
- embed.description = f"**Did you mean:**\n`{matches}`"
+ matches = "\n".join(error.possible_matches)
+ embed.description = f"**Did you mean:**\n{matches}"
await ctx.send(embed=embed)