~/bend-docscommunity

main.bend checks

raw source on the hub · import 0xba6940aab8a335b70bf79944bd9b53c4/main.bend as Main

shake: CLI argument parser for Bend 2. parse reads argv against a Cli; help writes usage for a command path. A compiled binary's runtime keeps --help (and --threads, --gpu, --gpu-build) and strips them; help is the subcommand that prints usage. A -- ends option parsing.

1 import
import Base

Types

type ArgKind source · line 8 · raw

Data

a flag, a valued option, a positional, or a rest positional

type Arg source · line 15 · raw

Data

one argument: name is the binding key; short/long are the CLI spellings

type Sub source · line 28 · raw

Data

a nested command

type Cli source · line 37 · raw

Data

the program: name, about, optional version, top-level args and commands

type Bind source · line 47 · raw

Data

one bound name and its text

type Matched source · line 51 · raw

Data

a successful parse: selected command path and the bindings

type ParseErr source · line 55 · raw

Data

a failed parse. NeedHelp is help / help <path>

type Mode source · line 63 · raw

Data

how the next token is read

type St source · line 70 · raw

Data

the walker: current spec, accumulated specs, selected path, bindings

type How source · line 84 · raw

Data

the page a help walk has reached

Definitions

def app source · line 95 · raw

@+name:String -> @+about:String -> @version:Maybe<&2, String> -> @args:List<&2, Arg> -> @subs:List<&2, Sub> -> Cli

a program spec

def sub source · line 100 · raw

@+name:String -> @+about:String -> @args:List<&2, Arg> -> @subs:List<&2, Sub> -> Sub

a nested command

def flag source · line 105 · raw

@+name:String -> @short:Maybe<&2, String> -> @long:Maybe<&2, String> -> @+help:String -> Arg

a boolean flag

def opt source · line 110 · raw

@+name:String -> @short:Maybe<&2, String> -> @long:Maybe<&2, String> -> @+help:String -> @required:Bool -> @default:Maybe<&2, String> -> @choices:List<&2, String> -> Arg

a valued option

def pos source · line 116 · raw

@+name:String -> @+help:String -> @required:Bool -> @default:Maybe<&2, String> -> @choices:List<&2, String> -> Arg

a positional

def rest source · line 121 · raw

@+name:String -> @+help:String -> @required:Bool -> @default:Maybe<&2, String> -> @choices:List<&2, String> -> Arg

a rest positional: every leftover word, as one name

def help.max source · line 126 · raw

@+a:Nat -> @+b:Nat -> Nat

the larger of two Nats

def help.spaces source · line 130 · raw

@n:Nat -> String

n spaces

def help.pad source · line 138 · raw

@+s:String -> @n:Nat -> String

s padded on the right to width n

def text.of source · line 142 · raw

@m:Maybe<&2, String> -> @+d:String -> String

a Maybe string's text, or the default

def looks_flag source · line 146 · raw

@+s:String -> Bool

whether a string is a flag token (- alone is not)

def from.rev source · line 150 · raw

@cs:List<&2, Char> -> String

chars reversed into a string

def cut_eq.pick source · line 154 · raw

@eq:Bool -> @acc:List<&2, Char> -> @t:List<&2, Char> -> @rest:Pair(String, Maybe<&2, String>) -> Pair(String, Maybe<&2, String>)

name and an optional =value, once the next char is known

def cut_eq.chr source · line 163 · raw

@+c:Char -> @t:List<&2, Char> -> @acc:List<&2, Char> -> @rest:Pair(String, Maybe<&2, String>) -> Pair(String, Maybe<&2, String>)

one char of a name=value cut

def cut_eq.go source · line 168 · raw

@cs:List<&2, Char> -> @+acc:List<&2, Char> -> Pair(String, Maybe<&2, String>)

name and an optional =value from the body after --

def cut_eq source · line 177 · raw

@s:String -> Pair(String, Maybe<&2, String>)

name and an optional =value

def short_of.go source · line 181 · raw

@+name:String -> @+rest:String -> Pair(String, Maybe<&2, String>)

a short spelling and a glued value

def short_of source · line 185 · raw

@+s:String -> Pair(String, Maybe<&2, String>)

the short name and optional glued value of the body after -

def by_long.hit source · line 189 · raw

@a:Arg -> @+name:String -> Bool

whether this Arg's long spelling is name

def by_long.at source · line 194 · raw

@hit:Bool -> @h:Arg -> @rest:Maybe<&2, Arg> -> Maybe<&2, Arg>

this Arg when the long spelling matches, else the rest

