Understanding the Synopsis section of man pages
This section is copied straight from https://github.com/docopt/docopt
- <arguments>, ARGUMENTS. Arguments are specified as either upper-case words, e.g.
my_program.py CONTENT-PATH
or words surrounded by angular brackets:my_program.py <content-path>
. - --options. Options are words started with dash (
-
), e.g.--output
,-o
. You can "stack" several of one-letter options, e.g.-oiv
which will be the same as-o -i -v
. The options can have arguments, e.g.--input=FILE
or-i FILE
or even-iFILE
. - commands are words that do not follow the described above conventions of
--options
or<arguments>
orARGUMENTS
,
Use the following constructs to specify patterns:
- [ ] (brackets) optional elements. e.g.:
my_program.py [-hvqo FILE]
- ( ) (parens) required elements. All elements that are not put in [ ] are also required, e.g.:
my_program.py --path=<path> <file>...
is the same asmy_program.py (--path=<path> <file>...)
. (Note, "required options" might be not a good idea for your users). - | (pipe) mutually exclusive elements. Group them using ( ) if one of the mutually exclusive elements is required:
my_program.py (--clockwise | --counter-clockwise) TIME
. Group them using [ ] if none of the mutually-exclusive elements are required:my_program.py [--left | --right]
. - ... (ellipsis) one or more elements. Specify that elements are variadic ie an arbitrary number of repeating elements could be accepted, use ellipsis (
...
), e.g.my_program.py FILE ...
means one or moreFILE
-s are accepted. If you want to accept zero or more elements, use brackets, e.g.:my_program.py [FILE ...]
. Ellipsis works as a unary operator on the expression to the left. - [options] (case sensitive) shortcut for any options. You can use it if you want to specify that the usage pattern could be provided with any options defined below in the option-descriptions and do not want to enumerate them all in usage-pattern.
- Special:
- "
[--]
". Double dash "--
" is used by convention to separate positional arguments- NOTE: Fig will handle this automatically
- "
[-]
". Single dash "-
" is used by convention to signify thatstdin
is used instead of a file- NOTE: You should not handle this, Fig will treat it as a file input
- "
Converting Synopsis from man pages to Fig Spec
In your head think:
- Is this value an option or an argument?
- If it's an argument
- Is its parent an option or a subcommand?
- Is it an optional argument?
isOptional: true
- Is it a variadic argument (repeats infinitely)? →
variadic: true
Arguments
[arg]
→ optional argument<arg>
→ mandatory argument[<arg>]
→ optional argument[<arg1> [arg2]]
→ both args are optional[<arg1> [<arg2>]]
→ both args are optional[<arg1> <arg2>]
→ arg1 is optional, arg2 is mandatory- Why? Inputting arguments is optional. But as soon as you input the first one, you must input the second one
<arg...>
→ Mandatory arg that is variadic[arg...]
→ Optional arg that is variadic[<arg1> [<arg2>...]
→ arg1 is optional, arg2 is optional and variadic[<arg1> [<arg1>...]
→ arg1 is optional and variadic- This syntax happens in man pages regularly.The same argument repeats twice but the second is variadic... In this case, just include one argument and then make it variadic. Do NOT include two arguments
[<arg1> [<arg1>...]]
→ arg1 is optional and variadic[<refname>[:<expect>]]
→ This is just one argument that is optional. Let's break this down- This argument is optional as it is surrounded by
[]
- Inside the argument we have
[:<expect>]
→ The square brackets around[:<expect>]
indicate that, if there is a:
, the user can optionally input a second argument afterwards calledexpect
within the same string. Because this second argument is part of the same string, Fig's tokenizer would treat this argument as the one token. - Therefore, as Fig's tokenizer treats it as one token, the completion spec must treat it as one argument
- e.g. a user could type
abc:def
for this argument, Fig's tokenizer would treat it as[..., "abc:def"]
- We would give this argument
name: "refname[:expect]"
- Can Fig still offer suggestions for the
expect
part of this argument?- Yes. Fig can offer special suggestions for the the
expect
section of the argument after the user inserts a:
even though the completion spec says it only has one argument. - You will need to look into
trigger
and script as a function in the Generator objects andfilterTerm
in the Argument object.
- Yes. Fig can offer special suggestions for the the
- This argument is optional as it is surrounded by
[ <arg1...> [arg2...]
→ TRICK! This shouldn't exist. Because arg1 is variadic we will never get to arg 2. Also note that that arg1 is optional
Options
--atomic
→ an option withname: "--atomic"
[--atomic]
→ an option withname: "--atomic"
- Although it is surrounded by square brackets indicating that it is optional, Fig currently doesn't support a syntax for "optional arguments"
[-ABCFGHLOPRSTUW@abcdefghiklmnopqrstuwx1%]
→ This is a list of options. The first option hasname: "-A"
, the second option hasname: "-B"
etc- Note: Users can chain options together like this, however, Fig will handle it in its parser
[-n | --dry-run]
→ an option withname: ["-n", "--dry-run"]
- A pipe separating a short option (one dash) and a long option (two dashes) usually means the options are the same but can be referred to in either way
[--all | --mirror | --tags]
→ three separate options- A pipe separating multiple long options or multiple short options usually indicates they are mutually exclusive
[-o <string>]
→ an option withname: "-o"
that takes a mandatory argument withname: string
[--receive-pack=<git-receive-pack>]
→ an option withname: "receive-pack"
that takes a mandatory argument withname: git-receive-pack
- Note: Do not worry about the
=
sign. Fig handles this in its Tokenizer
- Note: Do not worry about the
[--[no-]signed]
→ This is actually shorthand for[--signed] [--no-signed]
and so it simply two options:- The first has
name: "--no-signed"
- The second has
name: "--signed"
- The first has
[-S[<keyid>]]
→ this is an option withname: "-S"
with optional argument withname: "keyid"
- Why? Short options (options with one
-
) sometimes allow you to insert an argument without a space... e.g.git commit -m"Hello"
- Fig's parser will handle this special logic
- Why? Short options (options with one
[--chmod=(+|-)x]
→ this is an option withname: "chmod"
and one mandatory argument withname: "x"
- Note: the
()
indicate that you can precede the argument with a+
or-
. This should not be included in the spec. You can do custom suggestions here with trigger, filterTerm and script as a function.
- Note: the
[--force-with-lease[=<refname>[:<expect>]]]
→ Let's break this down- This is an option with
name: "--force-with-lease"
- It takes one argument with
name: "refname[:expect]"
- This argument is optional
[=<refname>[:<expect>]]
as it is surrounded by square brackets - Then we would parse the argument the same as we did in this example in the Arguments section above
- This argument is optional
- This is an option with
[--signed|--signed=(true|false|if-asked)]
→ This is an option withname: "--signed"
that takes an optional argument withname: "SIGNED"
- The
()
indicate that these are the possible arguments for the--signed
option. However, because we have the pipe symbol, clearly--signed
can exist on its own (ie without any options). Therefore, the argument is optional - An additional note: because we have a defined list of suggestions here, you could also give the argument object the
suggestion: ["true", "false", "if-asked"]
and Fig will generate these as suggestions for it.
- The
Annoyingly tricky:
[--[no-]signed|--signed=(true|false|if-asked)]
→ Let's break this down with everything we learned above- The pipe symbol indicates mutually exclusive (above) meaning
--signed
takes an optional argument - the
[no-]
indicates shorthand (above) meaning--no-signed
and--signed
are valid options
Other
[<options>]
,[options]
, or<options>
→ indicate that this is where a spec would insert their options[<command>]
,[command]
, or<command>
→ indicate that this is where a spec would insert their subcommands[<args>]
,[args]
, or<args>
→ indicate that this is where a spec would insert their arguments
Examples of Converting Common CLIs to Fig's standard
SYNOPSIS
git push [--all | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
[--repo=<repository>] [-f | --force] [-d | --delete] [--prune] [-v | --verbose]
[-u | --set-upstream] [-o <string> | --push-option=<string>]
[--[no-]signed|--signed=(true|false|if-asked)]
[--force-with-lease[=<refname>[:<expect>]]]
[--no-verify] [<repository> [<refspec>...]]
Coming soon!!
In the meantime, check out `git push --help` and the git completion spec