~/bend-docscommunity

src/cli.bend checks

raw source on the hub · import shake@0.4.0.0/src/cli.bend as Cli

shake/cli: the parser behind main.bend, internal. parse reads argv against a Cli; help writes usage for a command path, and help is the subcommand that asks for it (--help too, unless the command declares its own long help). A -- that reaches parse ends option parsing; in a compiled program the runtime takes the first -- itself.

1 import
import Base

Types

type ArgKind source · line 10 · raw

Data

a flag, a valued option, an option that may repeat, a positional, or a rest positional

type Arg source · line 18 · raw

Data

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

type Sub source · line 31 · raw

Data

a nested command

type Cli source · line 40 · raw

Data

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

type Bind source · line 50 · raw

Data

one bound name and its text

type Level source · line 55 · raw

Data

one command above the current one: its arguments and the bindings made while it was current

type Matched source · line 61 · raw

Data

a successful parse, read one command at a time, as clap's ArgMatches: the bindings the command made, in binding order, and, when a subcommand was selected under it, that subcommand's name and Matched

type ParseErr source · line 69 · raw

Data

a failed parse. NeedHelp is help / help <path> (or --help); NoValue is an option whose value never came, Missing a required argument nothing bound. Every error but NeedHelp carries at, the command path selected where it failed

type Mode source · line 79 · raw

Data

how the next token is read

type St source · line 88 · raw

Data

the walker: the current command's arguments, the commands above it (the nearest first, one per name of the selected path), its subcommands, the selected path, and the current command's own bindings

type How source · line 102 · raw

Data

the page a help walk has reached

Definitions

def app source · line 113 · 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 123 · raw

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

a nested command

def flag source · line 132 · raw

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

a boolean flag

def opt source · line 141 · 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 many source · line 153 · raw

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

an option that may be given more than once; get_all reads every value

def pos source · line 165 · raw

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

a positional

def rest source · line 175 · 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 185 · raw

@+aa:Nat -> @+bb:Nat -> Nat

the larger of two Nats

def help.spaces source · line 189 · raw

@nn:Nat -> String

n spaces

def help.pad source · line 197 · raw

@+ss:String -> @nn:Nat -> String

s padded on the right to width n

def text.of source · line 201 · raw

@mm:Maybe<&2, String> -> @+dd:String -> String

a Maybe string's text, or the default

def looks_flag source · line 205 · raw

@+ss:String -> Bool

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

def from.rev source · line 209 · raw

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

chars reversed into a string

def cut_eq.pick source · line 213 · raw

@eq:Bool -> @acc:List<&2, Char> -> @tt: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 226 · raw

@+cc:Char -> @tt: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 235 · 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 246 · raw

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

name and an optional =value

def short_of.val source · line 252 · raw

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

the value glued after a short letter: what follows one = when the rest starts with it (possibly empty, as --name= is), else the rest when there is any

def by_long.hit source · line 260 · raw

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

whether this Arg's long spelling is name

def by_long.at source · line 265 · raw

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

this Arg when the long spelling matches, else the rest

def by_long source · line 273 · raw

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

the Arg with this long spelling, if any

def by_short.hit source · line 281 · raw

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

whether this Arg's short spelling is name

def by_short.at source · line 286 · raw

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

this Arg when the short spelling matches, else the rest

def by_short source · line 294 · raw

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

the Arg with this short spelling, if any

def by_name.hit source · line 302 · raw

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

whether this Arg's name is name

def by_name.at source · line 307 · raw

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

this Arg when the binding name matches, else the rest

def by_name source · line 315 · raw

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

the Arg with this binding name, if any

def find_sub.at source · line 323 · raw

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

this Sub when its name matches, else the rest

def find_sub source · line 328 · raw

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

the Sub with this name, if any

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

@kk:ArgKind -> Bool

whether this Arg is a positional

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

@kk:ArgKind -> Bool

whether this ArgKind is rest

def pos.is source · line 364 · raw

@aa:Arg -> Bool

whether this Arg is a positional

def rest.is source · line 369 · raw

