mitchellh / cli

A Go library for implementing command-line interfaces.
Mozilla Public License 2.0
1.73k stars 123 forks source link

Subcommand and flag autocompletion support (bash + zsh) #58

Closed mitchellh closed 7 years ago

mitchellh commented 7 years ago

This is 100% backwards compatible. The only BC note would be: any application using NewCLI will now get Autocompletion enabled automatically. This should result in no notice-able behavior change other than a couple flags being introduced since autocompletion requires "installation" (see below) before any behavior changes.

This adds support for bash and zsh autocompletion of subcommands, flags, and arguments.

The value of autocompletion can be specified via Go callbacks. No need to write any bash.

Under the covers, this PR uses the fantastic and full-featured complete library. However, knowledge of this library is not required to use the cli lib or to get basic subcommand autocompletion. For more complex autocompletion, integration is required but is built right-in to the CLI lib.

Enabling Autocompletion

Autocompletion is opt-in. Users of the CLI lib only need to set Autocomplete to true:

runner := &cli.Cli{
  Commands: ...,

  Autocomplete: true,
}

🎉 With that, subcommand autocompletion automatically happens.

Autocompletion Install/Uninstall

After autocompletion is enabled, the global flags -autocomplete-install and -autocomplete-uninstall are added. When these are present they install or uninstall the autocompletion handler for your shell, respectively. After installation, the shell must be restarted for autocompletion to take effect.

$ terraform -autocomplete-install
...

Subcommand Autocompletion

Subcommand autocompletion comes for free. No additional code required.

Terraform example, assume a tab is typed at the end of each prompt line:

$ terraform f
fmt           force-unlock

$ terraform state p
pull  push

Argument and Flag Autocompletion

Commands may implement the optional CommandAutocomplete interface. This interface allows a command to return autocompletion code for arguments and flags. This allows complex integrations. For example, Nomad uses UUIDs for referencing almost anything and argument autocompletion would look like the following:

$ nomad job-status a
a421c15           afc514d

Or continuing Terraform examples, imagine the -target flag:

$ terraform apply -target a
aws_resource.foo           aws_resource.bar