Padded help output, because why not.

This commit is contained in:
Andrey Petrov 2015-01-01 16:17:52 -08:00
parent fb7cd83821
commit 3b5f4faf76
2 changed files with 70 additions and 14 deletions

View File

@ -3,7 +3,6 @@ package chat
import (
"errors"
"fmt"
"sort"
"strings"
"sync"
)
@ -23,22 +22,25 @@ var ErrMissingPrefix = errors.New("command missing prefix")
// Command is a definition of a handler for a command.
type Command struct {
Prefix string
// The command's key, such as /foo
Prefix string
// Extra help regarding arguments
PrefixHelp string
Help string
Handler func(*Channel, CommandMsg) error
// If omitted, command is hidden from /help
Help string
Handler func(*Channel, CommandMsg) error
}
// Commands is a registry of available commands.
type Commands struct {
commands map[string]Command
commands map[string]*Command
sync.RWMutex
}
// NewCommands returns a new Commands registry.
func NewCommands() *Commands {
return &Commands{
commands: map[string]Command{},
commands: map[string]*Command{},
}
}
@ -52,7 +54,7 @@ func (c *Commands) Add(cmd Command) error {
return ErrMissingPrefix
}
c.commands[cmd.Prefix] = cmd
c.commands[cmd.Prefix] = &cmd
return nil
}
@ -91,13 +93,9 @@ func (c *Commands) Help() string {
c.RLock()
defer c.RUnlock()
r := []string{}
for _, cmd := range c.commands {
r = append(r, fmt.Sprintf("%s %s - %s", cmd.Prefix, cmd.PrefixHelp, cmd.Help))
}
sort.Strings(r)
return strings.Join(r, Newline)
// TODO: Could cache this...
help := NewCommandsHelp(c)
return help.String()
}
var defaultCmdHandlers *Commands

58
chat/help.go Normal file
View File

@ -0,0 +1,58 @@
package chat
import (
"fmt"
"sort"
"strings"
)
type helpItem struct {
Prefix string
Text string
}
type help struct {
items []helpItem
prefixWidth int
}
// NewCommandsHelp creates a help container from a commands container.
func NewCommandsHelp(c *Commands) *help {
lookup := map[string]struct{}{}
h := help{
items: []helpItem{},
}
for _, cmd := range c.commands {
if cmd.Help == "" {
// Skip hidden commands.
continue
}
_, exists := lookup[cmd.Prefix]
if exists {
// Duplicate (alias)
continue
}
lookup[cmd.Prefix] = struct{}{}
prefix := fmt.Sprintf("%s %s", cmd.Prefix, cmd.PrefixHelp)
h.add(helpItem{prefix, cmd.Help})
}
return &h
}
func (h *help) add(item helpItem) {
h.items = append(h.items, item)
if len(item.Prefix) > h.prefixWidth {
h.prefixWidth = len(item.Prefix)
}
}
func (h help) String() string {
r := []string{}
format := fmt.Sprintf("%%-%ds - %%s", h.prefixWidth)
for _, item := range h.items {
r = append(r, fmt.Sprintf(format, item.Prefix, item.Text))
}
sort.Strings(r)
return strings.Join(r, Newline)
}