# ------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# ------------------------------------------------------------

# 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!
# Provides completion for the svnadmin, svndumpfilter, svnlook and svnsync
# commands as well.  Who wants to read man pages/help text...

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

shopt -s extglob

# Tree helper functions which only use bash, to ease readability.

# look for value associated to key from stdin in K/V hash file format
# val=$(_svn_read_hashfile svn:realmstring < some/file)
function _svn_read_hashfile()
{
  local tkey=$1 key= val=
  while true; do
    read tag len
    [ $tag = 'END' ] && break
    [ $tag != 'K' ] && {
      #echo "unexpected tag '$tag' instead of 'K'" >&2
      return
    }
    read -r -n $len key ; read
    read tag len
    [ $tag != 'V' ] && {
      #echo "unexpected tag '$tag' instead of 'V'" >&2
      return
    }
    read -r -n $len val ; read
    if [[ $key = $tkey ]] ; then
      echo "$val"
      return
    fi
  done
  #echo "target key '$tkey' not found" >&2
}

# _svn_grcut shell-regular-expression
# extract filenames from 'svn status' output
function _svn_grcut()
{
    local re=$1 line= old_IFS
    # fix IFS, so that leading spaces are not ignored by next read.
    # (there is a leading space in svn status output if only a prop is changed)
    old_IFS="$IFS"
    IFS=$'\n'
    while read -r line ; do
	[[ ! $re || $line == $re ]] && echo "${line/????????/}"
    done
    IFS="$old_IFS"
}

# extract stuff from svn info output
# _svn_info (URL|Repository Root)
function _svn_info()
{
  local what=$1 line=
  LANG=C LC_MESSAGES=C svn info --non-interactive 2> /dev/null | \
  while read line ; do
    [[ $line == *"$what: "* ]] && echo ${line#*: }
  done
}

# _svn_lls (dir|file|all) files...
# list svn-managed files from list
# some 'svn status --all-files' would be welcome here?
function _svn_lls()
{
    local opt=$1 f=
    shift
    for f in "$@" ; do
	# could try to check in .svn/entries? hmmm...
	if [[ $opt == @(dir|all) && -d "$f" ]] ; then
	    echo "$f/"
	elif [[ $opt == @(file|all) ]] ; then
	    # split f in directory/file names
	    local dn= fn="$f"
	    [[ "$f" == */* ]] && dn=${f%\/*}/ fn=${f##*\/}
	    # ??? this does not work for just added files, because they
	    # do not have a content reference yet...
	    [ -f "${dn}.svn/text-base/${fn}.svn-base" ] && echo "$f"
	fi
    done
}

# This completion guides the command/option order along the one suggested
# by "svn help", although other syntaxes are allowed.
#
# - there is a "real" parser to check for what is available and deduce what
#   can be suggested further.
# - the syntax should be coherent with subversion/svn/{cl.h,main.c}
# - although it is not a good practice, mixed options and arguments
#   is supported by the completion as it is by the svn command.
# - the completion works in the middle of a line,
#   but not really in the middle of an argument or option.
# - property names are completed: see comments about issues related to handling
#   ":" within property names although it is a word completion separator.
# - unknown properties are assumed to be simple file properties.
# - --revprop and --revision options are forced to revision properties
#   as they are mandatory in this case.
# - argument values are suggested to some other options, eg directory names
#   for --config-dir.
# - values for some options can be extended with environment variables:
#   SVN_BASH_FILE_PROPS: other properties on files/directories
#   SVN_BASH_REV_PROPS: other properties on revisions
#   SVN_BASH_ENCODINGS: encodings to be suggested
#   SVN_BASH_MIME_TYPE: mime types to be suggested
#   SVN_BASH_KEYWORDS: "svn:keywords" substitutions to be suggested
#   SVN_BASH_USERNAME: usernames suggested for --username
#   SVN_BASH_COMPL_EXT: completion extensions for file arguments, based on the
#      current subcommand, so that for instance only modified files are
#      suggested for 'revert', only not svn-managed files for 'add', and so on.
#      Possible values are:
#      - username: guess usernames from ~/.subversion/auth/...
#      - urls: guess urls from ~/.subversion/auth/... or others
#      - svnstatus: use 'svn status' for completion
#      - recurse: allow recursion (expensive)
#      - externals: recurse into externals (very expensive)
#     Former options are reasonable, but beware that both later options
#     may be unadvisable if used on large working copies.
#     None of these costly completions are activated by default.
#     Argument completion outside a working copy results in an error message.
#     Filenames with spaces are not completed properly.
#
# TODO
# - other options?
# - obsolete options could be removed from auto-comp? (e.g. -N)
# - obsolete commands could be removed? (e.g. resolved)
# - completion does not work properly when editing in the middle of the line
#   status/previous are those at the end of the line, not at the entry position
# - url completion should select more cases where it is relevant
# - url completion of http:// schemas could suggest sub directories?
# - add completion for experimental 'obliterate' feature?
_svn()
{
	local cur cmds cmdOpts pOpts mOpts rOpts qOpts nOpts optsParam opt

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

	# Possible expansions, without pure-prefix abbreviations such as "up".
	cmds='add auth blame annotate praise cat changelist cl checkout co cleanup'
	cmds="$cmds commit ci copy cp delete remove rm diff export help import"
	cmds="$cmds info list ls lock log merge mergeinfo mkdir move mv rename"
	cmds="$cmds patch propdel pdel propedit pedit propget pget proplist"
	cmds="$cmds plist propset pset relocate resolve resolved revert status"
	cmds="$cmds switch unlock update upgrade"

	# help options have a strange command status...
	local helpOpts='--help -h'
	# all special options that have a command status
	local specOpts="--version $helpOpts"

	# options that require a parameter
	# note: continued lines must end '|' continuing l                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      