Case in point:
I\'m a on mac with bash v3.2.17, I\'m using git installed via macports with the bash_completion variant.
When I type git checkout m<
This forum page shows a solution.
Put these lines into your .bashrc
or .bash_profile
:
# Author.: Ole J
# Date...: 23.03.2008
# License: Whatever
# Wraps a completion function
# make-completion-wrapper <actual completion function> <name of new func.>
# <command name> <list supplied arguments>
# eg.
# alias agi='apt-get install'
# make-completion-wrapper _apt_get _apt_get_install apt-get install
# defines a function called _apt_get_install (that's $2) that will complete
# the 'agi' alias. (complete -F _apt_get_install agi)
#
function make-completion-wrapper () {
local function_name="$2"
local arg_count=$(($#-3))
local comp_function_name="$1"
shift 2
local function="
function $function_name {
((COMP_CWORD+=$arg_count))
COMP_WORDS=( "$@" \${COMP_WORDS[@]:1} )
"$comp_function_name"
return 0
}"
eval "$function"
}
# and now the commands that are specific to this SO question
alias gco='git checkout'
# we create a _git_checkout_mine function that will do the completion for "gco"
# using the completion function "_git"
make-completion-wrapper _git _git_checkout_mine git checkout
# we tell bash to actually use _git_checkout_mine to complete "gco"
complete -o bashdefault -o default -o nospace -F _git_checkout_mine gco
This solution is similar to balshetzer's script, but only this one actually works for me. (balshetzer's script had problems with some of my aliases.)
There are a lot of answers to this question and like myself I bet a lot of confused readers. For my case I had also had the requirement to have my dotfiles work on multiple platforms with different versions of Git. I also don't alias g=git
but instead have g
defined as a function.
To accomplish this I had to slap together different answers here into one solution. Although this reiterates the answers already I thought someone in my boat might find this compilation useful as I would have when I first came to this question.
This assumes older and newer Git completion, Ubuntu defaults, and brew install git
on MacOS. In the later case the brew installed completions were not being processed by bash (something I will diagnose later).
# Alias g to git
g() {
if [[ $# > 0 ]]; then
git "$@"
else
git status -sb
fi
}
# Preload git completion in Ubuntu which is normally lazy loaded but we need
# the __git_wrap__git_main function available for our completion.
if [[ -e /usr/share/bash-completion/completions/git ]]; then
source /usr/share/bash-completion/completions/git
elif [[ -e /usr/local/etc/bash_completion.d/git-completion.bash ]]; then
source /usr/local/etc/bash_completion.d/git-completion.bash
fi
if command_exists __git_complete; then
__git_complete g _git
elif command_exists __git_wrap__git_main; then
complete -o bashdefault -o default -o nospace -F __git_wrap__git_main g
fi
As stated in the comments above,
complete -o default -o nospace -F _git_checkout gco
will no longer work. However, there's a __git_complete
function in git-completion.bash which can be used to set up completion for aliases like so:
__git_complete gco _git_checkout
I ran into this problem as well and came up with this code snippet. This will automatically give you completion for all aliases. Run it after declaring all (or any) alias.
# wrap_alias takes three arguments:
# $1: The name of the alias
# $2: The command used in the alias
# $3: The arguments in the alias all in one string
# Generate a wrapper completion function (completer) for an alias
# based on the command and the given arguments, if there is a
# completer for the command, and set the wrapper as the completer for
# the alias.
function wrap_alias() {
[[ "$#" == 3 ]] || return 1
local alias_name="$1"
local aliased_command="$2"
local alias_arguments="$3"
local num_alias_arguments=$(echo "$alias_arguments" | wc -w)
# The completion currently being used for the aliased command.
local completion=$(complete -p $aliased_command 2> /dev/null)
# Only a completer based on a function can be wrapped so look for -F
# in the current completion. This check will also catch commands
# with no completer for which $completion will be empty.
echo $completion | grep -q -- -F || return 0
local namespace=alias_completion::
# Extract the name of the completion function from a string that
# looks like: something -F function_name something
# First strip the beginning of the string up to the function name by
# removing "* -F " from the front.
local completion_function=${completion##* -F }
# Then strip " *" from the end, leaving only the function name.
completion_function=${completion_function%% *}
# Try to prevent an infinite loop by not wrapping a function
# generated by this function. This can happen when the user runs
# this twice for an alias like ls='ls --color=auto' or alias l='ls'
# and alias ls='l foo'
[[ "${completion_function#$namespace}" != $completion_function ]] && return 0
local wrapper_name="${namespace}${alias_name}"
eval "
function ${wrapper_name}() {
let COMP_CWORD+=$num_alias_arguments
args=( \"${alias_arguments}\" )
COMP_WORDS=( $aliased_command \${args[@]} \${COMP_WORDS[@]:1} )
$completion_function
}
"
# To create the new completion we use the old one with two
# replacements:
# 1) Replace the function with the wrapper.
local new_completion=${completion/-F * /-F $wrapper_name }
# 2) Replace the command being completed with the alias.
new_completion="${new_completion% *} $alias_name"
eval "$new_completion"
}
# For each defined alias, extract the necessary elements and use them
# to call wrap_alias.
eval "$(alias -p | sed -e 's/alias \([^=][^=]*\)='\''\([^ ][^ ]*\) *\(.*\)'\''/wrap_alias \1 \2 '\''\3'\'' /')"
unset wrap_alias
If you use alias g='git'
, i add this line of code in .bash_aliases
complete -o default -o nospace -F _git g
One more option is to use ~/.bash_completion
file. To create the gco
alias for git checkout
just put this in there:
_xfunc git __git_complete gco _git_checkout
Then in ~/.bashrc
you have to put just the alias itself:
alias gco='git checkout'
Two lines. That's it.
Explanation:
The ~/bash_completion
gets sourced at the end of the main bash_completion script. In gentoo I found the main script in /usr/share/bash-completion/bash_completion
.
The _xfunc git
bit takes care of sourcing the git-completion
file for you so you don't need to put anything else in ~/.bashrc
.
The accepted answer require you to copy .git-completion.sh
and source it from your ~/.bashrc
file which I find lame.
PS: I'm still trying to figure out how not to source the whole git-completion
script into my bash environment. Please comment or edit if you find a way.