picocli
picocli copied to clipboard
Support Path/Host completion in AutoComplete for custom types
Hello,
I have an @Option
being a List<Repository>
where Repository
is a custom type injected through a TypeConverter
.
I recently integrated the AutoComplete
bash completions generation and since then, I do have command completions, but I lost the path completions for this option.
I suspect the bash completion to complete overrule the shell built-in path completion and that the solution for this is to integrate the path completion within the completion generated by AutoComplete
.
Looking at the documentation I see support for java.io.File
/java.nio.file.Path
when it comes to path completion.
I wasn't however able to find a way to force it for custom types.
Looking at the code in picocli.AutoComplete
generatePositionalParamsCases
/generateOptionsCases
I see the java.io.File
/java.nio.file.Path
cases are hardcoded.
Do you think it would be valuable to make this configurable?
If yes, what would be the recommended approach?
- Through a new field in the
@Option
and@Parameters
annotations? - Through an annotation/default method on the
TypeConverter
? I don't know if this approach is compatible with theAutoComplete
, but I assume, it could be possible to scan the classpath for type converters of a given@Option
/@Parameters
without instantiating the command line itself. - Through an additional optional parameter
picocli.CommandLine#registerConverter
method? This seems not really compatible with theAutoComplete
command that does not instanciate the command line but only needs the main command and the factory.
From an API point of view, I like option 2 because you declare the behavior once and it applies everywhere it is used, but it might be more complex to implement/not matching the philosophy.
Regards,
PS: I might be able to find some time to work on this topic if you deem it valuable
I like the idea to make this configurable.
One additional way to accomplish this that I thought of was to have a command line option for the AutoComplete.App
and AutoComplete.GenerateCompletion
commands. Something like this:
@Option(names = "--fileTypes", split=",",
description = "Comma-separated list of fully qualified custom types for which to delegate to built-in file name completion.")
List<Class<?>> fileTypes = new ArrayList<>();
Then the logic could change to this:
} else if (type.equals(File.class) || "java.nio.file.Path".equals(type.getName()) || fileTypes.contains(type)) { //<-- check custom types
buff.append(format("%s %s (( currIndex >= %d && currIndex <= %d )); then\n", indent, ifOrElif, min, max)); // as before
buff.append(format("%s compopt -o filenames\n", indent)); // as before
buff.append(format("%s positionals=$( compgen -f -- \"%s\" ) # files\n", indent, currWord)); // as before
We would have to test this, and there may be other ideas.
What do you think?
If you have time to work on this, that would be great!
So your proposal is to not have this information as part of the command spec, but to have it as a parameter when calling the AutoComplete
command. Did I get this right?
Sounds way easier to implement than to actually make it part of the model but maybe not as declarative in the approach. Still it can a be a fairly decent first step, I like it. Later on, if need be we could still add auto-determination from the model for that new option. But KISS first!
I'll give it a try this week.