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

complete aliases for subcommands #1856

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Airblader
Copy link

When completing a subcommand, also take its aliases into consideration instead of only its name.

fixes #1852

When completing a subcommand, also take its aliases into consideration
instead of only its name.

fixes spf13#1852
@CLAassistant
Copy link

CLAassistant commented Nov 15, 2022

CLA assistant check
All committers have signed the CLA.

@marckhouzam
Copy link
Collaborator

This look reasonable. The important thing is to avoid aliases coming in the way of other completions.
I'll have to play around with the resulting behaviour to see how it feels.

Thanks @Airblader for the contribution.

@marckhouzam marckhouzam added kind/feature A feature request for cobra; new or enhanced behavior area/shell-completion All shell completions labels Nov 16, 2022
@github-actions
Copy link

The Cobra project currently lacks enough contributors to adequately respond to all PRs. This bot triages issues and PRs according to the following rules:

  • After 60d of inactivity, lifecycle/stale is applied. - After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied and the PR is closed.
    You can:
  • Make a comment to remove the stale label and show your support. The 60 days reset. - If a PR has lifecycle/rotten and is closed, comment and ask maintainers if they'd be interested in reopening.

@marckhouzam
Copy link
Collaborator

marckhouzam commented Feb 12, 2023

Sorry for the long delay @Airblader. I finally got back to this.
I've been trying it with kubectl and I'm hesitant about he impact of this change.
For example, the command kubectl create quota has an alias to kubectl create resourcequota.
So let's say a user does:

$ kubectl create <TAB>
clusterrole          -- Create a cluster role
clusterrolebinding   -- Create a cluster role binding for a particular cluster role
configmap            -- Create a config map from a local file, directory or literal value
cronjob              -- Create a cron job with the specified name
deployment           -- Create a deployment with the specified name
ingress              -- Create an ingress with the specified name
job                  -- Create a job with the specified name
namespace            -- Create a namespace with the specified name
poddisruptionbudget  -- Create a pod disruption budget with the specified name
priorityclass        -- Create a priority class with the specified name
quota                -- Create a quota with the specified name
role                 -- Create a role with single rule
rolebinding          -- Create a role binding for a particular role or cluster role
secret               -- Create a secret using specified subcommand
service              -- Create a service using a specified subcommand
serviceaccount       -- Create a service account with the specified name
token                -- Request a service account token

Notice that the choices starting with the letter r are role and rolebinding. This is fine.
Then I add the letter r to my command-line to help complete those choices:

$ kubectl create r<TAB>
resourcequota  -- Create a quota with the specified name
role           -- Create a role with single rule
rolebinding    -- Create a role binding for a particular role or cluster role

Now the completion does not complete role/rolebinding but suddenly provides a new third choice resourcequota.
This may be surprising and confusing to a user.

An alternative would be to only complete command aliases if no other completions are available.
In the above example the user would get the following:

$ kubectl create r<TAB>
$ kubectl create role<TAB>
role           -- Create a role with single rule
rolebinding    -- Create a role binding for a particular role or cluster role

$ kubectl create res<TAB>
$ kubectl create resourcequota

This might be less surprising for a user. What do you think?
This is actually the approach taken for alias for arguments (ArgAliases) here:

cobra/completions.go

Lines 450 to 458 in e839bb3

// If no completions were found within commands or ValidArgs,
// see if there are any ArgAliases that should be completed.
if len(completions) == 0 {
for _, argAlias := range finalCmd.ArgAliases {
if strings.HasPrefix(argAlias, toComplete) {
completions = append(completions, argAlias)
}
}
}

@marckhouzam
Copy link
Collaborator

I sent that last comment too early, so I have edited it to add an example of the suggestion.

@Airblader
Copy link
Author

Thanks for getting back! I see your point. Mh. This is a tricky one. There are two ways to use completions: as a visual list to look at and explore (as you did here), and for mindless tab-completion when you already know the command you're looking for and just want to save yourself keystrokes. Essentially either solution is good at one, but bad at the other.

That said, the solution you propose does also make it difficult to discover potential aliases through completions, because completing "r" would instantly complete to "role", and the user would never learn about resourcequota.

A third solution would be to just always provide all completions, even for all aliases. I'd argue this is the "technically correct" solution, but I imagine you wouldn't like this one very much?

@marckhouzam
Copy link
Collaborator

A third solution would be to just always provide all completions, even for all aliases. I'd argue this is the "technically correct" solution, but I imagine you wouldn't like this one very much?

That would be always correct, indeed. But as you expected I feel it would reduce the user experience. It would possibly add a whole bunch of new completions to some already large list of choices.

I'm a big fan of using the shell completion for discovery. However, I’m not sure we can use shell completion to help discover aliases without also reducing the user experience.

I feel like aliases should not be in the way of the normal shell completion. They should just be considered if they don’t add noise. We can imagine that there can be many aliases for one command that would create noise if we showed them unilaterally.

That’s why I’m thinking that if we do want to consider aliases, we would need to do them only if there are no other completions found.

But this discussion shows that maybe showing aliases altogether is not something we should do, which is maybe why it was never done before.

What do you think?

@Airblader
Copy link
Author

Airblader commented Feb 12, 2023

My concern (and motivation for this PR) isn't so much showing the aliases, but offering the tab completion for them. I do feel strongly that not offering aliases to be completed is more of a usability issue than showing too many completions (personal opinion): why offer an alias at all if it is very awkward to use them?

Since you brought up kubectl as an example, let me name another one that mirrors more closely where this PR is coming from. It's an internal tool similar to minikube, where there is a "pause" command aliased with "suspend" (and others, actually). Suspend might be the more intuitive verb for some users, but not being able to tab complete "sus" unfairly penalizes them with a worse experience.

Yet another option here is to give control over this decision to the users of the library. Largely this may even already be achievable (haven't verified), though be a bit awkward to include in every command. A less flexible but easier to use solution would be some global configuration in Cobra. However I would also understand being hesitant to increase configuration surface.

I do want to go on record and say that to me this isn't a minor usability topic, but a fundamental one. Tab completions is IMO one of the most impactful usability features in CLIs, and Cobra specifically has great support for it in general. 🙂

@MichaelMure
Copy link
Contributor

I'm in need for this for https://github.com/MichaelMure/git-bug. The current binary is named git-bug but for namespace reasons I'm considering renaming it to gb. It'd be great if the completion kept working, especially during a transition where users are instructed to adapt (or not).

My concern (and motivation for this PR) isn't so much showing the aliases, but offering the tab completion for them.

This is the key point IMHO. No need to list every aliases, but having the completion react on them would be a great QOL improvement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/shell-completion All shell completions kind/feature A feature request for cobra; new or enhanced behavior
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Command aliases are not tab-completed
4 participants