Skip to content

Instantly share code, notes, and snippets.

@InterStella0
Last active September 6, 2024 19:17
Show Gist options
  • Save InterStella0/b78488fb28cadf279dfd3164b9f0cf96 to your computer and use it in GitHub Desktop.
Save InterStella0/b78488fb28cadf279dfd3164b9f0cf96 to your computer and use it in GitHub Desktop.

Revisions

  1. InterStella0 revised this gist Jan 23, 2023. 1 changed file with 15 additions and 15 deletions.
    30 changes: 15 additions & 15 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -249,7 +249,9 @@ bot = commands.Bot(command_prefix="uwu ", help_command=help_command, intents=int
    # Both are equivalent
    ```
    #### Here's an example of what that looks like.
    ![img.png](https://api.interstella.online/files/1f54f18049c21749d698a53d4ee51f67.png)

    ![img.png](https://user-images.githubusercontent.com/70153286/214119386-aec6c0d8-5dc5-4b46-883e-92d68f9d0c25.png)

    _Now, of course, this is done by default. I'm only showing you this as a demonstration. Don't scream at me_

    Let's do the same thing with `MinimalHelpCommand` next.
    @@ -263,7 +265,7 @@ bot.help_command = commands.MinimalHelpCommand()
    ```
    #### This is how that would look like:

    ![minhelpcommand.png](https://api.interstella.online/files/38c1093d90160ae088775f08271e1d10.png)
    ![minhelpcommand.png](https://user-images.githubusercontent.com/70153286/214119201-5f301576-770c-45db-a8af-14bbee9623e4.png)

    ## <a name="start2"></a> Embed MinimalHelpCommand
    Now say, you want the content to be inside an embed. But you don't want to change the content of
    @@ -287,7 +289,7 @@ bot.help_command = MyNewHelp()
    ```
    The resulting code will show that it have the content of `MinimalHelpCommand` but in an embed.

    ![embedminimalhelp.png](https://api.interstella.online/files/7249032df857067e629402f308f21db3.png)
    ![embedminimalhelp.png](https://user-images.githubusercontent.com/70153286/214119099-ec94a584-2353-42a8-ac53-72192e02580a.png)

    ### How does this work?
    Looking over the `MinimalHelpCommand` source code,
    @@ -318,7 +320,7 @@ For more, [`Click here`](#utils)
    ## <a name="helping_flowchart"></a> HelpCommand Flowchart
    This is a bare minimum on what you should know on how a HelpCommand
    operate. As of discord version 1.* and 2.0. It remained the same flow.
    ![helpcommandflowchart.png](https://api.interstella.online/files/f163936e78b72859af8b90aa4e02bfb0.png)
    ![helpcommandflowchart.png](https://user-images.githubusercontent.com/70153286/214119519-5709c1cc-5aff-4249-b61f-381ad2c53840.png)


    Seems simple enough? Now let's see what happens if you override one of the methods. Here's an example code of how you
    @@ -342,7 +344,7 @@ bot.help_command = MyHelp()
    ```
    #### Output

    ![hellohelpcommand.png](https://api.interstella.online/files/89ab6cfbc5a086c6f103bd47c3d6bca7.png)
    ![hellohelpcommand.png](https://user-images.githubusercontent.com/70153286/214119950-836fc4fd-c409-4df5-aa3a-3106552d3e99.png)

    Keep in mind, using `HelpCommand` class will require overriding every `send_x_help` methods. For example, `<prefix>help jsk` is
    a command that should call `send_command_help` method. However, since `HelpCommand` is an empty class, it will not say
    @@ -403,7 +405,7 @@ bot.help_command = MyHelp()

    #### The result

    ![samplehelp.png](https://api.interstella.online/files/9d68a4eebee8ed02ff68e7b7b2dfa025.png)
    ![samplehelp.png](https://user-images.githubusercontent.com/70153286/214120054-9cdafc81-ec25-4285-be10-081c755e5e9c.png)

    **This looks pretty... terrible.** Those '|' are aliases of the command hence it appeared with a second command name.
    Let's make the signature prettier, and what if you wanna hide commands that you don't want to be shown
    @@ -441,7 +443,7 @@ bot.help_command = MyHelp()
    ```
    #### The resulting output

    ![betterhelpcommand.png](https://api.interstella.online/files/4f93ced5a00e006b143bf2a9dd75cbe8.png)
    ![betterhelpcommand.png](https://user-images.githubusercontent.com/70153286/214120124-86ba271d-fb2e-4a01-a2f1-b4e4717540d3.png)

    This looks more readable than the other one with a small modification to the code.
    While this should cover most of your needs, you may want to know more helpful
    @@ -494,7 +496,7 @@ bot.help_command = MyHelp()
    ```
    #### What you get

    ![commandhelpcommand.png](https://api.interstella.online/files/03ce5349b8dc02203d17ca85712eaf8a.png)
    ![commandhelpcommand.png](https://user-images.githubusercontent.com/70153286/214120186-10149671-5def-4272-9d27-f5e3515e1590.png)

    As you can see, it is very easy to create `<prefix>help [argument]`. The class already handles the pain of checking whether
    the given argument is a command, a cog, or a group command. It's up to you on how you want to display it, whether it's through
    @@ -550,7 +552,8 @@ bot = commands.Bot(command_prefix="uwu ", help_command=help_object, intents=inte

    _Note: on Number 3, Cooldown has been updated on 2.0. Please check the code on your own instead._
    #### The result
    ![cooldownhelp.png](https://api.interstella.online/files/240bd5fb1ab76206b87bffa21dbf2dbb.png)

    ![cooldownhelp.png](https://user-images.githubusercontent.com/70153286/214120265-0ed098fa-3904-4513-ab3c-04485545f0bc.png)

    As you can see, the name of the help command is now `"hell"`, and you can also trigger the help command by `"help"`. It
    will also raise an [`OnCommandCooldown`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.CommandOnCooldown)
    @@ -581,7 +584,7 @@ bot.help_command = MyHelp()

    #### The output:

    ![errorhelp.png](https://api.interstella.online/files/5d4923d27b85752dd10db55471c0da00.png)
    ![errorhelp.png](https://user-images.githubusercontent.com/70153286/214120322-911e240c-33ed-4085-a03e-ddc168420fdb.png)

    ### How about a local error handler?

    @@ -614,7 +617,7 @@ stored in `error` variable, and show the message.

    #### Output:

    ![errorhandler.png](https://api.interstella.online/files/5413ab5d5e2f8251ecd998fda9058d38.png)
    ![errorhandler.png](https://user-images.githubusercontent.com/70153286/214120371-62f9bfb7-31f2-40af-af1b-069458ae661c.png)

    To be fair, you should create a proper error handler through this official documentation. [Here](https://discordpy.readthedocs.io/en/stable/ext/commands/commands.html#ext-commands-error-handler).

    @@ -669,8 +672,7 @@ If you want a generic help command, here's an example of a help command written
    Here's the [code](https://mystb.in/HotmailRegionalCreatures)
    Here's how it looks like.

    ![help_simple](https://api.interstella.online/files/0300a3d728e0865a6421f527ad38972b.png)

    ![help_simple](https://user-images.githubusercontent.com/70153286/214120453-8473f167-38ba-4355-9e3c-7e51c699841b.png)

    For my implementation, its a bit complex. I wrote a library for myself that I use in several bots.
    You can see the codes through [this](https://github.com/InterStella0/starlight-dpy#menu-help-command) repository.
    @@ -684,8 +686,6 @@ Now, of course, any question regarding `HelpCommand` should be asked in the [dis
    because I don't really check this gist as much, and because there is a lot of helpful discord.py helpers if you're nice
    enough to them.

    If you're still confused about paginator, I've made a full walkthrough regarding menus and View pagination. [Click Here](https://gist.github.com/InterStella0/454cc51e05e60e63b81ea2e8490ef140)


    [defhelplink]: https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.DefaultHelpCommand
    [minhelplink]: https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.MinimalHelpCommand
  2. InterStella0 revised this gist Dec 30, 2022. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -674,10 +674,11 @@ Here's how it looks like.

    For my implementation, its a bit complex. I wrote a library for myself that I use in several bots.
    You can see the codes through [this](https://github.com/InterStella0/starlight-dpy#menu-help-command) repository.
    Which you're free to use if you want a quick setup for your help command.

    Looks like this

    ![menu_help_default](https://api.interstella.online/files/1tJOrY-CFJFoohBzZwfjf_eQxo8eBomjI.png)
    ![menuhelpdefault.png](https://i.imgur.com/cEBKl7J.png)

    Now, of course, any question regarding `HelpCommand` should be asked in the [discord.py](https://discord.gg/dpy) server
    because I don't really check this gist as much, and because there is a lot of helpful discord.py helpers if you're nice
  3. InterStella0 revised this gist Dec 30, 2022. 1 changed file with 8 additions and 0 deletions.
    8 changes: 8 additions & 0 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -671,6 +671,14 @@ Here's how it looks like.

    ![help_simple](https://api.interstella.online/files/0300a3d728e0865a6421f527ad38972b.png)


    For my implementation, its a bit complex. I wrote a library for myself that I use in several bots.
    You can see the codes through [this](https://github.com/InterStella0/starlight-dpy#menu-help-command) repository.

    Looks like this

    ![menu_help_default](https://api.interstella.online/files/1tJOrY-CFJFoohBzZwfjf_eQxo8eBomjI.png)

    Now, of course, any question regarding `HelpCommand` should be asked in the [discord.py](https://discord.gg/dpy) server
    because I don't really check this gist as much, and because there is a lot of helpful discord.py helpers if you're nice
    enough to them.
  4. InterStella0 revised this gist Dec 27, 2022. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -655,7 +655,9 @@ async def setup(bot):
    ```
    ### How does it work?
    1. It instantiates the HelpCommand class. `help_command = MyHelp()`
    2. It assigns the instance of `YourCog`(self) into `cog` attribute
    2. It assigns the instance of `YourCog`(self) into `cog` attribute.
    When you assign a `Cog` on a HelpCommand, discord.py will automatically know that the HelpCommand
    belongs to that `Cog`. It was [stated here](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.cog).


    # <a name="the_end"></a> The end
  5. InterStella0 revised this gist Sep 21, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -324,7 +324,7 @@ operate. As of discord version 1.* and 2.0. It remained the same flow.
    Seems simple enough? Now let's see what happens if you override one of the methods. Here's an example code of how you
    would do that. This override will say `"hello!"` when you type `<prefix>help` to demonstrate on what's going on.

    We'll use [`HelpCommand.get_destination()`(https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.get_destination) to get the [`abc.Messageable`](https://discordpy.readthedocs.io/en/stable/api.html#discord.abc.Messageable) instance for sending a message to the correct channel.
    We'll use [`HelpCommand.get_destination()`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.get_destination) to get the [`abc.Messageable`](https://discordpy.readthedocs.io/en/stable/api.html#discord.abc.Messageable) instance for sending a message to the correct channel.

    #### Code Example
    ```py
  6. InterStella0 revised this gist Sep 15, 2022. 1 changed file with 112 additions and 360 deletions.
    472 changes: 112 additions & 360 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -16,11 +16,6 @@ This guide will walkthrough the ways to create a custom help command by subclass
    - [Command Attributes](#command_attrs)
    - [Error handling for HelpCommand](#error_handling)
    - [Setting Cog for HelpCommand](#cog)
    - [Paginated Help Command](#paginate_help)
    - [Pagination for 1.7.x](#paginate_help_1_7)
    - [Pagination for 2.x](#paginate_help_2)
    - [ListPageSource class](#list_page_source)
    - [Integrating classes of pagination](#help_pagination_intergrate)
    - [The end](#the_end)


    @@ -116,7 +111,11 @@ For people who remove the HelpCommand? There is no handling, you have to do it y
    For example
    ##### Bad way
    ```py
    bot = commands.Bot(command_prefix="!", help_command=None)
    import discord
    from discord.ext import commands

    intents = discord.Intents.all()
    bot = commands.Bot(command_prefix="!", help_command=None, intents=intents)

    @bot.command()
    async def help(ctx, argument=None):
    @@ -146,7 +145,10 @@ I'm only simplifying the code.
    Now for the subclassed HelpCommand code.
    #### Good way
    ```py
    bot = commands.Bot(command_prefix="!")
    import discord
    from discord.ext import commands
    intents = discord.Intents.all()
    bot = commands.Bot(command_prefix="!", intents=intents)

    class MyHelp(commands.HelpCommand):
    # !help
    @@ -177,13 +179,12 @@ help command and formatting.
    | Methods / Attributes | Usage |
    |--------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
    | [HelpCommand.filter_commands()][Hgetfilter] | Filter commands to only show commands that the user can run. This help hide any secret commands from the general user. |
    | [HelpCommand.clean_prefix][Hgetcleanprefix] | Get a clean prefix that escape mentions and format them in a readable way such as `@Name` instead of `<@id>` format. **Works up to version 1.7.1.** |
    | Context.clean_prefix | HelpCommand.clean_prefix was removed in version 2.0 of discord.py and replaced with `Context.clean_prefix` |
    | [Context.clean_prefix][Hgetcleanprefix] | HelpCommand.clean_prefix was removed in version 2.0 of discord.py and replaced with `Context.clean_prefix`. This cleans your prefix from @everyone and @here as well as @mentions |
    | [HelpCommand.get_command_signature()][Hgetcommandsig] | Get the command signature and format them such as `command [argument]` for optional and `command <argument>` for required. |
    | [HelpCommand.prepare_help_command()][Hgetprepare] | Triggers before every `send_x_help` method are triggered, this work exactly like `command.before_invoke` |
    | [HelpCommand.get_bot_mapping()][Hgetbotmap] | Get all command that are available in the bot, sort them by Cogs and None for No Category as key in a dictionary. This method is triggered before HelpCommand.send_bot_help is triggered, and will get passed as the parameter. |
    | [HelpCommand.get_destination()][Hgetdestination] | Returns a Messageable on where the help command was invoked. |
    | `HelpCommand.command_callback` | The method that handles all `help/help cog/ help command/ help group` and call which method appropriately. This is useful if you want to modify the behavour of this. Though more knowledge is needed for you to do that. Most don't use this. |
    | [HelpCommand.command_callback][Hcommandcallback] | The method that handles all `help/help cog/ help command/ help group` and call which method appropriately. This is useful if you want to modify the behaviour of this. Though more knowledge is needed for you to do that. Most don't use this. |
    | [Context.send_help()][Csendhelp] | Calling `send_command_help` based on what the Context command object were. This is useful to be used when the user incorrectly invoke the command. Which you can call this method to show help quickly and efficiently. (Only works if you have HelpCommand configured) |

    All of this does not exist when you set `bot.help_command` to `None`. You miss out on this.
    @@ -193,12 +194,13 @@ All of this does not exist when you set `bot.help_command` to `None`. You miss o
    Since it's a class, most people would make it modular. They put it in a cog for example. There is a common code given in `discord.py`
    created by Vex.
    ```python
    from discord.ext import commands
    class MyHelpCommand(commands.MinimalHelpCommand):
    def get_command_signature(self, command):
    return '{0.clean_prefix}{1.qualified_name} {1.signature}'.format(self, command)
    pass

    class MyCog(commands.Cog):
    def __init__(self, bot):
    self.bot = bot
    self._original_help_command = bot.help_command
    bot.help_command = MyHelpCommand()
    bot.help_command.cog = self
    @@ -230,32 +232,38 @@ There are a few types of HelpCommand classes that you can choose;
    3. [`HelpCommand`][helplink] an empty class that is the base class for every HelpCommand you see. On its own, it will
    not do anything.

    By default, help command is using the class `DefaultHelpCommand`. This is stored in [`bot.help_command`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Bot.help_command). This attribute
    By default, help command is using the class `DefaultHelpCommand`. This is stored in [`bot.help_command`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.Bot.help_command). This attribute
    will **ONLY** accept instances that subclasses `HelpCommand`. Here is how you were to use the `DefaultHelpCommand` instance.
    ```py
    import discord
    from discord.ext import commands
    bot = commands.Bot(command_prefix="uwu ")
    intents = discord.Intents.all()
    bot = commands.Bot(command_prefix="uwu ", intents=intents)
    bot.help_command = commands.DefaultHelpCommand()

    # OR

    bot = commands.Bot(command_prefix="uwu ", help_command=commands.DefaultHelpCommand())
    help_command = commands.DefaultHelpCommand()
    intents = discord.Intents.all()
    bot = commands.Bot(command_prefix="uwu ", help_command=help_command, intents=intents)
    # Both are equivalent
    ```
    #### Here's an example of what that looks like.
    ![img.png](https://media.discordapp.net/attachments/784735050071408670/787570202593460224/unknown.png)
    ![img.png](https://api.interstella.online/files/1f54f18049c21749d698a53d4ee51f67.png)
    _Now, of course, this is done by default. I'm only showing you this as a demonstration. Don't scream at me_

    Let's do the same thing with `MinimalHelpCommand` next.

    ```py
    import discord
    from discord.ext import commands
    bot = commands.Bot(command_prefix="uwu ")
    intents = discord.Intents.all()
    bot = commands.Bot(command_prefix="uwu ", intents=intents)
    bot.help_command = commands.MinimalHelpCommand()
    ```
    #### This is how that would look like:

    ![minhelpcommand.png](https://cdn.discordapp.com/attachments/784735050071408670/787571374742962228/unknown.png)
    ![minhelpcommand.png](https://api.interstella.online/files/38c1093d90160ae088775f08271e1d10.png)

    ## <a name="start2"></a> Embed MinimalHelpCommand
    Now say, you want the content to be inside an embed. But you don't want to change the content of
    @@ -265,7 +273,8 @@ shows this;
    ```py
    import discord
    from discord.ext import commands
    bot = commands.Bot(command_prefix="uwu ")
    intents = discord.Intents.all()
    bot = commands.Bot(command_prefix="uwu ", intents=intents)

    class MyNewHelp(commands.MinimalHelpCommand):
    async def send_pages(self):
    @@ -278,11 +287,11 @@ bot.help_command = MyNewHelp()
    ```
    The resulting code will show that it have the content of `MinimalHelpCommand` but in an embed.

    ![embedminimalhelp.png](https://cdn.discordapp.com/attachments/784735050071408670/787574637117833236/unknown.png)
    ![embedminimalhelp.png](https://api.interstella.online/files/7249032df857067e629402f308f21db3.png)

    ### How does this work?
    Looking over the `MinimalHelpCommand` source code, [here](https://github.com/Rapptz/discord.py/blob/master/discord/ext/commands/help.py#L1075-L1331).
    Every method that is responsible for `<prefix>help <argument>` will call [`MinimalHelpCommand.send_pages`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.MinimalHelpCommand.send_pages)
    Looking over the `MinimalHelpCommand` source code,
    every method that is responsible for `<prefix>help <argument>` will call [`MinimalHelpCommand.send_pages`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.MinimalHelpCommand.send_pages)
    when it is about to send the content. This makes it easy to just override `send_pages` without having to override any
    other method there are in `MinimalHelpCommand`.

    @@ -293,39 +302,36 @@ Here are a list of HelpCommand relevant methods, and it's responsibility.

    1. [`HelpCommand.send_bot_help(mapping)`][sendbothelp]
    Gets called with `<prefix>help`
    2. [`HelpCommand.send_command_help(command)`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.send_command_help)
    2. [`HelpCommand.send_command_help(command)`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.send_command_help)
    Gets called with `<prefix>help <command>`
    3. [`HelpCommand.send_group_help(group)`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.send_group_help)
    3. [`HelpCommand.send_group_help(group)`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.send_group_help)
    Gets called with `<prefix>help <group>`
    4. [`HelpCommand.send_cog_help(cog)`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.send_cog_help)
    4. [`HelpCommand.send_cog_help(cog)`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.send_cog_help)
    Gets called with `<prefix>help <cog>`

    ## <a name="helping2"></a> Useful attributes
    1. [`HelpCommand.context`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.context)
    1. [`HelpCommand.context`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.context)
    the Context object in the help command.
    2. [`HelpCommand.clean_prefix`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.clean_prefix)
    a cleanup prefix version that remove any mentions.

    For more, [`Click here`](#utils)

    ## <a name="helping_flowchart"></a> HelpCommand Flowchart
    This is a bare minimum on what you should know on how a HelpCommand
    operate. As of discord version 1.* and 2.0. It remained the same flow.
    ![helpcommandflowchart.png](https://cdn.discordapp.com/attachments/777501555687292928/954724489625747466/help_command_flowchart.png)
    ![helpcommandflowchart.png](https://api.interstella.online/files/f163936e78b72859af8b90aa4e02bfb0.png)


    Seems simple enough? Now let's see what happens if you override one of the methods. Here's an example code of how you
    would do that. This override will say `"hello!"` when you type `<prefix>help` to demonstrate on what's going on.

    We'll use
    [`HelpCommand.get_destination()`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.get_destination)
    to get the [`abc.Messageable`](https://discordpy.readthedocs.io/en/latest/api.html#discord.abc.Messageable)
    instance for sending a message to the correct channel.
    We'll use [`HelpCommand.get_destination()`(https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.get_destination) to get the [`abc.Messageable`](https://discordpy.readthedocs.io/en/stable/api.html#discord.abc.Messageable) instance for sending a message to the correct channel.

    #### Code Example
    ```py
    import discord
    from discord.ext import commands
    bot = commands.Bot(command_prefix="uwu ")
    intents = discord.Intents.all()
    bot = commands.Bot(command_prefix="uwu ", intents=intents)

    class MyHelp(commands.HelpCommand):
    async def send_bot_help(self, mapping):
    @@ -336,7 +342,7 @@ bot.help_command = MyHelp()
    ```
    #### Output

    ![hellohelpcommand.png](https://media.discordapp.net/attachments/784735050071408670/787584311221813248/unknown.png)
    ![hellohelpcommand.png](https://api.interstella.online/files/89ab6cfbc5a086c6f103bd47c3d6bca7.png)

    Keep in mind, using `HelpCommand` class will require overriding every `send_x_help` methods. For example, `<prefix>help jsk` is
    a command that should call `send_command_help` method. However, since `HelpCommand` is an empty class, it will not say
    @@ -349,9 +355,9 @@ as its parameter. `await` indicates that it should be an async function.
    ### What does this mean?
    * `Mapping[]` is a [`collections.abc.Mapping`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping),
    for simplicity’s sake, this usually refers to a dictionary since it's under `collections.abc.Mapping`.
    * `Optional[Cog]` is a [`Cog`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Cog)
    * `Optional[Cog]` is a [`Cog`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.Cog)
    object that has a chance to be `None`.
    * `List[Command]` is a list of [`Command`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Command)
    * `List[Command]` is a list of [`Command`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.Command)
    objects.
    * `Mapping[Optional[Cog], List[Command]]` means it's a map object with `Optional[Cog]` as it's key and `List[Command]` as
    its value.
    @@ -366,7 +372,8 @@ form.
    ```py
    import discord
    from discord.ext import commands
    bot = commands.Bot(command_prefix="uwu ")
    intents = discord.Intents.all()
    bot = commands.Bot(command_prefix="uwu ", intents=intents)

    class MyHelp(commands.HelpCommand):
    async def send_bot_help(self, mapping):
    @@ -390,35 +397,34 @@ bot.help_command = MyHelp()
    4. If the list is empty, meaning, no commands is available in the cog, we don't need to show it, hence
    `if command_signatures:`.
    5. `cog` has a chance to be `None`, this refers to No Category. We'll use [`getattr`](https://docs.python.org/3/library/functions.html#getattr)
    to avoid getting an error to get cog's name through [`Cog.qualified_name`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Cog.qualified_name).
    to avoid getting an error to get cog's name through [`Cog.qualified_name`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.Cog.qualified_name).
    6. Using [`str.join`](https://docs.python.org/3/library/stdtypes.html#str.join) each command will be displayed on a separate line.
    7. Once all of this is finished, display it.

    #### The result

    ![samplehelp.png](https://cdn.discordapp.com/attachments/784735050071408670/787610952690040852/unknown.png)
    ![samplehelp.png](https://api.interstella.online/files/9d68a4eebee8ed02ff68e7b7b2dfa025.png)

    I agree, this does not look pretty. But this demonstrate how to create a help command with minimal effort. The reason why
    it looks ugly, is that we're using [`HelpCommand.get_command_signature(command)`][Hgetcommandsig].
    Let's override that method to make it a little more readable.
    **This looks pretty... terrible.** Those '|' are aliases of the command hence it appeared with a second command name.
    Let's make the signature prettier, and what if you wanna hide commands that you don't want to be shown
    on the help command? Such as "sync" command there, that's only for the developer not other people.

    We'll borrow codes from [`MinimalHelpCommand.get_command_signature`](https://github.com/Rapptz/discord.py/blob/v1.5.1/discord/ext/commands/help.py#L1144).
    Optionally, we can subclass `MinimalHelpCommand` instead of copying codes. I'm doing this as a demonstration of
    overriding other methods.
    We'll subclass `commands.MinimalHelpCommand` to use their `MinimalHelpCommand.get_command_signature`. It's actually more
    prettier than the default HelpCommand signature.

    We'll also use [`HelpCommand.filter_commands`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.filter_commands),
    We'll use [`HelpCommand.filter_commands`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.filter_commands),
    this method will filter commands by removing any commands that the user cannot use. It is a handy method to use.

    This works by checking if the [`Command.hidden`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.Command.hidden)
    is set to True and, it will run [`Command.can_run`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.Command.can_run)
    to see if it raise any errors. If there is any, it will be filtered.
    #### The Example
    ```py
    import discord
    from discord.ext import commands
    bot = commands.Bot(command_prefix="uwu ")

    class MyHelp(commands.HelpCommand):
    def get_command_signature(self, command):
    return '%s%s %s' % (self.clean_prefix, command.qualified_name, command.signature)
    intents = discord.Intents.all()
    bot = commands.Bot(command_prefix="uwu ", intents=intents)

    class MyHelp(commands.MinimalHelpCommand):
    async def send_bot_help(self, mapping):
    embed = discord.Embed(title="Help")
    for cog, commands in mapping.items():
    @@ -435,9 +441,10 @@ bot.help_command = MyHelp()
    ```
    #### The resulting output

    ![betterhelpcommand.png](https://cdn.discordapp.com/attachments/784735050071408670/787614011759919114/unknown.png)
    ![betterhelpcommand.png](https://api.interstella.online/files/4f93ced5a00e006b143bf2a9dd75cbe8.png)

    This looks more readable than the other one. While this should cover most of your needs, you may want to know more helpful
    This looks more readable than the other one with a small modification to the code.
    While this should cover most of your needs, you may want to know more helpful
    attribute that is available on `HelpCommand` in the official documentation.

    ## <a name="helping_guide2"></a> help [argument] command
    @@ -453,14 +460,14 @@ you have show is the attribute of the command.
    For example, this is your command code, your goal is you want to show the `help`,`aliases` and the `signature`.
    #### Command Code
    ```py
    @bot.command(help="Shows all bot's command usage in the server on a sorted list.",
    aliases=["br", "brrrr", "botranks", "botpos", "botposition", "botpositions"])
    async def botrank(ctx, bot: discord.Member):
    @bot.command(help="Generic help command for command hello.",
    aliases=["h", "hellos", "hell", "hehe"])
    async def hello(ctx, bot: discord.Member):
    pass
    ```

    Then it's simple, you can display each of the attribute by [`Command.help`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Command.help)
    and [`Command.aliases`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Command.aliases).
    Then it's simple, you can display each of the attribute by [`Command.help`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.Command.help)
    and [`Command.aliases`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.Command.aliases).

    For the signature, instead of using the previous `get_command_signature`, we're going to subclass `MinimalHelpCommand`.

    @@ -469,7 +476,8 @@ For the signature, instead of using the previous `get_command_signature`, we're
    ```py
    import discord
    from discord.ext import commands
    bot = commands.Bot(command_prefix="uwu ")
    intents = discord.Intents.all()
    bot = commands.Bot(command_prefix="uwu ", intents=intents)

    class MyHelp(commands.MinimalHelpCommand):
    async def send_command_help(self, command):
    @@ -486,24 +494,24 @@ bot.help_command = MyHelp()
    ```
    #### What you get

    ![commandhelpcommand.png](https://cdn.discordapp.com/attachments/784735050071408670/787629706358292490/unknown.png)
    ![commandhelpcommand.png](https://api.interstella.online/files/03ce5349b8dc02203d17ca85712eaf8a.png)

    As you can see, it is very easy to create `<prefix>help [argument]`. The class already handles the pain of checking whether
    the given argument is a command, a cog, or a group command. It's up to you on how you want to display it, whether it's through
    a plain message, an embed or even using [`discord.ext.menus`](https://github.com/Rapptz/discord-ext-menus).

    ## <a name="command_attrs"></a> Command Attributes
    Let's say, someone is spamming your help command. For a normal command, all you have to do to combat this is using a
    [`cooldown`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.cooldown) decorator
    [`cooldown`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.cooldown) decorator
    and slap that thing above the command declaration. Or, what about if you want an alias? Usually, you would put an
    aliases kwargs in the [`command`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Bot.command)
    aliases kwargs in the [`command`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.Bot.command)
    decorator. However, HelpCommand is a bit special, It's a god damn class. You can't just put a decorator on it and expect
    it to work.


    That is when [`HelpCommand.command_attrs`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.command_attrs)
    That is when [`HelpCommand.command_attrs`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.command_attrs)
    come to the rescue. This attribute can be set during the HelpCommand declaration, or a direct attribute assignment.
    According to the documentation, it accepts exactly the same thing as a [`command`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Bot.command)
    According to the documentation, it accepts exactly the same thing as a [`command`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.Bot.command)
    decorator in a form of a dictionary.

    For example, we want to rename the help command as `"hell"` instead of `"help"` for whatever reason. We also want to make
    @@ -512,15 +520,15 @@ because help command messages are big, and we don't want people to spam those. S

    #### Example Code
    ```py
    import discord
    from discord.ext import commands

    intents = discord.Intents.all()
    attributes = {
    'name': "hell",
    'aliases': ["help", "helps"],
    'cooldown': commands.Cooldown(2, 5.0, commands.BucketType.user)
    'cooldown': commands.CooldownMapping.from_cooldown(2, 5.0, commands.BucketType.user)
    }
    # For 2.0, you would use CooldownMapping.from_cooldown(rate, per, type)
    # because Cooldown no longer have type as it's arguments.

    # During declaration
    help_object = commands.MinimalHelpCommand(command_attrs=attributes)
    @@ -529,23 +537,23 @@ help_object = commands.MinimalHelpCommand(command_attrs=attributes)
    help_object = commands.MinimalHelpCommand()
    help_object.command_attrs = attributes

    bot = commands.Bot(command_prefix="uwu ", help_command=help_object)
    bot = commands.Bot(command_prefix="uwu ", help_command=help_object, intents=intents)
    ```
    ### How does it work?
    1. sets the name into `"hell"` is refers to here `'name': "hell"`.
    2. sets the aliases by passing the list of `str` to the `aliases` key, which refers to here `'aliases': ["help", "helps"]`.
    3. sets the cooldown through the `"cooldown"` key by passing in a [`Cooldown`](https://github.com/Rapptz/discord.py/blob/v1.5.1/discord/ext/commands/cooldowns.py#L70-L134)
    object. This object will make a cooldown with a rate of 2, per 5 with a bucket type [`BucketType.user`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.discord.ext.commands.BucketType),
    which in simple terms, for every [`discord.User`](https://discordpy.readthedocs.io/en/latest/api.html#discord.User),
    3. sets the cooldown through the `"cooldown"` key by passing in a `CooldownMapping`
    object. This object will make a cooldown with a rate of 2, per 5 with a bucket type [`BucketType.user`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.BucketType),
    which in simple terms, for every [`discord.User`](https://discordpy.readthedocs.io/en/stable/api.html#discord.User),
    they can call the command twice, every 5 seconds.
    4. We're going to use `MinimalHelpCommand` as the `HelpCommand` object.

    _Note: on Number 3, Cooldown has been updated on 2.0. Please check the code on your own instead._
    #### The result
    ![cooldownhelp.png](https://cdn.discordapp.com/attachments/784735050071408670/789471505145659412/unknown.png)
    ![cooldownhelp.png](https://api.interstella.online/files/240bd5fb1ab76206b87bffa21dbf2dbb.png)

    As you can see, the name of the help command is now `"hell"`, and you can also trigger the help command by `"help"`. It
    will also raise an [`OnCommandCooldown`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.CommandOnCooldown)
    will also raise an [`OnCommandCooldown`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.CommandOnCooldown)
    error if it was triggered 3 times in 5 seconds due to our `Cooldown` object. Of course, I didn't show that in the result,
    but you can try it yourself. You should handle the error in an error handler when an `OnCommandCooldown` is raised.

    @@ -558,7 +566,8 @@ be called. HelpCommand will not call `on_command_error` when it can't find an ex
    ```py
    import discord
    from discord.ext import commands
    bot = commands.Bot(command_prefix="uwu ")
    intents = discord.Intents.all()
    bot = commands.Bot(command_prefix="uwu ", intents=intents)

    class MyHelp(commands.HelpCommand):
    async def send_error_message(self, error):
    @@ -572,18 +581,19 @@ bot.help_command = MyHelp()

    #### The output:

    ![errorhelp.png](https://cdn.discordapp.com/attachments/784735050071408670/787639990515269662/unknown.png)
    ![errorhelp.png](https://api.interstella.online/files/5d4923d27b85752dd10db55471c0da00.png)

    ### How about a local error handler?

    Indeed, we have it. [`HelpCommand.on_help_command_error`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.on_help_command_error),
    Indeed, we have it. [`HelpCommand.on_help_command_error`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.on_help_command_error),
    this method is responsible for handling any error just like any other local error handler.

    #### Code
    ```py
    import discord
    from discord.ext import commands
    bot = commands.Bot(command_prefix="uwu ")
    intents = discord.Intents.all()
    bot = commands.Bot(command_prefix="uwu ", intents=intents)

    class MyHelp(commands.HelpCommand):
    async def send_bot_help(self, mapping):
    @@ -604,20 +614,18 @@ stored in `error` variable, and show the message.

    #### Output:

    ![errorhandler.png](https://cdn.discordapp.com/attachments/784735050071408670/787645587004588052/unknown.png)
    ![errorhandler.png](https://api.interstella.online/files/5413ab5d5e2f8251ecd998fda9058d38.png)

    To be fair, you should create a proper error handler through this official documentation. [Here](https://discordpy.readthedocs.io/en/latest/ext/commands/commands.html#ext-commands-error-handler).
    To be fair, you should create a proper error handler through this official documentation. [Here](https://discordpy.readthedocs.io/en/stable/ext/commands/commands.html#ext-commands-error-handler).

    There is also a lovely example by `Mysty` on error handling in general. [Here](https://gist.github.com/EvieePy/7822af90858ef65012ea500bcecf1612).
    This example shows how to properly create a global error handler and local error handler.

    ## <a name="cog"></a> Setting Cog for HelpCommand
    ### Super easy lol
    It works just like setting a cog on a Command object, you basically have to assign a
    [`commands.Cog`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Cog)
    instance into [`HelpCommand.cog`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.cog).
    It is pretty common for discord.py users to put a HelpCommand into a cog/separate file
    since people want organization.
    It works just like setting a cog on a Command object, you basically have to assign a [`commands.Cog`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.Cog)
    instance into [`HelpCommand.cog`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.cog).
    It is pretty common for discord.py users to put a HelpCommand into a cog/separate file since people want organization.

    ### Code Example
    This code example is if you're in a Cog file, which you have access to a Cog instance
    @@ -642,297 +650,41 @@ class YourCog(commands.Cog):
    bot.help_command = help_command


    def setup(bot):
    bot.add_cog(YourCog(bot))
    async def setup(bot):
    await bot.add_cog(YourCog(bot))
    ```
    ### How does it work?
    1. It instantiates the HelpCommand class. `help_command = MyHelp()`
    2. It assigns the instance of `YourCog`(self) into `cog` attribute


    # <a name="paginate_help"></a> Paginated Help Command
    Seems like there are a lot of request for this to be made, and my original plan was to
    wait for menus to be integrated with buttons. However, looking at the current event of
    where it seems like that won't happen. To clarify, I will not be walking through all of the
    specific feature that the classes I'm using in this tutorial.

    In this part, we will be using [discord-ext-menus](https://github.com/Rapptz/discord-ext-menus) to handle our pagination.
    This is an external library that Danny wrote that seems to never reached 2.0. You might be asking, _"why even bother using it
    if it won't ever reach 2.0"_. I will answer that by saying it is still useful for pagination use. You
    can even use this for other pagination, not just for help command. Even with 2.0, you will be able
    to use this efficiently with buttons. I will show that later in the walkthrough.

    Another walkthrough I made regarding paginator, here I talk about it more in depth. [click here](https://gist.github.com/InterStella0/454cc51e05e60e63b81ea2e8490ef140)

    ### <a name="paginate_help_1_7"></a> Pagination for 1.7.x
    Now for the people who have never use ext-menus before, you may be asking me,
    _"Stella, what the hell is a MenuPages class"_. To explain, this class inherits Menu class which handles everything
    such as waiting for user reactions, and adding reactions to your message. You can do fun things with Menu class such as
    a confirmation message with reactions which are shown [here](https://github.com/Rapptz/discord-ext-menus#getting-started).
    But for our use, we will use them as the button for the pagination. For MenuPages, this class is specifically for
    handling pages, when you click on a reaction, it will show you the next page.

    Now, here are the basic implementation for our use.

    **Code Example For MenuPages**
    ```python
    import discord
    from discord.ext import menus

    class MyMenuPages(menus.MenuPages, inherit_buttons=False):
    @menus.button("<:before_check:754948796487565332>", position=menus.First(1))
    async def go_before(self, payload):
    """Goes to the previous page."""
    await self.show_checked_page(self.current_page - 1)

    @menus.button("<:next_check:754948796361736213>", position=menus.Last(0))
    async def go_after(self, payload):
    """Goes to the next page."""
    await self.show_checked_page(self.current_page + 1)

    @menus.button("<:before_fast_check:754948796139569224>", position=menus.First(0))
    async def go_first(self, payload):
    """Goes to the first page."""
    await self.show_page(0)

    @menus.button("<:next_fast_check:754948796391227442>", position=menus.Last(1))
    async def go_last(self, payload):
    """Goes to the last page."""
    await self.show_page(self._source.get_max_pages() - 1)

    @menus.button("<:stop_check:754948796365930517>", position=menus.First(2))
    async def go_stop(self, payload):
    """Remove this message."""
    self.stop()
    ```
    **Explanation**
    1. `inherit_buttons` kwargs is set to False, this is to remove all default `menus.button` to set it your own.
    2. `MenuPages.show_page` is to show the page at a position that you gave, in this case, `0`.
    3. `MenuPages.show_checked_page` is to show a page, similar to `show_page`, but this will check if the position exist.
    `IndexError` error are ignored when it is raised.
    4. `First`/`Last` class is an anchor during adding reaction. For example, when given as `First(0)`, `Last(0)`, `First(1)`
    `First(2)`, `Last(1)`. Regardless of order, `First(0)` reaction will be added first, followed by `First(1)`, `First(2)`.
    After that, `Last(0)` and `Last(1)` are added. There are also `Position`, but I don't use them here.
    5. `MenuPages.stop()` will end the menu session, you can set them to delete the message by `delete_message_after` or
    `clear_reactions_after` to clear the reactions after the menu session ended.

    You will need to create `ListPageSource` class to use with this class. [Jump Here](#list_page_source)

    ### <a name="paginate_help_2"></a> Pagination for 2.x
    With the introduction of Buttons in 2.0. We are able to use them as a replacement of `MenuPages`. In fact, we
    can even re-use the code in `MenuPages` and recreate them for pagination.

    Similar to `MenuPages`, we have `View` that handles all the interaction with the user. This can be use in `Button`,
    `Select`. It is documented [here](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.ui.View). There are
    example usage for `View` written by Danny himself. This will help you understand how to use them, as I won't be explaining
    every niche things about them. The example is found [here](https://github.com/Rapptz/discord.py/blob/master/examples/views/tic_tac_toe.py)
    where he wrote a tictactoe game with [`View`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.ui.View) and
    [`Button`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.Button).

    In order to create a Pagination view, we will also subclass the `MenuPages` class to borrow the features that are
    available from them. They handle the pages for us, which is insanely useful thanks to Danny's way of coding.

    **Example Code for View Button**
    ```py
    import discord
    from discord import ui
    from discord.ext import menus

    class MyMenuPages(ui.View, menus.MenuPages):
    def __init__(self, source, *, delete_message_after=False):
    super().__init__(timeout=60)
    self._source = source
    self.current_page = 0
    self.ctx = None
    self.message = None
    self.delete_message_after = delete_message_after

    async def start(self, ctx, *, channel=None, wait=False):
    # We wont be using wait/channel, you can implement them yourself. This is to match the MenuPages signature.
    await self._source._prepare_once()
    self.ctx = ctx
    self.message = await self.send_initial_message(ctx, ctx.channel)

    async def _get_kwargs_from_page(self, page):
    """This method calls ListPageSource.format_page class"""
    value = await super()._get_kwargs_from_page(page)
    if 'view' not in value:
    value.update({'view': self})
    return value

    async def interaction_check(self, interaction):
    """Only allow the author that invoke the command to be able to use the interaction"""
    return interaction.user == self.ctx.author

    @ui.button(emoji='<:before_fast_check:754948796139569224>', style=discord.ButtonStyle.blurple)
    async def first_page(self, interaction, button):
    await self.show_page(0)
    await interaction.response.defer()

    @ui.button(emoji='<:before_check:754948796487565332>', style=discord.ButtonStyle.blurple)
    async def before_page(self, interaction, button):
    await self.show_checked_page(self.current_page - 1)
    await interaction.response.defer()

    @ui.button(emoji='<:stop_check:754948796365930517>', style=discord.ButtonStyle.blurple)
    async def stop_page(self, interaction, button):
    await interaction.response.defer()
    self.stop()
    if self.delete_message_after:
    await self.message.delete(delay=0)

    @ui.button(emoji='<:next_check:754948796361736213>', style=discord.ButtonStyle.blurple)
    async def next_page(self, interaction, button):
    await self.show_checked_page(self.current_page + 1)
    await interaction.response.defer()

    @ui.button(emoji='<:next_fast_check:754948796391227442>', style=discord.ButtonStyle.blurple)
    async def last_page(self, interaction, button):
    await self.show_page(self._source.get_max_pages() - 1)
    await interaction.response.defer()
    ```
    **Explanation**
    1. `ui.View` contains all the handling of Button interaction. While, we also need partial use of `menus.MenuPages` where
    it handles the core of pagination. This include calling `ListPageSource.format_page` which will be use.
    2. We won't call `super().start(...)` because those handles reactions, we're only borrowing the methods from them.
    3. `timeout=60` kwargs is passed to `ui.View`, Not `menus.MenuPages`. To understand how this works, learn Method
    Resolution Order (MRO). As I won't be covering them here.
    4. [`View.interaction_check`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.ui.View.interaction_check) is
    for the check. You can check if the interaction is your author. Returns True will result in calling the Button
    callback. Raising an error or returning False will prevent them from being called.
    5. [`ui.button`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.ui.button) basically is the button you're
    adding to `View`.
    6. for `show_check_page`/`show_page` are explained in the `1.7.x` section. [Jump Here](#paginate_help_1_7)
    7. [`message.delete(delay=0)`](https://discordpy.readthedocs.io/en/latest/api.html#discord.Message.delete) is a way to
    delete message without checking if they exist. When error, it silences them.

    You will need to create `ListPageSource` class to use with this class. [Jump Here](#list_page_source)

    ### <a name="list_page_source"></a> ListPageSource class
    As I stated before, `ListPageSource` are only from the external library `discord-ext-menus`. Make sure to install them.

    Now `MyMenuPages` are created for our use, lets create our `ListPageSource` now. To put it simply, `ListPageSource` is
    to format each page where `MyMenuPages` will call this class. There are also other types of class format. However, I
    will just use `ListPageSource` for simplicity sake.

    If you want to read more about `ListPageSource`, you can read them here. [Click Here](https://github.com/Rapptz/discord-ext-menus#pagination).

    Now this will be our basic implementation of `ListPageSource`.

    **Example Code For ListPageSource**
    ```py
    import discord
    from itertools import starmap
    from discord.ext import menus
    class HelpPageSource(menus.ListPageSource):
    def __init__(self, data, helpcommand):
    super().__init__(data, per_page=6)
    self.helpcommand = helpcommand

    def format_command_help(self, no, command):
    signature = self.helpcommand.get_command_signature(command)
    docs = self.helpcommand.get_command_brief(command)
    return f"{no}. {signature}\n{docs}"

    async def format_page(self, menu, entries):
    page = menu.current_page
    max_page = self.get_max_pages()
    starting_number = page * self.per_page + 1
    iterator = starmap(self.format_command_help, enumerate(entries, start=starting_number))
    page_content = "\n".join(iterator)
    embed = discord.Embed(
    title=f"Help Command[{page + 1}/{max_page}]",
    description=page_content,
    color=0xffcccb
    )
    author = menu.ctx.author
    embed.set_footer(text=f"Requested by {author}", icon_url=author.avatar_url) # author.avatar in 2.0
    return embed
    ```
    **Explanation**
    1. `per_page` kwargs is the amount of elements from `data` that will be passed to `ListPageSource.format_page` as `entries`.
    2. `starting_number` is just the starting number for the list of 6 that will be shown. So for example, at page 1, it will be
    1, at page 2, it will be 13 and page 3 would be 19. `menu.current_page` will start at 0, hence we add 1.`
    3. [`itertools.starmap`](https://docs.python.org/3/library/itertools.html#itertools.starmap)
    works exactly like `map` but it unpacks the argument when calling a function, in this case, `HelpPageSource.format_command_help`.
    4. We can get Context from `menu.ctx` attribute.
    5. For `ListPageSource.format_page`, whatever you return from this method, will be shown as a single page. You can return
    a `discord.Embed`, a `str` or a `dict` that will be as kwargs for `message.edit`.

    The output of them are in the [Integrating class of pagination](#help_pagination_intergrate) section.


    ### <a name="help_pagination_intergrate"></a> Integrating classes of pagination
    Now we will be creating the HelpCommand that uses classes that we've made. This HelpCommand class will also be able to
    use the 2.0 button. Hence, why it's in its own section.

    **Example Code**
    ```py
    import discord
    from itertools import chain
    from discord.ext import commands

    class MyHelp(commands.MinimalHelpCommand):
    def get_command_brief(self, command):
    return command.short_doc or "Command is not documented."

    async def send_bot_help(self, mapping):
    all_commands = list(chain.from_iterable(mapping.values()))
    formatter = HelpPageSource(all_commands, self)
    menu = MyMenuPages(formatter, delete_message_after=True)
    await menu.start(self.context)

    bot = commands.Bot("uwu ", help_command=MyHelp())
    ```
    **Explanation**
    1. [`itertools.chain.from_iterable`](https://docs.python.org/3/library/itertools.html#itertools.chain.from_iterable)
    flatten the result of `mapping.values()` into a single list. This is up to you on how you want to handle the command.
    I'm just making it flat to be as basic as possible.
    2. `HelpPageSource` acts as the formatter, this class will be the one that gets the data and the one that shows each
    page to the user.
    3. `MyMenuPages` depending on which class you're using, this will handle the `HelpPageSource` class. It will handle the
    buttons from the user, and determine whether to show the previous/next/forward/backward or stop.
    4. [`Command.short_doc`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Command.short_doc)
    will show the value from `Command.brief` or if None, show the first sentence of `Command.help`.

    ### The Output for 1.7.x
    ![helpMenu](https://cdn.discordapp.com/attachments/652696440396840963/883637607882457099/unknown.png)

    ### The Output for 2.x
    ![helpMenu](https://cdn.discordapp.com/attachments/652696440396840963/883635346271764481/unknown.png)


    # <a name="the_end"></a> The end
    I hope that reading this walkthrough will assist you and give a better understanding on how to subclass [`HelpCommand`][helplink].
    All the example code given are to demonstrate the feature of `HelpCommand` and feel free to try it. There are lots of
    creative things you can do to create a `HelpCommand`.

    If you need an inspiration, this is my help command. I mean, nobody asked but yeah here it is.
    ![helpEx](https://cdn.discordapp.com/attachments/784735050071408670/853268304565895188/unknown.png)

    Here's my code if you want to take a look. It's a bit complicated, but you only have to focus on the
    HelpCommand class [my help command](https://github.com/InterStella0/stella_bot/tree/master/cogs/helpful/help_command).
    If you want a more easier help command, here's an example of a help command written by pikaninja
    Here's the [code](https://mystb.in/EthicalBasketballPoliticians.python)
    If you want a generic help command, here's an example of a help command written by pikaninja
    Here's the [code](https://mystb.in/HotmailRegionalCreatures)
    Here's how it looks like.

    ![help_simple](https://cdn.discordapp.com/attachments/652696440396840963/858616279715676180/unknown.png)
    ![help_simple](https://api.interstella.online/files/0300a3d728e0865a6421f527ad38972b.png)

    Now, of course, any question regarding `HelpCommand` should be asked in the [discord.py](https://discord.gg/dpy) server
    because I don't really check this gist as much, and because there is a lot of helpful discord.py helpers if you're nice
    enough to them. :D
    enough to them.

    If you're still confused about paginator, I've made a full walkthrough regarding menus and View pagination. [Click Here](https://gist.github.com/InterStella0/454cc51e05e60e63b81ea2e8490ef140)


    [defhelplink]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.DefaultHelpCommand
    [minhelplink]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.MinimalHelpCommand
    [helplink]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand
    [sendbothelp]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.send_bot_help
    [Hgetcommandsig]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.get_command_signature
    [Hgetbotmap]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.get_bot_mapping
    [Hgetdestination]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.get_destination
    [Hgetprepare]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.prepare_help_command
    [Hgetcleanprefix]: https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.clean_prefix
    [Hgetfilter]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.filter_commands
    [Csendhelp]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Context.send_help
    [defhelplink]: https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.DefaultHelpCommand
    [minhelplink]: https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.MinimalHelpCommand
    [helplink]: https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand
    [sendbothelp]: https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.send_bot_help
    [Hgetcommandsig]: https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.get_command_signature
    [Hgetbotmap]: https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.get_bot_mapping
    [Hgetdestination]: https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.get_destination
    [Hgetprepare]: https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.prepare_help_command
    [Hgetcleanprefix]: https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.Context.clean_prefix
    [Hgetfilter]: https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.filter_commands
    [Csendhelp]: https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.Context.send_help
    [Hcommandcallback]: https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.command_callback
  7. InterStella0 revised this gist Aug 3, 2022. 1 changed file with 9 additions and 9 deletions.
    18 changes: 9 additions & 9 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -303,7 +303,7 @@ Here are a list of HelpCommand relevant methods, and it's responsibility.
    ## <a name="helping2"></a> Useful attributes
    1. [`HelpCommand.context`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.context)
    the Context object in the help command.
    2. [`HelpCommand.clean_prefix`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.clean_prefix)
    2. [`HelpCommand.clean_prefix`](https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.clean_prefix)
    a cleanup prefix version that remove any mentions.

    For more, [`Click here`](#utils)
    @@ -540,6 +540,7 @@ bot = commands.Bot(command_prefix="uwu ", help_command=help_object)
    they can call the command twice, every 5 seconds.
    4. We're going to use `MinimalHelpCommand` as the `HelpCommand` object.

    _Note: on Number 3, Cooldown has been updated on 2.0. Please check the code on your own instead._
    #### The result
    ![cooldownhelp.png](https://cdn.discordapp.com/attachments/784735050071408670/789471505145659412/unknown.png)

    @@ -722,11 +723,11 @@ With the introduction of Buttons in 2.0. We are able to use them as a replacemen
    can even re-use the code in `MenuPages` and recreate them for pagination.

    Similar to `MenuPages`, we have `View` that handles all the interaction with the user. This can be use in `Button`,
    `Select`. It is documented [here](https://discordpy.readthedocs.io/en/master/api.html#discord.ui.View). There are
    `Select`. It is documented [here](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.ui.View). There are
    example usage for `View` written by Danny himself. This will help you understand how to use them, as I won't be explaining
    every niche things about them. The example is found [here](https://github.com/Rapptz/discord.py/blob/master/examples/views/tic_tac_toe.py)
    where he wrote a tictactoe game with [`View`](https://discordpy.readthedocs.io/en/master/api.html#discord.ui.View) and
    [`Button`](https://discordpy.readthedocs.io/en/master/api.html#discord.Button).
    where he wrote a tictactoe game with [`View`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.ui.View) and
    [`Button`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.Button).

    In order to create a Pagination view, we will also subclass the `MenuPages` class to borrow the features that are
    available from them. They handle the pages for us, which is insanely useful thanks to Danny's way of coding.
    @@ -796,10 +797,10 @@ class MyMenuPages(ui.View, menus.MenuPages):
    2. We won't call `super().start(...)` because those handles reactions, we're only borrowing the methods from them.
    3. `timeout=60` kwargs is passed to `ui.View`, Not `menus.MenuPages`. To understand how this works, learn Method
    Resolution Order (MRO). As I won't be covering them here.
    4. [`View.interaction_check`](https://discordpy.readthedocs.io/en/master/api.html#discord.ui.View.interaction_check) is
    4. [`View.interaction_check`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.ui.View.interaction_check) is
    for the check. You can check if the interaction is your author. Returns True will result in calling the Button
    callback. Raising an error or returning False will prevent them from being called.
    5. [`ui.button`](https://discordpy.readthedocs.io/en/master/api.html#discord.ui.button) basically is the button you're
    5. [`ui.button`](https://discordpy.readthedocs.io/en/latest/interactions/api.html#discord.ui.button) basically is the button you're
    adding to `View`.
    6. for `show_check_page`/`show_page` are explained in the `1.7.x` section. [Jump Here](#paginate_help_1_7)
    7. [`message.delete(delay=0)`](https://discordpy.readthedocs.io/en/latest/api.html#discord.Message.delete) is a way to
    @@ -910,8 +911,7 @@ If you need an inspiration, this is my help command. I mean, nobody asked but ye
    ![helpEx](https://cdn.discordapp.com/attachments/784735050071408670/853268304565895188/unknown.png)

    Here's my code if you want to take a look. It's a bit complicated, but you only have to focus on the
    HelpCommand class [my help command](https://github.com/InterStella0/stella_bot/blob/master/cogs/helpful.py).

    HelpCommand class [my help command](https://github.com/InterStella0/stella_bot/tree/master/cogs/helpful/help_command).
    If you want a more easier help command, here's an example of a help command written by pikaninja
    Here's the [code](https://mystb.in/EthicalBasketballPoliticians.python)
    Here's how it looks like.
    @@ -933,6 +933,6 @@ If you're still confused about paginator, I've made a full walkthrough regarding
    [Hgetbotmap]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.get_bot_mapping
    [Hgetdestination]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.get_destination
    [Hgetprepare]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.prepare_help_command
    [Hgetcleanprefix]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.clean_prefix
    [Hgetcleanprefix]: https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.HelpCommand.clean_prefix
    [Hgetfilter]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.filter_commands
    [Csendhelp]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Context.send_help
  8. InterStella0 revised this gist Jun 27, 2022. 1 changed file with 10 additions and 5 deletions.
    15 changes: 10 additions & 5 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -764,26 +764,31 @@ class MyMenuPages(ui.View, menus.MenuPages):
    return interaction.user == self.ctx.author

    @ui.button(emoji='<:before_fast_check:754948796139569224>', style=discord.ButtonStyle.blurple)
    async def first_page(self, button, interaction):
    async def first_page(self, interaction, button):
    await self.show_page(0)
    await interaction.response.defer()

    @ui.button(emoji='<:before_check:754948796487565332>', style=discord.ButtonStyle.blurple)
    async def before_page(self, button, interaction):
    async def before_page(self, interaction, button):
    await self.show_checked_page(self.current_page - 1)
    await interaction.response.defer()

    @ui.button(emoji='<:stop_check:754948796365930517>', style=discord.ButtonStyle.blurple)
    async def stop_page(self, button, interaction):
    async def stop_page(self, interaction, button):
    await interaction.response.defer()
    self.stop()
    if self.delete_message_after:
    await self.message.delete(delay=0)

    @ui.button(emoji='<:next_check:754948796361736213>', style=discord.ButtonStyle.blurple)
    async def next_page(self, button, interaction):
    async def next_page(self, interaction, button):
    await self.show_checked_page(self.current_page + 1)
    await interaction.response.defer()

    @ui.button(emoji='<:next_fast_check:754948796391227442>', style=discord.ButtonStyle.blurple)
    async def last_page(self, button, interaction):
    async def last_page(self, interaction, button):
    await self.show_page(self._source.get_max_pages() - 1)
    await interaction.response.defer()
    ```
    **Explanation**
    1. `ui.View` contains all the handling of Button interaction. While, we also need partial use of `menus.MenuPages` where
  9. InterStella0 revised this gist Mar 19, 2022. 1 changed file with 7 additions and 0 deletions.
    7 changes: 7 additions & 0 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -10,6 +10,7 @@ This guide will walkthrough the ways to create a custom help command by subclass
    - [HelpCommand](#helping)
    - [Basic method to override](#helping1)
    - [Useful Attributes](#helping2)
    - [Flowchart](#helping_flowchart)
    - [help command](#helping_guide1)
    - [help \<argument>](#helping_guide2)
    - [Command Attributes](#command_attrs)
    @@ -307,6 +308,12 @@ Here are a list of HelpCommand relevant methods, and it's responsibility.

    For more, [`Click here`](#utils)

    ## <a name="helping_flowchart"></a> HelpCommand Flowchart
    This is a bare minimum on what you should know on how a HelpCommand
    operate. As of discord version 1.* and 2.0. It remained the same flow.
    ![helpcommandflowchart.png](https://cdn.discordapp.com/attachments/777501555687292928/954724489625747466/help_command_flowchart.png)


    Seems simple enough? Now let's see what happens if you override one of the methods. Here's an example code of how you
    would do that. This override will say `"hello!"` when you type `<prefix>help` to demonstrate on what's going on.

  10. InterStella0 revised this gist Dec 11, 2021. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -654,6 +654,8 @@ if it won't ever reach 2.0"_. I will answer that by saying it is still useful fo
    can even use this for other pagination, not just for help command. Even with 2.0, you will be able
    to use this efficiently with buttons. I will show that later in the walkthrough.

    Another walkthrough I made regarding paginator, here I talk about it more in depth. [click here](https://gist.github.com/InterStella0/454cc51e05e60e63b81ea2e8490ef140)

    ### <a name="paginate_help_1_7"></a> Pagination for 1.7.x
    Now for the people who have never use ext-menus before, you may be asking me,
    _"Stella, what the hell is a MenuPages class"_. To explain, this class inherits Menu class which handles everything
    @@ -908,6 +910,8 @@ Now, of course, any question regarding `HelpCommand` should be asked in the [dis
    because I don't really check this gist as much, and because there is a lot of helpful discord.py helpers if you're nice
    enough to them. :D

    If you're still confused about paginator, I've made a full walkthrough regarding menus and View pagination. [Click Here](https://gist.github.com/InterStella0/454cc51e05e60e63b81ea2e8490ef140)


    [defhelplink]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.DefaultHelpCommand
    [minhelplink]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.MinimalHelpCommand
  11. InterStella0 revised this gist Sep 4, 2021. 1 changed file with 251 additions and 0 deletions.
    251 changes: 251 additions & 0 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -15,6 +15,11 @@ This guide will walkthrough the ways to create a custom help command by subclass
    - [Command Attributes](#command_attrs)
    - [Error handling for HelpCommand](#error_handling)
    - [Setting Cog for HelpCommand](#cog)
    - [Paginated Help Command](#paginate_help)
    - [Pagination for 1.7.x](#paginate_help_1_7)
    - [Pagination for 2.x](#paginate_help_2)
    - [ListPageSource class](#list_page_source)
    - [Integrating classes of pagination](#help_pagination_intergrate)
    - [The end](#the_end)


    @@ -636,6 +641,252 @@ def setup(bot):
    1. It instantiates the HelpCommand class. `help_command = MyHelp()`
    2. It assigns the instance of `YourCog`(self) into `cog` attribute


    # <a name="paginate_help"></a> Paginated Help Command
    Seems like there are a lot of request for this to be made, and my original plan was to
    wait for menus to be integrated with buttons. However, looking at the current event of
    where it seems like that won't happen. To clarify, I will not be walking through all of the
    specific feature that the classes I'm using in this tutorial.

    In this part, we will be using [discord-ext-menus](https://github.com/Rapptz/discord-ext-menus) to handle our pagination.
    This is an external library that Danny wrote that seems to never reached 2.0. You might be asking, _"why even bother using it
    if it won't ever reach 2.0"_. I will answer that by saying it is still useful for pagination use. You
    can even use this for other pagination, not just for help command. Even with 2.0, you will be able
    to use this efficiently with buttons. I will show that later in the walkthrough.

    ### <a name="paginate_help_1_7"></a> Pagination for 1.7.x
    Now for the people who have never use ext-menus before, you may be asking me,
    _"Stella, what the hell is a MenuPages class"_. To explain, this class inherits Menu class which handles everything
    such as waiting for user reactions, and adding reactions to your message. You can do fun things with Menu class such as
    a confirmation message with reactions which are shown [here](https://github.com/Rapptz/discord-ext-menus#getting-started).
    But for our use, we will use them as the button for the pagination. For MenuPages, this class is specifically for
    handling pages, when you click on a reaction, it will show you the next page.

    Now, here are the basic implementation for our use.

    **Code Example For MenuPages**
    ```python
    import discord
    from discord.ext import menus

    class MyMenuPages(menus.MenuPages, inherit_buttons=False):
    @menus.button("<:before_check:754948796487565332>", position=menus.First(1))
    async def go_before(self, payload):
    """Goes to the previous page."""
    await self.show_checked_page(self.current_page - 1)

    @menus.button("<:next_check:754948796361736213>", position=menus.Last(0))
    async def go_after(self, payload):
    """Goes to the next page."""
    await self.show_checked_page(self.current_page + 1)

    @menus.button("<:before_fast_check:754948796139569224>", position=menus.First(0))
    async def go_first(self, payload):
    """Goes to the first page."""
    await self.show_page(0)

    @menus.button("<:next_fast_check:754948796391227442>", position=menus.Last(1))
    async def go_last(self, payload):
    """Goes to the last page."""
    await self.show_page(self._source.get_max_pages() - 1)

    @menus.button("<:stop_check:754948796365930517>", position=menus.First(2))
    async def go_stop(self, payload):
    """Remove this message."""
    self.stop()
    ```
    **Explanation**
    1. `inherit_buttons` kwargs is set to False, this is to remove all default `menus.button` to set it your own.
    2. `MenuPages.show_page` is to show the page at a position that you gave, in this case, `0`.
    3. `MenuPages.show_checked_page` is to show a page, similar to `show_page`, but this will check if the position exist.
    `IndexError` error are ignored when it is raised.
    4. `First`/`Last` class is an anchor during adding reaction. For example, when given as `First(0)`, `Last(0)`, `First(1)`
    `First(2)`, `Last(1)`. Regardless of order, `First(0)` reaction will be added first, followed by `First(1)`, `First(2)`.
    After that, `Last(0)` and `Last(1)` are added. There are also `Position`, but I don't use them here.
    5. `MenuPages.stop()` will end the menu session, you can set them to delete the message by `delete_message_after` or
    `clear_reactions_after` to clear the reactions after the menu session ended.

    You will need to create `ListPageSource` class to use with this class. [Jump Here](#list_page_source)

    ### <a name="paginate_help_2"></a> Pagination for 2.x
    With the introduction of Buttons in 2.0. We are able to use them as a replacement of `MenuPages`. In fact, we
    can even re-use the code in `MenuPages` and recreate them for pagination.

    Similar to `MenuPages`, we have `View` that handles all the interaction with the user. This can be use in `Button`,
    `Select`. It is documented [here](https://discordpy.readthedocs.io/en/master/api.html#discord.ui.View). There are
    example usage for `View` written by Danny himself. This will help you understand how to use them, as I won't be explaining
    every niche things about them. The example is found [here](https://github.com/Rapptz/discord.py/blob/master/examples/views/tic_tac_toe.py)
    where he wrote a tictactoe game with [`View`](https://discordpy.readthedocs.io/en/master/api.html#discord.ui.View) and
    [`Button`](https://discordpy.readthedocs.io/en/master/api.html#discord.Button).

    In order to create a Pagination view, we will also subclass the `MenuPages` class to borrow the features that are
    available from them. They handle the pages for us, which is insanely useful thanks to Danny's way of coding.

    **Example Code for View Button**
    ```py
    import discord
    from discord import ui
    from discord.ext import menus

    class MyMenuPages(ui.View, menus.MenuPages):
    def __init__(self, source, *, delete_message_after=False):
    super().__init__(timeout=60)
    self._source = source
    self.current_page = 0
    self.ctx = None
    self.message = None
    self.delete_message_after = delete_message_after

    async def start(self, ctx, *, channel=None, wait=False):
    # We wont be using wait/channel, you can implement them yourself. This is to match the MenuPages signature.
    await self._source._prepare_once()
    self.ctx = ctx
    self.message = await self.send_initial_message(ctx, ctx.channel)

    async def _get_kwargs_from_page(self, page):
    """This method calls ListPageSource.format_page class"""
    value = await super()._get_kwargs_from_page(page)
    if 'view' not in value:
    value.update({'view': self})
    return value

    async def interaction_check(self, interaction):
    """Only allow the author that invoke the command to be able to use the interaction"""
    return interaction.user == self.ctx.author

    @ui.button(emoji='<:before_fast_check:754948796139569224>', style=discord.ButtonStyle.blurple)
    async def first_page(self, button, interaction):
    await self.show_page(0)

    @ui.button(emoji='<:before_check:754948796487565332>', style=discord.ButtonStyle.blurple)
    async def before_page(self, button, interaction):
    await self.show_checked_page(self.current_page - 1)

    @ui.button(emoji='<:stop_check:754948796365930517>', style=discord.ButtonStyle.blurple)
    async def stop_page(self, button, interaction):
    self.stop()
    if self.delete_message_after:
    await self.message.delete(delay=0)

    @ui.button(emoji='<:next_check:754948796361736213>', style=discord.ButtonStyle.blurple)
    async def next_page(self, button, interaction):
    await self.show_checked_page(self.current_page + 1)

    @ui.button(emoji='<:next_fast_check:754948796391227442>', style=discord.ButtonStyle.blurple)
    async def last_page(self, button, interaction):
    await self.show_page(self._source.get_max_pages() - 1)
    ```
    **Explanation**
    1. `ui.View` contains all the handling of Button interaction. While, we also need partial use of `menus.MenuPages` where
    it handles the core of pagination. This include calling `ListPageSource.format_page` which will be use.
    2. We won't call `super().start(...)` because those handles reactions, we're only borrowing the methods from them.
    3. `timeout=60` kwargs is passed to `ui.View`, Not `menus.MenuPages`. To understand how this works, learn Method
    Resolution Order (MRO). As I won't be covering them here.
    4. [`View.interaction_check`](https://discordpy.readthedocs.io/en/master/api.html#discord.ui.View.interaction_check) is
    for the check. You can check if the interaction is your author. Returns True will result in calling the Button
    callback. Raising an error or returning False will prevent them from being called.
    5. [`ui.button`](https://discordpy.readthedocs.io/en/master/api.html#discord.ui.button) basically is the button you're
    adding to `View`.
    6. for `show_check_page`/`show_page` are explained in the `1.7.x` section. [Jump Here](#paginate_help_1_7)
    7. [`message.delete(delay=0)`](https://discordpy.readthedocs.io/en/latest/api.html#discord.Message.delete) is a way to
    delete message without checking if they exist. When error, it silences them.

    You will need to create `ListPageSource` class to use with this class. [Jump Here](#list_page_source)

    ### <a name="list_page_source"></a> ListPageSource class
    As I stated before, `ListPageSource` are only from the external library `discord-ext-menus`. Make sure to install them.

    Now `MyMenuPages` are created for our use, lets create our `ListPageSource` now. To put it simply, `ListPageSource` is
    to format each page where `MyMenuPages` will call this class. There are also other types of class format. However, I
    will just use `ListPageSource` for simplicity sake.

    If you want to read more about `ListPageSource`, you can read them here. [Click Here](https://github.com/Rapptz/discord-ext-menus#pagination).

    Now this will be our basic implementation of `ListPageSource`.

    **Example Code For ListPageSource**
    ```py
    import discord
    from itertools import starmap
    from discord.ext import menus
    class HelpPageSource(menus.ListPageSource):
    def __init__(self, data, helpcommand):
    super().__init__(data, per_page=6)
    self.helpcommand = helpcommand

    def format_command_help(self, no, command):
    signature = self.helpcommand.get_command_signature(command)
    docs = self.helpcommand.get_command_brief(command)
    return f"{no}. {signature}\n{docs}"

    async def format_page(self, menu, entries):
    page = menu.current_page
    max_page = self.get_max_pages()
    starting_number = page * self.per_page + 1
    iterator = starmap(self.format_command_help, enumerate(entries, start=starting_number))
    page_content = "\n".join(iterator)
    embed = discord.Embed(
    title=f"Help Command[{page + 1}/{max_page}]",
    description=page_content,
    color=0xffcccb
    )
    author = menu.ctx.author
    embed.set_footer(text=f"Requested by {author}", icon_url=author.avatar_url) # author.avatar in 2.0
    return embed
    ```
    **Explanation**
    1. `per_page` kwargs is the amount of elements from `data` that will be passed to `ListPageSource.format_page` as `entries`.
    2. `starting_number` is just the starting number for the list of 6 that will be shown. So for example, at page 1, it will be
    1, at page 2, it will be 13 and page 3 would be 19. `menu.current_page` will start at 0, hence we add 1.`
    3. [`itertools.starmap`](https://docs.python.org/3/library/itertools.html#itertools.starmap)
    works exactly like `map` but it unpacks the argument when calling a function, in this case, `HelpPageSource.format_command_help`.
    4. We can get Context from `menu.ctx` attribute.
    5. For `ListPageSource.format_page`, whatever you return from this method, will be shown as a single page. You can return
    a `discord.Embed`, a `str` or a `dict` that will be as kwargs for `message.edit`.

    The output of them are in the [Integrating class of pagination](#help_pagination_intergrate) section.


    ### <a name="help_pagination_intergrate"></a> Integrating classes of pagination
    Now we will be creating the HelpCommand that uses classes that we've made. This HelpCommand class will also be able to
    use the 2.0 button. Hence, why it's in its own section.

    **Example Code**
    ```py
    import discord
    from itertools import chain
    from discord.ext import commands

    class MyHelp(commands.MinimalHelpCommand):
    def get_command_brief(self, command):
    return command.short_doc or "Command is not documented."

    async def send_bot_help(self, mapping):
    all_commands = list(chain.from_iterable(mapping.values()))
    formatter = HelpPageSource(all_commands, self)
    menu = MyMenuPages(formatter, delete_message_after=True)
    await menu.start(self.context)

    bot = commands.Bot("uwu ", help_command=MyHelp())
    ```
    **Explanation**
    1. [`itertools.chain.from_iterable`](https://docs.python.org/3/library/itertools.html#itertools.chain.from_iterable)
    flatten the result of `mapping.values()` into a single list. This is up to you on how you want to handle the command.
    I'm just making it flat to be as basic as possible.
    2. `HelpPageSource` acts as the formatter, this class will be the one that gets the data and the one that shows each
    page to the user.
    3. `MyMenuPages` depending on which class you're using, this will handle the `HelpPageSource` class. It will handle the
    buttons from the user, and determine whether to show the previous/next/forward/backward or stop.
    4. [`Command.short_doc`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Command.short_doc)
    will show the value from `Command.brief` or if None, show the first sentence of `Command.help`.

    ### The Output for 1.7.x
    ![helpMenu](https://cdn.discordapp.com/attachments/652696440396840963/883637607882457099/unknown.png)

    ### The Output for 2.x
    ![helpMenu](https://cdn.discordapp.com/attachments/652696440396840963/883635346271764481/unknown.png)


    # <a name="the_end"></a> The end
    I hope that reading this walkthrough will assist you and give a better understanding on how to subclass [`HelpCommand`][helplink].
    All the example code given are to demonstrate the feature of `HelpCommand` and feel free to try it. There are lots of
  12. InterStella0 revised this gist Jun 30, 2021. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -506,7 +506,9 @@ attributes = {
    'name': "hell",
    'aliases': ["help", "helps"],
    'cooldown': commands.Cooldown(2, 5.0, commands.BucketType.user)
    }
    }
    # For 2.0, you would use CooldownMapping.from_cooldown(rate, per, type)
    # because Cooldown no longer have type as it's arguments.

    # During declaration
    help_object = commands.MinimalHelpCommand(command_attrs=attributes)
  13. InterStella0 revised this gist Jun 27, 2021. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -647,7 +647,8 @@ HelpCommand class [my help command](https://github.com/InterStella0/stella_bot/b

    If you want a more easier help command, here's an example of a help command written by pikaninja
    Here's the [code](https://mystb.in/EthicalBasketballPoliticians.python)
    Here's how it looks like
    Here's how it looks like.

    ![help_simple](https://cdn.discordapp.com/attachments/652696440396840963/858616279715676180/unknown.png)

    Now, of course, any question regarding `HelpCommand` should be asked in the [discord.py](https://discord.gg/dpy) server
  14. InterStella0 revised this gist Jun 27, 2021. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -645,6 +645,11 @@ If you need an inspiration, this is my help command. I mean, nobody asked but ye
    Here's my code if you want to take a look. It's a bit complicated, but you only have to focus on the
    HelpCommand class [my help command](https://github.com/InterStella0/stella_bot/blob/master/cogs/helpful.py).

    If you want a more easier help command, here's an example of a help command written by pikaninja
    Here's the [code](https://mystb.in/EthicalBasketballPoliticians.python)
    Here's how it looks like
    ![help_simple](https://cdn.discordapp.com/attachments/652696440396840963/858616279715676180/unknown.png)

    Now, of course, any question regarding `HelpCommand` should be asked in the [discord.py](https://discord.gg/dpy) server
    because I don't really check this gist as much, and because there is a lot of helpful discord.py helpers if you're nice
    enough to them. :D
  15. InterStella0 revised this gist Jun 15, 2021. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -547,7 +547,7 @@ bot = commands.Bot(command_prefix="uwu ")

    class MyHelp(commands.HelpCommand):
    async def send_error_message(self, error):
    embed = discord.Embed(title="Error", value=error)
    embed = discord.Embed(title="Error", description=error)
    channel = self.get_destination()
    await channel.send(embed=embed)

    @@ -639,10 +639,10 @@ I hope that reading this walkthrough will assist you and give a better understan
    All the example code given are to demonstrate the feature of `HelpCommand` and feel free to try it. There are lots of
    creative things you can do to create a `HelpCommand`.

    If you need an inspiration, this is my help command.
    If you need an inspiration, this is my help command. I mean, nobody asked but yeah here it is.
    ![helpEx](https://cdn.discordapp.com/attachments/784735050071408670/853268304565895188/unknown.png)

    Here's my code if you want to take a look. It's a bit complicated, but you only have ot focus on the
    Here's my code if you want to take a look. It's a bit complicated, but you only have to focus on the
    HelpCommand class [my help command](https://github.com/InterStella0/stella_bot/blob/master/cogs/helpful.py).

    Now, of course, any question regarding `HelpCommand` should be asked in the [discord.py](https://discord.gg/dpy) server
  16. InterStella0 revised this gist Jun 12, 2021. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -639,6 +639,9 @@ I hope that reading this walkthrough will assist you and give a better understan
    All the example code given are to demonstrate the feature of `HelpCommand` and feel free to try it. There are lots of
    creative things you can do to create a `HelpCommand`.

    If you need an inspiration, this is my help command.
    ![helpEx](https://cdn.discordapp.com/attachments/784735050071408670/853268304565895188/unknown.png)

    Here's my code if you want to take a look. It's a bit complicated, but you only have ot focus on the
    HelpCommand class [my help command](https://github.com/InterStella0/stella_bot/blob/master/cogs/helpful.py).

  17. InterStella0 revised this gist May 29, 2021. 1 changed file with 2 additions and 4 deletions.
    6 changes: 2 additions & 4 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -639,10 +639,8 @@ I hope that reading this walkthrough will assist you and give a better understan
    All the example code given are to demonstrate the feature of `HelpCommand` and feel free to try it. There are lots of
    creative things you can do to create a `HelpCommand`.

    #### Here is how my help command looks like as an inspiration.
    ![myhelp.png](https://cdn.discordapp.com/attachments/784735050071408670/789480296055177226/unknown.png)

    Here's my code if you want to take a look. [my help command](https://github.com/InterStella0/stella_bot/blob/master/cogs/helpful.py#L130-L261).
    Here's my code if you want to take a look. It's a bit complicated, but you only have ot focus on the
    HelpCommand class [my help command](https://github.com/InterStella0/stella_bot/blob/master/cogs/helpful.py).

    Now, of course, any question regarding `HelpCommand` should be asked in the [discord.py](https://discord.gg/dpy) server
    because I don't really check this gist as much, and because there is a lot of helpful discord.py helpers if you're nice
  18. InterStella0 revised this gist May 7, 2021. 1 changed file with 69 additions and 21 deletions.
    90 changes: 69 additions & 21 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -1,12 +1,24 @@
    # A basic guide on subclassing HelpCommand
    # A basic walkthrough guide on subclassing HelpCommand
    This guide will walkthrough the ways to create a custom help command by subclassing HelpCommand.


    ## Brief explanation of subclassing
    [`Skip to 'Why subclassing is better'`](#why)

    [`Skip to 'Getting started'`](#start)

    ## Table Content
    - [Brief explanation of subclassing](#brief)
    - [Why subclassing is better](#why)
    - [Getting started](#start)
    - [Types of HelpCommand class](#start1)
    - [Embed MinimalHelpCommand](#start2)
    - [HelpCommand](#helping)
    - [Basic method to override](#helping1)
    - [Useful Attributes](#helping2)
    - [help command](#helping_guide1)
    - [help \<argument>](#helping_guide2)
    - [Command Attributes](#command_attrs)
    - [Error handling for HelpCommand](#error_handling)
    - [Setting Cog for HelpCommand](#cog)
    - [The end](#the_end)


    ## <a name="brief"></a> Brief explanation of subclassing
    In simple terms, a subclass is a way to inherit a class behaviour/attributes from another class. Here's how you would subclass
    a class in Python.
    ```py
    @@ -54,9 +66,6 @@ Make sure to look and practice more into subclassing classes to understand fully
    HelpCommand.

    ## <a name="why"></a> Why subclassing HelpCommand is better
    [`Skip to 'Getting started'`](#start)


    Firstly, let me show you the wrong way of creating a help command.

    #### One of the most incorrect ways of to create a help command.
    @@ -163,7 +172,7 @@ help command and formatting.
    |--------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
    | [HelpCommand.filter_commands()][Hgetfilter] | Filter commands to only show commands that the user can run. This help hide any secret commands from the general user. |
    | [HelpCommand.clean_prefix][Hgetcleanprefix] | Get a clean prefix that escape mentions and format them in a readable way such as `@Name` instead of `<@id>` format. **Works up to version 1.7.1.** |
    | Context.clean_prefix | HelpCommand.clean_prefix was removed in 2.0 and replaced with `Context.clean_prefix` |
    | Context.clean_prefix | HelpCommand.clean_prefix was removed in version 2.0 of discord.py and replaced with `Context.clean_prefix` |
    | [HelpCommand.get_command_signature()][Hgetcommandsig] | Get the command signature and format them such as `command [argument]` for optional and `command <argument>` for required. |
    | [HelpCommand.prepare_help_command()][Hgetprepare] | Triggers before every `send_x_help` method are triggered, this work exactly like `command.before_invoke` |
    | [HelpCommand.get_bot_mapping()][Hgetbotmap] | Get all command that are available in the bot, sort them by Cogs and None for No Category as key in a dictionary. This method is triggered before HelpCommand.send_bot_help is triggered, and will get passed as the parameter. |
    @@ -208,7 +217,7 @@ to the bot so that you will always have a backup `HelpCommand` ready while you'r
    ## <a name="start"></a>Getting started
    With that out of the way, let's get started. For subclassing HelpCommand, first, you would need to know the types of `HelpCommand`.
    Where each class has their own usage.
    ### Types of HelpCommand class
    ### <a name="start1"></a> Types of HelpCommand class
    There are a few types of HelpCommand classes that you can choose;
    1. [`DefaultHelpCommand`][defhelplink] a help command that is given by default.
    2. [`MinimalHelpCommand`][minhelplink] a slightly better help command.
    @@ -242,7 +251,7 @@ bot.help_command = commands.MinimalHelpCommand()

    ![minhelpcommand.png](https://cdn.discordapp.com/attachments/784735050071408670/787571374742962228/unknown.png)

    ## Embed MinimalHelpCommand
    ## <a name="start2"></a> Embed MinimalHelpCommand
    Now say, you want the content to be inside an embed. But you don't want to change the content of
    `DefaultHelpCommand`/`MinimalHelpCommand` since you want a simple HelpCommand with minimal work. There is a short code
    from `?tag embed help example` by `gogert` in [discord.py](https://discord.gg/dpy) server, a sample code you can follow
    @@ -271,8 +280,8 @@ Every method that is responsible for `<prefix>help <argument>` will call [`Minim
    when it is about to send the content. This makes it easy to just override `send_pages` without having to override any
    other method there are in `MinimalHelpCommand`.

    # HelpCommand
    ## Basic methods to override
    # <a name="helping"></a> HelpCommand
    ## <a name="helping1"></a> Basic methods to override
    If you want to use `HelpCommand` class, we need to understand the basic of subclassing HelpCommand.
    Here are a list of HelpCommand relevant methods, and it's responsibility.

    @@ -285,7 +294,7 @@ Here are a list of HelpCommand relevant methods, and it's responsibility.
    4. [`HelpCommand.send_cog_help(cog)`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.send_cog_help)
    Gets called with `<prefix>help <cog>`

    ## Useful attributes
    ## <a name="helping2"></a> Useful attributes
    1. [`HelpCommand.context`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.context)
    the Context object in the help command.
    2. [`HelpCommand.clean_prefix`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.clean_prefix)
    @@ -321,7 +330,7 @@ Keep in mind, using `HelpCommand` class will require overriding every `send_x_he
    a command that should call `send_command_help` method. However, since `HelpCommand` is an empty class, it will not say
    anything.

    ## help command
    ## <a name="helping_guide1"></a> help command
    Let's work our way to create a `<prefix> help`.
    Given the documentation, [`await send_bot_help(mapping)`][sendbothelp] method receives `mapping(Mapping[Optional[Cog], List[Command]])`
    as its parameter. `await` indicates that it should be an async function.
    @@ -419,7 +428,7 @@ bot.help_command = MyHelp()
    This looks more readable than the other one. While this should cover most of your needs, you may want to know more helpful
    attribute that is available on `HelpCommand` in the official documentation.

    ## help [argument] command
    ## <a name="helping_guide2"></a> help [argument] command
    Now that the hard part is done, let's take a look at `<prefix>help [argument]`. The method responsible for this is as
    follows;
    1. `send_command_help`
    @@ -471,7 +480,7 @@ As you can see, it is very easy to create `<prefix>help [argument]`. The class a
    the given argument is a command, a cog, or a group command. It's up to you on how you want to display it, whether it's through
    a plain message, an embed or even using [`discord.ext.menus`](https://github.com/Rapptz/discord-ext-menus).

    ## Command Attributes
    ## <a name="command_attrs"></a> Command Attributes
    Let's say, someone is spamming your help command. For a normal command, all you have to do to combat this is using a
    [`cooldown`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.cooldown) decorator
    and slap that thing above the command declaration. Or, what about if you want an alias? Usually, you would put an
    @@ -525,7 +534,7 @@ will also raise an [`OnCommandCooldown`](https://discordpy.readthedocs.io/en/lat
    error if it was triggered 3 times in 5 seconds due to our `Cooldown` object. Of course, I didn't show that in the result,
    but you can try it yourself. You should handle the error in an error handler when an `OnCommandCooldown` is raised.

    ## Error handling for HelpCommand
    ## <a name="error_handling"></a> Error handling for HelpCommand
    ### Basic error message override
    What happens when `<prefix>help command` fails to get a command/cog/group? Simple, `HelpCommand.send_error_message` will
    be called. HelpCommand will not call `on_command_error` when it can't find an existing command. It will also give you an
    @@ -586,7 +595,46 @@ To be fair, you should create a proper error handler through this official docum

    There is also a lovely example by `Mysty` on error handling in general. [Here](https://gist.github.com/EvieePy/7822af90858ef65012ea500bcecf1612).
    This example shows how to properly create a global error handler and local error handler.
    ## The end

    ## <a name="cog"></a> Setting Cog for HelpCommand
    ### Super easy lol
    It works just like setting a cog on a Command object, you basically have to assign a
    [`commands.Cog`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Cog)
    instance into [`HelpCommand.cog`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.cog).
    It is pretty common for discord.py users to put a HelpCommand into a cog/separate file
    since people want organization.

    ### Code Example
    This code example is if you're in a Cog file, which you have access to a Cog instance
    ```python
    from discord.ext import commands

    # Unimportant part
    class MyHelp(commands.HelpCommand):
    async def send_bot_help(self, mapping):
    channel = self.get_destination()
    await channel.send("hey")


    class YourCog(commands.Cog):
    def __init__(self, bot):
    self.bot = bot

    # Focus here
    # Setting the cog for the help
    help_command = MyHelp()
    help_command.cog = self # Instance of YourCog class
    bot.help_command = help_command


    def setup(bot):
    bot.add_cog(YourCog(bot))
    ```
    ### How does it work?
    1. It instantiates the HelpCommand class. `help_command = MyHelp()`
    2. It assigns the instance of `YourCog`(self) into `cog` attribute

    # <a name="the_end"></a> The end
    I hope that reading this walkthrough will assist you and give a better understanding on how to subclass [`HelpCommand`][helplink].
    All the example code given are to demonstrate the feature of `HelpCommand` and feel free to try it. There are lots of
    creative things you can do to create a `HelpCommand`.
  19. InterStella0 revised this gist Apr 24, 2021. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -162,7 +162,8 @@ help command and formatting.
    | Methods / Attributes | Usage |
    |--------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
    | [HelpCommand.filter_commands()][Hgetfilter] | Filter commands to only show commands that the user can run. This help hide any secret commands from the general user. |
    | [HelpCommand.clean_prefix][Hgetcleanprefix] | Get a clean prefix that escape mentions and format them in a readable way such as `@Name` instead of `<@id>` format. |
    | [HelpCommand.clean_prefix][Hgetcleanprefix] | Get a clean prefix that escape mentions and format them in a readable way such as `@Name` instead of `<@id>` format. **Works up to version 1.7.1.** |
    | Context.clean_prefix | HelpCommand.clean_prefix was removed in 2.0 and replaced with `Context.clean_prefix` |
    | [HelpCommand.get_command_signature()][Hgetcommandsig] | Get the command signature and format them such as `command [argument]` for optional and `command <argument>` for required. |
    | [HelpCommand.prepare_help_command()][Hgetprepare] | Triggers before every `send_x_help` method are triggered, this work exactly like `command.before_invoke` |
    | [HelpCommand.get_bot_mapping()][Hgetbotmap] | Get all command that are available in the bot, sort them by Cogs and None for No Category as key in a dictionary. This method is triggered before HelpCommand.send_bot_help is triggered, and will get passed as the parameter. |
    @@ -593,7 +594,7 @@ creative things you can do to create a `HelpCommand`.
    #### Here is how my help command looks like as an inspiration.
    ![myhelp.png](https://cdn.discordapp.com/attachments/784735050071408670/789480296055177226/unknown.png)

    Here's my code if you want to take a look. [my help command](https://github.com/InterStella0/stella_bot/blob/master/cogs/helpful.py#L136-L248).
    Here's my code if you want to take a look. [my help command](https://github.com/InterStella0/stella_bot/blob/master/cogs/helpful.py#L130-L261).

    Now, of course, any question regarding `HelpCommand` should be asked in the [discord.py](https://discord.gg/dpy) server
    because I don't really check this gist as much, and because there is a lot of helpful discord.py helpers if you're nice
  20. InterStella0 revised this gist Apr 7, 2021. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -125,7 +125,7 @@ async def help(ctx, argument=None):
    await ctx.send("Invalid command or cog")

    ```
    This is an ok implementation an all, but you have to handle more than this.
    This is an ok implementation and all, but you have to handle more than this.
    I'm only simplifying the code.

    Now for the subclassed HelpCommand code.
    @@ -152,8 +152,8 @@ class MyHelp(commands.HelpCommand):

    bot.help_command = MyHelp()
    ```
    Not only does HelpCommand looks better, it is also much readable compared to the `bad way`.
    Did I mention that HelpCommand also handles invalid arguments for you? Yeah.
    Not only does HelpCommand looks better, it is also much more readable compared to the `bad way`.
    Oh, did I mention that HelpCommand also handles invalid arguments for you? Yeah. It does.

    #### <a name="utils"></a> 2. Utilities
    HelpCommand contains a bunch of useful methods you can use in order to assist you in creating your
  21. InterStella0 revised this gist Apr 7, 2021. 1 changed file with 7 additions and 4 deletions.
    11 changes: 7 additions & 4 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -81,7 +81,8 @@ discord.py.
    #### 1. Command handling specifically for HelpCommand
    Missing out on command handling that are specifically for HelpCommand.

    For instance, say my prefix is `!`.Command handling such as
    For instance, say my prefix is `!`. Command handling such as

    `!help`

    `!help <command>`
    @@ -90,10 +91,12 @@ For instance, say my prefix is `!`.Command handling such as

    `!help <cog>`

    For a HelpCommand, all of these are handled in the background, including showing
    appropriate error when `command`/`group`/`cog` are an invalid argument that were
    given. You can also show custom error when an invalid argument are given.

    For people who remove the HelpCommand? There is no handling, you have to do it yourself.

    All of these are handled in the background, including showing appropriate error
    when `command`/`group`/`cog` are an invalid argument that were given. You can
    also show custom error when an invalid argument are given.

    For example
    ##### Bad way
  22. InterStella0 revised this gist Apr 7, 2021. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -83,10 +83,14 @@ Missing out on command handling that are specifically for HelpCommand.

    For instance, say my prefix is `!`.Command handling such as
    `!help`

    `!help <command>`

    `!help <group>`

    `!help <cog>`


    All of these are handled in the background, including showing appropriate error
    when `command`/`group`/`cog` are an invalid argument that were given. You can
    also show custom error when an invalid argument are given.
  23. InterStella0 revised this gist Apr 7, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -129,7 +129,7 @@ bot = commands.Bot(command_prefix="!")
    class MyHelp(commands.HelpCommand):
    # !help
    async def send_bot_help(self, mapping):
    await self.context.send("This is help")
    await self.context.send("This is help")

    # !help <command>
    async def send_command_help(self, command):
  24. InterStella0 revised this gist Apr 7, 2021. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -184,14 +184,14 @@ class MyCog(commands.Cog):
    self.bot.help_command = self._original_help_command
    ```

    ####What does this mean?
    #### What does this mean?
    Well, first we have a `HelpCommand` made there called `MyHelpCommand`. When MyCog class is loaded,
    `bot.help_command` is stored into `self._original_help_command`. This preserve the old help command that was attached to
    the bot, and then it is assigned to a new `HelpCommand` that you've made.

    `cog_unload` is triggered when the cog is unloaded, which assign `bot.help_command` to the original help command.

    ####What good does this give?
    #### What good does this give?
    For example, you have a custom help command that is currently attached to `bot.help_command`. But you want to develop a
    new help command or modify the existing without killing the bot. So you can just unload the cog, which will assign the old help command
    to the bot so that you will always have a backup `HelpCommand` ready while you're modifying and testing your custom help.
  25. InterStella0 revised this gist Apr 7, 2021. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -3,9 +3,9 @@ This guide will walkthrough the ways to create a custom help command by subclass


    ## Brief explanation of subclassing
    [`Skip to 'Why subclassing is better'`](#start)
    [`Skip to 'Why subclassing is better'`](#why)

    [`Skip to 'Getting started'`](#why)
    [`Skip to 'Getting started'`](#start)

    In simple terms, a subclass is a way to inherit a class behaviour/attributes from another class. Here's how you would subclass
    a class in Python.
    @@ -54,7 +54,7 @@ Make sure to look and practice more into subclassing classes to understand fully
    HelpCommand.

    ## <a name="why"></a> Why subclassing HelpCommand is better
    [`Skip to 'Getting started'`](#why)
    [`Skip to 'Getting started'`](#start)


    Firstly, let me show you the wrong way of creating a help command.
  26. InterStella0 revised this gist Apr 7, 2021. 1 changed file with 159 additions and 5 deletions.
    164 changes: 159 additions & 5 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,9 @@ This guide will walkthrough the ways to create a custom help command by subclass


    ## Brief explanation of subclassing
    [`Skip ahead if you already know this.`](#start)
    [`Skip to 'Why subclassing is better'`](#start)

    [`Skip to 'Getting started'`](#why)

    In simple terms, a subclass is a way to inherit a class behaviour/attributes from another class. Here's how you would subclass
    a class in Python.
    @@ -51,6 +53,150 @@ it will have everything that class `A` have, but with an additional attribute/me
    Make sure to look and practice more into subclassing classes to understand fully on what it is before diving into subclassing
    HelpCommand.

    ## <a name="why"></a> Why subclassing HelpCommand is better
    [`Skip to 'Getting started'`](#why)


    Firstly, let me show you the wrong way of creating a help command.

    #### One of the most incorrect ways of to create a help command.

    ```python
    bot = commands.Bot(command_prefix="uwu ", help_command=None)

    # OR
    bot.help_command = None

    # OR
    bot.remove_command("help")

    @bot.command()
    async def help(ctx):
    ...
    ```
    This is directly from YouTube, which are known to have bad tutorials for
    discord.py.

    ### Why are these bad?
    #### 1. Command handling specifically for HelpCommand
    Missing out on command handling that are specifically for HelpCommand.

    For instance, say my prefix is `!`.Command handling such as
    `!help`
    `!help <command>`
    `!help <group>`
    `!help <cog>`

    All of these are handled in the background, including showing appropriate error
    when `command`/`group`/`cog` are an invalid argument that were given. You can
    also show custom error when an invalid argument are given.

    For example
    ##### Bad way
    ```py
    bot = commands.Bot(command_prefix="!", help_command=None)

    @bot.command()
    async def help(ctx, argument=None):
    # !help
    if argument is None:
    await ctx.send("This is help")

    elif argument in bot.all_commands:
    command = bot.get_command(argument)
    if isinstance(command, commands.Group):
    # !help <group>
    await ctx.send("This is help group")
    else:
    # !help <command>
    await ctx.send("This is help command")
    elif argument in bot.cogs:
    # !help <cog>
    cog = bot.get_cog(argument)
    await ctx.send("This is help cog")
    else:
    await ctx.send("Invalid command or cog")

    ```
    This is an ok implementation an all, but you have to handle more than this.
    I'm only simplifying the code.

    Now for the subclassed HelpCommand code.
    #### Good way
    ```py
    bot = commands.Bot(command_prefix="!")

    class MyHelp(commands.HelpCommand):
    # !help
    async def send_bot_help(self, mapping):
    await self.context.send("This is help")

    # !help <command>
    async def send_command_help(self, command):
    await self.context.send("This is help command")

    # !help <group>
    async def send_group_help(self, group):
    await self.context.send("This is help group")

    # !help <cog>
    async def send_cog_help(self, cog):
    await self.context.send("This is help cog")

    bot.help_command = MyHelp()
    ```
    Not only does HelpCommand looks better, it is also much readable compared to the `bad way`.
    Did I mention that HelpCommand also handles invalid arguments for you? Yeah.

    #### <a name="utils"></a> 2. Utilities
    HelpCommand contains a bunch of useful methods you can use in order to assist you in creating your
    help command and formatting.

    | Methods / Attributes | Usage |
    |--------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
    | [HelpCommand.filter_commands()][Hgetfilter] | Filter commands to only show commands that the user can run. This help hide any secret commands from the general user. |
    | [HelpCommand.clean_prefix][Hgetcleanprefix] | Get a clean prefix that escape mentions and format them in a readable way such as `@Name` instead of `<@id>` format. |
    | [HelpCommand.get_command_signature()][Hgetcommandsig] | Get the command signature and format them such as `command [argument]` for optional and `command <argument>` for required. |
    | [HelpCommand.prepare_help_command()][Hgetprepare] | Triggers before every `send_x_help` method are triggered, this work exactly like `command.before_invoke` |
    | [HelpCommand.get_bot_mapping()][Hgetbotmap] | Get all command that are available in the bot, sort them by Cogs and None for No Category as key in a dictionary. This method is triggered before HelpCommand.send_bot_help is triggered, and will get passed as the parameter. |
    | [HelpCommand.get_destination()][Hgetdestination] | Returns a Messageable on where the help command was invoked. |
    | `HelpCommand.command_callback` | The method that handles all `help/help cog/ help command/ help group` and call which method appropriately. This is useful if you want to modify the behavour of this. Though more knowledge is needed for you to do that. Most don't use this. |
    | [Context.send_help()][Csendhelp] | Calling `send_command_help` based on what the Context command object were. This is useful to be used when the user incorrectly invoke the command. Which you can call this method to show help quickly and efficiently. (Only works if you have HelpCommand configured) |

    All of this does not exist when you set `bot.help_command` to `None`. You miss out on this.


    ### 3. Modular/Dynamic
    Since it's a class, most people would make it modular. They put it in a cog for example. There is a common code given in `discord.py`
    created by Vex.
    ```python
    class MyHelpCommand(commands.MinimalHelpCommand):
    def get_command_signature(self, command):
    return '{0.clean_prefix}{1.qualified_name} {1.signature}'.format(self, command)

    class MyCog(commands.Cog):
    def __init__(self, bot):
    self._original_help_command = bot.help_command
    bot.help_command = MyHelpCommand()
    bot.help_command.cog = self

    def cog_unload(self):
    self.bot.help_command = self._original_help_command
    ```

    ####What does this mean?
    Well, first we have a `HelpCommand` made there called `MyHelpCommand`. When MyCog class is loaded,
    `bot.help_command` is stored into `self._original_help_command`. This preserve the old help command that was attached to
    the bot, and then it is assigned to a new `HelpCommand` that you've made.

    `cog_unload` is triggered when the cog is unloaded, which assign `bot.help_command` to the original help command.

    ####What good does this give?
    For example, you have a custom help command that is currently attached to `bot.help_command`. But you want to develop a
    new help command or modify the existing without killing the bot. So you can just unload the cog, which will assign the old help command
    to the bot so that you will always have a backup `HelpCommand` ready while you're modifying and testing your custom help.


    ## <a name="start"></a>Getting started
    With that out of the way, let's get started. For subclassing HelpCommand, first, you would need to know the types of `HelpCommand`.
    Where each class has their own usage.
    @@ -112,7 +258,7 @@ The resulting code will show that it have the content of `MinimalHelpCommand` bu
    ![embedminimalhelp.png](https://cdn.discordapp.com/attachments/784735050071408670/787574637117833236/unknown.png)

    ### How does this work?
    Looking over the `MinimalHelpCommand` source code, [here](https://github.com/Rapptz/discord.py/blob/master/discord/ext/commands/help.py#L1083-L1339).
    Looking over the `MinimalHelpCommand` source code, [here](https://github.com/Rapptz/discord.py/blob/master/discord/ext/commands/help.py#L1075-L1331).
    Every method that is responsible for `<prefix>help <argument>` will call [`MinimalHelpCommand.send_pages`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.MinimalHelpCommand.send_pages)
    when it is about to send the content. This makes it easy to just override `send_pages` without having to override any
    other method there are in `MinimalHelpCommand`.
    @@ -136,6 +282,8 @@ Here are a list of HelpCommand relevant methods, and it's responsibility.
    the Context object in the help command.
    2. [`HelpCommand.clean_prefix`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.clean_prefix)
    a cleanup prefix version that remove any mentions.

    For more, [`Click here`](#utils)

    Seems simple enough? Now let's see what happens if you override one of the methods. Here's an example code of how you
    would do that. This override will say `"hello!"` when you type `<prefix>help` to demonstrate on what's going on.
    @@ -225,7 +373,7 @@ I agree, this does not look pretty. But this demonstrate how to create a help co
    it looks ugly, is that we're using [`HelpCommand.get_command_signature(command)`][Hgetcommandsig].
    Let's override that method to make it a little more readable.

    We'll borrow codes from [`MinimalHelpCommand.get_command_signature`](https://github.com/Rapptz/discord.py/blob/v1.5.1/discord/ext/commands/help.py#L1144-L1145).
    We'll borrow codes from [`MinimalHelpCommand.get_command_signature`](https://github.com/Rapptz/discord.py/blob/v1.5.1/discord/ext/commands/help.py#L1144).
    Optionally, we can subclass `MinimalHelpCommand` instead of copying codes. I'm doing this as a demonstration of
    overriding other methods.

    @@ -438,7 +586,7 @@ creative things you can do to create a `HelpCommand`.
    #### Here is how my help command looks like as an inspiration.
    ![myhelp.png](https://cdn.discordapp.com/attachments/784735050071408670/789480296055177226/unknown.png)

    Here's my code if you want to take a look. [my help command](https://github.com/InterStella0/stella_bot/blob/master/cogs/helpful.py).
    Here's my code if you want to take a look. [my help command](https://github.com/InterStella0/stella_bot/blob/master/cogs/helpful.py#L136-L248).

    Now, of course, any question regarding `HelpCommand` should be asked in the [discord.py](https://discord.gg/dpy) server
    because I don't really check this gist as much, and because there is a lot of helpful discord.py helpers if you're nice
    @@ -449,4 +597,10 @@ enough to them. :D
    [minhelplink]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.MinimalHelpCommand
    [helplink]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand
    [sendbothelp]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.send_bot_help
    [Hgetcommandsig]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.get_command_signature
    [Hgetcommandsig]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.get_command_signature
    [Hgetbotmap]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.get_bot_mapping
    [Hgetdestination]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.get_destination
    [Hgetprepare]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.prepare_help_command
    [Hgetcleanprefix]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.clean_prefix
    [Hgetfilter]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.filter_commands
    [Csendhelp]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Context.send_help
  27. InterStella0 revised this gist Jan 23, 2021. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -112,7 +112,7 @@ The resulting code will show that it have the content of `MinimalHelpCommand` bu
    ![embedminimalhelp.png](https://cdn.discordapp.com/attachments/784735050071408670/787574637117833236/unknown.png)

    ### How does this work?
    Looking over the `MinimalHelpCommand` source code, [here](https://github.com/Rapptz/discord.py/blob/master/discord/ext/commands/help.py#L1075-L1331).
    Looking over the `MinimalHelpCommand` source code, [here](https://github.com/Rapptz/discord.py/blob/master/discord/ext/commands/help.py#L1083-L1339).
    Every method that is responsible for `<prefix>help <argument>` will call [`MinimalHelpCommand.send_pages`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.MinimalHelpCommand.send_pages)
    when it is about to send the content. This makes it easy to just override `send_pages` without having to override any
    other method there are in `MinimalHelpCommand`.
    @@ -225,7 +225,7 @@ I agree, this does not look pretty. But this demonstrate how to create a help co
    it looks ugly, is that we're using [`HelpCommand.get_command_signature(command)`][Hgetcommandsig].
    Let's override that method to make it a little more readable.

    We'll borrow codes from [`MinimalHelpCommand.get_command_signature`](https://github.com/Rapptz/discord.py/blob/v1.5.1/discord/ext/commands/help.py#L1144).
    We'll borrow codes from [`MinimalHelpCommand.get_command_signature`](https://github.com/Rapptz/discord.py/blob/v1.5.1/discord/ext/commands/help.py#L1144-L1145).
    Optionally, we can subclass `MinimalHelpCommand` instead of copying codes. I'm doing this as a demonstration of
    overriding other methods.

  28. InterStella0 revised this gist Jan 8, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -438,7 +438,7 @@ creative things you can do to create a `HelpCommand`.
    #### Here is how my help command looks like as an inspiration.
    ![myhelp.png](https://cdn.discordapp.com/attachments/784735050071408670/789480296055177226/unknown.png)

    Here's my code if you want to take a look. [my help command](https://github.com/InterStella0/stella_bot/blob/master/cogs/helpful.py#L131-L239).
    Here's my code if you want to take a look. [my help command](https://github.com/InterStella0/stella_bot/blob/master/cogs/helpful.py).

    Now, of course, any question regarding `HelpCommand` should be asked in the [discord.py](https://discord.gg/dpy) server
    because I don't really check this gist as much, and because there is a lot of helpful discord.py helpers if you're nice
  29. InterStella0 revised this gist Dec 25, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -438,7 +438,7 @@ creative things you can do to create a `HelpCommand`.
    #### Here is how my help command looks like as an inspiration.
    ![myhelp.png](https://cdn.discordapp.com/attachments/784735050071408670/789480296055177226/unknown.png)

    Here's my code if you want to take a look. [my help command](https://github.com/InterStella0/stella_bot/blob/master/cogs/helpful.py#L136-L248).
    Here's my code if you want to take a look. [my help command](https://github.com/InterStella0/stella_bot/blob/master/cogs/helpful.py#L131-L239).

    Now, of course, any question regarding `HelpCommand` should be asked in the [discord.py](https://discord.gg/dpy) server
    because I don't really check this gist as much, and because there is a lot of helpful discord.py helpers if you're nice
  30. InterStella0 revised this gist Dec 18, 2020. 1 changed file with 86 additions and 16 deletions.
    102 changes: 86 additions & 16 deletions HelpCommand_walkthrough_guide.md
    Original file line number Diff line number Diff line change
    @@ -56,9 +56,10 @@ With that out of the way, let's get started. For subclassing HelpCommand, first,
    Where each class has their own usage.
    ### Types of HelpCommand class
    There are a few types of HelpCommand classes that you can choose;
    1. [`DefaultHelpCommand`][defhelplink] a default help that is given by default.
    1. [`DefaultHelpCommand`][defhelplink] a help command that is given by default.
    2. [`MinimalHelpCommand`][minhelplink] a slightly better help command.
    3. [`HelpCommand`][helplink] an empty class that is the base class for every HelpCommand you see. On its own, it will not do anything.
    3. [`HelpCommand`][helplink] an empty class that is the base class for every HelpCommand you see. On its own, it will
    not do anything.

    By default, help command is using the class `DefaultHelpCommand`. This is stored in [`bot.help_command`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Bot.help_command). This attribute
    will **ONLY** accept instances that subclasses `HelpCommand`. Here is how you were to use the `DefaultHelpCommand` instance.
    @@ -74,7 +75,7 @@ bot = commands.Bot(command_prefix="uwu ", help_command=commands.DefaultHelpComma
    ```
    #### Here's an example of what that looks like.
    ![img.png](https://media.discordapp.net/attachments/784735050071408670/787570202593460224/unknown.png)
    _Now, of course, this is done by default. I'm only showing you this as a demonstration._
    _Now, of course, this is done by default. I'm only showing you this as a demonstration. Don't scream at me_

    Let's do the same thing with `MinimalHelpCommand` next.

    @@ -161,7 +162,8 @@ bot.help_command = MyHelp()
    ![hellohelpcommand.png](https://media.discordapp.net/attachments/784735050071408670/787584311221813248/unknown.png)

    Keep in mind, using `HelpCommand` class will require overriding every `send_x_help` methods. For example, `<prefix>help jsk` is
    a command that should call `send_command_help` method. However, since `HelpCommand` is an empty class, it will not say anything.
    a command that should call `send_command_help` method. However, since `HelpCommand` is an empty class, it will not say
    anything.

    ## help command
    Let's work our way to create a `<prefix> help`.
    @@ -171,16 +173,17 @@ as its parameter. `await` indicates that it should be an async function.
    * `Mapping[]` is a [`collections.abc.Mapping`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping),
    for simplicity’s sake, this usually refers to a dictionary since it's under `collections.abc.Mapping`.
    * `Optional[Cog]` is a [`Cog`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Cog)
    object that has a chance to be `None`
    object that has a chance to be `None`.
    * `List[Command]` is a list of [`Command`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Command)
    objects
    objects.
    * `Mapping[Optional[Cog], List[Command]]` means it's a map object with `Optional[Cog]` as it's key and `List[Command]` as
    its value.

    _All of these are typehints in the `typing` module. You can learn more about it [here](https://docs.python.org/3/library/typing.html#module-typing)_
    _All of these are typehints in the `typing` module. You can learn more about it [here](https://docs.python.org/3/library/typing.html#module-typing)._

    Now, for an example, we will use this `mapping` given in the parameter of `send_bot_help`. For each of the command, we'll
    use [`HelpCommand.get_command_signature(command)`][Hgetcommandsig] to get the command signature of a command in an `str` form.
    use [`HelpCommand.get_command_signature(command)`][Hgetcommandsig] to get the command signature of a command in an `str`
    form.

    #### Example Code
    ```py
    @@ -203,11 +206,12 @@ class MyHelp(commands.HelpCommand):
    bot.help_command = MyHelp()
    ```
    ### How does it work?
    1. Create an embed
    2. Use dict.items() to get an iterable of `(Cog, list[Command])`
    3. Each element in `list[Command]`, we will call `self.get_command_signature(command)` to get the proper signature of the command.
    1. Create an embed.
    2. Use dict.items() to get an iterable of `(Cog, list[Command])`.
    3. Each element in `list[Command]`, we will call `self.get_command_signature(command)` to get the proper signature of
    the command.
    4. If the list is empty, meaning, no commands is available in the cog, we don't need to show it, hence
    `if command_signatures:`
    `if command_signatures:`.
    5. `cog` has a chance to be `None`, this refers to No Category. We'll use [`getattr`](https://docs.python.org/3/library/functions.html#getattr)
    to avoid getting an error to get cog's name through [`Cog.qualified_name`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Cog.qualified_name).
    6. Using [`str.join`](https://docs.python.org/3/library/stdtypes.html#str.join) each command will be displayed on a separate line.
    @@ -260,7 +264,8 @@ This looks more readable than the other one. While this should cover most of you
    attribute that is available on `HelpCommand` in the official documentation.

    ## help [argument] command
    Now that the hard part is done, let's take a look at `<prefix>help [argument]`. The method responsible for this is as follows;
    Now that the hard part is done, let's take a look at `<prefix>help [argument]`. The method responsible for this is as
    follows;
    1. `send_command_help`
    2. `send_cog_help`
    3. `send_group_help`
    @@ -308,7 +313,61 @@ bot.help_command = MyHelp()

    As you can see, it is very easy to create `<prefix>help [argument]`. The class already handles the pain of checking whether
    the given argument is a command, a cog, or a group command. It's up to you on how you want to display it, whether it's through
    a plain message, an embed or even using discord.ext.menus.
    a plain message, an embed or even using [`discord.ext.menus`](https://github.com/Rapptz/discord-ext-menus).

    ## Command Attributes
    Let's say, someone is spamming your help command. For a normal command, all you have to do to combat this is using a
    [`cooldown`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.cooldown) decorator
    and slap that thing above the command declaration. Or, what about if you want an alias? Usually, you would put an
    aliases kwargs in the [`command`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Bot.command)
    decorator. However, HelpCommand is a bit special, It's a god damn class. You can't just put a decorator on it and expect
    it to work.


    That is when [`HelpCommand.command_attrs`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.HelpCommand.command_attrs)
    come to the rescue. This attribute can be set during the HelpCommand declaration, or a direct attribute assignment.
    According to the documentation, it accepts exactly the same thing as a [`command`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.Bot.command)
    decorator in a form of a dictionary.

    For example, we want to rename the help command as `"hell"` instead of `"help"` for whatever reason. We also want to make
    an alias for `"help"` so users can call the command with `"hell"` and `"help"`. Finally, we want to put a cooldown,
    because help command messages are big, and we don't want people to spam those. So, what would the code look like?

    #### Example Code
    ```py
    from discord.ext import commands

    attributes = {
    'name': "hell",
    'aliases': ["help", "helps"],
    'cooldown': commands.Cooldown(2, 5.0, commands.BucketType.user)
    }

    # During declaration
    help_object = commands.MinimalHelpCommand(command_attrs=attributes)

    # OR through attribute assignment
    help_object = commands.MinimalHelpCommand()
    help_object.command_attrs = attributes

    bot = commands.Bot(command_prefix="uwu ", help_command=help_object)
    ```
    ### How does it work?
    1. sets the name into `"hell"` is refers to here `'name': "hell"`.
    2. sets the aliases by passing the list of `str` to the `aliases` key, which refers to here `'aliases': ["help", "helps"]`.
    3. sets the cooldown through the `"cooldown"` key by passing in a [`Cooldown`](https://github.com/Rapptz/discord.py/blob/v1.5.1/discord/ext/commands/cooldowns.py#L70-L134)
    object. This object will make a cooldown with a rate of 2, per 5 with a bucket type [`BucketType.user`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.discord.ext.commands.BucketType),
    which in simple terms, for every [`discord.User`](https://discordpy.readthedocs.io/en/latest/api.html#discord.User),
    they can call the command twice, every 5 seconds.
    4. We're going to use `MinimalHelpCommand` as the `HelpCommand` object.

    #### The result
    ![cooldownhelp.png](https://cdn.discordapp.com/attachments/784735050071408670/789471505145659412/unknown.png)

    As you can see, the name of the help command is now `"hell"`, and you can also trigger the help command by `"help"`. It
    will also raise an [`OnCommandCooldown`](https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.CommandOnCooldown)
    error if it was triggered 3 times in 5 seconds due to our `Cooldown` object. Of course, I didn't show that in the result,
    but you can try it yourself. You should handle the error in an error handler when an `OnCommandCooldown` is raised.

    ## Error handling for HelpCommand
    ### Basic error message override
    @@ -370,10 +429,21 @@ stored in `error` variable, and show the message.
    To be fair, you should create a proper error handler through this official documentation. [Here](https://discordpy.readthedocs.io/en/latest/ext/commands/commands.html#ext-commands-error-handler).

    There is also a lovely example by `Mysty` on error handling in general. [Here](https://gist.github.com/EvieePy/7822af90858ef65012ea500bcecf1612).
    This example shows how to properly create a global error handler and local error handler.
    ## The end
    I hope that reading this walkthrough will assist you and give a better understanding on how to subclass [`HelpCommand`][helplink].
    All the example code given are to demonstrate the feature of `HelpCommand` and feel free to try it. Any
    question regarding this should be ask in [discord.py](https://discord.gg/dpy) server.
    All the example code given are to demonstrate the feature of `HelpCommand` and feel free to try it. There are lots of
    creative things you can do to create a `HelpCommand`.

    #### Here is how my help command looks like as an inspiration.
    ![myhelp.png](https://cdn.discordapp.com/attachments/784735050071408670/789480296055177226/unknown.png)

    Here's my code if you want to take a look. [my help command](https://github.com/InterStella0/stella_bot/blob/master/cogs/helpful.py#L136-L248).

    Now, of course, any question regarding `HelpCommand` should be asked in the [discord.py](https://discord.gg/dpy) server
    because I don't really check this gist as much, and because there is a lot of helpful discord.py helpers if you're nice
    enough to them. :D


    [defhelplink]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.DefaultHelpCommand
    [minhelplink]: https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.MinimalHelpCommand