picocli icon indicating copy to clipboard operation
picocli copied to clipboard

JLine3 autocomplete file path

Open f-renout opened this issue 5 years ago • 4 comments

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

f-renout avatar Jul 04 '19 15:07 f-renout

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.)

remkop avatar Jul 04 '19 16:07 remkop

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 : <TAB> 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

f-renout avatar Jul 05 '19 06:07 f-renout

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).

remkop avatar Jul 05 '19 06:07 remkop

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

anantharaman93 avatar Feb 17 '23 09:02 anantharaman93