~/bend-docscommunity

src/cli.bend checks

raw source on the hub · import shake@0.5.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 Fallback source · line 19 · raw

Data

what an argument the words leave unbound falls back to: the value of its env var, when parse_env is given one, else its default

type Arg source · line 23 · raw

Data

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

type Sub source · line 36 · raw

Data

a nested command

type Cli source · line 45 · raw

Data

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

type Bind source · line 59 · raw

Data

one bound name and its text

type Level source · line 64 · raw

Data

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

type Matched source · line 70 · 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 78 · 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 88 · raw

Data

how the next token is read

type St source · line 97 · 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 111 · raw

Data

the page a help walk has reached

Definitions

def Var source · line 55 · raw

Data

an env var's name and its value, as parse_env is given them

def app source · line 122 · 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 132 · raw

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

a nested command

def flag source · line 141 · raw

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

a boolean flag

def opt source · line 150 · 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 162 · 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 174 · raw

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

a positional

def rest source · line 184 · 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 env source · line 194 · raw

@aa:Arg -> @+var:String -> Arg

this argument, falling back to the env var var (clap's .env)

def help.max source · line 199 · raw

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

the larger of two Nats

def help.spaces source · line 203 · raw

@nn:Nat -> String

n spaces

def help.pad source · line 211 · raw

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

s padded on the right to width n

def text.of source · line 215 · raw

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

a Maybe string's text, or the default

def looks_flag source · line 219 · raw

@+ss:String -> Bool

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

def from.rev source · line 223 · raw

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

chars reversed into a string

def cut_eq.pick source · line 227 · 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 240 · 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 249 · 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 260 · raw

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

name and an optional =value

def short_of.val source · line 266 · 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 274 · raw

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

whether this Arg's long spelling is name

def by_long.at source · line 279 · 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 287 · raw

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

the Arg with this long spelling, if any

def by_short.hit source · line 295 · raw

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

whether this Arg's short spelling is name

def by_short.at source · line 300 · 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 308 · raw

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

the Arg with this short spelling, if any

def by_name.hit source · line 316 · raw

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

whether this Arg's name is name

def by_name.at source · line 321 · 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 329 · raw

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

the Arg with this binding name, if any

def find_sub.at source · line 337 · 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 342 · raw

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

the Sub with this name, if any

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

@kk:ArgKind -> Bool

whether this Arg is a positional

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

@kk:ArgKind -> Bool

whether this ArgKind is rest

def pos.is source · line 378 · raw

@aa:Arg -> Bool

whether this Arg is a positional

def rest.is source · line 383 · raw

@aa:Arg -> Bool

whether this Arg is a rest positional

def pos_of.put source · line 388 · 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 396 · raw

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

the positionals of a spec, in order

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

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

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

def allowed.ok source · line 412 · raw

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

whether v is listed; the empty list answers no

def allowed source · line 420 · raw

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

empty choices accept any value; otherwise v must be listed

def bound.hit source · line 424 · raw

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

whether this bind's name is name

def bound.at source · line 429 · raw

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

True when the head matches, else the rest

def bound source · line 437 · raw

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

whether name is already bound

def get_all.bind.hit source · line 445 · 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 457 · 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 466 · raw

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

every value bound to name

def own source · line 474 · raw

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

the bindings this command made, in binding order

def get_all source · line 482 · raw

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

every value this command bound to name

def get.last source · line 486 · 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 494 · 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 498 · raw

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

whether a value is true

def on source · line 506 · raw

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

whether a flag named name was set

def path_of source · line 510 · raw

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

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

def sub_name source · line 518 · raw

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

the name of the subcommand selected under this command

def sub_of.pick source · line 526 · raw

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

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

def sub_of source · line 534 · raw

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

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

def at.step source · line 542 · 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 550 · 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 559 · 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 563 · raw

@app:Cli -> St

the starting walker for a Cli

def parse.dead source · line 568 · 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 582 · 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 597 · raw

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

the choices of a found Arg, or none

def parse.take_choice source · line 606 · 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 628 · 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 644 · 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 664 · 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 684 · 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 693 · 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 722 · 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 745 · 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 754 · 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 773 · 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 795 · 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 817 · 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 834 · 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 851 · 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 860 · 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 874 · 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 884 · 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 899 · 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 909 · 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 932 · raw

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

one letter against the walker

def cluster.letter source · line 937 · 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 945 · raw

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

whether the cluster has ended after this letter

def cluster source · line 957 · 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 965 · 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 980 · 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 988 · 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 1008 · 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 1021 · raw

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

required and no default → Some{name}

def parse.req source · line 1025 · raw

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

a required Arg without a default, as a missing name

def parse.first_req.at source · line 1030 · 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 1041 · 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 1049 · raw

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

the first leftover required positional

def parse.enter_or source · line 1057 · 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 1076 · 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 1096 · 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 1111 · 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 1130 · 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 1149 · 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 1169 · 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 1183 · 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 1201 · 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 1220 · 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 1239 · 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 1260 · 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 1281 · 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 1306 · raw

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

one token

def parse.walk source · line 1311 · raw

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

every token, in order

def fill.one source · line 1319 · 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 1332 · 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 1344 · 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 1349 · raw

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

defaults of every spec Arg

def miss.one source · line 1357 · raw

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

a required name that is not bound

def miss.arg source · line 1369 · 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 1378 · 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 1386 · raw

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

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

def miss.levels source · line 1395 · raw

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

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

def level.binds source · line 1404 · raw

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

the bindings a command made

def matched.build source · line 1409 · 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 1421 · 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 1433 · 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 1437 · 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 1455 · raw

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

the walker, finished

def parse source · line 1460 · raw

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

argv against a Cli

def env.get.at source · line 1464 · raw

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

this pair's value when its name matches, else the rest

def env.get source · line 1472 · raw

@vars:List<&2, Var> -> @+name:String -> Maybe<&2, String>

the value of the first pair named name

def env.full source · line 1481 · raw

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

a value that is not empty

def env.of source · line 1489 · raw

@ev:Maybe<&2, String> -> @vars:List<&2, Var> -> Maybe<&2, String>

the env value of an env var: its first pair's value, when that is not empty

def env.off source · line 1497 · raw

@+vv:String -> Bool

whether an env value turns a flag off, as clap's SetTrue reads it

def env.kind source · line 1502 · raw

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

the default an env value gives an argument of this kind: a flag is set unless the value turns it off; every other kind takes the value

def resolve.with source · line 1517 · raw

@found:Maybe<&2, String> -> @kk:ArgKind -> @ev:Maybe<&2, String> -> @dd:Maybe<&2, String> -> Fallback

a fallback with its default replaced by what the env value gives, when there is one

def resolve.arg source · line 1530 · raw

@aa:Arg -> @vars:List<&2, Var> -> Arg

an argument whose default is its fallback under vars

def resolve.args source · line 1535 · raw

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

every argument's default is its fallback

def resolve.subs source · line 1543 · raw

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

every argument of every subcommand, its default its fallback

def resolve source · line 1552 · raw

@app:Cli -> @+vars:List<&2, Var> -> Cli

the spec whose every argument's default is its fallback under vars

def env.flag.is source · line 1557 · raw

@kk:ArgKind -> Bool

whether this kind is a flag

def env.bad.val source · line 1572 · raw

@found:Maybe<&2, String> -> @kk:ArgKind -> @+name:String -> @+cs:List<&2, String> -> @+binds:List<&2, Bind> -> Maybe<&2, Var>

an argument bound to an env value outside its choices: never a flag, and only for a value its command's bindings hold

def env.bad.arg source · line 1590 · raw

@aa:Arg -> @vars:List<&2, Var> -> @+binds:List<&2, Bind> -> Maybe<&2, Var>

this argument's name and env value, when its command's bindings hold that value and its choices do not

def env.first source · line 1595 · raw

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

the first of two answers that is one

def env.bad.args source · line 1603 · raw

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

the first argument of a command bound to an env value outside its choices

def env.sub.args source · line 1615 · raw

@found:Maybe<&2, Sub> -> List<&2, Arg>

the arguments of a found subcommand, or none

def env.sub.kids source · line 1624 · raw

@found:Maybe<&2, Sub> -> List<&2, Sub>

the subcommands of a found subcommand, or none

def env.bad.go source · line 1634 · raw

@mm:Matched -> @+args:List<&2, Arg> -> @+subs:List<&2, Sub> -> @+vars:List<&2, Var> -> Maybe<&2, Var>

the first argument bound to an env value outside its choices, the command first, then down the selected path

def env.check.done source · line 1648 · raw

@bad:Maybe<&2, Var> -> @+mm:Matched -> Result<&2, &2, ParseErr, Matched>

a success, or the first env value outside its choices that it bound

def env.check.ok source · line 1657 · raw

@app:Cli -> @+vars:List<&2, Var> -> @+mm:Matched -> Result<&2, &2, ParseErr, Matched>

a successful parse checked for env values outside their choices

def env.check source · line 1663 · raw

@app:Cli -> @+vars:List<&2, Var> -> @got:Result<&2, &2, ParseErr, Matched> -> Result<&2, &2, ParseErr, Matched>

a failed parse as it is; a successful one checked for env values outside their choices

def parse_env source · line 1676 · raw

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

argv against a Cli, every argument falling back to its env value under vars, then to its default

def env.names.put source · line 1684 · raw

@ev:Maybe<&2, String> -> @rest:List<&2, String> -> List<&2, String>

an env var in front of the names, when there is one

def env.names.args source · line 1692 · raw

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

the env vars of a command's arguments, in order

def env.names.forest source · line 1701 · raw

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

the env vars of every subcommand's arguments, depth first

def env.names source · line 1711 · raw

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

the env vars of a spec: the root's arguments', then every subcommand's

def help.label.kind source · line 1716 · 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 1730 · raw

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

-s, --long or one of them

def help.label source · line 1737 · raw

@aa:Arg -> String

the usage label of an option

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

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

extras after the help string: default and choices

def help.env source · line 1752 · raw

@ev:Maybe<&2, String> -> String

the env var after the help string, before the default

def help.extra source · line 1760 · raw

@aa:Arg -> String

extras after the help string: env var, default and choices

def help.opt_line source · line 1765 · raw

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

one option line, given the label width

def help.opt_width source · line 1770 · raw

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

the max option-label width

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

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

a non-positional option line

def help.opt_lines source · line 1786 · raw

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

option lines, skipping positionals

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

@+body:String -> String

wrap option lines in a heading

def help.opts source · line 1798 · raw

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

the Options block, or empty when there are none

def help.sub_name source · line 1802 · raw

@ss:Sub -> String

a command's name

def help.sub_about source · line 1807 · raw

@ss:Sub -> String

a command's about

def help.cmd_width source · line 1812 · raw

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

max command-name width, including help

def help.cmd_line source · line 1820 · raw

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

one command line

def help.cmd_lines source · line 1824 · raw

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

command lines, then help

def help.cmds source · line 1833 · raw

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

the Commands block

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

@many:Bool -> String

a rest mark: ..., or empty

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

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

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

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

@aa:Arg -> String

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

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

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

this positional's hint, else the rest

def help.pos source · line 1858 · raw

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

every positional in a usage line

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

@has:Bool -> String

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

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

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

whether any Arg is not a positional

def help.opts_hint source · line 1886 · raw

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

the options hint when needed

def help.cmd_hint source · line 1890 · raw

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

[COMMAND] when there are subcommands

def help.usage source · line 1894 · raw

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

Usage: name ...

def title.go source · line 1902 · raw

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

name or name version

def help.page source · line 1910 · 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 1921 · 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 1939 · raw

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

one path segment against the current page

def help.go source · line 1945 · raw

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

the page at the end of a shrinking path

def help source · line 1955 · 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 1960 · 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 1969 · 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 1974 · raw

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

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

def err.wrap source · line 1979 · 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 osa.head source · line 1983 · raw

@xs:List<&2, Nat> -> Nat

the head of a row, or 0 past its end

def osa.tail source · line 1991 · raw

@xs:List<&2, Nat> -> List<&2, Nat>

a row after its head

def osa.last source · line 1999 · raw

@xs:List<&2, Nat> -> @dd:Nat -> Nat

the last cell of a row, dd for an empty one

def osa.first source · line 2007 · raw

@bs:List<&2, Char> -> @+ii:Nat -> List<&2, Nat>

the first row: ii, then one more for each char

def osa.swap.b source · line 2015 · raw

@+xa:Char -> @pb:Maybe<&2, Char> -> @+ca:Char -> @+cb:Char -> Bool

whether the char before cb is ca, once the char before ca is xa

def osa.swap source · line 2023 · raw

@pa:Maybe<&2, Char> -> @pb:Maybe<&2, Char> -> @+ca:Char -> @+cb:Char -> Bool

whether the two chars before these, swapped, are these two

def osa.cell.swap source · line 2031 · raw

@swap:Bool -> @+best:Nat -> @+far:Nat -> Nat

the cheaper of a cell and a swap from two rows up and two cells left

def osa.cell source · line 2036 · raw

@swap:Bool -> @+up:Nat -> @+left:Nat -> @+diag:Nat -> @+cost:Nat -> @+far:Nat -> Nat

one cell: the cheapest of a deletion, an insertion, a substitution and a swap of two adjacent chars

def osa.row source · line 2049 · raw

@bs:List<&2, Char> -> @+ca:Char -> @+pa:Maybe<&2, Char> -> @pb:Maybe<&2, Char> -> @left:Nat -> @+ps:List<&2, Nat> -> @+qs:List<&2, Nat> -> List<&2, Nat>

the rest of a row for the char ca, whose char before is pa: ps is the row above from the cell above-left on, qs the row two up from two cells left on, pb the char of bs before its head

def osa.rows source · line 2068 · raw

@as:List<&2, Char> -> @+bs:List<&2, Char> -> @pa:Maybe<&2, Char> -> @+ii:Nat -> @+pp:List<&2, Nat> -> @qq:List<&2, Nat> -> Nat

the rows for the chars of as, the last row pp and the one before qq, down to the distance in the last row's last cell

def osa source · line 2085 · raw

@aa:String -> @bb:String -> Nat

the optimal string alignment distance from aa to bb: the fewest insertions, deletions, substitutions and swaps of two adjacent chars, no char edited twice

def sug.close.go source · line 2090 · raw

@+dd:Nat -> @+room:Nat -> Bool

whether a candidate is close to the typed spelling

def sug.close source · line 2095 · raw

@+typed:String -> @+cc:String -> Bool

whether cc is close to typed: some edits away, and at most a third of the longer as many

def sug.keep.rest source · line 2099 · raw

@+typed:String -> @+cc:String -> @rest:Maybe<&2, String> -> Maybe<&2, String>

a close candidate against the closest one after it: the earlier on a tie

def sug.keep source · line 2107 · raw

@close:Bool -> @+typed:String -> @+cc:String -> @rest:Maybe<&2, String> -> Maybe<&2, String>

a candidate, when it is close, against the closest one after it

def sug.best source · line 2115 · raw

@cands:List<&2, String> -> @+typed:String -> Maybe<&2, String>

the closest close candidate, the first among equals

def sug.cands.put source · line 2123 · raw

@long:Maybe<&2, String> -> @rest:List<&2, String> -> List<&2, String>

a long spelling in front of the rest, when there is one

def sug.cands source · line 2131 · raw

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

the long spellings of a command's arguments, in order

def sug.args.go source · line 2140 · raw

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

the arguments of the page at the end of a shrinking path

def sug.args source · line 2149 · raw

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

the arguments of the command at path, reached as help reaches it

def sug.typed source · line 2154 · raw

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

the spelling a long option word was typed with: its chars up to =

def sug.found source · line 2159 · raw

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

a candidate spelled as a long option word

def sug.word.go source · line 2167 · raw

@long:Bool -> @+app:Cli -> @+at:List<&2, String> -> @+word:String -> Maybe<&2, String>

the suggestion for a word, when it is a long option word

def sug.word source · line 2175 · raw

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

the long spelling a word refused at at was likely meant to be

def suggestion source · line 2180 · raw

@+app:Cli -> @ee:ParseErr -> Maybe<&2, String>

the long spelling an unknown long option was likely meant to be, as clap's "a similar argument exists"; None for every other error

def sug.tip source · line 2198 · raw

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

clap's tip line for a suggestion, or nothing

def err_text source · line 2206 · raw

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

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