contrib/bash_completion
author Josef "Jeff" Sipek <jeffpc@optonline.net>
Sun, 05 Feb 2006 20:52:55 -0500
changeset 1668 586b50294ea8
parent 1643 747c8d03bd29
child 1683 063e04831a09
permissions -rw-r--r--
[hgweb] Added rename information to gitweb templates & misc cleanups Fixed up file log template's title Removed double entry for filelogentry in gitweb map file

shopt -s extglob

_hg_command_list()
{
    hg --debug help 2>/dev/null | \
	awk 'function command_line(line) {
		 gsub(/,/, "", line)
		 gsub(/:.*/, "", line)
		 split(line, aliases)
		 command = aliases[1]
		 delete aliases[1]
		 print command
		 for (i in aliases)
		     if (index(command, aliases[i]) != 1)
			 print aliases[i]
	     }
	     /^list of commands:/ {commands=1}
	     commands && /^ debug/ {a[i++] = $0; next;}
	     commands && /^ [^ ]/ {command_line($0)}
	     /^global options:/ {exit 0}
	     END {for (i in a) command_line(a[i])}'

}

_hg_option_list()
{
    hg -v help $1 2> /dev/null | \
        awk '/^ *-/ {
		 for (i = 1; i <= NF; i ++) {
		    if (index($i, "-") != 1)
			 break;
		    print $i;
		 }
	     }'
}


_hg_commands()
{
    local all commands result

    all=$(_hg_command_list)
    commands=${all%%$'\n'debug*}
    result=$(compgen -W '$commands' -- "$cur")

    # hide debug commands from users, but complete them if
    # there is no other possible command
    if [ "$result" = "" ]; then
	local debug
	debug=debug${all#*$'\n'debug}
	result=$(compgen -W '$debug' -- "$cur")
    fi

    COMPREPLY=(${COMPREPLY[@]:-} $result)
}

_hg_paths()
{
    local paths="$(hg paths 2> /dev/null | sed -e 's/ = .*$//')"
    COMPREPLY=(${COMPREPLY[@]:-} $( compgen -W '$paths' -- "$cur" ))
}

_hg_repos()
{
    local i
    for i in $( compgen -d -- "$cur" ); do
        test ! -d "$i"/.hg || COMPREPLY=(${COMPREPLY[@]:-} "$i")
    done
}

_hg_status()
{
    local files="$( hg status -n$1 . 2> /dev/null)"
    COMPREPLY=(${COMPREPLY[@]:-} $( compgen -W '$files' -- "$cur" ))
}

_hg_tags()
{
    local tags="$(hg tags 2> /dev/null |
                      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
	    if [[ ${COMP_WORDS[i-1]} == @($filters|$global_args) ]]; then
		continue
	    fi
	    count=$(($count + 1))
	fi
    done

    echo $(($count - 1))
}

_hg()
{
    local cur prev cmd opts i
    # global options that receive an argument
    local global_args='--cwd|-R|--repository'

    COMPREPLY=()
    cur="$2"
    prev="$3"

    # searching for the command
    # (first non-option argument that doesn't follow a global option that
    #  receives an argument)
    for (( i=1; $i<=$COMP_CWORD; i++ )); do
	if [[ ${COMP_WORDS[i]} != -* ]]; then
	    if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then
		cmd="${COMP_WORDS[i]}"
		break
	    fi
	fi
    done

    if [[ "$cur" == -* ]]; then
	opts=$(_hg_option_list $cmd)

	COMPREPLY=( ${COMPREPLY[@]:-} $(compgen -W '$opts' -- "$cur") )
	return
    fi

    # global options
    case "$prev" in
	-R|--repository)
	    _hg_repos
	    return
	;;
	--cwd)
	    # Stick with default bash completion
	    return
	;;
    esac

    if [ -z "$cmd" ] || [ $COMP_CWORD -eq $i ]; then
	_hg_commands
	return
    fi

    # canonicalize command name
    cmd=$(hg -q help "$cmd" 2> /dev/null | sed -e 's/^hg //; s/ .*//; 1q')

    if [ "$cmd" != status ] && [ "$prev" = -r ] || [ "$prev" = --rev ]; then
	_hg_tags
	return
    fi

    case "$cmd" in
	help)
	    _hg_commands
	;;
	export|manifest|update)
	    _hg_tags
	;;
	pull|push|outgoing|incoming)
	    _hg_paths
	    _hg_repos
	;;
	paths)
	    _hg_paths
	;;
	add)
	    _hg_status "u"
	;;
	commit)
	    _hg_status "mar"
	;;
	remove)
	    _hg_status "d"
	;;
	forget)
	    _hg_status "a"
	;;
	diff)
	    _hg_status "mar"
	;;
	revert)
	    _hg_status "mard"
	;;
	clone)
	    local count=$(_hg_count_non_option)
	    if [ $count = 1 ]; then
		_hg_paths
	    fi
            _hg_repos
	;;
	debugindex|debugindexdot)
	    COMPREPLY=(${COMPREPLY[@]:-} $( compgen -f -X "!*.i" -- "$cur" ))
	;;
	debugdata)
	    COMPREPLY=(${COMPREPLY[@]:-} $( compgen -f -X "!*.d" -- "$cur" ))
	;;
    esac

}

complete -o bashdefault -o default -F _hg hg 2> /dev/null \
    || complete -o default -F _hg hg