Skip to content

Commit a0e6612

Browse files
authored
Merge pull request #361 from zeffo/autocontext
Add AutocompleteContext for autocomplete callbacks
1 parent 6c45c44 commit a0e6612

File tree

3 files changed

+50
-6
lines changed

3 files changed

+50
-6
lines changed

discord/commands/commands.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
from ..member import Member
3737
from ..user import User
3838
from ..message import Message
39-
from .context import ApplicationContext
39+
from .context import ApplicationContext, AutocompleteContext
4040
from ..utils import find, get_or_fetch, async_all
4141
from ..errors import ValidationError, ClientException
4242
from .errors import ApplicationCommandError, CheckFailure, ApplicationCommandInvokeError
@@ -500,10 +500,8 @@ async def invoke_autocomplete_callback(self, interaction: Interaction):
500500
i["name"]:i["value"]
501501
for i in interaction.data["options"]
502502
})
503-
# This will only pass args depending on the argcount
504-
arg_count = option.autocomplete.__code__.co_argcount
505-
args = [interaction, op.get("value", None), values][:arg_count]
506-
result = await option.autocomplete(*args)
503+
ctx = AutocompleteContext(interaction, command=self, focused=option, value=op.get("value"), options=values)
504+
result = await option.autocomplete(ctx)
507505
choices = [
508506
o if isinstance(o, OptionChoice) else OptionChoice(o)
509507
for o in result

discord/commands/context.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
import discord
3333
from discord.state import ConnectionState
3434

35-
from .commands import ApplicationCommand
35+
from .commands import ApplicationCommand, Option
3636
from ..cog import Cog
3737

3838
from ..guild import Guild
@@ -142,3 +142,34 @@ def cog(self) -> Optional[Cog]:
142142
return None
143143

144144
return self.command.cog
145+
146+
147+
class AutocompleteContext:
148+
"""Represents context for a slash command's option autocomplete.
149+
150+
This class is not created manually and is instead passed to an Option's autocomplete callback.
151+
152+
.. versionadded:: 2.0
153+
154+
Attributes
155+
-----------
156+
interaction: :class:`.Interaction`
157+
The interaction object that invoked the autocomplete.
158+
command: :class:`.ApplicationCommand`
159+
The command that this context belongs to.
160+
focused: :class:`.Option`
161+
The option the user is currently typing.
162+
value: :class:`.str`
163+
The content of the focused option.
164+
options :class:`.dict`
165+
A name to value mapping of the options that the user has selected before this option.
166+
"""
167+
168+
__slots__ = ("interaction", "command", "focused", "value", "options")
169+
170+
def __init__(self, interaction: Interaction, *, command: ApplicationCommand, focused: Option, value: str, options: dict) -> None:
171+
self.interaction = interaction
172+
self.command = command
173+
self.focused = focused
174+
self.value = value
175+
self.options = options

discord/utils.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
'escape_mentions',
8686
'as_chunks',
8787
'format_dt',
88+
'basic_autocomplete'
8889
)
8990

9091
DISCORD_EPOCH = 1420070400000
@@ -128,6 +129,7 @@ def __get__(self, instance, owner):
128129
from .abc import Snowflake
129130
from .invite import Invite
130131
from .template import Template
132+
from .commands.context import AutocompleteContext
131133

132134
class _RequestLike(Protocol):
133135
headers: Mapping[str, Any]
@@ -1027,3 +1029,16 @@ def format_dt(dt: datetime.datetime, /, style: Optional[TimestampStyle] = None)
10271029
if style is None:
10281030
return f'<t:{int(dt.timestamp())}>'
10291031
return f'<t:{int(dt.timestamp())}:{style}>'
1032+
1033+
def basic_autocomplete(*values):
1034+
"""A helper function to make a basic autocomplete for slash commands. This is a pretty standard autocomplete and
1035+
will return any options that start with the value from the user, case insensitive.
1036+
.. versionadded:: 2.0
1037+
Parameters
1038+
-----------
1039+
values: `str`
1040+
Possible values for the option."""
1041+
async def autocomplete_callback(ctx: AutocompleteContext):
1042+
return [x for x in values if x.lower().startswith(ctx.value.lower())]
1043+
1044+
return autocomplete_callback

0 commit comments

Comments
 (0)