Set and respect Hidden on group
diff --git a/command.go b/command.go
index f8579d2..13332ae 100644
--- a/command.go
+++ b/command.go
@@ -23,9 +23,6 @@
 	// Whether positional arguments are required
 	ArgsRequired bool
 
-	// If true, the option is not displayed in the help output
-	Hidden bool
-
 	commands            []*Command
 	hasBuiltinHelpGroup bool
 	args                []*Arg
diff --git a/command_private.go b/command_private.go
index 0a77ab2..f2a2435 100644
--- a/command_private.go
+++ b/command_private.go
@@ -79,6 +79,8 @@
 
 			subc, err := c.AddCommand(subcommand, shortDescription, longDescription, ptrval.Interface())
 
+			subc.Hidden = mtag.Get("hidden") != ""
+
 			if err != nil {
 				return true, err
 			}
@@ -235,18 +237,23 @@
 	c[i], c[j] = c[j], c[i]
 }
 
-// FIXME: maybe call this sortedVisibleCommands ?
-func (c *Command) sortedCommands() []*Command {
-	ret := make(commandList, 0, len(c.commands))
+func (c *Command) sortedVisibleCommands() []*Command {
+	ret := commandList(c.visibleCommands())
+	sort.Sort(ret)
 
-	for _, e := range c.commands {
-		if !e.Hidden {
-			ret = append(ret, e)
+	return []*Command(ret)
+}
+
+func (c *Command) visibleCommands() []*Command {
+	ret := make([]*Command, 0, len(c.commands))
+
+	for _, cmd := range c.commands {
+		if !cmd.Hidden {
+			ret = append(ret, cmd)
 		}
 	}
 
-	sort.Sort(ret)
-	return []*Command(ret)
+	return ret
 }
 
 func (c *Command) match(name string) bool {
diff --git a/group.go b/group.go
index 8b609a3..0e74f92 100644
--- a/group.go
+++ b/group.go
@@ -32,6 +32,9 @@
 	// The namespace of the group
 	Namespace string
 
+	// If true, the group is not displayed in the help or man page
+	Hidden bool
+
 	// The parent of the group or nil if it has no parent
 	parent interface{}
 
diff --git a/group_private.go b/group_private.go
index 96c3619..b54bfd2 100644
--- a/group_private.go
+++ b/group_private.go
@@ -211,6 +211,7 @@
 		}
 
 		group.Namespace = mtag.Get("namespace")
+		group.Hidden = mtag.Get("hidden") != ""
 
 		return true, nil
 	}
diff --git a/help.go b/help.go
index fab5450..c0b808d 100644
--- a/help.go
+++ b/help.go
@@ -340,10 +340,12 @@
 					co, cc = "<", ">"
 				}
 
-				if len(allcmd.commands) > 3 {
+				visibleCommands := allcmd.visibleCommands()
+
+				if len(visibleCommands) > 3 {
 					fmt.Fprintf(wr, " %scommand%s", co, cc)
 				} else {
-					subcommands := allcmd.sortedCommands()
+					subcommands := allcmd.sortedVisibleCommands()
 					names := make([]string, len(subcommands))
 
 					for i, subc := range subcommands {
@@ -380,12 +382,12 @@
 
 			// Skip built-in help group for all commands except the top-level
 			// parser
-			if grp.isBuiltinHelp && c != p.Command {
+			if grp.Hidden || (grp.isBuiltinHelp && c != p.Command) {
 				return
 			}
 
 			for _, info := range grp.options {
-				if !info.canCli() {
+				if !info.canCli() || info.Hidden {
 					continue
 				}
 
@@ -435,7 +437,7 @@
 		c = c.Active
 	}
 
-	scommands := cmd.sortedCommands()
+	scommands := cmd.sortedVisibleCommands()
 
 	if len(scommands) > 0 {
 		maxnamelen := maxCommandLength(scommands)
diff --git a/man.go b/man.go
index cd4cadd..5529d92 100644
--- a/man.go
+++ b/man.go
@@ -38,8 +38,12 @@
 
 func writeManPageOptions(wr io.Writer, grp *Group) {
 	grp.eachGroup(func(group *Group) {
+		if grp.Hidden {
+			return
+		}
+
 		for _, opt := range group.options {
-			if !opt.canCli() {
+			if !opt.canCli() || opt.Hidden {
 				continue
 			}
 
@@ -91,11 +95,15 @@
 }
 
 func writeManPageSubcommands(wr io.Writer, name string, root *Command) {
-	commands := root.sortedCommands()
+	commands := root.sortedVisibleCommands()
 
 	for _, c := range commands {
 		var nn string
 
+		if c.Hidden {
+			continue
+		}
+
 		if len(name) != 0 {
 			nn = name + " " + c.Name
 		} else {
@@ -178,7 +186,7 @@
 
 	writeManPageOptions(wr, p.Command.Group)
 
-	if len(p.commands) > 0 {
+	if len(p.visibleCommands()) > 0 {
 		fmt.Fprintln(wr, ".SH COMMANDS")
 
 		writeManPageSubcommands(wr, "", p.Command)
diff --git a/option.go b/option.go
index afad7e4..8764e25 100644
--- a/option.go
+++ b/option.go
@@ -51,9 +51,6 @@
 	// error.
 	Required bool
 
-	// If true, the option is not displayed in the help output
-	Hidden bool
-
 	// A name for the value of an option shown in the Help as --flag [ValueName]
 	ValueName string
 
@@ -65,6 +62,9 @@
 	// If non empty, only a certain set of values is allowed for an option.
 	Choices []string
 
+	// If true, the option is not displayed in the help or man page
+	Hidden bool
+
 	// The group which the option belongs to
 	group *Group
 
diff --git a/parser_private.go b/parser_private.go
index 76be4a7..7469c03 100644
--- a/parser_private.go
+++ b/parser_private.go
@@ -114,7 +114,7 @@
 }
 
 func (p *parseState) estimateCommand() error {
-	commands := p.command.sortedCommands()
+	commands := p.command.sortedVisibleCommands()
 	cmdnames := make([]string, len(commands))
 
 	for i, v := range commands {