Groups aliased commands with original (#16)

diff --git a/subcommands.go b/subcommands.go
index bb5ff01..951a4f6 100644
--- a/subcommands.go
+++ b/subcommands.go
@@ -26,6 +26,7 @@
 	"os"
 	"path"
 	"sort"
+	"strings"
 )
 
 // A Command represents a single command.
@@ -197,8 +198,32 @@
 		fmt.Fprintf(w, "Subcommands for %s:\n", group.name)
 	}
 	sort.Sort(group)
+
+	aliases := make(map[string][]string)
 	for _, cmd := range group.commands {
-		fmt.Fprintf(w, "\t%-15s  %s\n", cmd.Name(), cmd.Synopsis())
+		if alias, ok := cmd.(*aliaser); ok {
+			root := dealias(alias).Name()
+
+			if _, ok := aliases[root]; !ok {
+				aliases[root] = []string{}
+			}
+			aliases[root] = append(aliases[root], alias.Name())
+		}
+	}
+
+	for _, cmd := range group.commands {
+		if _, ok := cmd.(*aliaser); ok {
+			continue
+		}
+
+		name := cmd.Name()
+		names := []string{name}
+
+		if a, ok := aliases[name]; ok {
+			names = append(names, a...)
+		}
+
+		fmt.Fprintf(w, "\t%-15s  %s\n", strings.Join(names, ", "), cmd.Synopsis())
 	}
 	fmt.Fprintln(w)
 }
@@ -348,6 +373,16 @@
 	return &aliaser{alias, cmd}
 }
 
+// dealias recursivly dealiases a command until a non-aliased command
+// is reached.
+func dealias(cmd Command) Command {
+	if alias, ok := cmd.(*aliaser); ok {
+		return dealias(alias.Command)
+	}
+
+	return cmd
+}
+
 // DefaultCommander is the default commander using flag.CommandLine for flags
 // and os.Args[0] for the command name.
 var DefaultCommander *Commander