Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Output completion script as a subcommand in an existing command #809

Closed
gastaldi opened this issue Sep 9, 2019 · 3 comments
Closed

Output completion script as a subcommand in an existing command #809

gastaldi opened this issue Sep 9, 2019 · 3 comments
Labels
theme: auto-completion An issue or change related to auto-completion theme: codegen An issue or change related to the picocli-codegen module type: API 🔌 type: enhancement ✨
Milestone

Comments

@gastaldi
Copy link

gastaldi commented Sep 9, 2019

It would be nice if there was an option to output the bash or zsh script for a given command through a Subcommand.

eg.
checksum completion zsh outputs the ZSH script in the standard out, making it possible to do something like:

source <(checksum completion zsh)
@remkop
Copy link
Owner

remkop commented Sep 9, 2019

That is a good idea! You can already accomplish this with the building blocks that the library provides (see example below), but it may be good to add something to the documentation, perhaps show this example in the TAB Autocomplete section of the user manual (docs/index.adoc). Would you be able to provide a pull request to update the doc? Feel free to alter the example as needed.

import picocli.AutoComplete;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;

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

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

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

@Command(name = "completion",
        description = "Generate a completion script for the parent command")
class Completion implements Runnable {

    @Override
    public void run() {
        System.out.println(
                AutoComplete.bash("mycommand", spec.parent().commandLine()));
    }
}

@remkop remkop added this to the 4.0.5 milestone Sep 9, 2019
@remkop remkop added theme: codegen An issue or change related to the picocli-codegen module type: doc 📘 theme: auto-completion An issue or change related to auto-completion labels Sep 9, 2019
remkop added a commit that referenced this issue Sep 9, 2019
@remkop remkop closed this as completed in bc6ab69 Sep 19, 2019
@remkop
Copy link
Owner

remkop commented Sep 19, 2019

@gastaldi Thanks again for raising this!

Your suggestion is now part of the documentation: https://picocli.info/autocomplete.html#_distribution

@remkop
Copy link
Owner

remkop commented Nov 21, 2019

Reopening since I am considering adding a GenerateCompletion subcommand implementation.

import picocli.AutoComplete;
import picocli.CommandLine.Spec;

@Command(name = "generate-completion", version = "generate-completion " + CommandLine.VERSION,
        mixinStandardHelpOptions = true,
        description = {
            "Generate bash/zsh completion script for ${PARENT-COMMAND-NAME}.",
            "Run the following command to give `${PARENT-COMMAND-NAME}` TAB completion in the current shell:",
            "",
            "source <(${PARENT-COMMAND-NAME} ${COMMAND-NAME})",
            ""},
        optionListHeading = "Options:%n"
)
class GenerateCompletion implements Runnable {

    @Spec CommandLine.Model.CommandSpec spec;

    public void run() {
        String script = AutoComplete.bash(
                spec.parent().name(),
                spec.parent().commandLine());
        // not PrintWriter.println: scripts with Windows line separators fail in strange ways!
        spec.commandLine().getOut().print(script);
        spec.commandLine().getOut().print('\n');
        spec.commandLine().getOut().flush();
    }
}

Expected usage:

import picocli.AutoComplete.GenerateCompletion;

@Command(name = "checksum", subcommands = GenerateCompletion.class)
class Checksum implements Runnable { //...

If applications want this command to be hidden, they can do this:

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);
}

@remkop remkop reopened this Nov 21, 2019
remkop added a commit that referenced this issue Nov 21, 2019
… completion script for its parent command
@remkop remkop closed this as completed in a92e794 Nov 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
theme: auto-completion An issue or change related to auto-completion theme: codegen An issue or change related to the picocli-codegen module type: API 🔌 type: enhancement ✨
Projects
None yet
Development

No branches or pull requests

2 participants