DocsSubcommand

Subcommand

Used to define subcommands under a main command.

For example, within git commit, commit is a subcommand of git.

Subcommands can also be nested within subcommands.

Properties

name

The exact name of the subcommand as defined in the CLI tool.

Declaration:name: string | string[];

Discussion

Fig's parser relies on your subcommand name being exactly what the user would type. e.g. if the user types git "commit", you must have name: "commit" and not something like name: "your commit message".

If you want to customize what the text the popup says, use displayName.

The name prop in a Subcommand object compiles down to the name prop in a Suggestion object

Final note: the name prop can be a string (most common) or an array of strings

Examples

  • For git checkout, the subcommand checkout would have name: "checkout"
  • For npm install, the subcommand install would have name: ["install", "i"] as these two values both represent the same subcommand.

subcommands

An array of subcommand objects representing all the subcommands that exist beneath the current subcommand. Subcommands can be nested recursively.

Optional Property:true

Declaration:subcommands?: Subcommand[];

Example

aws has plenty of subcommands (s3, ec2, eks...) and each of these have plenty of subcommands of their own. This is where these subcommands nest.


options

An array of option objects representing the options that nest beneath this subcommand.

Optional Property:true

Declaration:options?: Option[];

Example

git checkout can take lots of options e.g. -b, -f, -d ... These option objects are all represented here.


args

An array of arg objects or a single arg object

Optional Property:true

Declaration:args?: Arg | Arg[];

Discussion

If a subcommand takes an argument, please at least include an empty Arg Object. (e.g. { }). Why? If you don't, Fig will assume the subcommand does not take an argument. When the user types their argument If the argument is optional, you can set isOptional: true on the arg.

Examples

  • npm run takes one mandatory argument. This can be represented by args: { }
  • git push takes two mandatory arguments. This can be represented by: args: [{ isOptional: true }, { isOptional: true }]
  • git clone takes two optional arguments. This can be represented by: args: [{ isOptional: true }, { }]

additionalSuggestions

A list of Suggestion objects that are appended to the suggestions shown beneath a subcommand.

Optional Property:true

Declaration:additionalSuggestions?: (string | Suggestion)[];

Discussion

These are often shortcuts with type="shortcut"


loadSpec

Dynamically load up another completion spec at runtime.

Optional Property:true

Parameters

NameDescription
tokensa tokenized array of what the user has typed
executeShellCommandan async function that allows you to execute a shell command on the user's system and get the output as a string.

Return Value

A SpecLocation object or an array of SpecLocation obejcts.

Declaration

loadSpec?: string | ((token: string, executeShellCommand: (commandToExecute: string) => Promise<string>) => Promise<SpecLocation | SpecLocation[]>);

Discussion

When is this used?

  • For very very large specs (e.g. aws or gcloud) where loading the full completion spec would be slow. Instead, we load up the list of subcommands then dynamically load up the sub-subcommands using loadSpec.
  • For CLI tools that take a command as an argument e.g. time <cmd> or builtin <cmd>. loadSpec will load up the completion spec for the CLI the user inputs. e.g. if the user types time git we should load up the git spec
  • For CLI tools that take a local script as an argument e.g. python <script> or node <script>. loadSpec will load up the completion spec for the script the user inputs. e.g. if the user types python main.py we should load up the main.py completion spec.
  • For CLI tools that have modules that function like their own CLI tools. e.g. python -m <module>. LoadSpec will load up the completion spec for the module e.g. the http.server completion spec

The SpecLocation Object

The SpecLocation object defines well... the location of the completion spec we want to load. Specs can be "global" (ie hosted by Fig's cloud) or "local" (ie stored on your local machine).

// e.g.
{ type: "global", name: "aws/s3" } // Loads up the aws s3 completion spec
{ type: "global", name: "python/http.server" } // Loads up the http.server completion spec
  • Local SpecLocation: Load specs saved on your local system / machine. Assume the current working directory is the user's current working directory. The name prop should take the name of the spec (without the .js file extension) e.g. my_cli_tool The path prop should take an absolute path OR a relative path (relative to the user's current working directory). The path should be to the directory that contains the .fig folder. Fig will then assume your spec is located in .fig/autocomplete/build/
// e.g.
{ type: "global", path: "node_modules/cowsay", name: "cowsay_cli" }  // will look for `cwd/node_modules/cowsay/.fig/autocomplete/build/cowsay_cli.js`
{ type: "global", path: "~", name: "my_cli" }  // will look for `~/.fig/autocomplete/build/my_cli.js`

Syntactic Sugars

We have three bits of syntactic sugar that can make this easier:

  1. Pass a single string to loadSpec instead of a function. We interpret this string as the "name" prop of global SpecLocation object
// e.g.
loadSpec: python/http.server
// compiles to
{ type: "global", name: "python/http.server" }
  1. isCommand (See Arg Object).
  2. isScript (See Arg Object).

generateSpec

Dynamically generate a subcommand object to be merged in at the same level as the subcommand this is nested beneath.

Optional Property:true

Parameters

NameDescription
tokensa tokenised array of strings of what the user typed
executeShellCommandan async function that allows you to execute a shell command on the user's system and get the output as a string.

Return Value

a Fig.Spec object

Declaration

