_hg_commands()
{
local commands="$(hg -v help | sed -e '1,/^list of commands:/d' \
-e '/^global options:/,$d' \
-e '/^ [^ ]/!d; s/[,:]//g;')"
# hide debug commands from users, but complete them if
# specifically asked for
if [[ "$cur" == de* ]]; then
commands="$commands debugcheckstate debugstate debugindex"
commands="$commands debugindexdot debugwalk"
fi
COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "$commands" -- "$cur") )
}
_hg_paths()
{
local paths="$(hg paths | sed -e 's/ = .*$//')"
COMPREPLY=(${COMPREPLY[@]:-} $( compgen -W "$paths" -- "$cur" ))
}
_hg_status()
{
local files="$( hg status -$1 | cut -b 3- )"
COMPREPLY=(${COMPREPLY[@]:-} $( compgen -W "$files" -- "$cur" ))
}
_hg_tags()
{
local tags="$(hg tags | sed -e 's/[0-9]*:[a-f0-9]\{40\}$//; s/ *$//')"
COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "$tags" -- "$cur") )
}
# this is "kind of" ugly...
_hg_count_non_option()
{
local i count=0
local filters="$1"
for (( i=1; $i<=$COMP_CWORD; i++ )); do
if [[ "${COMP_WORDS[i]}" != -* ]]; then
for f in $filters; do
if [[ ${COMP_WORDS[i-1]} == $f ]]; then
continue 2
fi
done
count=$(($count + 1))
fi
done
echo $(($count - 1))
}
_hg()
{
local cur prev cmd opts i
COMPREPLY=()
cur="$2"
prev="$3"
# searching for the command
# (first non-option argument that doesn't follow -R/--repository)
for (( i=1; $i<=$COMP_CWORD; i++ )); do
if [[ ${COMP_WORDS[i]} != -* ]] \
&& [ "${COMP_WORDS[i-1]}" != -R ] \
&& [ "${COMP_WORDS[i-1]}" != --repository ]; then
cmd="${COMP_WORDS[i]}"
break
fi
done
if [[ "$cur" == -* ]]; then
opts="$(hg -v help | sed -e '1,/^global options/d; /^ -/!d')"
if [ -n "$cmd" ]; then
opts="$opts $(hg help "$cmd" | sed -e '/^ -/!d; s/ [^-][^ ]*//')"
fi
COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W "$opts" -- "$cur") )
return
fi
if [ "$prev" = -R ] || [ "$prev" = --repository ]; then
COMPREPLY=(${COMPREPLY[@]:-} $( compgen -d -- "$cur" ))
return
fi
if [ -z "$cmd" ] || [ $COMP_CWORD -eq $i ]; then
_hg_commands
return
fi
if [ "$cmd" != status ] && [ "$prev" = -r ] || [ "$prev" = --rev ]; then
_hg_tags
return
fi
case "$cmd" in
help)
_hg_commands
;;
export|manifest|update|checkout|up|co)
_hg_tags
;;
pull|push|outgoing|incoming|out|in)
_hg_paths
COMPREPLY=(${COMPREPLY[@]:-} $( compgen -d -- "$cur" ))
;;
paths)
_hg_paths
;;
add)
_hg_status "u"
;;
commit|ci)
_hg_status "mra"
;;
remove)
_hg_status "r"
;;
forget)
_hg_status "a"
;;
diff)
_hg_status "mra"
;;
revert)
_hg_status "mra"
;;
clone)
local count=$(_hg_count_non_option)
if [ $count = 1 ]; then
_hg_paths
fi
COMPREPLY=(${COMPREPLY[@]:-} $( compgen -d -- "$cur" ))
;;
cat)
local count=$(_hg_count_non_option -o --output)
if [ $count = 2 ]; then
_hg_tags
else
COMPREPLY=(${COMPREPLY[@]:-} $( compgen -f -- "$cur" ))
fi
;;
*)
COMPREPLY=(${COMPREPLY[@]:-} $( compgen -f -- "$cur" ))
;;
esac
}
complete -o default -F _hg hg