DocsOthers

Others

Other types used to construct a completion spec, like Subcommand and Option, are subclasses of Suggestion and inherit its properties. Generators produce a list of Suggestion objects.

Types

Templates are generators prebuilt by Fig.

type TemplateStrings = "filepaths" | "folders" | "history" | "help"
Discussion

Here are the three templates:

  • filepaths: show folders and filepaths. Allow autoexecute on filepaths
  • folders: show folders only. Allow autoexecute on folders
  • history: show suggestions for all items in history matching this pattern
  • help: show subcommands. Only includes the 'siblings' of the nearest 'parent' subcommand

A template which is a single TemplateString or an array of TemplateStrings

type Template =
  | ("filepaths" | "folders" | "history" | "help")
  | ("filepaths" | "folders" | "history" | "help")[]
Examples

cd uses the "folders" template ls used ["filepaths", "folders"]. Why both? Because if I ls a directory, we want to enable a user to autoexecute on this directory. If we just did "filepaths" they couldn't autoexecute.

Discussion

Templates are generators prebuilt by Fig. Here are the three templates:

  • filepaths: show folders and filepaths. Allow autoexecute on filepaths
  • folders: show folders only. Allow autoexecute on folders
  • history: show suggestions for all items in history matching this pattern
  • help: show subcommands. Only includes the 'siblings' of the nearest 'parent' subcommand

type HistoryContext = {
  currentWorkingDirectory: string
  time: number
  exitCode: number
  shell: string
}

type TemplateSuggestionContext =
  | {
      templateType: "filepaths"
    }
  | {
      templateType: "folders"
    }
  | {
      templateType: "help"
    }
  | ({
      templateType: "history"
    } & Partial<{
      currentWorkingDirectory: string
      time: number
      exitCode: number
      shell: string
    }>)

type TemplateSuggestion = Modify<
  Suggestion,
  {
    name?: string
    context:
      | {
          templateType: "filepaths"
        }
      | {
          templateType: "folders"
        }
      | {
          templateType: "help"
        }
      | ({
          templateType: "history"
        } & Partial<{
          currentWorkingDirectory: string
          time: number
          exitCode: number
          shell: string
        }>)
  }
>

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)

type SpecLocation =
  | {
      type: "local"
      path?: string
      name: string
    }
  | {
      type: "global"
      name: string
    }
Discussion

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).

  • Global SpecLocation: Load specs hosted in Fig's Cloud. Assume the current working directory is here: https://github.com/withfig/autocomplete/tree/master/src. Now set the value for the "name" prop to the relative location of your spec (without the .js file extension)
// 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. myclitool 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`

Dynamically load up another completion spec at runtime.

See loadSpec property in Subcommand Object.

type LoadSpec =
  | string
  | Subcommand
  | ((
      token: string,
      executeShellCommand: (
        commandToExecute: string,
        cwd?: string
      ) => Promise<string>
    ) => Promise<SpecLocation | SpecLocation[] | Subcommand>)

The type of a suggestion object.

type SuggestionType =
  | "folder"
  | "file"
  | "arg"
  | "subcommand"
  | "option"
  | "special"
  | "mixin"
  | "shortcut"
Discussion

The type determines:

  • the default icon Fig uses (e.g. a file or folder searches for the system icon, a subcommand has a specific icon etc)
  • whether we allow users to auto-execute a command

A single object of type T or an array of objects of type T.

type SingleOrArray<T> = T | T[]

An async function that returns the version of a given CLI tool.

type GetVersionCommand = (
  executeShellCommand: (
    commandToExecute: string,
    cwd?: string
  ) => Promise<string>
) => Promise<string>
Examples

1.0.22

v26

Parameters
NameDescription
executeShellCommandan async function that allows you to execute a shell command on the user's system and get the output as a string.
Discussion

This is used in completion specs that want to version themselves the same way CLI tools are versioned. See fig.io/docs


Context about a current shell session.

type ShellContext = {
  currentWorkingDirectory: string
  environmentVariables: Record<string, string>
  currentProcess: string
  /**
   * @hidden
   * @deprecated
   */
  sshPrefix: string
}

type GeneratorContext = {
  currentWorkingDirectory: string
  environmentVariables: Record<string, string>
  currentProcess: string
  /**
   * @hidden
   * @deprecated
   */
  sshPrefix: string
} & {
  isDangerous?: boolean
  searchTerm: string
}

A function which can have a T argument and a R result.

type Function<T = void, R = void> = (param: T) => R
Parameters
NameDescription
paramA param of type `R`

A utility type to modify a property type

type Modify<T, R> = Omit<T, keyof R> & R

A string OR a function which can have a T argument and a R result.

type StringOrFunction<T = void, R = void> = string | ((param: T) => R)
Parameters
NameDescription
paramA param of type `R`

type ArgDiff = Modify<
  Fig.Arg,
  {
    remove?: true
  }
>

type OptionDiff = Modify<
  Fig.Option,
  {
    args?: ArgDiff | ArgDiff[]
    remove?: true
  }
