src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/mods/flag/flag.d.elv (about)

     1  #//each:eval use flag
     2  
     3  # Parses flags from `$args` according to the signature of the
     4  # `$fn`, using the [Go convention](#go-convention), and calls `$fn`.
     5  #
     6  # The `$fn` must be a user-defined function (i.e. not a builtin
     7  # function or external command). Each option corresponds to a flag; see
     8  # [`flag:parse`]() for how the default value affects the behavior of flags.
     9  # After parsing, the non-flag arguments are used as function arguments.
    10  #
    11  # The `&on-parse-error` function can be supplied to control the behavior when
    12  # `$args` contains invalid flags or when the number of arguments after parsing
    13  # flags doesn't match what `$fn` expects. The function gets an argument that
    14  # describes the error condition; the argument should be treated as an opaque
    15  # value for now, but will expose more useful fields in future. If
    16  # `&on-parse-error` is not supplied, such errors are raised as exceptions.
    17  #
    18  # Example:
    19  #
    20  # ```elvish-transcript
    21  # ~> use flag
    22  # ~> fn f {|&verbose=$false &port=(num 8000) name| put $verbose $port $name }
    23  # ~> flag:call $f~ [-verbose -port 80 a.c]
    24  # ▶ $true
    25  # ▶ (num 80)
    26  # ▶ a.c
    27  # ~> flag:call $f~ [-unknown-flag] &on-parse-error={|_| echo 'bad usage' }
    28  # bad usage
    29  # ~> flag:call $f~ [-verbose a b c] &on-parse-error={|_| echo 'bad usage' }
    30  # bad usage
    31  # ```
    32  #
    33  # This function is most useful when creating an Elvish script that accepts
    34  # command-line arguments. For example, if a script `a.elv` contains the
    35  # following code:
    36  #
    37  # ```elvish
    38  # use flag
    39  # fn main { |&verbose=$false &port=(num 8000) name|
    40  #   ...
    41  # }
    42  # flag:call $main~ $args &on-parse-error={|_|
    43  #   echo 'Usage: '(src)[name]' [-verbose] [-port PORT-NUM] name'
    44  #   exit 1
    45  # }
    46  # ```
    47  #
    48  # **Note**: This example shows how `&on-parse-error` can be used to print out a
    49  # usage text, but it needs to duplicate the names of the options and arguments
    50  # accepted by `main`. This is a known limitation and will hopefully be addressed
    51  # with a different API in future.
    52  #
    53  # The script can be used as follows:
    54  #
    55  # ```elvish-transcript
    56  # //skip-test
    57  # ~> elvish a.elv -verbose -port 80 foo
    58  # ...
    59  # ```
    60  #
    61  # See also [`flag:parse`]().
    62  fn call {|fn args &on-parse-error=$nil| }
    63  
    64  # Parses flags from `$args` according to the `$specs`, using the [Go
    65  # convention](#go-convention).
    66  #
    67  # The `$args` must be a list of strings containing the command-line arguments
    68  # to parse.
    69  #
    70  # The `$specs` must be a list of flag specs:
    71  #
    72  # ```elvish
    73  # [
    74  #   [flag default-value 'description of the flag']
    75  #   ...
    76  # ]
    77  # ```
    78  #
    79  # Each flag spec consists of the name of the flag (without the leading `-`),
    80  # its default value, and a description. The default value influences the how
    81  # the flag gets converted from string:
    82  #
    83  # -   If it is boolean, the flag is a boolean flag (see [Go
    84  #     convention](#go-convention) for implications). Flag values `0`, `f`, `F`,
    85  #     `false`, `False` and `FALSE` are converted to `$false`, and `1`, `t`,
    86  #     `T`, `true`, `True` and `TRUE` to `$true`. Other values are invalid.
    87  #
    88  # -   If it is a string, no conversion is done.
    89  #
    90  # -   If it is a [typed number](language.html#number), the flag value is
    91  #     converted using [`num`]().
    92  #
    93  # -   If it is a list, the flag value is split at `,` (equivalent to `{|s| put
    94  #     [(str:split , $s)] }`).
    95  #
    96  # -   If it is none of the above, an exception is thrown.
    97  #
    98  # On success, this command outputs two values: a map containing the value of
    99  # flags defined in `$specs` (whether they appear in `$args` or not), and a list
   100  # containing non-flag arguments.
   101  #
   102  # Example:
   103  #
   104  # ```elvish-transcript
   105  # ~> flag:parse [-v -times 10 foo] [
   106  #      [v $false 'Verbose']
   107  #      [times (num 1) 'How many times']
   108  #    ]
   109  # ▶ [&times=(num 10) &v=$true]
   110  # ▶ [foo]
   111  # ~> flag:parse [] [
   112  #      [v $false 'Verbose']
   113  #      [times (num 1) 'How many times']
   114  #    ]
   115  # ▶ [&times=(num 1) &v=$false]
   116  # ▶ []
   117  # ```
   118  #
   119  # See also [`flag:call`]() and [`flag:parse-getopt`]().
   120  fn parse {|args specs| }
   121  
   122  # Parses flags from `$args` according to the `$specs`, using the [getopt
   123  # convention](#getopt-convention) (see there for the semantics of the options),
   124  # and outputs the result.
   125  #
   126  # The `$args` must be a list of strings containing the command-line arguments
   127  # to parse.
   128  #
   129  # The `$specs` must be a list of flag specs:
   130  #
   131  # ```elvish
   132  # [
   133  #   [&short=f &long=flag &arg-optional=$false &arg-required=$false]
   134  #   ...
   135  # ]
   136  # ```
   137  #
   138  # Each flag spec can contain the following:
   139  #
   140  # -   The short and long form of the flag, without the leading `-` or `--`. The
   141  #     short form, if non-empty, must be one character. At least one of `&short`
   142  #     and `&long` must be non-empty.
   143  #
   144  # -   Whether the flag takes an optional argument or a required argument. At
   145  #     most one of `&arg-optional` and `&arg-required` may be true.
   146  #
   147  # It is not an error for a flag spec to contain more keys.
   148  #
   149  # On success, this command outputs two values: a list describing all flags
   150  # parsed from `$args`, and a list containing non-flag arguments. The former
   151  # list looks like:
   152  #
   153  # ```elvish
   154  # [
   155  #   [&spec=... &arg=value &long=$false]
   156  #   ...
   157  # ]
   158  # ```
   159  #
   160  # Each entry contains the original spec for the flag, its argument, and whether
   161  # the flag appeared in its long form.
   162  #
   163  # Example (some output reformatted for readability):
   164  #
   165  # ```elvish-transcript
   166  # ~> var specs = [
   167  #      [&short=v &long=verbose]
   168  #      [&short=p &long=port &arg-required]
   169  #    ]
   170  # ~> flag:parse-getopt [-v -p 80 foo] $specs
   171  # ▶ [[&arg='' &long=$false &spec=[&long=verbose &short=v]] [&arg=80 &long=$false &spec=[&arg-required=$true &long=port &short=p]]]
   172  # ▶ [foo]
   173  # ~> flag:parse-getopt [--verbose] $specs
   174  # ▶ [[&arg='' &long=$true &spec=[&long=verbose &short=v]]]
   175  # ▶ []
   176  # ~> flag:parse-getopt [-v] [[&short=v &extra-info=foo]] # extra key in spec
   177  # ▶ [[&arg='' &long=$false &spec=[&extra-info=foo &short=v]]]
   178  # ▶ []
   179  # ```
   180  #
   181  # See also [`flag:parse`]() and [`edit:complete-getopt`]().
   182  fn parse-getopt {|args specs &stop-after-double-dash=$true &stop-before-non-flag=$false &long-only=$false| }