Fork me on GitHub
Every main method deserves picocli!

1. Introduction

Picocli-based applications can now have command line completion in Bash or Zsh Unix shells. Picocli can generate an autocompletion script tailored to your application.

With this script installed, users can type the first few letters of a subcommand or an option, then press the TAB key, and the Unix shell will complete the subcommand or option.

In the case of multiple possible completions, the Unix shell will display all subcommands or options beginning with those few characters. The user can type more characters and press TAB again to see a new, narrowed-down list if the typed characters are still ambiguous, or else complete the subcommand or option.

Autocompletion demo animation

2. Command Line Completion Example

Assume we have a picocli-based command line application with subcommands, all of which have some options. Below is an example:

import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;

@Command(name = "hierarchy", subcommands = { Subcommand1.class, Subcommand2.class })
class MainCommand {
    @Option(names = {"-V", "--version"}, help = true) boolean versionRequested;
    @Option(names = {"-h", "--help"},    help = true) boolean helpRequested;
}

@Command(name = "sub1", description = "subcommand 1")
class Subcommand1 {
    @Option(names = {"--directory", "-d"}, description = "a directory") File directory;
    @Option(names = {"-h", "--host"},      description = "a host")      InetAddress host;
}

@Command(name = "sub2", description = "subcommand 2")
class Subcommand2 {
    @Option(names = {"-u", "--timeUnit"}) private TimeUnit timeUnit;
    @Option(names = {"-t", "--timeout"})  private long timeout;
}

Assume we generated and installed a completion script for this application. Assume the command script to run the application is called hierarchy.

2.1. Options and Subcommands

After the command name, press the TAB key to trigger autocomplete. The shell will show all options and all subcommands for the hierarchy main command:

$ hierarchy <TAB><TAB>
-h         --help     sub1       sub2       -V         --version

2.2. Partial Input

If the option or subcommand is partially specified, a narrowed-down list is shown. For example, after typing 's' and triggering autocomplete, only the completion options starting with 's' are shown:

$ hierarchy s<TAB><TAB>
sub1  sub2

2.3. Context-sensitive

Picocli autocomplete is context-sensitive to the selected subcommand and the selected option.

After selecting a subcommand, the user can hit <TAB><TAB> again to see what options are available on that subcommand. Only the options for the selected subcommand are shown:

$ hierarchy sub1 <TAB><TAB>
-d           --directory  --h       --host

2.4. Nested sub-subcommands

There is no restriction to the number of levels for nested subcommands. The completion script generated by picocli will show context-sensitive matches for the most specific (deepest) subcommand.

2.5. Option Values

In addition to showing a list of option names, tab completion can also generate possible option values. The type of the field annotated with @Option determines the generated values.

Picocli can generate completion matches for the following types:

  • java.io.File

  • java.nio.file.Path

  • java.net.InetAddress

  • any java enum

2.5.1. Files and Directories