>

type SubcommandDiff = Modify<
  Fig.Subcommand,
  {
    subcommands?: SubcommandDiff[]
    options?: OptionDiff[]
    args?: ArgDiff | ArgDiff[]
    remove?: true
  }
>

type SpecDiff = Omit<SubcommandDiff, "name" | "remove">

type VersionDiffMap = Record<string, SpecDiff>

A spec object. Can be one of

  1. A subcommand
  2. A function that dynamically computes a subcommand
  3. A function that returns the path to a versioned spec files (that exports a base subcommand and { versions: VersionDiffMap }
type Spec =
  | Subcommand
  | ((version?: string) => Subcommand)
  | ((version?: string) => {
      versionedSpecPath: string
      version?: string
    })

An async function to execute a shell command

type ExecuteShellCommandFunction = (
  commandToExecute: string,
  cwd?: string
) => Promise<string>
Examples

ExecuteShellCommandFunction("echo hello world") will return hello world

Parameters
NameDescription
commandToExecuteThe shell command you want to execute
cwdThe directory in which to execute the command
Discussion

The cwd parameter will add a cd [cwd] && before the command itself.


type ExecFunctionOptions = (
  | {
      /**
       * The command to execute, this will be executed in bash like a normal shell command.
       * @example
       * `echo hello world`
       * @example
       * `ls`
       */
      command: string
    }
  | {
      /**
       * This will execute the command without a shell, so you can use this to execute a binary.
       * @example
       * ["ls", "-a"]
       */
      args: string[]
    }
) & {
  /**
   * The directory in which to execute the command, if not specified, the current working directory will be used.
   */
  cwd?: string
  /**
   * Whether to clear the environment variables or not before executing the command.
   * @default false
   */
  clearEnv?: boolean
  /**
   * The environment variables to set before executing the command.
   * @example
   * { PATH: "/usr/bin", HELLO: "world", FOO: null }
   */
  env?: Record<string, string | null>
}

The result of the ExecuteShellCommandFunction

type ExecFunctionResult = {
  /**
   * The output of the command on stdout.
   */
  stdout: string
  /**
   * The output of the command on stderr.
   */
  stderr: string
  /**
   * The exit code of the command.
   */
  exitCode: number
}

type ExecFunction = (
  options: (
    | {
        /**
         * The command to execute, this will be executed in bash like a normal shell command.
         * @example
         * `echo hello world`
         * @example
         * `ls`
         */
        command: string
      }
    | {
        /**
         * This will execute the command without a shell, so you can use this to execute a binary.
         * @example
         * ["ls", "-a"]
         */
        args: string[]
      }
  ) & {
    /**
     * The directory in which to execute the command, if not specified, the current working directory will be used.
     */
    cwd?: string
    /**
     * Whether to clear the environment variables or not before executing the command.
     * @default false
     */
    clearEnv?: boolean
    /**
     * The environment variables to set before executing the command.
     * @example
     * { PATH: "/usr/bin", HELLO: "world", FOO: null }
     */
    env?: Record<string, string | null>
  }
) => Promise<{
  /**
   * The output of the command on stdout.
   */
  stdout: string
  /**
   * The output of the command on stderr.
   */
  stderr: string
  /**
   * The exit code of the command.
   */
  exitCode: number
}>

type CacheMaxAge = {
  strategy: "max-age"
  /**
   * The time to live for the cache in milliseconds.
   * @example
   * 3600
   */
  ttl: number
}

type CacheStaleWhileRevalidate = {
  strategy?: "stale-while-revalidate"
  /**
   * The time to live for the cache in milliseconds.
   * @example
   * 3600
   */
  ttl?: number
}

type Cache = (
  | {
      strategy: "max-age"
      /**
       * The time to live for the cache in milliseconds.
       * @example
       * 3600
       */
      ttl: number
    }
  | {
      strategy?: "stale-while-revalidate"
      /**
       * The time to live for the cache in milliseconds.
       * @example
       * 3600
       */
      ttl?: number
    }
) & {
  /**
   * Whether the cache should be based on the directory the user was currently in or not.
   * @defaultValue false
   */
  cacheByDirectory?: boolean
  /**
   * Hardcoded cache key that can be used to cache a single generator across
   * multiple argument locations in a spec.
   */
  cacheKey?: string
}

type TriggerOnChange = {
  /** Trigger on any change to the token */
  on: "change"
}

type TriggerOnThreshold = {
  /** Trigger when the length of the token changes past a threshold */
  on: "threshold"
  length: number
}

type TriggerOnMatch = {
  /** Trigger when the index of a string changes */
  on: "match"
  string: string | string[]
}

type Trigger =
  | string
  | ((newToken: string, oldToken: string) => boolean)
  | {
      /** Trigger on any change to the token */
      on: "change"
    }
  | {
      /** Trigger when the length of the token changes past a threshold */
      on: "threshold"
      length: number
    }
  | {
      /** Trigger when the index of a string changes */
      on: "match"
      string: string | string[]
    }

On this page