def by_long source · line 202 · raw

@args:List<&2, Arg> -> @+name:String -> Maybe<&2, Arg>

the Arg with this long spelling, if any

def by_short.hit source · line 210 · raw

@a:Arg -> @+name:String -> Bool

whether this Arg's short spelling is name

def by_short.at source · line 215 · raw

@hit:Bool -> @h:Arg -> @rest:Maybe<&2, Arg> -> Maybe<&2, Arg>

this Arg when the short spelling matches, else the rest

def by_short source · line 223 · raw

@args:List<&2, Arg> -> @+name:String -> Maybe<&2, Arg>

the Arg with this short spelling, if any

def by_name.hit source · line 231 · raw

@a:Arg -> @+name:String -> Bool

whether this Arg's name is name

def by_name.at source · line 236 · raw

@hit:Bool -> @h:Arg -> @rest:Maybe<&2, Arg> -> Maybe<&2, Arg>

this Arg when the binding name matches, else the rest

def by_name source · line 244 · raw

@args:List<&2, Arg> -> @+name:String -> Maybe<&2, Arg>

the Arg with this binding name, if any

def find_sub.at source · line 252 · raw

@s:Sub -> @rest:Maybe<&2, Sub> -> @+name:String -> Maybe<&2, Sub>

this Sub when its name matches, else the rest

def find_sub source · line 257 · raw

@subs:List<&2, Sub> -> @+name:String -> Maybe<&2, Sub>

the Sub with this name, if any

def pos.is.kind source · line 265 · raw

@k:ArgKind -> Bool

whether this Arg is a positional

def rest.is.kind source · line 277 · raw

@k:ArgKind -> Bool

whether this ArgKind is rest

def pos.is source · line 289 · raw

@a:Arg -> Bool

whether this Arg is a positional

def rest.is source · line 294 · raw

@a:Arg -> Bool

whether this Arg is a rest positional

def pos_of.put source · line 299 · raw

@keep:Bool -> @h:Arg -> @rest:List<&2, Arg> -> List<&2, Arg>

this Arg kept when it is a positional

def pos_of source · line 307 · raw

@args:List<&2, Arg> -> List<&2, Arg>

the positionals of a spec, in order

def rest.last.hit source · line 315 · raw

@is_rest:Bool -> @empty:Bool -> @tail_ok:Bool -> Bool

a rest is last only when nothing follows

def rest.last source · line 323 · raw

@pos:List<&2, Arg> -> Bool

whether rest positionals are last (and at most one)

def allowed.ok.at source · line 331 · raw

@hit:Bool -> @rest:Bool -> Bool

whether v is among the choices; an empty list accepts any value

def allowed.ok source · line 339 · raw

@cs:List<&2, String> -> @+v:String -> Bool

whether v is listed; the empty list answers no

def allowed source · line 347 · raw

@+cs:List<&2, String> -> @+v:String -> Bool

empty choices accept any value; otherwise v must be listed

def bound.hit source · line 351 · raw

@b:Bind -> @+name:String -> Bool

whether this bind's name is name

def bound.at source · line 356 · raw

@hit:Bool -> @rest:Bool -> Bool

True when the head matches, else the rest

def bound source · line 364 · raw

@bs:List<&2, Bind> -> @+name:String -> Bool

whether name is already bound

def get.bind.at source · line 372 · raw

@b:Bind -> @rest:String -> @+name:String -> String

this bind's value when the name matches, else the rest

def get.bind source · line 377 · raw

@bs:List<&2, Bind> -> @+name:String -> String

the value bound to name, or ""

def get source · line 385 · raw

@m:Matched -> @+name:String -> String

the value bound to name, or ""

def get_all.bind.hit source · line 390 · raw

@hit:Bool -> @+v:String -> @more:List<&2, String> -> List<&2, String>

this bind's value when the name matches, else the rest

def get_all.bind.at source · line 399 · raw

@b:Bind -> @more:List<&2, String> -> @+name:String -> List<&2, String>

this bind's value when the name matches, else the rest

def get_all.bind source · line 405 · raw

@bs:List<&2, Bind> -> @+name:String -> List<&2, String>

every value bound to name

def get_all source · line 413 · raw

@m:Matched -> @+name:String -> List<&2, String>

every value bound to name

def on source · line 418 · raw

@m:Matched -> @+name:String -> Bool

whether a flag named name was set

def path_of source · line 422 · raw

@m:Matched -> List<&2, String>

the selected command path

def parse.start source · line 427 · raw

@app:Cli -> St

the starting walker for a Cli

