Skip to content

Commit

Permalink
help: Split commands into groups by module
Browse files Browse the repository at this point in the history
Close #662, close #791. They needed to be reworked to deal with the new
6.0 loader. Same general idea, so thanks to @qsantos and @firerogue for
their work there. Eventually, I'd like to open up that category to be
settable to something other than the module name, but I'm not sure how I
want to do that so we'll leave it as an undocumented little private hack
for now.
  • Loading branch information
embolalia committed Aug 29, 2015
1 parent 5175660 commit 1252d5c
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 16 deletions.
8 changes: 8 additions & 0 deletions sopel/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ def __init__(self, config, daemon=False):
key in version *3.2* onward. Prior to *3.2*, the name of the function
as declared in the source code was used.
"""
self.commands = collections.defaultdict(list)
"""A mapping of module names to a list of commands in it."""
self.stats = {}
"""
A dictionary which maps a tuple of a function name and where it was
Expand Down Expand Up @@ -173,6 +175,12 @@ def register(self, callables, jobs, shutdowns):
for callbl in callables:
for rule in callbl.rule:
self._callables[callbl.priority][rule].append(callbl)
if hasattr(callbl, 'commands'):
module_name = callbl.__module__.rsplit('.', 1)[-1]
# TODO doc and make decorator for this. Not sure if this is how
# it should work yet, so not making it public for 6.0.
category = getattr(callbl, 'category', module_name)
self.commands[category].append(callbl.commands[0])
for command, docs in callbl._docs.items():
self.doc[command] = docs
for func in jobs:
Expand Down
38 changes: 22 additions & 16 deletions sopel/modules/help.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@
"""
from __future__ import unicode_literals

import textwrap

from sopel.formatting import bold
from sopel.module import commands, rule, example, priority
from sopel.tools import iterkeys


@rule('$nick' '(?i)(help|doc) +([A-Za-z]+)(?:\?+)?$')
@example('.help tell')
@commands('help')
@commands('help', 'commands')
@priority('low')
def help(bot, trigger):
"""Shows a command's documentation, and possibly an example."""
if not trigger.group(2):
bot.reply('Say .help <command> (for example .help c) to get help for a command, or .commands for a list of commands.')
else:
if trigger.group(2):
name = trigger.group(2)
name = name.lower()

Expand All @@ -40,18 +40,24 @@ def help(bot, trigger):
msgfun(line)
if bot.doc[name][1]:
msgfun('e.g. ' + bot.doc[name][1])
else:
if not trigger.is_privmsg:
bot.reply("I'm sending you a list of my commands in a private message!")
bot.say(
'You can see more info about any of these commands by doing .help '
'<command> (e.g. .help time)',
trigger.nick
)


@commands('commands')
@priority('low')
def commands(bot, trigger):
"""Return a list of bot's commands"""
names = ', '.join(sorted(iterkeys(bot.doc)))
if not trigger.is_privmsg:
bot.reply("I am sending you a private message of all my commands!")
bot.msg(trigger.nick, 'Commands I recognise: ' + names + '.', max_messages=10)
bot.msg(trigger.nick, ("For help, do '%s: help example' where example is the " +
"name of the command you want help for.") % bot.nick)
name_length = max(6, max(len(k) for k in bot.commands.keys()))
for category, cmds in bot.commands.items():
category = category.upper().ljust(name_length)
cmds = ' '.join(cmds)
msg = bold(category) + ' ' + cmds
indent = ' ' * (name_length + 2)
msg = textwrap.wrap(msg, subsequent_indent=indent)
for line in msg:
bot.say(line, trigger.nick)


@rule('$nick' r'(?i)help(?:[?!]+)?$')
Expand Down

0 comments on commit 1252d5c

Please sign in to comment.