There are many resources available (1, 2, 3) that explain how to make use of bash's ability to auto-complete commands and arguments, but all of these resources require the addition of code to a user's ~/.bash_profile
or /etc/bash_completion.d/*
but is there a way to make a script and its available completions self-contained? As a crude and incomplete example:
~/bin/script-with-integrated-autocomplete.sh:
#!/usr/bin/env bash
function _completions {
complete ...
}
if [ "$1" == "completions" ]; then
_completions
exit 0
fi
# (Whatever the script really does goes here.)
# ...
# ...
The deal-breaker (in the context of this question) is that the above example still requires you to add something like ~/bin/script-with-integrated-autocomplete.sh completions
to your .profile
to engage the completions.
Is there a way for a single bash script (file) to declare its own completions and have bash recognize them at the time of invocation (ideally with no additional system or environment setup)?
Best Answer
As stated in comments to your question, Bash cannot complete the command line for a command without any previous configuration and without changing the current environment. Bash does not peek into files, nor it tries to interpret them unless you explicitly execute or source them.
My read on the subject is that such a feature is unlikely to make its way into Bash anytime soon, because of compatibility and resources concerns—as a shell, it is meant to reliably run on a variety of different systems, with a variety of purposes and adapting to the preferences of a variety of users; and it has only one person as developer and maintainer1.
While Bash provides the tools to implement autocompletion, completion generators seem to be by design intended as external facilities. And indeed what you are looking for can be easily implemented with the existing tools and a small amount of work.
Given the sample script
foo
:using bash-completion, self-contained autocompletion can be enabled by adding a symbolic link to
foo
to the directory that stores dynamically loaded user completions:The exact path may vary, you can refer to bash-completion's FAQ for how to check its value on your system.
Without bash-completion, one approach could be to define a default completion function that sources (files corresponding to) commands if they meet certain conditions; here we are using an associative array as a whitelist (to avoid blindly sourcing every command on the system). This code has to be added to your
.bashrc
(or equivalent, i.e. a file that is sourced in the current environment every time an interactive shell is started):I know, you asked for a solution that didn't require to edit configuration files, but please note that a certain amount of configuration is always required. A substantial part of it is done by distribution/package maintainers, even if users may never come to realize it.
1 Reference: the Bash home page on Chet Ramey's website and point "A1" in the related Bash FAQ.