-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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 completion (including support for Go custom completion) #1048
Conversation
6901007
to
b83ef54
Compare
I will get this one ready for review ASAP. |
da428b5
to
228a672
Compare
Ok, I just pushed the rebased feature. However, I'd like to take the time to make a small improvement I recently thought of. Both Fish shell and Zsh allow for completions to be associated with a description shown to the user. This PR currently provides the description for sub-commands (the It won't change the feature much, so it is fine to start playing with it already. |
Here is how to test this feature. Slightly modified test program that can generate the Fish completion script:
Some tests step (the below output in the comments hasn't been updated to reflect the latest version of the above test program):
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, great work on this! Went through your testing script and everything works.
I also tested that the source file could be loaded during fish initialization:
fish> ./testprog1 completion fish --no-descriptions > ~/.config/fish/conf.d/testprog.fish
fish> exit
# load a new fish shell
fish> ./testprog <TAB>
# shows: completion ds pod rs
Do we want to recommend in fish_completions.md
users place the custom completion script in their ~./config/fish/conf.d
folder or simply source it as you had?
If not, +lgtm
228a672
to
3121c7f
Compare
Alright, this is ready for review. I've made it possible to add a description text in
and in a similar fashion in the output of However, I expect that Cobra's Zsh completion requires some adjustments for this to be handled properly. But I don't yet understand the details of the Zsh completion done by Cobra. Therefore, I simply haven't documented the concept of adding descriptions to |
Thanks @jpmcb! I actually had not tested for fish initialization, so it is great that you did and confirm it works.
We could mention both in the readme, but in the end it will be up to the program using Cobra to make the final recommendation. Is one better than the other in the context of the Fish shell? Also, let me ask about a point I haven't quite figured out for Fish. Notice in the script the lines:
The |
Oh, I forgot to mention that I updated the test program in the comment above to include extra descriptions. |
3121c7f
to
99fa66f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# TODO this cleanup is not sufficient. Fish completions are only loaded once the user triggers
# them, so the below deletion will not work as it is run too early. What else can we do?
First, I do believe the provided complete
line is sufficient for removing completions at the time of being run. From man complete
:
When erasing completions, it is possible to either erase all completions
for a specific command by specifying complete -c COMMAND -e, or by
specifying a specific completion option to delete by specifying either a long,
short or old style option.
So, I believe that this line
complete -c %[1]s -e
is correct as it will erase all existing completions for the specified command at the time it is run or sourced. I've tested this out:
# set a list of some junk completions
fish> complete -c testprog1 -a 'bad completions`
fish> ./testprog1 <TAB>
# shows up with both 'bad' and 'completions'
# run and source the completion script which deletes existing completions
fish> ./testprog1 completion fish | source
fish> ./testprog1 <TAB>
# no longer see 'bad' or 'completions' but instead, the correct set from the go code.
# previous set completions are gone
This will at least remove any existing completions at that time of sourcing.
The problem is that this script is out of date and provides invalid completions for the latest version of Helm. I'm looking for a way to force the loading of the original Fish completions for helm so that once we load the new script of this PR, it will delete the old ones.
Good question. After some digging, I think this may actually be a symptom of fish's completion initialization ordering which appears to be slightly different from fish's shell initialization ordering. Placing this command:
complete -c helm -e
in a user defined config file will not remove the default completions as these are initialized separately from shell initialization.
But, looks like fish does provide a way to define some user completions. User set completions will take the highest precedence followed by "third party" software over default fish completions:
By default, Fish searches the following for completions, using the first available file that it finds:
- A directory for end-users to keep their own completions, usually ~/.config/fish/completions (controlled by the XDG_CONFIG_HOME environment variable);
...- Directories for third-party software vendors to ship their own completions for their software. Fish searches the directories in the XDG_DATA_DIRS environment variable for a fish/vendor_completions.d directory; if this variable is not defined, the default is usually to search /usr/share/fish/vendor_completions.d and /usr/local/share/fish/vendor_completions.d;
- The completions shipped with fish, usually installed in /usr/share/fish/completions;
I've confirmed the default helm script you linked to is located at $__fish_data_dir/completions/helm.fish
and is being loaded on my system as I have no other helm.fish
files loaded in the mentioned locations.
It appears I was slightly wrong in my first review as the completion should have been:
fish> ./testprog1 completion fish --no-descriptions > ~/.config/fish/completions/testprog.fish
fish> exit
# load a new fish shell
fish> ./testprog <TAB>
# shows: completion ds pod rs
instead of being placed in the user's conf.d
folder. I've confirmed the above also works.
So, I believe that if an application developer wishes to have their completions supersede those bundled with default fish, they should recommend the user place the completion script in ether ~/.config/fish/completions/helm.fish
or within their own vendor application defined configuration folder /usr/share/fish/vendor_completions.d/helm.fish
.
Note that the name of the file must match the command name:
A completion file must have a filename consisting of the name of the command to complete and the suffix '.fish'.
I've tested this with helm and it appears to work:
fish> echo "complete -c helm -l debug" > ~/.config/fish/completions/helm.fish
fish> exit
# start new terminal
fish> helm -<TAB>
# auto completes with "debug" flag. No other options provided.
Maybe even on install, the application could automatically place it's completion script into the vendor directory at /usr/share/fish/vendor_completions.d/some-program.fish
.
Regarding the changes since my last review, I've tested again with the program you provided and looks good! 👍
Apologies at the length of this review, let me know your thoughts @marckhouzam
Signed-off-by: Marc Khouzam <marc.khouzam@montreal.ca>
99fa66f
to
8b694a8
Compare
I rebased this PR to the master branch after the |
Great investigation @jpmcb on the whole loading completions. I have also test following your recommendation and you are correct that adding the completion script to
This is a good idea. For example, the Homebrew recipe install bash and zsh completion script for Helm; it would eventually also install the Fish completion as well. But for the people that prefer to source the completion script, there would not be a good way to erase the completions shipped with Fish itself. I think the thing to do would be to contribute to the Fish project and use the Helm-generated completion as the default fish completion. Something to think about once all this is in. |
@jpmcb I notice you always use the |
No reason beyond it being the most recent command in my history and creating a little less noise. I do think it has value and that it's useful for people who don't want the long descriptions. I say leave it in! @jharshman I think this is ready to go! |
Thank you @jharshman for your reviews! |
* add basic implementation of bash completion * update cobra to 1.0.0 because of spf13/cobra#1048 * add support for zsh and fish, improved help messages * add flag ´--no-descriptions´ to disable automatic command description (for shells that supports it) * fix fish not supporting env variables with dash in the name * fixed zsh completion not working * revert "#compdef" patch * add check on --no-description flag add comments regarding "hacks" change Replacer with ReplaceAll (for readability) * add docs * Apply suggestions from code review fix typos and corrections Co-authored-by: per1234 <accounts@perglass.com> * forgot a space * fix fish docs * add test for completion Co-authored-by: per1234 <accounts@perglass.com>
* add basic implementation of bash completion * update cobra to 1.0.0 because of spf13/cobra#1048 * add support for zsh and fish, improved help messages * add flag ´--no-descriptions´ to disable automatic command description (for shells that supports it) * fix fish not supporting env variables with dash in the name * fixed zsh completion not working * revert "#compdef" patch * add check on --no-description flag add comments regarding "hacks" change Replacer with ReplaceAll (for readability) * add docs * Apply suggestions from code review fix typos and corrections Co-authored-by: per1234 <accounts@perglass.com> * forgot a space * fix fish docs * add test for completion Co-authored-by: per1234 <accounts@perglass.com>
This is an implementation of Fish completion based on the Custom Go Completions of PR #1035
The PR takes a different approach to completion. Instead of coding the entire completion in shell script, it delegates to the Go program the responsibility of determining the completion choices. This makes it simpler to implement completion support, as Cobra provides all the necessary info to easily determine completions.
It automatically supports custom completions once they have been migrated to the Custom Go Completion method of PR #1035.
And it supports automatically adding the "usage" string for command and flag completions to describe these completions. This is something bash completion doesn't have.
I haven't yet tried to support the other annotations
BashCompFilenameExt
,BashCompOneRequiredFlag
orBashCompSubdirsInDir
.To easily try this out I have adapted
kubectl
in my repo to use this PR. Bear in mind that I haven't migrated the custom completions forkubectl
(e.g.,kubectl get <TAB>
) to use the new Custom Go Completions of #1035, so custom completions will not yet work with this PR. Thekubectl
that works with basic completions is here: https://github.com/VilledeMontreal/kubernetes/tree/feat/fishCompletionMy experience with Fish is limited, so it would be good for others to try this out and provide feedback.