DocsConceptsBuilding first spec

In this section, you'll learn the autocompletion spec skeleton, and understand how to extend the format to any other CLI tool. To demonstrate, we'll build a basic git autocompletion spec that includes support for a few subcommands, arguments, and options.

1. Defining the spec

To start, let's define the completionSpec variable, and add a name and description. Fig uses the name property when figuring out which spec to load. In this example, when the user enters "git" into their terminal, our completionSpec will be loaded. The name property should match the file name.

Make sure to use export your completion spec using export default

const completionSpec: Fig.Spec = {
    name: "git",
  description: "the stupid content tracker"
}

export default completionSpec;

2. Adding a subcommand

Now that we have our spec defined, let's add autocomplete support for git checkout, so Fig can suggest checkout when the user types in git.

checkout is a subcommand of git, so we'll include it under git's subcommands array. The subcommand object takes a name, description, as well as its own options and arguments. For more information on subcommand's properties, see Subcommand Object.

const completionSpec: Fig.Spec = {
  name: "git",
  description: "the stupid content tracker",
  subcommands: [
    {
      name: "checkout",
      description: "Switch branches or restore working tree files"
    }
  ]
}

3. Adding options and args

git checkout can also take an option or an argument. Now, we'll add support for the -b option flag, and also notify Fig to expect an argument following checkout.

Under the checkout subcommand, we added an empty args object. Including this argument object signals to Fig that there checkout potentially takes an argument.

-b is an option of the checkout subcommand, so we'll nest the flag under the subcommand's options array. Options take a name and description, both of which will show in the Fig UI.

Nested under the -b option is another argument named branch. The Fig parser won't function properly if args aren't included when there should be user input, so don't forget to at least insert an empty args: {} property when there should be an argument.

const completionSpec: Fig.Spec = {
  name: "git",
  description: "the stupid content tracker",
  subcommands: [
    {
      name: "checkout",
      description: "Switch branches or restore working tree files",
      args: {},
      options: [
        {
          name: ["-b"],
          description: "create and checkout a new branch",
          args: {
            name: "branch"
          }
        },
      ]
    }
  ]
}

4. Including an option to the root object

We now have a spec that supports the primary functionality of git checkout. The root object, defined as completionSpec, is actually a command in itself, with the same properties as the Subcommand Object.

If we want to add support for git --version, the --version flag can be added as an option under the root object as follows:

const completionSpec: Fig.Spec = {
  name: "git",
  description: "the stupid content tracker",
  subcommands: [
    {
      name: "checkout",
      description: "Switch branches or restore working tree files",
      args: {},
      options: [
        {
          name: ["-b"],
          description: "create and checkout a new branch",
          args: {
            name: "branch"
          }
        },
      ]
    },
  ],
  options: [
    {
      name: ["--version"],
      description: ["View your current git version"]
    }
  ]
}

Making Advanced Suggestions

Above, we put together a spec that supports git checkout, and git --version. But by using some of Fig's advanced features, we can improve autocomplete even more for git checkout.

Using Generators

1. Generating branches

When a user runs git checkout, they typically want to move to another local branch. In our current configuration, Fig is expecting an argument in the form of the empty args object we added to checkout. Fig doesn't provide any suggestions by default when an empty args object is provided.

const checkout: Fig.Subcommand = {
  name: "checkout",
  description: "Switch branches or restore working tree files",
  args: {},
};

But, we can generate a list of suggestions that show the user all their local git branches using Generators.

A generator runs a script in the user's terminal, and Fig will capture the output of that script. We want to run git branch --no-color to have git display the list of branches.

The postProcess function captures the output from the terminal as a string, and within the function you can write logic to convert the output string into suggestions. We want to split our list of branches by the newline character, and convert each line containing a branch into a [Suggestion Object](#Suggestion Object) containing a name and description. Note that postProcess should return an array of generated suggestion objects.

const branches:Fig.Generator = {
  script: "git branch --no-color",
  postProcess: (output) => {
    if (output.startsWith("fatal:")) {
      return []
    }
    return output.split('\n').map((branch) => {
      return { name: branch.replace("*", "").trim(), description: "branch" }
    })
  }
}

2. Passing the generator into the completion spec

The last step is to pass our new generator into the spec. Because we want the generator to get the list of branches following git checkout, we pass branches into the checkout subcommand's args.

const branches: Fig.Generator = {
  script: "git branch --no-color",
  postProcess: (output) => {
    if (output.startsWith("fatal:")) {
      return [];
    }
    return output.split("\n").map((branch) => {
      return { name: branch.replace("*", "").trim(), description: "branch" };
    });
  },
};

const completionSpec: Fig.Spec = {
  name: "git",
  description: "the stupid content tracker",
  subcommands: [
    {
      name: "checkout",
      description: "Switch branches or restore working tree files",
      args: {
        generators: branches,
      },
      options: [
        {
          name: ["-b"],
          description: "create and checkout a new branch",
          args: {
            name: "branch",
          },
        },
      ],
    },
  ],
  options: [
    {
      name: ["--version"],
      description: ["View your current git version"],
    },
  ],
};

Our one branch, main, now shows as an autocomplete suggestion.

For more details about writing generators, see Generators.

Using argument templates

1. Suggesting files and folders

Fig has a few commonly used generators built-in as templates.

Let's improve our git completion spec by adding support for git add. When running the command, users can select individual files and folders. We can have Fig show suggestions for possible files and folders to add using the "filepaths" template.

We include the add subcommand under checkout, which accepts one argument. Entering the "filepaths" template under that argument automatically suggests files from the user's working directory when git add is typed into the terminal.

const branches: Fig.Generator = {
  script: "git branch --no-color",
  postProcess: (output) => {
    if (output.startsWith("fatal:")) {
      return [];
    }
    return output.split("\n").map((branch) => {
      return { name: branch.replace("*", "").trim(), description: "branch" };
    });
  },
};

const completionSpec: Fig.Spec = {
  name: "git",
  description: "the stupid content tracker",
  subcommands: [
    {
      name: "checkout",
      description: "Switch branches or restore working tree files",
      args: {
        generators: branches,
      },
      options: [
        {
          name: ["-b"],
          description: "create and checkout a new branch",
          args: {
            name: "branch",
          },
        },
      ],
    },
    {
      name: "add",
      description: "Stage files to commit",
      args: {
        template: "filepaths",
      },
    },
  ],
  options: [
    {
      name: ["--version"],
      description: ["View your current git version"],
    },
  ],
};

Here's what the filepaths template looks like in action:


The fastest way to learn is by looking at examples. We suggest looking at some of the completion specs for commands you know well, like git or npm. You should be able to pick up the format pretty quickly.

All current specs: withfig/autocomplete

Next up

Ready to test your spec and put it into action? See Testing Autocomplete