Is it possible to have separate bash completion functions for separate commands which happen to share the same name?

Viewed 247

I have two separate scripts with the same filename, in different paths, for different projects: /home/me/projects/alpha/bin/hithere and /home/me/projects/beta/bin/hithere.

Correspondingly, I have two separate bash completion scripts, because the proper completions differ for each of the scripts. In the completion scripts, the "complete" command is run for each completion specifying the full name of the script in question, i.e.

complete -F _alpha_hithere_completion /home/me/projects/alpha/bin/hithere

However, only the most-recently-run script seems to have an effect, regardless of which actual version of hithere is invoked: it seems that bash completion only cares about the filename of the command and disregards path information.

Is there any way to change this behavior so that I can have these two independent scripts with the same name, each with different completion functions?

Please note that I'm not interested in a solution which requires alpha to know about beta, or which would require a third component to know about either of them--that would defeat the purpose in my case.

2 Answers

Yes, this is possible. But it's a bit tricky. I am using this for a future scripting concept I am developing: All scripts have the same name as they are build scripts, but still bash completion can do its job.

For this I use a two step process: First of all I place a main script in ~/.config/bash_completion.d. This script is designed to cover all scripts of the particular shared script name. I configured ~/.bashrc in order to load that bash completion file for these scripts.

The script will obtain the full file path of the particular script file I want to have bash completion for. From this path I generate an identifier. For this identifier there exists a file that provides actual bash completion data. So if bash completion is performed the bash completion function from the main bash completion script will check for that file and load it's content. Then it will continue with regular bash completion operation.

If you have two scripts with the same name you will have two different identifiers as those scripts share the same name but have different paths. Therefore two different configurations for bash completion can be used.

This concept works like a charm.


NOTE: I will update this answer soon providing some source code.

Related