diff --git a/base.go b/base.go index 450b3fa..de2fd19 100644 --- a/base.go +++ b/base.go @@ -143,7 +143,7 @@ type base struct { // helpVars custom add vars for render help template. helpVars map[string]any - // Ctx for command + // Ctx data for command, allow add custom context data. Ctx *Context // Logo ASCII logo setting Logo *Logo diff --git a/cmd.go b/cmd.go index 1421ea8..71c08d2 100644 --- a/cmd.go +++ b/cmd.go @@ -55,6 +55,7 @@ type Command struct { // Name is the command name. Name string // Desc is the command description message. + // Can use string-var in contents, eg: {$cmd} Desc string // Aliases is the command name's alias names @@ -100,6 +101,7 @@ type Command struct { // Func is the command handler func. Func Runner Func RunnerFunc // Help is the long help message text + // Can use string-var in contents, eg: {$cmd} Help string // HelpRender custom render cmd help message HelpRender func(c *Command) @@ -574,7 +576,6 @@ func (c *Command) Root() *Command { if c.parent != nil { return c.parent.Root() } - return c } @@ -598,7 +599,6 @@ func (c *Command) ParentName() string { if c.parent != nil { return c.parent.Name } - return "" } diff --git a/gflag/args.go b/gflag/args.go index 5b554fa..25bc812 100644 --- a/gflag/args.go +++ b/gflag/args.go @@ -238,14 +238,26 @@ func (ags *CliArgs) BuildArgsHelp() string { return "" } + indent := strutil.Repeat(" ", ags.argWidth+3) + var sb strings.Builder for _, arg := range ags.args { sb.WriteString(fmt.Sprintf( - "%s %s%s\n", + " %s %s", strutil.PadRight(arg.HelpName(), " ", ags.argWidth), getRequiredMark(arg.Required), - strutil.UpperFirst(arg.Desc), )) + + // multi lines + if strings.ContainsRune(arg.Desc, '\n') { + first, other := strutil.QuietCut(arg.Desc, "\n") + sb.WriteString(strutil.UpperFirst(first)) + sb.WriteByte('\n') + sb.WriteString(strutil.Indent(other, indent)) + } else { + sb.WriteString(strutil.UpperFirst(arg.Desc)) + } + sb.WriteByte('\n') } return sb.String() diff --git a/gflag/opts.go b/gflag/opts.go index 0f0da7d..f2808e1 100644 --- a/gflag/opts.go +++ b/gflag/opts.go @@ -19,6 +19,9 @@ const ( shortSepChar = "," ) +// DefaultOptWidth for render help +var DefaultOptWidth = 20 + // CliOpts cli options management type CliOpts struct { // name inherited from gcli.Command @@ -55,6 +58,7 @@ func (ops *CliOpts) InitFlagSet(name string) { ops.fSet.SetOutput(io.Discard) // nothing to do ... render usage on after parsed ops.fSet.Usage = func() {} + ops.optMaxLen = DefaultOptWidth } // SetName for CliArgs @@ -342,7 +346,8 @@ func (ops *CliOpts) checkFlagInfo(opt *CliOpt) string { helpLen := opt.helpNameLen() // fix: must exclude Hidden option if !opt.Hidden { - ops.optMaxLen = mathutil.MaxInt(ops.optMaxLen, helpLen) + // +7: type placeholder width + ops.optMaxLen = mathutil.MaxInt(ops.optMaxLen, helpLen+6) } // check short names diff --git a/help.go b/help.go index ca32e91..246be25 100644 --- a/help.go +++ b/help.go @@ -183,10 +183,9 @@ var CmdHelpTemplate = `{{.Desc}} Global Options: {{.GOpts}}{{end}}{{if .Options}} Options: -{{.Options}}{{end}}{{if .Cmd.HasArgs}} -Arguments:{{range $a := .Cmd.Args}} - {{$a.HelpName | printf "%-12s"}} {{if $a.Required}}*{{end}}{{$a.Desc | ucFirst}}{{end}} -{{end}}{{ if .Subs }} +{{.Options}}{{end}}{{if .ArgsHelp}} +Arguments: +{{.ArgsHelp}}{{end}}{{ if .Subs }} Subcommands:{{range $n,$c := .Subs}} {{$c.Name | paddingName }} {{$c.HelpDesc}}{{if $c.Aliases}} (alias: {{ join $c.Aliases ","}}){{end}}{{end}} {{end}}{{if .Cmd.Examples}} @@ -223,6 +222,8 @@ func (c *Command) ShowHelp() (err error) { "GOpts": nil, // parse options to string "Options": c.Flags.BuildOptsHelp(), + // parse options to string + "ArgsHelp": c.Flags.BuildArgsHelp(), // always upper first char "Desc": c.HelpDesc(), // user custom help vars