DocsGenerating argument suggestions

Generating Argument Suggestions

This section teaches you how to generate suggestions for arguments in the git checkout completion spec.

We're following on from the git checkout completion spec we built in the last section.

Generators

Generator objects allow you to generate suggestions for arguments.

They are what is used to generate branch suggestions for git checkout, file and folder suggestions for cd, and the list of scripts from your package.json in npm run.

Generators consist of two things: a script and a postProcess function. The script property runs any shell command in the background and returns the result.

The postProcess function is a regular TypeScript function that takes the output of the script as an input, does some processing, and outputs a list of suggestion objects.

1. Generating branches

Now that we've learned what generators are, let's generate a list of suggestions for git checkout.

When a user runs git checkout, they typically want to move to another local branch. In our current configuration, Fig is expecting an argument since we added an args object under the checkout subcommand.

const completionSpec: Fig.Spec = {
  name: "git",
  description: "the stupid content tracker",
  subcommands: [
    {
      name: "checkout",
      description: "Switch branches or restore working tree files",
      args: {
        name: "branch",
        description: "the branch you want to checkout",
        isOptional: true,
      },
    },
  ],
};

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

In our case, we want to list all of the user's local git branches which can be done with the git branch --no-color command.

We want to capture the output of that command, do some parsing and processing, and output an array of suggestion objects, which are objects that take a name and description property.

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 checkout's args.

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

Now, when we run git checkout in our terminal, we can see suggestions pop up for all our local branches that we saw when we run the script!

For more about writing more complex generators, see Generators.

Other types of generators

1. Suggesting files and folders

Fig has a few generators that are so common, we made templates for them. The only two that are currently supported are filepaths and folders for suggesting files and folders in the user's current directory.

To demonstrate the use of these, 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.

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: {
        name: "branch",
        description: "the branch you want to checkout",
        isOptional: true,
        generators: branches,
      },
      options: [
        {
          name: ["-b"],
          description: "create and checkout a new branch",
          args: {
            name: "New branch",
          },
        },
      ],
    },
    {
      name: "add",
      description: "Stage files to commit",
      args: {
        template: "filepaths",
      },
    },
  ],
};

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

And there you have it, your first completion Spec is officially done!


Next

You've just learnt how to generate suggestions for arguments. the different object types for Fig's completion spec standard.

Now let's take a look at a few things to keep in mind when building completion specs.

Go to Things to Keep in Mind