DocsMap synopsis to fig

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> or ARGUMENTS,

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 as my_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 more FILE-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 that stdin 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:

  1. Is this value an option or an argument?
  2. If it's an argument
    1. Is its parent an option or a subcommand?
    2. Is it an optional argument? isOptional: true
    3. 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 called expect 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 and filterTerm in the Argument object.
  • [ <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 with name: "--atomic"

  • [--atomic] → an option with name: "--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 has name: "-A", the second option has name: "-B" etc

    • Note: Users can chain options together like this, however, Fig will handle it in its parser
  • [-n | --dry-run] → an option with name: ["-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 with name: "-o" that takes a mandatory argument with name: string

  • [--receive-pack=<git-receive-pack>]→ an option with name: "receive-pack" that takes a mandatory argument with name: git-receive-pack

    • Note: Do not worry about the = sign. Fig handles this in its Tokenizer
  • [--[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"
  • [-S[<keyid>]] → this is an option with name: "-S" with optional argument with name: "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
  • [--chmod=(+|-)x]→ this is an option with name: "chmod" and one mandatory argument with name: "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.
  • [--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
  • [--signed|--signed=(true|false|if-asked)] → This is an option with name: "--signed" that takes an optional argument with name: "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.
  • 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