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

[clap_complete/dyamic] subcommands per shell for complete/generate and restructure #5157

Conversation

AndreasBackx
Copy link
Contributor

@AndreasBackx AndreasBackx commented Oct 3, 2023

This is to make progress for #1232.

It's hard to understand how each shell works. They all have their own environment variables and more. To make it all easier to understand and not one big file, I moved shell specific implementations into 2 separate parts/subcommands and into separate files:

  1. The part that generates the Shell autocomplete file.
  2. The part that is called from that file to "autocomplete" or provide suggestions.

This makes the autocomplete example's --help look like this as well:

➜ cargo run --example dynamic --features unstable-dynamic -- --help
Usage: 

Commands:
  complete  Complete a command for a given shell, to be called from autocomplete scripts primarily
  generate  Generate shell completions for this program
  help      Print this message or the help of the given subcommand(s)

Options:
  -i, --input <input>    
  -F, --format <format>  [possible values: json, yaml, toml]
  -h, --help             Print help

Where the complete and generate subcommands now have a subcommand for each shell:

➜ cargo run --example dynamic --features unstable-dynamic -- complete --help
Complete a command for a given shell, to be called from autocomplete scripts primarily

Usage: 

Commands:
  bash  
  fish  
  help  Print this message or the help of the given subcommand(s)

Options:
  -h, --help  Print help
➜ cargo run --example dynamic --features unstable-dynamic -- complete bash --help
Usage: 

Arguments:
  [COMP_WORDS]...
          `COMP_WORDS` environment variable from Bash.
          
          An array variable (see Arrays below) consisting of the individual words in the current command line.  The line is split into words as readline would split it, using COMP_WORDBREAKS as described above.  This variable is available only in shell functions invoked by the programmable completion facilities.
          
          Quoted from the bash man pages: https://man7.org/linux/man-pages/man1/bash.1.html.

Options:
      --index <COMP_CWORD>
          `COMP_CWORD` environment variable from Bash.

[...]

For Bash the generation does not have any CLI arguments but has the following changes:

  • complete options (-o) set to nosort, noquote, and nospace from nospace, and bashdefault. Meaning the results are not sorted nor quoted are appended with a space. This should make it easier to make all shells act the same.

The completion part's arguments are those that were previously passed via environment variables, making it easier to use.

Some refactoring as well and the structure of the dynamic folder looks like this:

  • shells/
    • bash/
      • comp_type.rs: everything for making the COMP_TYPE env var typed.
      • complete.rs: the complete bash subcommand struct and implementation
      • generate.rs: the generate bash subcommand struct and implementation
      • mod.rs
    • fish/ (same as bash)
    • command.rs complete and generate command struct and implementation.
    • mod.rs
  • complete.rs: completion generation that is general to all shells.
  • registrar.rs: this houses the previously named Completer struct.

Completer was renamed to Registrar because it did both generation and completion which made it actually hard to follow what data is used where. Still somewhat unsure whether to keep it or not, but for now I've chosen to keep it because this PR is already too big.

Some of the next steps for future PRs:

  1. Add examples of barebones shell autocomplete examples for documentation and explanation.
  2. Create a completion struct that allows adapting to each shell's autocomplete capabilities
  3. Add more shells
  4. Add more examples and actually make this easier to use, it's very hard to understand how it currently works
  5. Add more testing

@epage
Copy link
Member

epage commented Oct 3, 2023

In #5018, we intentionally moved to the environment variable approach to make adding more shells easier. I think a strong case is needed to instead switch to something like this but I'm not seeing it

@AndreasBackx
Copy link
Contributor Author

In #5018, we intentionally moved to the environment variable approach to make adding more shells easier. I think a strong case is needed to instead switch to something like this but I'm not seeing it

Sorry, wasn't aware of that previous change. I thought to publish this code after a bit of polish from a few months back. This is easier to experiment with, than environment variables, though I could directly do more TDD instead of manual testing. I had some samples for the most prominent shells, but I can adapt them to what is currently in master.

@epage
Copy link
Member

epage commented Oct 3, 2023

This is easier to experiment with, than environment variables

Funny, I felt environment variables would be much easier :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants