Add bash_completion to contrib

Contributed by "Alexis S. L. Carvalho" <alexis@cecm.usp.br>

Attached is a file that implements bash completion for hg.  Just
reading it from your .bashrc should be enough to use it - I think: I'm
using the /etc/bash_completion from debian and I'm not sure whether it
sets some important option.

It gets the list of commands, aliases and options from the output of hg
help and then adds some specific stuff - e.g. completing update with
tags; pull and push with path aliases and directories, etc.
This commit is contained in:
mpm@selenic.com 2005-08-16 14:17:27 -08:00
parent 2616af791c
commit fe60cec7c8

129
contrib/bash_completion Normal file
View File

@ -0,0 +1,129 @@
_hg_commands()
{
local commands="$(hg -v help | sed -e '1,/^list of commands:/d' \
-e '/^global options:/Q' \
-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_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)
_hg_paths
COMPREPLY=(${COMPREPLY[@]:-} $( compgen -d -- "$cur" ))
;;
paths)
_hg_paths
;;
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 filenames -F _hg hg