def parse.dead source · line 432 · raw

@e:ParseErr -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @pos:List<&2, Arg> -> @+raw:Bool -> @+seen:Bool -> St

a failed walker that keeps the rest of the state

def parse.put source · line 438 · raw

@+name:String -> @+val:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+raw:Bool -> @+seen:Bool -> St

a successful bind of name to val

def parse.choices source · line 444 · raw

@m:Maybe<&2, Arg> -> List<&2, String>

the choices of a found Arg, or none

def parse.take_choice source · line 453 · raw

@ok:Bool -> @+name:String -> @+val:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+raw:Bool -> @+seen:Bool -> St

bind name to val when the value is allowed

def parse.take_opt_val source · line 463 · raw

@+name:String -> @+val:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+raw:Bool -> @+seen:Bool -> St

bind an option that already has its value

def parse.take_flag source · line 470 · raw

@val:Maybe<&2, String> -> @+name:String -> @+orig:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @pos:List<&2, Arg> -> @+raw:Bool -> @+seen:Bool -> St

a flag with no glued value is set; a glued value is unexpected

def parse.take_opt source · line 481 · raw

@val:Maybe<&2, String> -> @+name:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+raw:Bool -> @+seen:Bool -> St

an option: glued value now, or the next token

def parse.take_arg.kind source · line 491 · raw

@k:ArgKind -> @+name:String -> @val:Maybe<&2, String> -> @+orig:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+raw:Bool -> @+seen:Bool -> St

dispatch on the found Arg's kind

def parse.take_arg source · line 506 · raw

@found:Maybe<&2, Arg> -> @val:Maybe<&2, String> -> @+orig:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @pos:List<&2, Arg> -> @+raw:Bool -> @+seen:Bool -> St

a found Arg, or an unknown flag

def parse.take_long.named source · line 519 · raw

@empty:Bool -> @+name:String -> @val:Maybe<&2, String> -> @+orig:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+raw:Bool -> @+seen:Bool -> St

a long option with a name, or --=...

def parse.take_long.cut source · line 531 · raw

@nv:Pair(String, Maybe<&2, String>) -> @+orig:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @pos:List<&2, Arg> -> @+raw:Bool -> @+seen:Bool -> St

a long option after the = cut

def parse.take_long source · line 540 · raw

@body:String -> @+orig:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+raw:Bool -> @+seen:Bool -> St

a long option body after --

def parse.take_short.cut source · line 547 · raw

@nv:Pair(String, Maybe<&2, String>) -> @+orig:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @pos:List<&2, Arg> -> @+raw:Bool -> @+seen:Bool -> St

a short option after the glued-value cut

def parse.take_short source · line 556 · raw

@body:String -> @+orig:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+raw:Bool -> @+seen:Bool -> St

a short option body after -

def parse.take_pos.keep source · line 563 · raw

@keep:Bool -> @h:Arg -> @t:List<&2, Arg> -> List<&2, Arg>

a rest positional stays; a plain one is consumed

def parse.take_pos source · line 571 · raw

@+tok:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @pos:List<&2, Arg> -> @raw:Bool -> St

the next remaining positional, or an unexpected word

def parse.enter source · line 583 · raw

@s:Sub -> @+specs:List<&2, Arg> -> @+path:List<&2, String> -> @binds:List<&2, Bind> -> St

this Sub's spec becomes current; parent bindings stay

def parse.req.go source · line 591 · raw

@req:Bool -> @bare:Bool -> @+n:String -> Maybe<&2, String>

required and no default → Some{name}

def parse.req source · line 595 · raw

@a:Arg -> Maybe<&2, String>

a required Arg without a default, as a missing name

def parse.first_req.at source · line 600 · raw

@here:Maybe<&2, String> -> @rest:Maybe<&2, String> -> Maybe<&2, String>

this missing name, else the rest

def parse.first_req.skip source · line 609 · raw

@skip:Bool -> @a:Arg -> Maybe<&2, String>

a rest stays in the list, so it does not block a subcommand

def parse.first_req source · line 617 · raw

@pos:List<&2, Arg> -> Maybe<&2, String>

the first leftover required positional

def parse.enter_or source · line 625 · raw

@miss:Maybe<&2, String> -> @s:Sub -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+raw:Bool -> @+seen:Bool -> St

a leftover required positional blocks entering a subcommand

def parse.word.go source · line 635 · raw

@found:Maybe<&2, Sub> -> @+tok:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+raw:Bool -> @+seen:Bool -> St

a found subcommand, or a positional

def parse.word source · line 646 · raw

