# Programmable completion for the Subversion svn command under bash. Source
# this file (or on some systems add it to ~/.bash_completion and start a new
# shell) and bash's completion mechanism will know all about svn's options!
# Who wants to read man pages/help text...

# Doesn't do --xml-file and its associated options, that's intentional :)

# Known to work with bash 2.05a with programmable completion and extended
# pattern matching enabled (use 'shopt -s extglob progcomp' to enable
# these if they are not already enabled).

_svn()
{
	local cur cmds cmdOpts pOpts mOpts rOpts qOpts nOpts optsParam opt

	COMPREPLY=()
	cur=${COMP_WORDS[COMP_CWORD]}

	cmds='add checkout co cleanup commit ci copy cp delete del remove   \
	      rm diff di import info h help log merge mkdir move mv rename  \
	      ren propdel pdel propedit pedit pe propget pget pg proplist   \
	      plist pl propset pset ps revert resolve status stat st switch \
	      sw update up --version'

	if [[ $COMP_CWORD -eq 1 ]] ; then
		COMPREPLY=( $( compgen -W "$cmds" -- $cur ) )
		return 0
	else
		# if we're completing for 'svn help' or 'svn h', then just 
		# complete on any valid svn command
		case ${COMP_WORDS[1]} in
		help|h)
			COMPREPLY=( $( compgen -W "$cmds" -- $cur ) )
			return 0
			;;
		*)
			;;
		esac
	fi

	# options that require a parameter
	# note: continued lines must end '|' continuing lines must start '|'
	optsParam="-r|--revision|-D|--date|--username|--password|--targets|\
	           |-d|--destination|-x|--extensions|-m|--message|-F|--file"

	# if not typing an option, or if the previous option required a
	# parameter, then fallback on ordinary filename expansion
	if [[ "$cur" != -* ]] || \
	   [[ ${COMP_WORDS[COMP_CWORD-1]} == @($optsParam) ]] ; then
		return 0
	fi

	pOpts="--username --password"
	mOpts="-m --message -F --file"
	rOpts="-r --revision -D --date"
	qOpts="-q --quiet"
	nOpts="-n --nonrecursive"

	# possible options for the command
	cmdOpts=
	case ${COMP_WORDS[1]} in
	add)
		cmdOpts="--targets --recursive"
		;;
	checkout|co)
		cmdOpts="-d --destination $rOpts $pOpts $qOpts"
		;;
	cleanup)
		;;
	commit|ci)
		cmdOpts="$mOpts $qOpts $nOpts --targets --force $pOpts"
		;;
	copy|cp)
		cmdOpts="$mOpts $rOpts $pOpts"
		;;
	delete|del|remove|rm)
		cmdOpts="--force $mOpts --targets $pOpts"
		;;
	diff|di)
		cmdOpts="$nOpts $rOpts $pOpts -x --extensions"
		;;
	import)
		cmdOpts="$mOpts $qOpts $nOpts $pOpts"
		;; 
	info)
		cmdOpts="--targets"
		;;
	log)
		cmdOpts="$rOpts -v --verbose --targets --xml $pOpts"
		;;
	merge)
		cmdOpts="$rOpts $nOpts $pOpts"
		;;
	mkdir)
		cmdOpts="$mOpts $pOpts"
		;;
	move|mv|rename|ren)
		cmdOpts="$mOpts $rOpts $pOpts --force"
		;;
	propdel|pdel)
		cmdOpts="$qOpts --recursive"
		;;
	propedit|pedit)
		cmdOpts="$qOpts --recursive"
		;;
	propget|pget|pg)
		cmdOpts="--recursive"
		;;
	proplist|plist|pl)
		cmdOpts="-v --verbose --recursive"
		;;
	propset|pset|ps)
		cmdOpts="$mOpts --targets --recursive"
		;;
	revert)
		cmdOpts="--targets --recursive"
		;;
	resolve)
		cmdOpts="--targets"
		;;
	status|stat|st)
		cmdOpts="-u --show-updates -v --verbose $nOpts $qOpts $pOpts"
		;;
	switch|sw)
		cmdOpts="$rOpts $nOpts $pOpts"
		;;
	update|up)
		cmdOpts="$rOpts $nOpts $pOpts"
		;;
	*)
		;;
	esac

	# take out options already given
	for (( i=2; i<=$COMP_CWORD-1; ++i )) ; do
		opt=${COMP_WORDS[$i]}
		cmdOpts=" $cmdOpts "
		cmdOpts=${cmdOpts/ ${opt} / }

		# take out alternatives
		case $opt in
		-d)             cmdOpts=${cmdOpts/ --destination / } ;;
		--destination)  cmdOpts=${cmdOpts/ -d / } ;;
		-v)             cmdOpts=${cmdOpts/ --verbose / } ;;
		--verbose)      cmdOpts=${cmdOpts/ -v / } ;;
		-n)             cmdOpts=${cmdOpts/ --nonrecursive / } ;;
		--nonrecursive) cmdOpts=${cmdOpts/ -n / } ;;
		-x)             cmdOpts=${cmdOpts/ --extensions / } ;;
		--extensions)   cmdOpts=${cmdOpts/ -x / } ;;
		-q)             cmdOpts=${cmdOpts/ --quiet / } ;;
		--quiet)        cmdOpts=${cmdOpts/ -q / } ;;

		-r|--revision|-D|--date)
			cmdOpts=${cmdOpts/ --revision / }
			cmdOpts=${cmdOpts/ -r / }
			cmdOpts=${cmdOpts/ --date / }
			cmdOpts=${cmdOpts/ -D / }
			;;

		-m|--message|-F|--file)
			cmdOpts=${cmdOpts/ --message / }
			cmdOpts=${cmdOpts/ -m / }
			cmdOpts=${cmdOpts/ --file / }
			cmdOpts=${cmdOpts/ -F / }
			;;
		esac

		# skip next option if this one requires a parameter
		if [[ $opt == @($optsParam) ]] ; then
			((++i))
		fi
	done

	COMPREPLY=( $( compgen -W "$cmdOpts" -- $cur ) )

	return 0
}
complete -F _svn -o default svn