generateSpec?: (tokens?: string[], executeShellCommand?: (commandToExecute: string) => Promise<string>) => Promise<Subcommand | ((version?: string) => Subcommand)>;

Discussion

For instance, if generateSpec was added beneath the git command, the subcommand object generated by the generateSpec function would be deep merged with the git spec.

Examples

  • The python spec uses generateSpec to insert the django-admin spec if django manage.py exists.
  • php uses this to see if artisan exists. Then php artisan uses this to see if

parserDirectives

Flags that allow customization of how Fig parses tokens.

Optional Property:true

Declaration

parserDirectives?: {
            flagsArePosixNoncompliant?: boolean;
            optionsMustPrecedeArguments?: boolean;
        };

Discussion

  • flagsArePosixNoncompliant: when flagsArePosixNoncompliant is true, options with one hyphen to have multiple characters.
  • optionsMustPrecedeArguments: when optionsMustPrecedeArguments is true, options will not be suggested after a subcommand arg is typed.

Example

The -work option from the go spec is parsed as a single flag when parserDirectives.flagsArePosixNoncompliant is set to true. Normally, this would be chained and parsed as -w -o -r -k if flagsArePosixNoncompliant is not set to true.


displayName

The string that is displayed in the UI for a given suggestion.

Optional Property:true

Declaration:displayName?: string;

Default Value:the name prop

Example

The npm CLI has a subcommand called install. If we wanted to display some custom text like Install an NPM package 📦 we would set name: "install" and displayName: "Install an NPM package 📦"


insertValue

The value that's inserted into the terminal when a user presses enter/tab or clicks on a menu item.

Optional Property:true

Declaration:insertValue?: string;

Discussion

You can use \n to insert a newline or \b to insert a backspace. You can also optionally specify {cursor} in the string and Fig will automatically place the cursor there after insert.

Default Value:The value of the name prop.

Example

For the git commit subcommand, the -m option has an insert value of -m '{cursor}'


description

The text that gets rendered at the bottom of the autocomplete box (or the side if you hit ⌘i)

Optional Property:true

Declaration:description?: string;

Example

"Your commit message"


icon

The icon that is rendered is based on the type.

Optional Property:true

Declaration:icon?: string;

Discussion

Icons can be a 1 character string, a URL, or Fig's icon protocol (fig://) which lets you generate colorful and fun systems icons.

Default Value

related to the type of the object (e.g. Suggestion, Subcommand, Option, Arg)

Examples

  • A
  • 😊
  • https://www.herokucdn.com/favicon.ico
  • fig://icon?type=file

isDangerous

Specifies whether the suggestion is "dangerous".

Optional Property:true

Declaration:isDangerous?: boolean;

Discussion

If true, Fig will not enable its autoexecute functionality. Autoexecute means if a user selects a suggestion it will insert the text and run the command. We signal this by changing the icon to red. Setting isDangerous to true will make it harder for a user to accidentally run a dangerous command.

Default Value:false

Example

This is used in the rm spec. Why? Because we don't want users to accidentally delete their files so we make it just a little bit harder...


priority

The number used to rank suggestions in autocomplete. Number must be from 0-100. Higher priorities rank higher.

Optional Property:true

Declaration:priority?: number;

Discussion

Fig ranks suggestions by recency. To do this, we check if a suggestion has been selected before. If yes and the suggestions has:

  • a priority between 50-75, the priority will be replaced with 75, then we will add the timestamp of when that suggestion was selected as a decimal.
  • a priority ourside of 50-75, the priority will be increased by the timestamp of when that suggestion was selected as a decimal. If it has not been selected before, Fig will keep the same priority as was set in the completion spec If it was not set in the spec, it will default to 50.

Default Value:50

Examples

  • Let's say a user has previously selected a suggestion at unix timestamp 1634087677:
    • If completion spec did not set a priority (Fig treats this as priority 50), its priority would change to 75 + 0.1634087677 = 75.1634087677;
    • If completion spec set a priority of 49 or less, its priority would change to 49 + 0.1634087677 = 49.1634087677;
    • If completion spec set a priority of 76 or more, its priority would change to 76 + 0.1634087677 = 76.1634087677;
    • If a user had never selected a suggestion, then its priority would just stay as is (or if not set, default to 50).
  • If you want your suggestions to always be:
    • at the top order, rank them 76 or above.
    • at the bottom, rank them 49 or below

hidden

Specifies whether a suggestion should be hidden from results.

Optional Property:true

Declaration:hidden?: boolean;

Discussion

Fig will only show it if the user exactly types the name.

Default Value:false

Example

The "-" suggestion is hidden in the cd spec. You will only see it if you type exactly cd -


deprecated

Specifies whether a suggestion is deprecated.

Optional Property:true

Declaration

deprecated?: boolean | Omit<BaseSuggestion, "deprecated">;

Discussion

It is possible to specify a suggestion to replace the deprecated one.

  • The description of the deprecated object (e.g deprecated: { description: 'The --no-ansi option has been deprecated in v2' }) is used to provide infos about the deprecation.
  • deprecated: true and deprecated: { } behave the same and will just display the suggestion as deprecated.

Example

deprecated: { insertValue: '--ansi never', description: 'The --no-ansi option has been deprecated in v2' }