@ -51,6 +51,64 @@ from .errors import CommandError
# Type <prefix>help command for more info on a command.
# You can also type <prefix>help category for more info on a category.
class Paginator :
""" A class that aids in paginating code blocks for Discord messages.
Attributes
- - - - - - - - - - -
prefix : str
The prefix inserted to every page . e . g . three backticks .
suffix : str
The suffix appended at the end of every page . e . g . three backticks .
max_size : int
The maximum amount of codepoints allowed in a page .
"""
def __init__ ( self , prefix = ' ``` ' , suffix = ' ``` ' , max_size = 2000 ) :
self . prefix = prefix
self . suffix = suffix
self . max_size = max_size - len ( suffix )
self . _current_page = [ prefix ]
self . _count = len ( prefix ) + 1 # prefix + newline
self . _pages = [ ]
def add_line ( self , line = ' ' , * , empty = False ) :
""" Adds a line to the current page.
Parameters
- - - - - - - - - - -
line : str
The line to add .
empty : bool
Indicates if another empty line should be added .
"""
if self . _count + len ( line ) + 1 > self . max_size :
self . close_page ( )
self . _count + = len ( line ) + 1
self . _current_page . append ( line )
if empty :
self . _current_page . append ( ' ' )
self . _count + = 1
def close_page ( self ) :
""" Prematurely terminate a page. """
self . _current_page . append ( self . suffix )
self . _pages . append ( ' \n ' . join ( self . _current_page ) )
self . _current_page = [ self . prefix ]
self . _count = len ( self . prefix ) + 1 # prefix + newline
@property
def pages ( self ) :
""" Returns the rendered list of pages. """
# we have more than just the prefix in our current page
if len ( self . _current_page ) > 1 :
self . close_page ( )
return self . _pages
def __repr__ ( self ) :
fmt = ' <Paginator prefix: {0.prefix} suffix: {0.suffix} max_size: {0.max_size} count: {0._count} > '
return fmt . format ( self )
class HelpFormatter :
""" The default base implementation that handles formatting of the help
@ -190,18 +248,6 @@ class HelpFormatter:
iterator = self . command . commands . items ( ) if not self . is_cog ( ) else self . context . bot . commands . items ( )
return filter ( predicate , iterator )
def _check_new_page ( self ) :
# be a little on the safe side
# we're adding 1 extra newline per page
if self . _count + len ( self . _current_page ) > = 1980 :
# add the page
self . _current_page . append ( ' ``` ' )
self . _pages . append ( ' \n ' . join ( self . _current_page ) )
self . _current_page = [ ' ``` ' ]
self . _count = 4
return True
return False
def _add_subcommands_to_page ( self , max_width , commands ) :
for name , command in commands :
if name in command . aliases :
@ -210,10 +256,7 @@ class HelpFormatter:
entry = ' { 0:< {width} } {1} ' . format ( name , command . short_doc , width = max_width )
shortened = self . shorten ( entry )
self . _count + = len ( shortened )
if self . _check_new_page ( ) :
self . _count + = len ( shortened )
self . _current_page . append ( shortened )
self . _paginator . add_line ( shortened )
def format_help_for ( self , context , command_or_bot ) :
""" Formats the help page and handles the actual heavy lifting of how
@ -246,9 +289,7 @@ class HelpFormatter:
list
A paginated output of the help command .
"""
self . _pages = [ ]
self . _count = 4 # ``` + '\n'
self . _current_page = [ ' ``` ' ]
self . _paginator = Paginator ( )
# we need a padding of ~80 or so
@ -256,30 +297,21 @@ class HelpFormatter:
if description :
# <description> portion
self . _current_page . append ( description )
self . _current_page . append ( ' ' )
self . _count + = len ( description )
self . _paginator . add_line ( description , empty = True )
if isinstance ( self . command , Command ) :
# <signature portion>
signature = self . get_command_signature ( )
self . _count + = 2 + len ( signature ) # '\n' sig '\n'
self . _current_page . append ( signature )
self . _current_page . append ( ' ' )
self . _paginator . add_line ( signature , empty = True )
# <long doc> section
if self . command . help :
self . _count + = 2 + len ( self . command . help )
self . _current_page . append ( self . command . help )
self . _current_page . append ( ' ' )
self . _check_new_page ( )
self . _paginator . add_line ( self . command . help , empty = True )
# end it here if it's just a regular command
if not self . has_subcommands ( ) :
self . _current_page . append ( ' ``` ' )
self . _pages . append ( ' \n ' . join ( self . _current_page ) )
return self . _pages
self . _paginator . close_page ( )
return self . _paginator . pages
max_width = self . max_name_size
@ -295,25 +327,15 @@ class HelpFormatter:
# there simply is no prettier way of doing this.
commands = list ( commands )
if len ( commands ) > 0 :
self . _current_page . append ( category )
self . _count + = len ( category )
self . _check_new_page ( )
self . _paginator . add_line ( category )
self . _add_subcommands_to_page ( max_width , commands )
else :
self . _current_page . append ( ' Commands: ' )
self . _count + = 1 + len ( self . _current_page [ - 1 ] )
self . _paginator . add_line ( ' Commands: ' )
self . _add_subcommands_to_page ( max_width , self . filter_command_list ( ) )
# add the ending note
self . _current_page . append ( ' ' )
self . _paginator . add_line ( )
ending_note = self . get_ending_note ( )
self . _count + = len ( ending_note )
self . _check_new_page ( )
self . _current_page . append ( ending_note )
if len ( self . _current_page ) > 1 :
self . _current_page . append ( ' ``` ' )
self . _pages . append ( ' \n ' . join ( self . _current_page ) )
return self . _pages
self . _paginator . add_line ( ending_note )
return self . _paginator . pages