demergent-labs / azle

A WebAssembly runtime for TypeScript and JavaScript on ICP
MIT License
204 stars 37 forks source link

Tab completion for CLI #1038

Open dansteren opened 1 year ago

dansteren commented 1 year ago

It would be really nice if the Azle CLI had tab auto completion. I would like to type npx azle [tab] [tab] and have it pull up the list of canister names in my canister and auto complete if there's only one.

Consider using tabtab.

dansteren commented 1 year ago

Suggestion from Chat GPT:

Creating an autocomplete function for your CLI (Command Line Interface) is a good way to improve its user experience. You can follow these general steps to achieve it:

  1. Install the necessary libraries: For auto completion in Node.js CLIs, one commonly used library is tabtab. It handles the installation and uninstallation of completion scripts for your CLI tool, and the parsing of the ENV VARs that the shell sends to you when hitting TAB. To install it, use the following command:

    npm install --save tabtab
  2. Setup auto completion: Now you need to set up tabtab in your CLI. Below is a basic configuration to add to your Azle CLI script:

    const tabtab = require('tabtab');
    
    tabtab
      .install({
        name: 'azle',
        completer: 'azle'
      })
      .then(() => {}, err => console.error('Error:', err));

    This installs the autocomplete behavior for your command azle. The completer argument can be the same as your command name, but it could be a different script file where the logic of your autocompletion is.

  3. Generate autocompletion options: Now, you need to generate options to autocomplete. This involves reading the dfx.json file and extracting the names of canisters. This could be a separate script (like azle-complete.js) that you would specify in the completer parameter in the install function:

    const fs = require('fs');
    const tabtab = require('tabtab');
    
    const dfxJson = JSON.parse(fs.readFileSync('./dfx.json', 'utf-8'));
    
    const canisterNames = Object.keys(dfxJson.canisters);
    
    // Parse env var given by tabtab when hitting TAB
    const env = tabtab.parseEnv(process.env);
    
    // Log each command to console for tabtab to consume
    canisterNames.forEach(name => {
      if (name.startsWith(env.lastPartial)) {
        tabtab.log([name], env);
      }
    });
  4. Provide the completer in the install function: Update your install function in your Azle CLI script to use this new completer:

    const tabtab = require('tabtab');
    
    tabtab
      .install({
        name: 'azle',
        completer: 'azle-complete'
      })
      .then(() => {}, err => console.error('Error:', err));

    This way, the script azle-complete.js is run every time the user hits TAB after typing azle. It reads the current dfx.json file, generates a list of canister names and logs the names that match the currently typed input.

Remember to call tabtab.install() when the user installs your CLI, you might need to create a post-install script for that.

Also, be aware that tab completion scripts are written to the user's .bashrc, .zshrc, or .config/fish/completions file. Therefore, it might not work in some restricted environments.

This should give you a basic autocompletion setup.