@@ -11,6 +11,8 @@ import (
1111 "strings"
1212 "unicode/utf8"
1313
14+ "go.followtheprocess.codes/hue/tabwriter"
15+
1416 publicflag "go.followtheprocess.codes/cli/flag"
1517
1618 "go.followtheprocess.codes/cli/internal/arg"
@@ -481,6 +483,11 @@ func showHelp(cmd *Command) error {
481483 s := & strings.Builder {}
482484 s .Grow (helpBufferSize )
483485
486+ // One tabwriter threaded through every aligned section, reset
487+ // between them with ResetTabwriter so only the first section pays the
488+ // internal-buffer allocation cost.
489+ tw := style .Tabwriter (s )
490+
484491 // If we have a short description, write that
485492 if cmd .short != "" {
486493 s .WriteString (cmd .short )
@@ -517,7 +524,7 @@ func showHelp(cmd *Command) error {
517524
518525 // If we have defined, list them explicitly and use their descriptions
519526 if len (cmd .args ) != 0 {
520- if err := writeArgumentsSection (cmd , s ); err != nil {
527+ if err := writeArgumentsSection (cmd , s , tw ); err != nil {
521528 return err
522529 }
523530 }
@@ -529,7 +536,7 @@ func showHelp(cmd *Command) error {
529536
530537 // Now show subcommands
531538 if len (cmd .subcommands ) != 0 {
532- if err := writeSubcommands (cmd , s ); err != nil {
539+ if err := writeSubcommands (cmd , s , tw ); err != nil {
533540 return err
534541 }
535542 }
@@ -546,7 +553,7 @@ func showHelp(cmd *Command) error {
546553 s .WriteString (optionsTitle )
547554 s .WriteString (":\n \n " )
548555
549- if err := writeFlags (cmd , s ); err != nil {
556+ if err := writeFlags (cmd , s , tw ); err != nil {
550557 return err
551558 }
552559
@@ -584,11 +591,11 @@ func writePositionalArgs(cmd *Command, s *strings.Builder) {
584591
585592// writeArgumentsSection writes the entire positional arguments block to the help
586593// text string builder.
587- func writeArgumentsSection (cmd * Command , s * strings.Builder ) error {
594+ func writeArgumentsSection (cmd * Command , s * strings.Builder , tw * tabwriter. Writer ) error {
588595 s .WriteString ("\n \n " )
589596 s .WriteString (argumentsTitle )
590597 s .WriteString (":\n \n " )
591- tw := style .Tabwriter ( s )
598+ style .ResetTabwriter ( tw , s )
592599
593600 for _ , arg := range cmd .args {
594601 if def := arg .Default (); def != "" {
@@ -638,7 +645,7 @@ func writeExamples(cmd *Command, s *strings.Builder) {
638645}
639646
640647// writeSubcommands writes the subcommand block to the help text string builder.
641- func writeSubcommands (cmd * Command , s * strings.Builder ) error {
648+ func writeSubcommands (cmd * Command , s * strings.Builder , tw * tabwriter. Writer ) error {
642649 // If there were examples, the last one would have printed a newline
643650 if len (cmd .examples ) != 0 {
644651 s .WriteByte ('\n' )
@@ -650,7 +657,8 @@ func writeSubcommands(cmd *Command, s *strings.Builder) error {
650657 s .WriteByte (':' )
651658 s .WriteString ("\n \n " )
652659
653- tw := style .Tabwriter (s )
660+ style .ResetTabwriter (tw , s )
661+
654662 for _ , subcommand := range cmd .subcommands {
655663 fmt .Fprintf (tw , " %s\t %s\n " , style .Bold .Text (subcommand .name ), subcommand .short )
656664 }
@@ -663,8 +671,8 @@ func writeSubcommands(cmd *Command, s *strings.Builder) error {
663671}
664672
665673// writeFlags writes the flag usage block to the help text string builder.
666- func writeFlags (cmd * Command , s * strings.Builder ) error {
667- tw := style .Tabwriter ( s )
674+ func writeFlags (cmd * Command , s * strings.Builder , tw * tabwriter. Writer ) error {
675+ style .ResetTabwriter ( tw , s )
668676
669677 for name , fl := range cmd .flags .Sorted () {
670678 var shorthand string
0 commit comments