@aa:Arg -> Bool

whether this Arg is a rest positional

def pos_of.put source · line 374 · raw

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

this Arg kept when it is a positional

def pos_of source · line 382 · raw

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

the positionals of a spec, in order

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

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

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

def allowed.ok source · line 398 · raw

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

whether v is listed; the empty list answers no

def allowed source · line 406 · raw

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

empty choices accept any value; otherwise v must be listed

def bound.hit source · line 410 · raw

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

whether this bind's name is name

def bound.at source · line 415 · raw

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

True when the head matches, else the rest

def bound source · line 423 · raw

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

whether name is already bound

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

@hit:Bool -> @+vv: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 443 · raw

@bb: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 452 · raw

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

every value bound to name

def own source · line 460 · raw

@mm:Matched -> List<&2, Bind>

the bindings this command made, in binding order

def get_all source · line 468 · raw

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

every value this command bound to name

def get.last source · line 472 · raw

@vs:List<&2, String> -> @dflt:Maybe<&2, String> -> Maybe<&2, String>

the last of a list of values, or dflt when it is empty

def get source · line 480 · raw

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

the value bound to name last, or None when nothing bound it

def on.of source · line 484 · raw

@mv:Maybe<&2, String> -> Bool

whether a value is true

def on source · line 492 · raw

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

whether a flag named name was set

def path_of source · line 496 · raw

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

the names of the subcommands selected below this command, in order

def sub_name source · line 504 · raw

@mm:Matched -> Maybe<&2, String>

the name of the subcommand selected under this command

def sub_of.pick source · line 512 · raw

@hit:Bool -> @next:Matched -> Maybe<&2, Matched>

a subcommand's Matched when it is the one asked for

def sub_of source · line 520 · raw

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

the Matched of subcommand name, when it is the one selected

def at.step source · line 528 · raw

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

one name further down, when there is still a Matched to go down from

def at.go source · line 536 · raw

@path:List<&2, String> -> @cur:Maybe<&2, Matched> -> Maybe<&2, Matched>

the rest of a path, followed from where the walk down stands

def at source · line 545 · raw

@mm:Matched -> @path:List<&2, String> -> Maybe<&2, Matched>

the Matched of the command path names below this one, name by name, or None where a name is not the subcommand selected

def parse.start source · line 549 · raw

@app:Cli -> St

the starting walker for a Cli

def parse.dead source · line 554 · raw

@ee:ParseErr -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 568 · raw

@+name:String -> @+val:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 583 · raw

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

the choices of a found Arg, or none

def parse.take_choice source · line 592 · raw

@ok:Bool -> @+name:String -> @+val:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 614 · raw

@+name:String -> @+val:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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, checked against the choices of the current command's argument of that name: a parent's argument of the same name has its own

def parse.take_flag source · line 630 · raw

@val:Maybe<&2, String> -> @+name:String -> @+orig:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 650 · raw

@val:Maybe<&2, String> -> @+name:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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.once source · line 670 · raw

@again:Bool -> @st:St -> @+name:String -> @+path:List<&2, String> -> St

a flag or single-valued option given again is refused, whatever the walk would have done with it; the walker keeps the rest of its state

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

@kk:ArgKind -> @+name:String -> @val:Maybe<&2, String> -> @+orig:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 708 · raw

@found:Maybe<&2, Arg> -> @val:Maybe<&2, String> -> @+orig:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 long_help source · line 731 · raw

@+name:String -> @val:Maybe<&2, String> -> @seen:Bool -> Bool

whether an unknown long option is a request for help: a bare --help, with no = value, before any positional of the current command is bound

def parse.take_long.help source · line 740 · raw

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

an unknown long option: a request for help (--help, as help), or an unknown flag

def parse.take_long.found source · line 759 · raw

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

a long option the current command spells, or an unknown one

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

@empty:Bool -> @+name:String -> @val:Maybe<&2, String> -> @+orig:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 803 · raw

@nv:Pair(String, Maybe<&2, String>) -> @+orig:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 820 · raw

