DocsReferenceGenerator

Generators

Generators let you run shell commands to generate a list of Suggestions for a given Argument.

Generators are used to programatically generate suggestion objects. For instance, a generator can fetch a list of git remotes, grab all the folders in the current working directory, or even hit an API endpoint.

For a high level overview of Generators and their usage, see "Dynamic Suggestions".

Quick Summary

Generators let you run shell commands on the user's device to generate suggestions for arguments

Basic Generators

Run a shell command to provide dynamic suggestions.

See "Basic Generators" to understand the most common usage pattern.

Templates

Some generators, like the ones for filepaths and folders, are so common across CLI tools that it doesn't make sense for every spec to reimplement them from scratch.

See "Templates" to quickly provide rich suggestions for files and folders.

Contextual Generators

Provide suggestions that require context from other flags or options in the current edit buffer.

To handle this case, a Generator needs to run a script which incorporates text that the user has typed.

heroku addons:remove --app my-example-app |

For example, when completing this heroku command, Fig should only suggest addons that are associated with the specific app, my-example-app.

See "Contextual Generators" to learn how to run a script that incorporates text from the user's edit buffer.

Triggers & Filtering

Provide a new set of suggestions after the user types a certain character, like the / in a filepath, for instance.

See "Reimplementing the Filepath Generator" for more information of how to use triggers and filterTerm.

Caching & Debouncing

Suggestions are computed by an expensive function — a web request, for instance — and should be cached or debounced.

See "Making an HTTP Request from a Generator" for details on how to handle expensive functions.

Custom Generators

Write imperative code where suggestions must be recomputed on every keypress, to handle tools with non-standard parsing, like chmod.

See "Custom Generators" to learn more.

Properties

template

Type: Template

Required:

Description:

Fig has pre-built generators for common suggestion types. Currently, we support templates for either "filepaths" or "folders". You can do either of these as a string or both in an array. Folders will only show folders. Filepaths will show folders and filepaths but will only offer the insert and execute functionality (the red automatic insert icon you see when using cd) for files NOT folders.

Example:

cd uses the folders template whereas ls uses [filepaths, folders]


filterTemplateSuggestions

Type: Function\< Modify\<Suggestion, { name?: string }>[], Suggestion[] >

Required:

Description:

This function takes a single argument: the array of suggestion objects output by the template prop. It then lets you edit them as you see fit. You must then return an array of suggestion objects.

Example:

The python spec has an arg object which has a template for "filepaths" and then filters out all suggestions generated that don't end with "/" (to keep folders) or ".py" (to keep python files)


script

Type: StringOrFunction\<string[], string>

Required:

Description:

In order to generate contextual suggestions for arguments, Fig lets you execute a shell command on the users local device as if it were done in their current working directory. You can either specify

  1. a string to be executed (like ls or git branch)
  2. a function to generate the string to be executed. The function takes in an array of tokens of the user input and should output a string. You use a function when the script you run is dependent upon one of the tokens the user has already input (for instance an app name, a Kubernetes token etc.) After executing the script, the output will be passed to one of splitOn or postProcess for further processing to produce suggestion objects.

Example:

git checkout takes one argument which is a git branch. Its arg object has a generator with a script of git branch to list out the branches.


postProcess

Type: (out: string, tokens?: string[]) => Suggestion[]

Required:

Description:

This function takes one parameter: the output of script. You can do whatever processing you want, but you must return an array of Suggestion objects.


splitOn

Type: string

Required:

Description:

Syntactic sugar for postProcess. This takes in the text output of script, splits it on the string you provide here, and then automatically generates an array of suggestion objects for each item.

Example:

Specify "," or "\n", and Fig will do the work of the postProcess prop for you


trigger

Type: string

Required:

Description:

Fig performs numerous optimizations to avoid running expensive shell functions many times. For instance, after you type cd[space] we load up a list of folders (the suggestions). After you start typing, we instead filter over this list of folders (the filteredSuggestions). The suggestions remain the same while the filteredSuggestions change on each input.

Typically, Fig regenerates the suggestions every time the user hits space as in bash, a space typically delimits commands. However, if the trigger prop is defined, Fig will run the trigger function on each keystroke. If it returns true, instead of filtering over the suggestions, Fig will regenerate the list of suggestions THEN filter over them. The trigger function takes two inputs: the new token the user typed and the token on the keystroke before.

Trigger as a function takes two arguments: 1. the new token 2. the old token e.g. the old token might be desktop and the new token might be desktop/. The function may look for a different in the number of slashes. In this case there is a difference so it would return true.

The trigger prop can also be a simple string. This is syntactic sugar that allows you to specify a single character. If count of this character in the string before !== the count of the new string, Fig will regenerate the suggestions.

Using a trigger is especially beneficial when you have an argument contained inside a single string that is not separated by a space. It is often used with a custom prop or script (as a function)

Finally, make sure you don't confuse trigger with debounce. Debounce will regenerate suggestions after a period of inactivity typing. Trigger will regenerate suggestions when the function you define returns true!

Use some logging in the function to work out when trigger is being run

Example:

You can see the trigger in action every time you use file and folder completions (e.g. with cd). When you type a /, Fig will regenerate its list of file and folder suggestions by appending the path of what you've already typed to your current working directory. e.g. If I had already typed "desktop". The current list of suggestions is from the ~ directory and getQueryTerm is "desktop". Then I type "/" so it says "desktop/", the trigger would return true, Fig will generate suggestions for the directory ~/desktop/ and the query term will become an empty string.


getQueryTerm

Type: StringOrFunction\<string, string>

Required:

Description:

Read the note above on how triggers work. Triggers and query term may seem similar but are actually different. The trigger defines when to regenerate new suggestions. The query term defines what characters we should use to filter over these suggestions.

It can be a function: this takes in what the user has currently typed as a string and outputs a separate string that is used for filtering. It can also be a string: this is syntactic sugar that takes everything in the string after the character(s) you choose.

Use some logging in the function to work out what the trigger is.

Example:

cd has a filter term of "/". If an argument to cd includes a "/" Fig will filter over all of the suggestions generated using the string AFTER the last "/"


custom

Type: ( tokens: string[], executeShellCommand: ExecuteShellCommandFunction, shellContext?: ShellContext ) => Promise\<Suggestion[]>

Required:

Description:

Custom function is a bit like script as a function, however, it gives you full control.

It is an async function.

It takes two or three arguments:

  1. Tokens: an array of tokens of what the user has typed
  2. executeShellCommand: a function that takes a string as input. It executes this string as a shell command on the user's device from the same current working directory as their terminal. It outputs a text blob. It is also async.
  3. shellContext: information about the shell session the user is currently working in

It must return an array of suggestion objects.

Example:

const generator: Fig.Generator = {
custom: async (tokens, executeShellCommand) => {
const out = await executeShellCommand("ls");
return out.split("\n").map((elm) => ({ name: elm }));
},
};

cache

Type: Cache

Required:

Description:

For commands that take a long time to run, Fig gives you the option to cache their response. You can cache the response globally or just by the directory they were run in You just need to specify a ttl (time to live) for how long the cache will last (this is a number) You can also optionally turn on the ability to just cache by directory (cacheByDirectory: true)

Example:

The kubernetes spec makes use of this.