@+tok:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+raw:Bool -> @+seen:Bool -> St

a word: a subcommand, or a positional

def parse.step.short.go source · line 653 · raw

@alone:Bool -> @+tok:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+seen:Bool -> St

- as a word, or a short option

def parse.step.short source · line 664 · raw

@dash:Bool -> @+tok:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+seen:Bool -> St

- alone is a positional; otherwise a short option

def parse.step.kind.go source · line 675 · raw

@long:Bool -> @dash:Bool -> @+tok:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+seen:Bool -> St

--long first, then -s, then a word

def parse.step.kind source · line 686 · raw

@+tok:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+seen:Bool -> St

a long option, a short option, or a word

def parse.step.help source · line 693 · raw

@hit:Bool -> @+tok:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+seen:Bool -> St

help in command position collects the rest of argv as a path

def parse.step.end source · line 703 · raw

@end:Bool -> @+tok:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+seen:Bool -> St

-- ends option parsing

def parse.step.raw source · line 714 · raw

@raw:Bool -> @+tok:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+seen:Bool -> St

after --, every token is a positional

def parse.step.need source · line 725 · raw

@flag:Bool -> @+name:String -> @+tok:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+raw:Bool -> @+seen:Bool -> St

a pending option value: a flag-shaped token is a missing value

def parse.step.mode source · line 735 · raw

@mode:Mode -> @+tok:String -> @+args:List<&2, Arg> -> @+specs:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+raw:Bool -> @+seen:Bool -> St

one token against the walker

def parse.step source · line 751 · raw

@+tok:String -> @st:St -> St

one token

def parse.walk source · line 756 · raw

@argv:List<&2, String> -> @st:St -> St

every token, in order

def fill.one source · line 764 · raw

@skip:Bool -> @+name:String -> @+val:String -> @rest:List<&2, Bind> -> List<&2, Bind>

a default value kept when the name is not already bound

def fill.arg.go source · line 773 · raw

@d:Maybe<&2, String> -> @+name:String -> @+binds:List<&2, Bind> -> List<&2, Bind>

a Some default is filled when unbound

def fill.arg source · line 782 · raw

@a:Arg -> @+binds:List<&2, Bind> -> List<&2, Bind>

this Arg's default, when it has one and is not bound

def fill.args source · line 787 · raw

@args:List<&2, Arg> -> @+binds:List<&2, Bind> -> List<&2, Bind>

defaults of every spec Arg

def miss.one source · line 795 · raw

@need:Bool -> @+name:String -> @rest:Maybe<&2, String> -> Maybe<&2, String>

a required name that is not bound

def miss.arg source · line 804 · raw

@a:Arg -> @+binds:List<&2, Bind> -> @rest:Maybe<&2, String> -> Maybe<&2, String>

whether this Arg is required and unbound

def miss.args source · line 810 · raw

@args:List<&2, Arg> -> @+binds:List<&2, Bind> -> Maybe<&2, String>

the first required name that is not bound

def parse.finish.miss source · line 818 · raw

@m:Maybe<&2, String> -> @path:List<&2, String> -> @binds:List<&2, Bind> -> Result<&2, &2, ParseErr, Matched>

a missing required name, or the matched result

def parse.finish.ok source · line 827 · raw

@specs:List<&2, Arg> -> @path:List<&2, String> -> @+binds:List<&2, Bind> -> Result<&2, &2, ParseErr, Matched>

required names after defaults

def parse.finish.mode source · line 832 · raw

@mode:Mode -> @+specs:List<&2, Arg> -> @path:List<&2, String> -> @+binds:List<&2, Bind> -> Result<&2, &2, ParseErr, Matched>

a finished walker: help, a pending value, an error, or defaults + required

def parse.finish source · line 845 · raw

@st:St -> Result<&2, &2, ParseErr, Matched>

the walker, finished

def parse source · line 850 · raw

@app:Cli -> @argv:List<&2, String> -> Result<&2, &2, ParseErr, Matched>

argv against a Cli

def show.err source · line 854 · raw

@e:ParseErr -> String

a ParseErr as a short tag

def show.bind source · line 868 · raw

@b:Bind -> @+rest:String -> String

one bind as name=value

def show.binds source · line 873 · raw

@bs:List<&2, Bind> -> String

the bindings as name=value words

def show.matched source · line 881 · raw

@m:Matched -> String

a Matched as path | binds

def show source · line 886 · raw

@r:Result<&2, &2, ParseErr, Matched> -> String

a parse result as a single line

def help.label.kind source · line 894 · raw