@body:String -> @+orig:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 cluster.val.flag source · line 837 · raw

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

a flag's value in a cluster: the rest when it starts with = (which take_arg refuses), else none, so the next letter goes on

def cluster.val.kind source · line 846 · raw

@kk:ArgKind -> @+rest:String -> Maybe<&2, String>

the value a letter of this kind gives its argument: an option takes the rest of the word, after one =

def cluster.val source · line 860 · raw

@found:Maybe<&2, Arg> -> @+rest:String -> Maybe<&2, String>

the value the letter's argument gets, or none when no argument has it

def cluster.ends.kind source · line 870 · raw

@kk:ArgKind -> @+rest:String -> Bool

whether a letter of this kind ends the cluster: every kind but a flag that is not followed by =

def cluster.ends source · line 885 · raw

@found:Maybe<&2, Arg> -> @+rest:String -> Bool

whether the letters after this one are no longer read as letters: an unknown letter, an option (they are its value) or a flag given =

def cluster.apply.mode source · line 895 · raw

@mode:Mode -> @+cc:Char -> @+rest:String -> @+orig:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+subs:List<&2, Sub> -> @+path:List<&2, String> -> @+binds:List<&2, Bind> -> @+pos:List<&2, Arg> -> @+raw:Bool -> @+seen:Bool -> St

one letter against a walker an earlier letter failed changes nothing; otherwise it goes through take_arg

def cluster.apply source · line 918 · raw

@st:St -> @+cc:Char -> @+rest:String -> @+orig:String -> St

one letter against the walker

def cluster.letter source · line 923 · raw

@done:Bool -> @+cc:Char -> @+rest:String -> @+orig:String -> @st:St -> St

one letter of a cluster, unless an earlier one ended it

def cluster.done source · line 931 · raw

@done:Bool -> @+cc:Char -> @+rest:String -> @st:St -> Bool

whether the cluster has ended after this letter

def cluster source · line 943 · raw

@body:String -> @+orig:String -> @+st:St -> @+done:Bool -> St

every letter of a short cluster -abc, in order: a flag binds and the next letter goes on; an option takes the rest of the word, after one =, or the next word when nothing is left; an unknown letter, or a flag given =, refuses the whole word

def parse.take_short source · line 951 · raw

@body:String -> @+orig:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 966 · raw

@keep:Bool -> @hh:Arg -> @tt:List<&2, Arg> -> List<&2, Arg>

a rest positional stays; a plain one is consumed

def parse.take_pos source · line 974 · raw

@+tok:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @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 994 · raw

@ss:Sub -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+path:List<&2, String> -> @binds:List<&2, Bind> -> St

this Sub's arguments become current, with no bindings of its own; the command it leaves keeps its arguments and bindings above it

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

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

required and no default → Some{name}

def parse.req source · line 1011 · raw

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

a required Arg without a default, as a missing name

def parse.first_req.at source · line 1016 · 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 1027 · raw

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

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

def parse.first_req source · line 1035 · raw

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

the first leftover required positional

def parse.enter_or source · line 1043 · raw

@miss:Maybe<&2, String> -> @ss:Sub -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 1062 · raw

@found:Maybe<&2, Sub> -> @+tok:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 1082 · raw

@+tok:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 1097 · raw

@alone:Bool -> @+tok:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 1116 · raw

@dash:Bool -> @+tok:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 1135 · raw

@long:Bool -> @dash:Bool -> @+tok:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 1155 · raw

@+tok:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @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 1169 · raw

@hit:Bool -> @+tok:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 1187 · raw

@end:Bool -> @+tok:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 1206 · raw

@raw:Bool -> @+tok:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 1225 · raw

@flag:Bool -> @+name:String -> @+tok:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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.help_path source · line 1246 · raw

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

a word after help: the subcommand it names, whose own subcommands the next word is looked up in, or an unexpected word

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

@mode:Mode -> @+tok:String -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 1292 · raw

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

one token

def parse.walk source · line 1297 · raw

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

every token, in order

def fill.one source · line 1305 · 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 1318 · raw

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