In the above example, Subcommand1 has a java.io.File field annotated with @Option(names = {"--directory", "-d"}. Generating autocomplete matches for that option will display a list of all files and directories in the current directory.

$ hierarchy sub1 -d <TAB><TAB>
basic.bash              hierarchy               nestedSubcommands.bash

The same tab completion matches are shown for fields of type java.nio.file.Path annotated with @Option.

2.5.2. Host Names

In the above example, Subcommand1 has a java.net.InetAddress field annotated with @Option(names = {"-h", "--host"}. Generating autocomplete matches for that option will display a list of known hosts.

$ hierarchy sub1 --host <TAB><TAB>
cluster-p-1                          openvpn-client.myvpn.picocli.com
cluster-p-2                          picop1
cluster-p-3                          picop2
cluster-p-4                          picop3
cluster-scm-1                        picop4
client.openvpn.net                   picoscm1

2.5.3. Java enum Values

In the above example, Subcommand2 has a field of type java.util.concurrent.TimeUnit, which is a Java enum. Generating autocomplete matches for that option will display the list of enum values.

$ hierarchy sub2 --timeUnit <TAB><TAB>
DAYS     HOURS     MICROSECONDS  MILLISECONDS  MINUTES    NANOSECONDS   SECONDS

3. Generating the Completion Script

3.1. Overview

To generate the completion script, run the picocli.AutoComplete class as a java application, passing it the fully qualified class name of the annotated command object.

$ java -jar picocli-1.0.0.jar com.myproject.MyCommand

This will instantiate your command, and inspect it for @Option and @Command annotations. Based on these annotations it will generate a completion script in the current directory.

3.2. Command Name

The name of the generated completion script is based on the @Command(name ="<COMMAND-NAME>") annotation, or, if that is missing, the command class name. Use the -n or --name option to control the name of the command that the completion script is for.

$ java -jar picocli-1.0.0.jar -n hierarchy com.myproject.MyCommand

This will generate a hierarchy_completion script in the current directory.

Other options are:

  • Use -o or --completionScript to specify the full path to the completion script to generate.

  • Use the -f or --force option to overwrite existing files.

  • Use the -w, --writeCommandScript option to generate a sample command script.

3.3. Subcommands

For commands with subcommands, bear in mind that the class that generates the completion script (picocli.AutoComplete) needs the full hierarchy of command and subcommands to generate a completion script that also works for the subcommands.

The above will work when subcommands are registered declaratively with annotations like @Command(subcommands = { …​ }).

3.4. Subcommands (The Do-It-Yourself Way)

Otherwise, you need to do a bit more work. You need to create a small program that does the following:

  • Create a CommandLine instance with the full hierarchy of nested subcommands.

// programmatically (see above for declarative example)
CommandLine hierarchy = new CommandLine(new TopLevel())
        .addSubcommand("sub1", new Subcommand1())
        .addSubcommand("sub2", new Subcommand2());
  • Pass this CommandLine instance and the name of the script to the picocli.AutoComplete::bash method. The method will return the source code of a completion script. Save the source code to a file and install it.

3.5. Command Script

Finally, create the accompanying command script to run the application. This is the script that Bash will recognize and generate completion matches for.

The name of this script is important! The command completion script will only generate completions for the matching command.

It should contain something like this:

#!/usr/bin/env bash

java -cp myApp.jar com.myorg.myproject.MainClass $@

4. Installing the Completion Script in Bash

Make sure bash completion is installed.

The generated completion script needs to be sourced to install it in your current bash session.

To install it more permanently, place the completion script file in /etc/bash_completion.d (or /usr/local/etc/bash_completion.d on a Mac). If bash-completion is installed, placing the completion script in either of these directories should be sufficient. (Source your ~/.bash_profile or launch a new terminal to start using this completion script.)

Alternatively, make a directory mkdir ~/bash_completion.d, and place the completion script in this directory. Edit your ~/.bashrc file and add the following:

for bcfile in ~/bash_completion.d/* ; do
  . $bcfile
done

Source your ~/.bash_profile or launch a new terminal to start using this completion script.

5. Installing the Completion Script in ZSH

Zsh can handle bash completions functions. The latest development version of zsh has a function bashcompinit, that when run will allow zsh to read bash completion specifications and functions. This is documented in the zshcompsys man page. To use it all you need to do is run bashcompinit at any time after compinit. It will define complete and compgen functions corresponding to the bash builtins.

The generated completion script needs to be sourced to install it in your current session.

To install it more permanently, make a directory mkdir ~/bash_completion.d, and place the completion script in this directory. Edit your ~/.zshrc file and add the following:

autoload -U +X compinit && compinit
autoload -U +X bashcompinit && bashcompinit
for bcfile in ~/bash_completion.d/* ; do
  . $bcfile
done

Then reload your shell:

exec $SHELL -l

6. Picocli User Manual

The picocli user manual explains how to build Java command line applications with picocli.

7. GitHub Project

The GitHub project has the source code, tests, build scripts, etc.

Star or fork this project on GitHub if you like it! (Projects with many forks are easier to find on GitHub Search.)

8. Issue Tracker

Please use the Issue Tracker to report bugs or request features.

9. License

Picocli is licensed under the Apache License 2.0.

10. Releases

Previous versions are available from the GitHub project Releases.