Fix duplicate commands in fuzzy help (#2798)

* Fix duplicate commands in fuzzy help

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>

* Use help command's filter for all fuzzy

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
This commit is contained in:
Toby Harradine 2019-06-28 03:31:44 +10:00 committed by Michael H
parent 461f56bca1
commit f3bbfdc64d
3 changed files with 25 additions and 14 deletions

View File

@ -417,8 +417,9 @@ class RedHelpFormatter:
pages = [box(p) for p in pagify(to_page)]
await self.send_pages(ctx, pages, embed=False)
@staticmethod
async def help_filter_func(
self, ctx, objects: Iterable[SupportsCanSee], bypass_hidden=False
ctx, objects: Iterable[SupportsCanSee], bypass_hidden=False
) -> AsyncIterator[SupportsCanSee]:
"""
This does most of actual filtering.
@ -450,7 +451,7 @@ class RedHelpFormatter:
"""
Sends an error, fuzzy help, or stays quiet based on settings
"""
coms = [c async for c in self.help_filter_func(ctx, ctx.bot.walk_commands())]
coms = {c async for c in self.help_filter_func(ctx, ctx.bot.walk_commands())}
fuzzy_commands = await fuzzy_command_search(ctx, help_for, commands=coms, min_score=75)
use_embeds = await ctx.embed_requested()
if fuzzy_commands:

View File

@ -13,6 +13,7 @@ import pkg_resources
from colorama import Fore, Style, init
from pkg_resources import DistributionNotFound
from redbot.core.commands import RedHelpFormatter
from .. import __version__ as red_version, version_info as red_version_info, VersionInfo
from . import commands
from .config import get_latest_confs
@ -201,7 +202,12 @@ def init_events(bot, cli_flags):
bot._last_exception = exception_log
await ctx.send(inline(message))
elif isinstance(error, commands.CommandNotFound):
fuzzy_commands = await fuzzy_command_search(ctx)
fuzzy_commands = await fuzzy_command_search(
ctx,
commands={
c async for c in RedHelpFormatter.help_filter_func(ctx, bot.walk_commands())
},
)
if not fuzzy_commands:
pass
elif await ctx.embed_requested():

View File

@ -19,14 +19,18 @@ from typing import (
Tuple,
TypeVar,
Union,
Set,
TYPE_CHECKING,
)
import discord
from fuzzywuzzy import fuzz, process
from redbot.core import commands
from .chat_formatting import box
if TYPE_CHECKING:
from ..commands import Command, Context
__all__ = [
"bounded_gather",
"safe_delete",
@ -180,12 +184,12 @@ async def async_enumerate(
async def fuzzy_command_search(
ctx: commands.Context,
ctx: "Context",
term: Optional[str] = None,
*,
commands: Optional[list] = None,
commands: Optional[Set["Command"]] = None,
min_score: int = 80,
) -> Optional[List[commands.Command]]:
) -> Optional[List["Command"]]:
"""Search for commands which are similar in name to the one invoked.
Returns a maximum of 5 commands which must all be at least matched
@ -196,8 +200,11 @@ async def fuzzy_command_search(
ctx : `commands.Context <redbot.core.commands.Context>`
The command invocation context.
term : Optional[str]
The name of the invoked command. If ``None``, `Context.invoked_with`
will be used instead.
The name of the invoked command. If ``None``,
`Context.invoked_with` will be used instead.
commands : Optional[Set[commands.Command]]
The commands available to choose from when doing a fuzzy match.
When omitted, `Bot.walk_commands` will be used instead.
min_score : int
The minimum score for matched commands to reach. Defaults to 80.
@ -239,7 +246,7 @@ async def fuzzy_command_search(
# Do the scoring. `extracted` is a list of tuples in the form `(command, score)`
extracted = process.extract(
term, (commands or ctx.bot.walk_commands()), limit=5, scorer=fuzz.QRatio
term, (commands or set(ctx.bot.walk_commands())), limit=5, scorer=fuzz.QRatio
)
if not extracted:
return
@ -257,10 +264,7 @@ async def fuzzy_command_search(
async def format_fuzzy_results(
ctx: commands.Context,
matched_commands: List[commands.Command],
*,
embed: Optional[bool] = None,
ctx: "Context", matched_commands: List["Command"], *, embed: Optional[bool] = None
) -> Union[str, discord.Embed]:
"""Format the result of a fuzzy command search.