a Some default is filled when unbound

def fill.arg source · line 1330 · raw

@aa: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 1335 · raw

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

defaults of every spec Arg

def miss.one source · line 1343 · raw

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

a required name that is not bound

def miss.arg source · line 1355 · raw

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

whether this Arg is required and unbound

def miss.args source · line 1364 · raw

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

the first required name that is not bound

def fill.levels source · line 1372 · raw

@lvs:List<&2, Level> -> List<&2, Level>

each command's defaults, filled in among its own bindings

def miss.levels source · line 1381 · raw

@lvs:List<&2, Level> -> Maybe<&2, String>

the first required argument a command left unbound, in list order

def level.binds source · line 1390 · raw

@lv:Level -> List<&2, Bind>

the bindings a command made

def matched.build source · line 1395 · raw

@lvs:List<&2, Level> -> @names:List<&2, String> -> Matched

each command's Matched, root first, with the name selected under it

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

@mm:Maybe<&2, String> -> @path:List<&2, String> -> @+lvs:List<&2, Level> -> Result<&2, &2, ParseErr, Matched>

a missing required name, or the matched result

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

@+path:List<&2, String> -> @+lvs:List<&2, Level> -> Result<&2, &2, ParseErr, Matched>

every command's defaults, then its required arguments, root first

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

@mode:Mode -> @+args:List<&2, Arg> -> @+up:List<&2, Level> -> @+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 1441 · raw

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

the walker, finished

def parse source · line 1446 · raw

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

argv against a Cli

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

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

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

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

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

-s, --long or one of them

def help.label source · line 1471 · raw

@aa:Arg -> String

the usage label of an option

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

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

extras after the help string: default and choices

def help.extra source · line 1486 · raw

@aa:Arg -> String

extras after the help string

def help.opt_line source · line 1491 · raw

@+aa:Arg -> @ww:Nat -> String

one option line, given the label width

def help.opt_width source · line 1496 · raw

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

the max option-label width

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

@skip:Bool -> @hh:Arg -> @rest:String -> @ww:Nat -> String

a non-positional option line

def help.opt_lines source · line 1512 · raw

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

option lines, skipping positionals

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

@+body:String -> String

wrap option lines in a heading

def help.opts source · line 1524 · raw

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

the Options block, or empty when there are none

def help.sub_name source · line 1528 · raw

@ss:Sub -> String

a command's name

def help.sub_about source · line 1533 · raw

@ss:Sub -> String

a command's about

def help.cmd_width source · line 1538 · raw

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

max command-name width, including help

def help.cmd_line source · line 1546 · raw

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

one command line

def help.cmd_lines source · line 1550 · raw

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

command lines, then help

def help.cmds source · line 1559 · raw

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

the Commands block

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

@many:Bool -> String

a rest mark: ..., or empty

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

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

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

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

@aa:Arg -> String

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

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

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

this positional's hint, else the rest

def help.pos source · line 1584 · raw

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

every positional in a usage line

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

@has:Bool -> String

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

def help.has_opt.at source · line 1596 · 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 1604 · raw

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

whether any Arg is not a positional

def help.opts_hint source · line 1612 · raw

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

the options hint when needed

def help.cmd_hint source · line 1616 · raw

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

[COMMAND] when there are subcommands

def help.usage source · line 1620 · raw

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

Usage: name ...

def title.go source · line 1628 · raw

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

name or name version

def help.page source · line 1636 · 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 1647 · 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 1665 · raw

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

one path segment against the current page

def help.go source · line 1671 · raw

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

the page at the end of a shrinking path

def help source · line 1681 · raw

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

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

def usage.go source · line 1686 · raw

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

the usage line of the page at the end of a shrinking path

def usage.at source · line 1695 · raw

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

the usage line of the command at path, as help shows it

def err.hint source · line 1700 · raw

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

where to look for more: help, and the path when there is one

def err.wrap source · line 1705 · raw

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

a short error, the usage line of the command where it happened, and the hint

def err_text source · line 1709 · raw

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

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