-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Fix: include sub-actions in tab completion #13140
base: main
Are you sure you want to change the base?
Fix: include sub-actions in tab completion #13140
Conversation
For commands like `pip cache` with sub-actions like `remove`, so that e.g. `pip cache re<TAB>` completes to `pip cache remove`. All the existing commands that used such sub-actions followed the same approach for: using a dictionary of names to methods to run, so the implementation is just teaching the `Command` object about this mapping and using it in the autocompletion function. There's no handling for the position of the argument, so e.g. `pip cache re<TAB>` and `pip cache --user re<TAB>` will both complete the final word to `remove`. This is mostly because it was simpler to implement like this, but also I think due to how `optparse` works such invocations are valid, e.g. `pip config --user set global.timeout 60`. Similarly, there's no duplication handling so `pip cache remove re<TAB>` will also complete. This is a feature that may be simpler to implement, or just work out of the box, with some argument parsing libraries, but moving to another such library looks to be quite a bit of work (see discussion[1]). I also took the opportunity to tighten some typing: dropping some use of `Any` Link: pypa#4659 [1] Fixes: pypa#13133
("cache", "d", "dir"), | ||
("cache", "in", "info"), | ||
("cache", "l", "list"), | ||
("cache", "re", "remove"), | ||
("cache", "pu", "purge"), | ||
("config", "li", "list"), | ||
("config", "e", "edit"), | ||
("config", "ge", "get"), | ||
("config", "se", "set"), | ||
("config", "unse", "unset"), | ||
("config", "d", "debug"), | ||
("index", "ve", "versions"), |
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.
this list could probably be auto-generated from all commands with a non-empty handler_map
but I just hard coded it for simplicity (read: laziness 🙃)
Do such limitation apply to the current completions for the main commands ? At first sight it seems they don't (at least |
No, those limitations don't apply: for the sub-commands the completion behaviour is split:
So the only time we present sub-commands as completion options is when we haven't already seen any sub-commands The relevant code starts at
If we want to avoid the behaviour you mentioned in this change I think we can do something like: handler_names = subcommand.handler_map().keys()
# present handler names as completion only if we haven't already seen any handler names
if not any(name in cwords for name in handler_names):
for handler_name in handler_names:
if handler_name.startswith(current):
print(handler_name) This comes with two edge cases I can think of:
|
For commands like
pip cache
with sub-actions likeremove
, so that e.g.pip cache re<TAB>
completes topip cache remove
.All the existing commands that used such sub-actions followed the same approach for: using a dictionary of names to methods to run, so the implementation is just teaching the
Command
object about this mapping and using it in the autocompletion function.There's no handling for the position of the argument, so e.g.
pip cache re<TAB>
andpip cache --user re<TAB>
will both complete the final word toremove
. This is mostly because it was simpler to implement like this, but also I think due to howoptparse
works such invocations are valid, e.g.pip config --user set global.timeout 60
. Similarly, there's no duplication handling sopip cache remove re<TAB>
will also complete.This is a feature that may be simpler to implement, or just work out of the box, with some argument parsing libraries, but moving to another such library looks to be quite a bit of work (see discussion[1]).
I also took the opportunity to tighten some typing: dropping some use of
Any
Link: #4659 [1]
Fixes: #13133