Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash: how to simplify autocompletion of custom created functions by using the already available bash-completion functions?

How can I reuse the completion functions that already exist inside /usr/share/bash-completion/completions into my own custom functions, without having to write another function just to build the list of possible completions?


If the question isn't clear, take this example:

• I created a function on my .bashrc:

function gitdelbranch {
    git branch --delete ${1} && git push origin --delete ${1}
}

• I'm already sourcing . /usr/share/bash-completion/bash_completion on my .bashrc

• Now, I want to be able to autocomplete my gitdelbranch function with the same options that git branch -d would give me.

• Looking inside /usr/share/bash-completion/completions/git:599, I can see that there is already a function that completes local branches, called __git_heads():

[...]
# Lists branches from the local repository.
# 1: A prefix to be added to each listed branch (optional).
# 2: List only branches matching this word (optional; list all branches if
#    unset or empty).
# 3: A suffix to be appended to each listed branch (optional).
__git_heads ()
[...]

Also, another trick I learned while researching this: if I type on my shell git branch -d, press <Tab>, and then run complete -p git, I can see the whole complete command that was used for that (you really have to run it once before it works):

complete -o bashdefault -o default -o nospace -F __git_wrap__git_main git


However, no matter what I try, I can't get to autocomplete my custom function with a single command, like complete -o [...] -F __[...] gitdelbranch.

Question is: Why is that? Is there any way around it or do I really have to write a new, custom completion function, build the options list and COMMREPLY, just to get the behaviour I want? It looks to me that this has to be possible, given that there's already a well written completion file on my system.


As a bonus question: why doesn't even complete -o bashdefault -o default -o nospace -F __git_wrap__git_main gitdelbranch work, given that it's being used in the shell and working just fine with git branch -d?

like image 553
emi Avatar asked Oct 12 '25 05:10

emi


1 Answers

Git completion is quite easy to add to your own bash functions actually, for example, this little script autocompletes your git branches:

my_func () { return; }
source /usr/share/bash-completion/completions/git
__git_complete my_func __git_complete_refs

Now my_func has autocompletion for branch names.

Or like this you can have an alias g to git with working auto completion:

source /usr/share/bash-completion/completions/git
alias g=git
__git_complete g __git_main

Look in the /usr/share/bash-completion/completions/git file for all completions possible. The original file in the source code: https://github.com/git/git/blob/master/contrib/completion/git-completion.bash

There are a bunch of default complete functions, but they might not always do what you want, because they are made specially for git commands. In some cases you might want to make a custom auto complete function. Looking in the source code of the git-completion.bash you can figure stuff out. For example this auto complete function only completes local branch names:

source /usr/share/bash-completion/completions/git
git_local_branches () {
    __gitcomp_direct "$(__git_heads "" "$cur" " ")"
}
my_func () { return; }
__git_complete my_func git_local_branches

Also see this answer for more info on how general bash completion works. Normally you would use the complete command, but Git created its own complete function __git_complete, which you should use for git completion.

like image 166
gitaarik Avatar answered Oct 14 '25 21:10

gitaarik