@k:ArgKind -> @+name:String -> @+label:String -> String

the short/long label of an option, plus a metavar for Opt

def help.label.pair source · line 906 · raw

@+short:String -> @+long:String -> String

-s, --long or one of them

def help.label source · line 913 · raw

@a:Arg -> String

the usage label of an option

def help.extra.go source · line 918 · raw

@+d:String -> @+cs:List<&2, String> -> String

extras after the help string: default and choices

def help.extra source · line 928 · raw

@a:Arg -> String

extras after the help string

def help.opt_line source · line 933 · raw

@+a:Arg -> @w:Nat -> String

one option line, given the label width

def help.opt_width source · line 938 · raw

@args:List<&2, Arg> -> @n:Nat -> Nat

the max option-label width

def help.opt_lines.at source · line 946 · raw

@skip:Bool -> @h:Arg -> @rest:String -> @w:Nat -> String

a non-positional option line

def help.opt_lines source · line 954 · raw

@args:List<&2, Arg> -> @+w:Nat -> String

option lines, skipping positionals

def help.opts.go source · line 962 · raw

@+body:String -> String

wrap option lines in a heading

def help.opts source · line 966 · raw

@+args:List<&2, Arg> -> String

the Options block, or empty when there are none

def help.sub_name source · line 970 · raw

@s:Sub -> String

a command's name

def help.sub_about source · line 975 · raw

@s:Sub -> String

a command's about

def help.cmd_width source · line 980 · raw

@subs:List<&2, Sub> -> @n:Nat -> Nat

max command-name width, including help

def help.cmd_line source · line 988 · raw

@+name:String -> @+about:String -> @w:Nat -> String

one command line

def help.cmd_lines source · line 992 · raw

@subs:List<&2, Sub> -> @+w:Nat -> String

command lines, then help

def help.cmds source · line 1001 · raw

@+subs:List<&2, Sub> -> String

the Commands block

def help.pos.dots source · line 1005 · raw

@many:Bool -> String

a rest mark: ..., or empty

def help.pos.wrap source · line 1009 · raw

@req:Bool -> @+n:String -> String

a positional in a usage line: <NAME> or [NAME]

def help.pos.one source · line 1013 · raw

@a:Arg -> String

a positional in a usage line: <NAME> or [NAME], plus ... when rest

def help.pos.at source · line 1018 · raw

@keep:Bool -> @h:Arg -> @rest:String -> String

this positional's hint, else the rest

def help.pos source · line 1026 · raw

@args:List<&2, Arg> -> String

every positional in a usage line

def help.opts_hint.go source · line 1034 · raw

@has:Bool -> String

the bracketed options word when the spec has a flag or option

def help.has_opt.at source · line 1038 · raw

@is_pos:Bool -> @rest:Bool -> Bool

True when this Arg is a flag or option, else the rest

def help.has_opt source · line 1046 · raw

@args:List<&2, Arg> -> Bool

whether any Arg is not a positional

def help.opts_hint source · line 1054 · raw

@args:List<&2, Arg> -> String

the options hint when needed

def help.cmd_hint source · line 1058 · raw

@+subs:List<&2, Sub> -> String

[COMMAND] when there are subcommands

def help.usage source · line 1062 · raw

@+name:String -> @+args:List<&2, Arg> -> @+subs:List<&2, Sub> -> String

Usage: name ...

def title.go source · line 1067 · raw

@+name:String -> @v:Maybe<&2, String> -> String

name or name version

def help.page source · line 1075 · raw

@+title:String -> @+about:String -> @+usage:String -> @+args:List<&2, Arg> -> @+subs:List<&2, Sub> -> String

one help page

def help.step.go source · line 1081 · raw

@found:Maybe<&2, Sub> -> @+bin:String -> @+about:String -> @version:Maybe<&2, String> -> @args:List<&2, Arg> -> @subs:List<&2, Sub> -> @+next:String -> @+usage:String -> How

a found child becomes the page; an unknown name stays

def help.step source · line 1092 · raw

@how:How -> @+name:String -> How

one path segment against the current page

def help.go source · line 1098 · raw

@path:List<&2, String> -> @how:How -> String

the page at the end of a shrinking path

def help source · line 1108 · raw

@+app:Cli -> @path:List<&2, String> -> String

usage for path under app; an unknown segment shows the last found page

def err.wrap source · line 1113 · raw

@app:Cli -> @+msg:String -> String

a short error with the root usage line

def err_text source · line 1119 · raw

@+app:Cli -> @e:ParseErr -> String

error text; NeedHelp is empty (the caller prints help)