remkop / picocli

Picocli is a modern framework for building powerful, user-friendly, GraalVM-enabled command line apps with ease. It supports colors, autocompletion, subcommands, and more. In 1 source file so apps can include as source & avoid adding a dependency. Written in Java, usable from Groovy, Kotlin, Scala, etc.
https://picocli.info
Apache License 2.0
4.94k stars 424 forks source link

JLine3 autocomplete file path #762

Open f-renout opened 5 years ago

f-renout commented 5 years ago

Is it possible to have an file path autocomplete using picocli in an interactive shell with JLine3 (or another component)

For example let say I've a command

@Command
public void myCommand(@Parameter File myFile){
 out.println(myFile.getAbsolutePath());
}

when I try to use picocli and JLine3 I get autocompletion for "myCommand" but I haven't any for filling the parameter path so

>myApp myC<TAB>

complete well to

>myApp myCommand 

but for example

>myApp myCommand /etc/apa<TAB>

didn't complete to

>myApp myCommand /etc/apache2

It will be really great to b able to archive this (perhaps did I miss something wile reading the doc and samples but I didn't figure out how to obtain this result)

Just in case my OS is Ubuntu

remkop commented 5 years ago

I haven't tried this myself, but have you experimented with the completionCandidates attribute of the @Parameters annotation?

For example:

@Command
public void myCommand(@Parameter(completionCandidates = CurrentDirCompletions.class) File myFile) {
    out.println(myFile.getAbsolutePath());
}

class CurrentDirCompletions implements Iterable<String> {
    // return the files in the current directory
}

This does not take into account the (partial) value that the user specified, so it may not be that useful. I wonder if JLine3 has some example file completers that solve this problem. (If they do, then we can think about how to hook up this file completer with the picocli completer.)

f-renout commented 5 years ago

Hi, Indeed JLine3 has multiple file completers (https://github.com/jline/jline3/wiki/Completion)

I manage to archieve quite a good compromise by using JFile3 composer : LineReader reader = LineReaderBuilder.builder() .terminal(terminal) .completer(new AggregateCompleter(new PicocliJLineCompleter(cmd.getCommandSpec()), new Completers.FileNameCompleter()))

The problem with this solution is that it's not contextual aware : propose completion based on Parameter or Options as proposed by picocli (for example enum) and file completion.

It could be interresting to be able to says that if the current completion is about an option or a parameter of class File then delegate to FileNameCompleter (or DirectoryCompleter ... depending of what kind of completion you want)

I'm far from being fluent with either picocli or JLine3 (I just discovered both project yesterday) so I still have no clue on how to archieve such a result. But in case I find a solution I'll share it with you

remkop commented 5 years ago

Nice work!

Yes, it may be a good idea to enhance the PicocliJLineCompleter to allow better integration.

The main logic currently lives in AutoComplete.java from line 612, and especially line 755 and line 760.

The logic currently uses the completionCandidates of the OptionSpec or PositionalParamSpec, but if no completionCandidates attribute is defined, it may be an idea to enhance this logic to look at the type of the OptionSpec or PositionalParamSpec, and if the type is java.io.File or java.nio.file.Path, then delegate to the JLine FileNameCompleter.

A more general alternative is to add API to the PicocliJLineCompleter class to allow applications to associate any JLine3 completer with certain options or positional parameters, and this completer would be used to generate completion candidates for this option or positional parameter.

If you are interested in working on this that would be great! Any contributions are welcome!

I would not mind moving the above logic out of the AutoComplete class and into the picocli-shell-jline2 and picocli-shell-jline3 subprojects. That may be better anyway to allow the picocli-shell-jline3 completer to leverage the extra features that JLine3 offers over JLine2 (e.g. #614).

anantharaman93 commented 1 year ago

Hi. Would be very much helpful if we could get this support. Thanks.