Files
thpeetz-notes/Quellen/IT/Autocomplete for Java Command Line Applications.md
T

4.3 KiB
Raw Blame History

title, source
title source
Autocomplete for Java Command Line Applications https://picocli.info/autocomplete.html

This tutorial uses the CheckSum example application from the picocli user manual. We created a class com.myproject.CheckSum and put it in a jar file, myproject.jar.

Follow these steps to give this application command line autocompletion.

2.1. Create Command

First, create an executable command that runs the main application class. For this tutorial, the command name is jchecksum.

We use an alias here to create the command (see alternatives):

alias jchecksum='java -cp "picocli-1.0.0.jar;myproject.jar" com.myproject.CheckSum'

Lets test that the command works:

$ jchecksum --help
Usage: jchecksum [-h] [-a=<algorithm>] <file>
Prints the checksum (MD5 by default) of a file to STDOUT.
      file                    The file whose checksum to calculate.
  -a, --algorithm=<algorithm> MD5, SHA-1, SHA-256, ...
  -h, --help                  Show this help message and exit.

2.2. Generate Completion Script

To generate the completion script, run the picocli.AutoComplete class as a java application. Pass it the command name and the fully qualified class name of the annotated command class. (See also full description for using AutoComplete.)

java -cp "picocli-1.0.0.jar;myproject.jar" picocli.AutoComplete -n jchecksum com.myproject.CheckSum

This generates a jchecksum_completion script in the current directory. To verify:

$ ls
jchecksum_completion  myproject.jar  picocli-1.0.0.jar

2.3. Install Completion Script

Finally, source the completion script:

…​and you are done. The jchecksum command now has autocompletion:

$ jchecksum <TAB><TAB>
-a           --algorithm  -h           --help

2.4. Permanent Installation

The above will last for the duration of your shell session. If you want to make this permanent you need to modify your ~/.bashrc or ~/.zshrc file to add a line that defines the command alias and a line that sources the completion script:

Bash

echo "alias jchecksum='java -cp \"picocli-1.0.0.jar;myproject.jar\" com.myproject.CheckSum'" >> ~/.bashrc
echo ". jchecksum_completion" >> ~/.bashrc

Make sure to use >> (append), using a single > would overwrite the file.

~/.bashrc indicates .bashrc is in your home directory.

2.5. Distribution

Have a subcommand that generates a completion script.

You could generate completion scripts for your commands during the build and distribute them with your application, but an alternative is to give your application the ability to generate its own completion script on demand.

That allows end users to install completion for your application with a single command. For example, if your utility is called mycommand, users can install completion for it by running the following command:

Bash

$ source <(mycommand generate-completion)

This can be accomplished by registering the built-in picocli.AutoComplete.GenerateCompletion class as a subcommand of the top-level command.

For example:

import picocli.AutoComplete.GenerateCompletion;
import picocli.CommandLine;
import picocli.CommandLine.Command;

@Command(name = "mycommand", subcommands = GenerateCompletion.class)
public class MyApp implements Runnable {

    @Override
    public void run() { // top-level command business logic here
    }

    public static void main(String[] args) {
        new CommandLine(new MyApp()).execute(args);
    }
}

By default, the generate-completion command shows up as a subcommand in the usage help message of its parent command. Applications that want the completion subcommand to be hidden in the usage help message, can do the following:

public static void main(String... args) {
    CommandLine cmd = new CommandLine(new MyApp());
    CommandLine gen = cmd.getSubcommands().get("generate-completion");
    gen.getCommandSpec().usageMessage().hidden(true);
    int exitCode = cmd.execute(args);
    // ...
}