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

adding an alias completion helper #521

Open
calestyo opened this issue May 4, 2021 · 15 comments
Open

adding an alias completion helper #521

calestyo opened this issue May 4, 2021 · 15 comments

Comments

@calestyo
Copy link
Contributor

calestyo commented May 4, 2021

Hey there.

A recurring question seems to be how to automatically get completions for aliases. Numerous code snippets and helper functions can be found, e.g. here:

It seems that getting it right and especially covering all cases, like support for git or to get aliases completed that already contained arguments, is trickier than a one liner.

I think it would be nice if bash-completion could provide a proper helper for this, i.e. one that covers all cases and solves it reasonably cleanly.
Shipping this with bash-completion would have the great benefit, that sooner or later most distros would get it out-of-the box, while a separate small project has often only little chances to really find its way into all distros.

Cheers,
Chris.

@scop
Copy link
Owner

scop commented May 4, 2021

I can have a look if someone submits one, however if it doesn't come with a promise to help maintain it (well to take ownership to be fair), it needs to be one that doesn't make my head hurt (and come with a bunch of test cases). I'm afraid the ones quickly visible from the links all do inflict that ache.

Failing that, I could add a FAQ entry for this and point towards https://github.com/cykerway/complete-alias, that one seems a cleanly installable thing that works for all cases if it works as advertised. But I'd need to take a closer look at it before doing so.

@calestyo
Copy link
Contributor Author

calestyo commented May 4, 2021

Should I ask the maintainer of complete-alias whether he'd consider to merge it into bash-completion?

@scop
Copy link
Owner

scop commented May 11, 2021

If the test cases and offer for long term maintainership within bash-completion are in order, sure.

@cykerway
Copy link
Contributor

I think a FAQ entry is good for now, and take your time to review complete-alias if you are interested in merging.

Long answer.

@akinomyoga
Copy link
Collaborator

Ref: PR #104

@calestyo
Copy link
Contributor Author

calestyo commented May 2, 2023

Nice... how does it come that this seems so much smaller in terms of of code than cykerway/complete-alias?

@akinomyoga
Copy link
Collaborator

#104 is the version 7 years before. I just today realized that @cykerway has already submitted the very initial version of cykerway/complete-alias in bash-completion as a PR, so I thought it'd be good to mention it for reference.

No one has yet started to work on the migration of the latest version of complete-alias to bash-completion, but if it would finally be merged, it should replace #104 (or we might work on it by adding commits in #104, but I haven't checked in detail how much the latest version has been changed since #104).

@jw013
Copy link

jw013 commented Sep 23, 2023

I found that bash has a progcomp_alias shopt that is close to doing the desired behavior of expanding aliases for completions, but it is only used as a last resort if complete -D is not active which makes it incompatible with dynamically loaded completions. If the relative priorities could be flipped around I believe that would solve everything and architecturally that seems much cleaner than a reimplementation of alias parsing and expansion in shell functions. It seems like this idea has been raised at least once in the past but not met with much enthusiasm.

One workaround I have been using is to simply expand the alias manually before attempting to trigger completion. By default bash binds the key chord Alt-Control-e to the command shell-expand-line, which will expand the alias. It will also expand any $variables in the input line so if so if this is not desirable one may prefer a binding to the alias-expand-line command instead.

@akinomyoga
Copy link
Collaborator

I remember there were similar discussions about complete -D and progcomp_alias in the past. FWIW, these are the discussions that I can find now:

@calestyo
Copy link
Contributor Author

calestyo commented Sep 8, 2024

Is there a proper way to have completions for some command (e.g. systemctl, as given in /usr/share/bash-completion/completions/systemctl) be loaded for some other (alias) command name (like sc)?

I'd basically like to use:

alias sc=systemctl
complete -F _systemctl sc

but _systemctl is only loaded when /usr/share/bash-completion/completions/systemctl is loaded (which happens only dynamically.

I can of course add another:

_comp_load -D -- 'systemctl' && return 124

to trigger the loading unconditionally, but then I always have the functions from the dynamic completions for systemctl around, even if not used.

I also tried making ~/.local/share/bash-completion/completions/sc a symlink to /usr/share/bash-completion/completions/systemctl, but that doesn't seem to do the job.

Thanks,
Chris.

@beavailable
Copy link

beavailable commented Sep 8, 2024

@calestyo Here is the command I use:

sed -E 's/^(\s*complete -F _systemctl )systemctl$/\1sc/' /usr/share/bash-completion/completions/systemctl >~/.local/share/bash-completion/completions/sc

For other commands, you just need to substitute the command name, the completion function name and the aliases, then execute it.
But I'm not sure if it works for all commands.

@calestyo
Copy link
Contributor Author

calestyo commented Sep 9, 2024

@beavailable Thanks, that works :-) but has IMO two downsides:

  • re-writing the completion file over and over again (ok, not a big cost, bust ideally it would still be avoided)
  • AFAIU, if someone would have completed sc and later systemctl (or vice versa) the same functions would effectively be loaded twice (overwriting the previous ones for no good reason).

I played a bit and came up with the following for ~/.local/share/bash-completion/completions/sc:

#load `systemctl`’s completion code, if the completion for `systemctl` has not been defined yet
# The latter could have happened by previously completing `systemctl`. If `sc`
# would have been previously completed, this script would not be sourced again
# (see the `-D`-option of bash’s `complete`-built-in-utility and the definition
# of the completion for `sc` below).
if ! complete -p systemctl 2>/dev/null; then
	_comp_complete_load systemctl
fi


complete -F _systemctl sc

That should do the following:

  • only if no completion for systemctl exists yet, it should load that via _comp_complete_load
  • as that helper wouldn't be sourced again (once after complete -F _systemctl sc is executed), it won't even run that check multiple times

The only thing I don't know right now is whether one should call _comp_complete_load or rather _comp_load directly... @akinomyoga @scop... what would you recommend? :-)

@akinomyoga
Copy link
Collaborator

The only thing I don't know right now is whether one should call _comp_complete_load or rather _comp_load directly... @akinomyoga @scop... what would you recommend? :-)

Use _comp_load. See Naming: _comp_complete_* are the functions to be specified to complete -F. They are not intended to be called by scripts. While the exit status of _comp_complete_load follows a specific way of Bash's programmable completion scheme, the exit status of _comp_load returns whether a dynamic completion setting is found. In case a corresponding completion setting is not found in the system, you should write it in the following way:

if complete -p systemctl 2>/dev/null || _comp_load systemctl; then
    complete -F _systemctl sc
fi

@calestyo
Copy link
Contributor Author

calestyo commented Sep 9, 2024

Thanks... :-)

And nice that this doesn't even define the completion for sc, when that for systemctl couldn’t be loaded!

@beavailable
Copy link

@calestyo You're right, I haven't thought that much, because it just works.
But your solution is indeed better and I'm gonna use it too.

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

No branches or pull requests

6 participants