@@ -963,12 +963,39 @@ impl HelpTemplate<'_, '_> {
963963
964964 let next_line_help = self . will_subcommands_wrap ( cmd. get_subcommands ( ) , longest) ;
965965
966- for ( i, ( sc_str, sc) ) in ord_v. into_iter ( ) . enumerate ( ) {
966+ // First for the commands that don't have a heading
967+ for ( i, ( sc_str, sc) ) in ord_v
968+ . clone ( )
969+ . into_iter ( )
970+ . filter ( |item| !should_show_help_heading ( item. 1 ) )
971+ . enumerate ( )
972+ {
973+ debug ! ( "Processing without heading {}" , sc. get_name( ) ) ;
967974 if 0 < i {
968975 self . writer . push_str ( "\n " ) ;
969976 }
970977 self . write_subcommand ( sc_str. 1 , sc, next_line_help, longest) ;
971978 }
979+
980+ let header = & self . styles . get_header ( ) ;
981+ let mut current_heading = "" ;
982+
983+ // Then for the commands that do have a heading
984+ for ( sc_str, sc) in ord_v
985+ . into_iter ( )
986+ . filter ( |item| should_show_help_heading ( item. 1 ) )
987+ {
988+ debug ! ( "Processing with heading {}" , sc. get_name( ) ) ;
989+ self . writer . push_str ( "\n " ) ;
990+ if sc. get_help_heading ( ) . unwrap ( ) != current_heading {
991+ current_heading = sc. get_help_heading ( ) . unwrap ( ) ;
992+ debug ! ( "Heading changed; print new heading {}." , current_heading) ;
993+ self . writer . push_str ( "\n " ) ;
994+ let _ = write ! ( self . writer, "{header}{current_heading}:{header:#}\n " , ) ;
995+ }
996+
997+ self . write_subcommand ( sc_str. 1 , sc, next_line_help, longest) ;
998+ }
972999 }
9731000
9741001 /// Will use next line help on writing subcommands.
@@ -1142,6 +1169,10 @@ fn should_show_subcommand(subcommand: &Command) -> bool {
11421169 !subcommand. is_hide_set ( )
11431170}
11441171
1172+ fn should_show_help_heading ( subcommand : & Command ) -> bool {
1173+ subcommand. is_help_heading_set ( )
1174+ }
1175+
11451176#[ cfg( test) ]
11461177mod test {
11471178 #[ test]
0 commit comments