Skip to content
Ion Dodon edited this page Feb 19, 2023 · 12 revisions

Welcome to the project! This wiki page will guide you on how to add new suggestions.

Navigate to {project directory}/src/cli/library.

The contract

export type Group = {
  suggestions: Suggestion[];
  next?: () => (Group | Suggestion)[];
};

export type DynamicGroup = Group & {
  script: string;
  postProcessor: (line: string) => Suggestion;
};

export type Suggestion = {
  names: string | string[];
  regex: RegExp | RegExp[];
  next?: () => (Group | Suggestion)[];
};
  1. Suggestion: This type defines the shape of an object that represents a suggestion. It has two properties:

    • names: a string, or list of strings, that represents the name/names of the suggestion.
    • regex: a regular expression, or list of regular expressions, that matches the input entered by the user to generate the suggestion.
    • next: an optional function that returns an array of suggestions or groups that the user can choose as the next command. If no next property is provided, it implies that this suggestion is the end of the command chain.
  2. Group: This type defines the shape of an object that represents a group of suggestions. It has two properties:

    • suggestions: an array of Suggestion objects that represent the possible suggestions for this group.
    • next: an optional function that returns an array of suggestions or groups that the user can choose as the next command. If no next property is provided, it implies that this group is at the end of the command chain.
  3. DynamicGroup: This type extends the Group type and adds two properties:

    • script: a string that represents a shell script to run on the command line to generate dynamic suggestions.
    • postProcessor: a function that takes the output of the script as input and processes it to generate an array of Suggestion objects.

Together, these types provide a way to define and group suggestions for a command-line interface, including the ability to generate dynamic suggestions based on shell scripts.

The "next" property can be present both in the suggestion and its group. In such a case, the "next" from the suggestion is given precedence. If there is no "next" property in the suggestion, the "next" from the group is taken. If neither the suggestion nor its group have a "next" property, then it indicates that there is nothing to follow.

For DynamicGroups, it's recommended to include default suggestions in the "suggestions" array, as these will be displayed on operating systems where it's not possible to run the script to generate suggestions.

Using groups provides the benefit of grouping suggestions that have common properties such as the "next" property. In case of conflicts between the "next" property of a suggestion and its group, the "next" property of the suggestion is given precedence.

How to add new suggestions

The project provides a command-line interface (CLI) with suggestions. Suggestions are the next possible inputs that the user can make based on the current input. Suggestions can be a single word or a list of words and can be generated dynamically by running scripts or be static.

To add a new suggestion, you need to modify the suggestions array in the appropriate Group or DynamicGroup object. Here are the steps you need to follow:

  1. Identify the appropriate group for your suggestion. The Group or DynamicGroup objects are defined in the contract.ts file.

  2. In the appropriate Group or DynamicGroup object, add a new Suggestion object to the suggestions array. A Suggestion object contains the following properties:

    • names: A string or list of strings that represents the suggestion/suggestions.
    • regex: A regular expression, or list of regular expressions, that matches the input for the suggestion.
    • next (optional): A function that returns an array of Group or Suggestion objects. This is used to generate the next set of suggestions.

    For example, here's a new Suggestion object that suggests a new command called hello:

    const helloCommand: Suggestion = {
       names: "hello",
       regex: /^hello$/,
    };
  3. If you added the next property in the Suggestion object, define the corresponding Group or DynamicGroup objects that will be returned by the next function. If the next property is not defined, the user will not receive any suggestions for the next input. You can define a new Group or DynamicGroup object or use an existing one.

    For example, here's a new Group object that contains two suggestions:

    const myGroup: Group = {
      suggestions: [
        {
           names: "one",
           regex: /^one$/,
        },
        {
           names: "two",
           regex: /^two$/,
        },
      ],
    };
  4. If you added a new DynamicGroup object, you also need to define the script and postProcessor properties. The script property is a string that contains the command to be run to generate the dynamic suggestions. The postProcessor function takes the output of the command as input and returns an array of Suggestion objects.

    For example, here's a new DynamicGroup object that suggests a list of files in the current directory:

    const filesGroup: DynamicGroup = {
      suggestions: [
        {
          names: "file",
          regex: /^.*$/,
        },
      ],
      script: "ls",
      postProcessor: (output) => {
        const filenames = output.split("\n").filter((filename) => filename !== "");
        return filenames.map((filename) => ({
          names: filename,
          regex: new RegExp(`^${filename}$`),
        }));
      },
    };

Once you have added the new suggestion, you should test it to ensure it works as expected. To test it, you can run the CLI and navigate to the point where your new suggestion should appear. If it appears and works as expected, then you can be confident that your new suggestion has been successfully added.

Clone this wiki locally