1 changed files with 268 additions and 0 deletions
@ -0,0 +1,268 @@ |
|||
.. currentmodule:: discord |
|||
|
|||
.. _ext_commands_help: |
|||
|
|||
The Help Command |
|||
=================== |
|||
|
|||
Using The Help Command |
|||
------------------------- |
|||
|
|||
There is a help command made for you. It walks through your commands and formats them like |
|||
``<Command Name> Description``. Commands are then sorted into categories by their Cog. By default, your commands will be |
|||
in ``No Category``, which is always at the bottom of the commands list. |
|||
|
|||
Here is a simple example of the default behaviour: |
|||
|
|||
:: |
|||
|
|||
An example bot to showcase the discord.ext.commands extension module. |
|||
|
|||
There are a number of utility commands being showcased here. |
|||
|
|||
MyCoolCog: |
|||
cool Says if a user is cool. |
|||
No Category: |
|||
add Adds two numbers together. |
|||
choose Chooses between multiple choices. |
|||
help Shows this message |
|||
joined Says when a member joined. |
|||
repeat Repeats a message multiple times. |
|||
roll Rolls a dice in NdN format. |
|||
|
|||
Type !help command for more info on a command. |
|||
You can also type !help category for more info on a category. |
|||
|
|||
You may want to send help if the user doesn't use a command correctly. Here is an example of how to do this: |
|||
|
|||
.. code-block:: python3 |
|||
:caption: sos.py |
|||
:emphasize-lines: 8, 10, 18 |
|||
|
|||
from discord.ext import commands |
|||
|
|||
bot = commands.Bot(command_prefix='!', description="Nothing to worry about here.") |
|||
|
|||
@bot.command() |
|||
async def sos(ctx, what: str = None): |
|||
"""Send Help!""" |
|||
if not what: |
|||
return await ctx.send_help(sos) |
|||
await ctx.send('Sending help for {0}!'.format(what)) |
|||
await ctx.send_help(what) |
|||
|
|||
class MyCoolCog(commands.Cog): |
|||
"""It's OK, we saved the damsel.""" |
|||
|
|||
@commands.command() |
|||
async def damsel(self, ctx): |
|||
"""There's a damsel in distress!""" |
|||
await ctx.send_help(self) # TODO not sure about this change |
|||
|
|||
bot.add_cog(MyCoolCog()) |
|||
|
|||
:meth:`~.commands.Context.send_help` allows you to specify a :class:`~.commands.Command`, :class:`~commands.Cog`, or |
|||
even a regular string. |
|||
|
|||
Let's take a look at this code step by step: |
|||
|
|||
1. In the command ``sos``, there is a parameter called ``what``. |
|||
- If the parameter is not passed, it will send help for itself a :meth:`~.commands.Command` instance. |
|||
- If the parameter is passed, it will attempt to send help for a matching cog name or command. |
|||
- Doing ``!sos damsel`` would invoke :meth:`~.commands.HelpCommand.send_command_help` with ``command`` being |
|||
``damsel``, and send the help for it. |
|||
|
|||
2. In the cog ``MyCoolCog``, there is a docstring provided for help commands. |
|||
|
|||
3. In the command ``damsel``, it will send help for the cog called ``MyCoolCog``. |
|||
- This would send the docstring of ``MyCoolCog``, and its commands. |
|||
|
|||
:: |
|||
|
|||
It's OK, we saved the damsel. |
|||
|
|||
Commands: |
|||
damsel There's a damsel in distress! |
|||
|
|||
Type !help command for more info on a command. |
|||
You can also type !help category for more info on a category. |
|||
|
|||
Replacing The Help Command |
|||
----------------------------- |
|||
|
|||
If you don't like the default help command, you can replace the normal help command by setting |
|||
:attr:`~commands.Bot.help_command` to a subclass of :class:`~.commands.HelpCommand` or ``None`` to remove it. |
|||
|
|||
Here is an example of an alternative help command you can set, :class:`~.commands.MinimalHelpCommand` |
|||
|
|||
.. code-block:: python3 |
|||
:caption: mini_help_bot.py |
|||
:emphasize-lines: 5 |
|||
|
|||
from discord.ext import commands |
|||
|
|||
description = """Hey! I am your local test bot.""" |
|||
bot = commands.Bot(command_prefix='!', description=description, |
|||
help_command=commands.MinimalHelpCommand()) |
|||
|
|||
By default, the help command appears in ``No Category``, which can seem like a bit of a nuisance when categorising |
|||
commands. One way of doing this is by setting the :attr:`~.commands.DefaultHelpCommand.no_category`, an attribute also |
|||
found on :attr:`~.commands.MinimalHelpCommand`. |
|||
|
|||
.. code-block:: python3 |
|||
:emphasize-lines: 4 |
|||
|
|||
from discord.ext import commands |
|||
|
|||
bot = commands.Bot(command_prefix='!', description="There is no saviour.", |
|||
help_command=commands.DefaultHelpCommand(no_category='Help Me!')) |
|||
|
|||
You can also set the :class:`~commands.Cog` of a help command, simply by setting :attr:`~commands.HelpCommand.cog`. |
|||
However, if you plan on having the ability to reload or disable extensions containing cogs, just setting it isn't wise |
|||
idea. |
|||
|
|||
To counter this, you could set the new help command to default, during the teardown of an extension. |
|||
|
|||
.. code-block:: python3 |
|||
:emphasize-lines: 22-23 |
|||
|
|||
from discord.ext import commands |
|||
|
|||
|
|||
class Help(commands.Cog): |
|||
"""This isn't the right place for help.""" |
|||
|
|||
@commands.command() |
|||
async def sos(self, ctx, what: str = None): |
|||
"""Send Help!""" |
|||
if not what: |
|||
return await ctx.send_help(self.sos) |
|||
await ctx.send('Sending help for {0}!'.format(what)) |
|||
await ctx.send_help(what) |
|||
|
|||
|
|||
def setup(bot): |
|||
help_cog = Help() |
|||
bot.add_cog(help_cog) |
|||
bot.help_command = commands.DefaultHelpCommand(no_category='Help.') |
|||
bot.help_command.cog = help_cog |
|||
|
|||
|
|||
def teardown(bot): |
|||
bot.help_command = commands.DefaultHelpCommand() |
|||
|
|||
Here is an example of what you are able to do by subclassing :class:`~.commands.MinimalHelpCommand`: |
|||
|
|||
.. code-block:: python3 |
|||
|
|||
from discord.ext import commands |
|||
|
|||
class MyHelp(commands.MinimalHelpCommand): |
|||
def __init__(self): |
|||
super().__init__(no_category='Misc') |
|||
|
|||
def add_bot_commands_formatting(self, commands, heading): |
|||
if commands: |
|||
joined = ', '.join('`{0}`'.format(c.name) for c in commands) |
|||
self.paginator.add_line('Category: [__**%s**__]' % heading) |
|||
self.paginator.add_line(joined) |
|||
|
|||
bot = commands.Bot(command_prefix='!', help_command=MyHelp()) |
|||
|
|||
Writing A Help Command |
|||
------------------------- |
|||
|
|||
For this tutorial, we will be using the standard :class:`~.commands.HelpCommand`. |
|||
|
|||
|
|||
The Help Command Name |
|||
~~~~~~~~~~~~~~~~~~~~~ |
|||
|
|||
If you would like to use a different name for the help command, there is an option to change it: |
|||
|
|||
.. code-block:: python3 |
|||
|
|||
class MyHelpCommand(commands.HelpCommand): |
|||
def __init__(self): |
|||
super().__init__(command_attrs={'name': 'commands'}) |
|||
|
|||
This allows the help command to be called via ``!commands``. |
|||
|
|||
|
|||
Bot Help |
|||
~~~~~~~~ |
|||
|
|||
The main help sent when ``!help`` is called, this calls :meth:`~discord.ext.commands.HelpCommand.send_bot_help`. |
|||
|
|||
This is the default implementation: |
|||
|
|||
:: |
|||
|
|||
This is my cool bot made in discord.py! ]--- Description |
|||
|
|||
Help: ]--- Cog Name |
|||
sos Send Help! ]--- Cog Command |
|||
No Category: ]--- No Cog |
|||
add Adds two numbers together. \ |
|||
choose Chooses between multiple choices. This will get cut... | |
|||
cool Says if a user is cool. | |
|||
help Shows this message. |--- No Cog Commands |
|||
joined Says when a member joined. | |
|||
repeat Repeats a message multiple times. | |
|||
roll Rolls a dice in NdN format. / |
|||
|
|||
Type ?help command for more info on a command. \___ Ending Note |
|||
You can also type ?help category for more info on a category. / |
|||
|
|||
To make it a little easier, it should start off with: |
|||
|
|||
.. code-block:: python3 |
|||
|
|||
async def send_bot_help(self, mapping): |
|||
ctx = self.context |
|||
bot = ctx.bot |
|||
|
|||
|
|||
Description |
|||
+++++++++++ |
|||
|
|||
By default, the description is set when :class:`commands.Bot` is instantiated, with the |
|||
``description`` keyword argument: ``commands.Bot(description='Hey! This is my Cool Bot:tm:')``. |
|||
|
|||
However, it is possible to disregard that, as it is only used in :meth:`~commands.DefaultHelpCommand.send_bot_help`. |
|||
This can be done by adding the line ``self.paginator.add_line('My Description!', empty=True)`` to the end of |
|||
the function. |
|||
|
|||
In the default help command, the description is added first, then the category and commands are added. |
|||
The position of the description is entirely your choice. |
|||
|
|||
|
|||
Cog Name |
|||
++++++++ |
|||
|
|||
The cog name is usually determined by :attr:`~commands.Cog.qualified_name` - or ``No Category`` - and is formatted to |
|||
be: ``My Cog:`` or ``No Category:``. |
|||
|
|||
In the default help command it is done as so: |
|||
|
|||
.. code-block:: python3 |
|||
:emphasize-lines: 1-5 |
|||
|
|||
no_category = '\u200b{0.no_category}:'.format(self) |
|||
|
|||
def get_category(command, *, no_category=no_category): |
|||
cog = command.cog |
|||
return cog.qualified_name + ':' if cog is not None else no_category |
|||
|
|||
filtered = await self.filter_commands(bot.commands, sort=True, key=get_category) |
|||
max_size = self.get_max_size(filtered) |
|||
to_iterate = itertools.groupby(filtered, key=get_category) |
|||
|
|||
self.no_category is set to ``No Category:`` when you instantiate :class:`commands.DefaultHelpCommand`, however you can |
|||
pass ``no_category='...'`` to the HelpCommand constructor to this. The next local function, ``get_category`` |
|||
determines :attr:`commands.Command.cog`'s name via :attr:`commands.Cog.qualified_name`. |
|||
|
|||
|
|||
Command |
|||
+++++++ |
|||
|
Loading…
Reference in new issue