-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Fish dynamic completion #4177
Fish dynamic completion #4177
Conversation
sigh need to get CI setup to properly test dynamic completions |
6a20bc9
to
76c8e1c
Compare
Since I'm prepping for the v4 release, I've gone ahead and pulled in your lint changes into #4197 |
makes sense. I'm currently designing the API for fish completions. When I have them finished we could maybe have a look how a unified api could look for the different shells if that makes sense. Or would you prefere to have them completely seperated? |
If we can have it unified, that'd be great. Also, bpaf recently added dynamic completion support, so it might provide ideas: https://github.com/pacak/bpaf/blob/master/src/complete_run.rs |
I looked into how the API could look for using completions with derive/builder pattern. The current approach in the dynamic example, to apply manually with augment_subcommands feels a bit laborious, maybe this could be done similarly to the help/version flags? Though there should also be an option to have them, but hide them from the public API displayed in --help. But this would require it to be more tightly integrated in clap, maybe behind a feature flag, but not in a separate crate. It could also be a trait implemented for fn main() {
// derive
Opts::complete();
Opts::complete_with_flag("cmp");
dbg!(Opts::parse());
// builder
command().complete();
dbg!(command().get_matches());
} |
This seems separate from the discussion of fish, right? Can we break this out into a separate issue? |
Makes sense, but as this API is currently part of the bash implementation, it would be part of a shared API. But I'll prepare the fish-"backend" here and leave the enduser API for a separate issue. |
So AFAICT fish would only need a function it can call with the current line+cursor position and get all the available completions where:
We would not need to do any filtering on this, clap does that already. With these, completion could be called like this: complete -x -c my_app -a "my_app complete --commandline (commandline) --cursor (commandline -C)" |
b574c00
to
9b48d20
Compare
4fb10dc
to
890c93e
Compare
9e60d30
to
fc50beb
Compare
This implements dynamic completions for fish now, and I put some shell agnostic completion logic in the dynamic module, that should deal with all the intricacies of parsing arguments correctly (multiple values, optional before subcommand etc.) |
One thing that I'm not certain about is, if my handling of OsStrings due to utf8 incompatible strings is ideal or needs to be reworked. |
This is a bit difficult to review atm. Could you make the following changes so I can better see whats going on?
|
I tried documenting it in the description. And you're right, I mixed these commit up a bit and will clean them up in the next days. |
Cleaned up my commits a little bit. |
They still mix moving major sections of code with changing those sections of code. Those at least should be split out. Even better if its split out more to show step by step what changes are made. Not that its the most important but also this would be a "refactor" and not a "feat". |
I would recommend we work together to figure this out. I want to start from the position of all completers being the same with any differences being handled in the registration script. Any stepping back from this ideal should be with a documented understanding of why the general design couldn't work and what is the minimal step back we can make, preserving as much of what we are trying to accomplish. There might hit a breaking point where we have to move to a model like this but I want us to learn and document why a unified model does not work.
This isn't explaining the "why". I'm seeing trait methods that are unused and its unclear why they exist. Oh, is it for derive integration? That looks to be a separate feature, unrelated to fisxh support. Let's split that out into its own Issue followed by a PR once we have an agreement on it. |
That sounds like a good idea, what method would you prefer? Written discussion here or a voice call?
Right, should at least have put that in a separate commit. |
Trait `Completer` that contains the API necessary for triggering completions for a specific Shell. `CompleteComand` moved to `dynamic` and prepared for additional shells.
4b63fa2
to
6b4827e
Compare
Moved derive api support to #4356 |
First, this isn't a focus area which will require a lot more groundwork from you on this. Second, let's start with a hackmd and then move to a phone call, if needed. |
I started writing the fish requirements into the hackmd, on deciding what fish would need additionally, I was unsure about what the current completion implementation actually provides and what all the flags mean. Do you have any documentation you could point me to, on what the current API actually looks like? |
I've added some notes. As I said though, this is something you'll have to drive including how to harmonize the two systems or to be able to provide a good case for why they can't be harmonized. |
This could be a shared interface that at least fish and bash could use. Copied from hackmd: Proposed shared interfaceThis interface would allow the dynamic bash completions to be the same as it is currently, and support almost the full fish feature Necessary flags
starts with dash condition for flagsdecision in clap
decision in shell
Shell native like path completionsEmulate in clapProbably not a great idea as e.g. fish does quite a lot here:
pass path completions inPrefered, but requires us to allow
have a complete files/dirs query flagNot ideal as it removes us from the ability to filter the results
Potential flagsThese are the flags the current bash implementation taking, but don't have any implementation yet. I'd skip them for now.
|
@epage I tried to design an interface that could be shared between fish and bash allowing to move all shell specific logic into the completion script. Do you have input on this? |
with fish-shell/fish-shell@4a8ebc0 this could now be changed to |
@epage Just remembered that this was still open. Was there any thought put into dynamic completions in the meantime? |
After discussing this further with others interested in this effort, I've been thinking that trying to define registration/completion communication through a more format channel of CLI args is messy. I've created #5018 which instead uses env variables for this. This makes the end result for multiple shell support a hybrid between this PR and the pre-generated / static completions. Thoughts? |
btw we now have a way to test completions. See #5026 |
Replaced by #5048 |
I didn't follow the bash model for completions because I didn't fully understand how it worked, and wanted to have the
CompletionContext
as a way for the shell specific part to handle how it selects the completions.I thought it should be possible to use the methods I added in mod to use for bash, but I don't know for sure, as I didn't understand what all the options there did.
End developer api
The completion logic is made available in too ways:
Completable
trait, it supports both methods to just trigger completions and a direct replacement forOpts::parse()
that will do completions or parse.CompleteComand::augment_subcommands
and manually handle the outcome by callingCompleteCommand::complete()
CompleteCommand
as a subcommand using the derive macro.Internal completion flow
CompleteCommand::try_complete()
try_complete
either triggers the Shell's registration being printed, or the shell to handle its own completions through theCompleter
trait.Completer
trait is a trait exposing the methods required to both complete a command and to register a shells completionsFish
(Bash
also implements completer, but has it's old internal completion logic still):a.
complete(command, tokens_in_commandline)
is triggered to parse the current tokens and returnCompleteArgs
b.
complete_internal
is a recursive function that goes through the tokens and parses them, storing already present arguments and options to filter them out of any completions provided, gets recursively called on all subcommands.c. in
Fish::try_complete
the options are returned if current starts with--
or-
d. if value_for is set the completions for the argument are returned they are queried with
completions_for_arg
e. subcommands are returned
Fish completions
The fish completions work by taking in the tokens in the command + the current token if the cursor is in any.
Afterwards it will provide the completions as fish would normally:
If you don't mind, I'd appreciate having this labeled as
hacktoberfest-accepted
.Fixes #3917