From e517e169842b48b60ca3fe8901d49685bf0a96a6 Mon Sep 17 00:00:00 2001 From: John D Pell Date: Sat, 11 Sep 2021 21:08:30 -0700 Subject: [PATCH] completion/subversion: load system completion Load the completion script from the subversion package installed on the system, instead of bundling a copy. This addresses Bash-it/bash-it#1818. NOTE: If `completions/system` is enabled, then it will load this same file anyway automatically. --- .../available/subversion.completion.bash | 7 + completion/available/svn.completion.bash | 1514 ----------------- 2 files changed, 7 insertions(+), 1514 deletions(-) create mode 100644 completion/available/subversion.completion.bash delete mode 100644 completion/available/svn.completion.bash diff --git a/completion/available/subversion.completion.bash b/completion/available/subversion.completion.bash new file mode 100644 index 0000000000..742a0d22eb --- /dev/null +++ b/completion/available/subversion.completion.bash @@ -0,0 +1,7 @@ +# shellcheck shell=bash + +scm +if test -s "${SVN_EXE%/*}/../etc/bash_completion.d/subversion" +then + source "$_" +fi diff --git a/completion/available/svn.completion.bash b/completion/available/svn.completion.bash deleted file mode 100644 index eabc15c969..0000000000 --- a/completion/available/svn.completion.bash +++ /dev/null @@ -1,1514 +0,0 @@ -# ------------------------------------------------------------ -# 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 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 lines must start '|' - optsParam="-r|--revision|--username|--password|--targets" - optsParam="$optsParam|-x|--extensions|-m|--message|-F|--file" - optsParam="$optsParam|--encoding|--diff-cmd|--diff3-cmd|--editor-cmd" - optsParam="$optsParam|--old|--new|--config-dir|--config-option" - optsParam="$optsParam|--native-eol|-l|--limit|-c|--change" - optsParam="$optsParam|--depth|--set-depth|--with-revprop" - optsParam="$optsParam|--cl|--changelist|--accept|--show-revs" - - # svn:* and other (env SVN_BASH_*_PROPS) properties - local svnProps revProps allProps psCmds propCmds - - # svn and user configured "file" (or directory) properties - # the "svn:mergeinfo" prop is not included by default because it is - # managed automatically, so there should be no need to edit it by hand. - svnProps="svn:keywords svn:executable svn:needs-lock svn:externals - svn:ignore svn:eol-style svn:mime-type $SVN_BASH_FILE_PROPS" - - # svn and user configured revision properties - revProps="svn:author svn:log svn:date $SVN_BASH_REV_PROPS" - - # all properties as an array variable - allProps=( $svnProps $revProps ) - - # subcommands that expect property names - psCmds='propset|pset|ps' - propCmds="$psCmds|propget|pget|pg|propedit|pedit|pe|propdel|pdel|pd" - - # possible URL schemas to access a subversion server - local urlSchemas='file:/// http:// https:// svn:// svn+ssh://' - - # Parse arguments and set various variables about what was found. - # - # cmd: the current command if available - # isPropCmd: whether it expects a property name argument - # isPsCmd: whether it also expects a property value argument - # isHelpCmd: whether it is about help - # nExpectArgs: how many arguments are expected by the command - # help: help requested about this command (if cmd=='help') - # prop: property name (if appropriate) - # isRevProp: is it a special revision property - # val: property value (if appropriate, under pset) - # options: all options encountered - # hasRevPropOpt: is --revprop set - # hasRevisionOpt: is --revision set - # hasRelocateOpt: is --relocate set - # hasReintegrateOpt: is --reintegrate set - # acceptOpt: the value of --accept - # nargs: how many arguments were found - # stat: status of parsing at the 'current' word - # - # prev: previous command in the loop - # last: status of last parameter analyzed - # i: index - local cmd= isPropCmd= isPsCmd= isHelpCmd= nExpectArgs= isCur= i=0 - local prev= help= prop= val= isRevProp= last='none' nargs=0 stat= - local options= hasRevPropOpt= hasRevisionOpt= hasRelocateOpt= - local acceptOpt= URL= hasReintegrateOpt= - - for opt in "${COMP_WORDS[@]}" - do - # get status of current word (from previous iteration) - [[ $isCur ]] && stat=$last - - # are we processing the current word - isCur= - [[ $i -eq $COMP_CWORD ]] && isCur=1 - let i++ - - # FIRST must be the "svn" command - [ $last = 'none' ] && { last='first'; continue ; } - - # SKIP option arguments - if [[ $prev == @($optsParam) ]] ; then - - # record accept value - [[ $prev = '--accept' ]] && acceptOpt=$opt - - prev='' - last='skip' - continue ; - fi - - # Argh... This looks like a bash bug... - # Redirections are passed to the completion function - # although it is managed by the shell directly... - # It matters because we want to tell the user when no more - # completion is available, so it does not necessary - # fallback to the default case. - if [[ $prev == @(<|>|>>|[12]>|[12]>>) ]] ; then - prev='' - last='skip' - continue ; - fi - prev=$opt - - # get the subCoMmanD - if [[ ! $cmd && $opt \ - && ( $opt != -* || $opt == @(${specOpts// /|}) ) ]] - then - cmd=$opt - [[ $cmd == @($propCmds) ]] && isPropCmd=1 - [[ $cmd == @($psCmds) ]] && isPsCmd=1 - [[ $cmd == @(${helpOpts// /|}) ]] && cmd='help' - [[ $cmd = 'help' ]] && isHelpCmd=1 - # HELP about a command asked with an option - if [[ $isHelpCmd && $cmd && $cmd != 'help' && ! $help ]] - then - help=$cmd - cmd='help' - fi - last='cmd' - continue - fi - - # HELP about a command - if [[ $isHelpCmd && ! $help && $opt && $opt != -* ]] - then - help=$opt - last='help' - continue - fi - - # PROPerty name - if [[ $isPropCmd && ! $prop && $opt && $opt != -* ]] - then - prop=$opt - [[ $prop == @(${revProps// /|}) ]] && isRevProp=1 - last='prop' - continue - fi - - # property VALue - if [[ $isPsCmd && $prop && ! $val && $opt != -* ]] ; - then - val=$opt - last='val' - continue - fi - - if [[ $last != 'onlyarg' ]] - then - # more OPTions - case $opt in - -r|--revision|--revision=*) - hasRevisionOpt=1 - ;; - --revprop) - hasRevPropOpt=1 - # restrict to revision properties! - allProps=( $revProps ) - # on revprops, only one URL is expected - nExpectArgs=1 - ;; - -h|--help) - isHelpCmd=1 - ;; - -F|--file) - val='-F' - ;; - --relocate) - hasRelocateOpt=1 - ;; - --reintegrate) - hasReintegrateOpt=1 - ;; - esac - - # no more options, only arguments, whatever they look like. - if [[ $opt = '--' && ! $isCur ]] ; then - last='onlyarg' - continue - fi - - # options are recorded... - if [[ $opt == -* ]] ; then - # but not the current one! - [[ ! $isCur ]] && options="$options $opt " - last='opt' - continue - fi - else - # onlyarg - let nargs++ - continue - fi - - # then we have an argument - if [[ $cmd = 'merge' && ! $URL ]] ; then - # fist argument is the source URL for the merge - URL=$opt - fi - - last='arg' - let nargs++ - done - # end opt option processing... - [[ $stat ]] || stat=$last - - # suggest all subcommands, including special help - if [[ ! $cmd || $stat = 'cmd' ]] - then - COMPREPLY=( $( compgen -W "$cmds $specOpts" -- $cur ) ) - return 0 - fi - - # suggest all subcommands - if [[ $stat = 'help' || ( $isHelpCmd && ! $help ) ]] - then - COMPREPLY=( $( compgen -W "$cmds" -- $cur ) ) - return 0 - fi - - # URL completion - if [[ $cmd == @(co|checkout|ls|list) && $stat = 'arg' && \ - $SVN_BASH_COMPL_EXT == *urls* ]] - then - # see about COMP_WORDBREAKS workaround in prop completion - if [[ $cur == file:* ]] - then - # file completion for file:// urls - local where=${cur/file:/} - COMPREPLY=( $(compgen -d -S '/' -X '*/.*' -- $where ) ) - return - elif [[ $cur == *:* ]] - then - # get known urls - local urls= file= - for file in ~/.subversion/auth/svn.simple/* ; do - if [ -r $file ] ; then - local url=$(_svn_read_hashfile svn:realmstring < $file) - url=${url/**/} - urls="$urls $url" - fi - done - - # only suggest/show possible suffixes - local prefix=${cur%:*} suffix=${cur#*:} c= choices= - for c in $urls ; do - [[ $c == $prefix:* ]] && choices="$choices ${c#*:}" - done - - COMPREPLY=( $(compgen -W "$choices" -- $suffix ) ) - return - else - # show schemas - COMPREPLY=( $(compgen -W "$urlSchemas" -- $cur) ) - return - fi - fi - - if [[ $cmd = 'merge' || $cmd = 'mergeinfo' ]] - then - local here=$(_svn_info URL) - # suggest a possible URL for merging - if [[ ! $URL && $stat = 'arg' ]] ; then - # we assume a 'standard' repos with branches and trunk - if [[ "$here" == */branches/* ]] ; then - # we guess that it is a merge from the trunk - COMPREPLY=( $(compgen -W ${here/\/branches\/*/\/trunk} -- $cur ) ) - return 0 - elif [[ "$here" == */trunk* ]] ; then - # we guess that it is a merge from a branch - COMPREPLY=( $(compgen -W ${here/\/trunk*/\/branches\/} -- $cur ) ) - return 0 - else - # no se, let us suggest the repository root... - COMPREPLY=( $(compgen -W $(_svn_info Root) -- $cur ) ) - return 0 - fi - elif [[ $URL == */branches/* && $here == */trunk* && \ - ! $hasReintegrateOpt && $cur = '' && $stat = 'arg' ]] ; then - # force --reintegrate only if the current word is empty - COMPREPLY=( $(compgen -W '--reintegrate' -- $cur ) ) - return 0 - fi - fi - - # help about option arguments - if [[ $stat = 'skip' ]] - then - local previous=${COMP_WORDS[COMP_CWORD-1]} - local values= dirs= beep= exes= - - [[ $previous = '--config-dir' ]] && dirs=1 - - # external editor, diff, diff3... - [[ $previous = --*-cmd ]] && exes=1 - - [[ $previous = '--native-eol' ]] && values='LF CR CRLF' - - # just to suggest that a number is expected. hummm. - [[ $previous = '--limit' ]] && values='0 1 2 3 4 5 6 7 8 9' - - # some special partial help about --revision option. - [[ $previous = '--revision' || $previous = '-r' ]] && \ - values='HEAD BASE PREV COMMITTED 0 {' - - [[ $previous = '--encoding' ]] && \ - values="latin1 utf8 $SVN_BASH_ENCODINGS" - - [[ $previous = '--extensions' || $previous = '-x' ]] && \ - values="--unified --ignore-space-change \ - --ignore-all-space --ignore-eol-style --show-c-functions" - - [[ $previous = '--depth' ]] && \ - values='empty files immediates infinity' - - [[ $previous = '--set-depth' ]] && \ - values='empty exclude files immediates infinity' - - [[ $previous = '--accept' ]] && \ - { - # the list is different for 'resolve' - if [[ $cmd = 'resolve' ]] ; then - # from svn help resolve - values='base working mine-full theirs-full' - else # checkout merge switch update - values="postpone base mine-full theirs-full edit launch \ - mine-conflict theirs-conflict" - fi - } - - [[ $previous = '--show-revs' ]] && values='merged eligible' - - if [[ $previous = '--username' ]] ; then - values="$SVN_BASH_USERNAME" - if [[ $SVN_BASH_COMPL_EXT == *username* ]] ; then - local file= - # digest? others? - for file in ~/.subversion/auth/svn.simple/* ; do - if [ -r $file ] ; then - values="$values $(_svn_read_hashfile username < $file)" - fi - done - fi - [[ ! "$values" ]] && beep=1 - fi - - # could look at ~/.subversion/ ? - # hmmm... this option should not exist - [[ $previous = '--password' ]] && beep=1 - - # TODO: provide help about other options such as: - # --old --new --with-revprop - - # if the previous option required a parameter, do something - # or fallback on ordinary filename expansion - [[ $values ]] && COMPREPLY=( $( compgen -W "$values" -- $cur ) ) - [[ $dirs ]] && COMPREPLY=( $( compgen -o dirnames -- $cur ) ) - [[ $exes ]] && COMPREPLY=( $( compgen -c -- $cur ) ) - [[ $beep ]] && - { - # 'no known completion'. hummm. - echo -en "\a" - COMPREPLY=( '' ) - } - return 0 - fi - - # provide allowed property names after property commands - if [[ $isPropCmd && ( ! $prop || $stat = 'prop' ) && $cur != -* ]] - then - # - # Ok, this part is pretty ugly. - # - # The issue is that ":" is a completion word separator, - # which is a good idea for file:// urls but not within - # property names... - # - # The first idea was to remove locally ":" from COMP_WORDBREAKS - # and then put it back in all cases but in property name - # completion. It does not always work. There is a strange bug - # where one may get "svn:svn:xxx" in some unclear cases. - # - # Thus the handling is reprogrammed here... - # The code assumes that property names look like *:*, - # but it also works reasonably well with simple names. - # - # This hack is broken in bash4... not sure what to do about it, - # especially while keeping the bash3 compatibility:-( - local choices= - - if [[ $cur == *:* ]] - then - # only suggest/show possible suffixes - local prefix=${cur%:*} suffix=${cur#*:} c= - for c in ${allProps[@]} ; do - [[ $c == $prefix:* ]] && choices="$choices ${c#*:}" - done - # everything will be appended to the prefix because ':' is - # a separator, so cur is restricted to the suffix part. - cur=$suffix - else - # only one choice is fine - COMPREPLY=( $( compgen -W "${allProps[*]}" -- $cur ) ) - [ ${#COMPREPLY[@]} -eq 1 ] && return 0 - - # no ':' so only suggest prefixes? - local seen= n=0 last= c= - for c in ${allProps[@]%:*} ; do - # do not put the same prefix twice... - if [[ $c == $cur* && ( ! $seen || $c != @($seen) ) ]] - then - let n++ - last=$c - choices="$choices $c:" - if [[ $seen ]] - then - seen="$seen|$c*" - else - seen="$c*" - fi - fi - done - - # supply two choices to force a partial completion and a beep - [[ $n -eq 1 ]] && choices="$last:1 $last:2" - fi - - COMPREPLY=( $( compgen -W "$choices" -- $cur ) ) - return 0 - fi - - # force mandatory --revprop option on revision properties - if [[ $isRevProp && ! $hasRevPropOpt ]] - then - COMPREPLY=( $( compgen -W '--revprop' -- $cur ) ) - return 0 - fi - - # force mandatory --revision option on revision properties - if [[ $isRevProp && $hasRevPropOpt && ! $hasRevisionOpt ]] - then - COMPREPLY=( $( compgen -W '--revision' -- $cur ) ) - return 0 - fi - - # possible completion when setting property values - if [[ $isPsCmd && $prop && ( ! $val || $stat = 'val' ) ]] - then - # ' is a reminder for an arbitrary value - local values="\' --file" - case $prop in - svn:keywords) - # just a subset? - values="Id Rev URL Date Author Header \' $SVN_BASH_KEYWORDS" - ;; - svn:executable|svn:needs-lock) - # hmmm... canonical value * is special to the shell. - values='\\*' - ;; - svn:eol-style) - values='native LF CR CRLF' - ;; - svn:mime-type) - # could read /etc/mime.types if available. overkill. - values="text/ text/plain text/html text/xml text/rtf - image/ image/png image/gif image/jpeg image/tiff - audio/ audio/midi audio/mpeg - video/ video/mpeg video/mp4 - application/ application/octet-stream - $SVN_BASH_MIME_TYPE" - ;; - esac - - COMPREPLY=( $( compgen -W "$values" -- $cur ) ) - # special case for --file... return even if within an option - [[ ${COMPREPLY} ]] && return 0 - fi - - # maximum number of additional arguments expected in various forms - case $cmd in - merge) - nExpectArgs=3 - ;; - mergeinfo) - nExpectArgs=1 - ;; - copy|cp|move|mv|rename|ren|export|import) - nExpectArgs=2 - ;; - switch|sw) - [[ ! $hasRelocateOpt ]] && nExpectArgs=2 - ;; - help|h) - nExpectArgs=0 - ;; - --version) - nExpectArgs=0 - ;; - esac - - # the maximum number of arguments is reached for a command - if [[ $nExpectArgs && $nargs -gt $nExpectArgs ]] - then - # some way to tell 'no completion at all'... is there a better one? - # Do not say 'file completion' here. - echo -en "\a" - COMPREPLY=( '' ) - return 0 - fi - - # if not typing an option, - # then fallback on filename expansion... - if [[ $cur != -* || $stat = 'onlyarg' ]] ; then - - # do we allow possible expensive completion here? - if [[ $SVN_BASH_COMPL_EXT == *svnstatus* ]] ; then - - # build status command and options - # "--quiet" removes 'unknown' files - local status='svn status --non-interactive' - - [[ $SVN_BASH_COMPL_EXT == *recurse* ]] || \ - status="$status --non-recursive" - - # I'm not sure that it can work with externals in call cases - # the output contains translatable sentences (even with quiet) - [[ $SVN_BASH_COMPL_EXT == *externals* ]] || \ - status="$status --ignore-externals" - - local cs= files= - # subtlety: must not set $cur* if $cur is empty in some cases - [[ $cur ]] && cs=$cur* - - # 'files' is set according to the current subcommand - case $cmd in - st*) # status completion must include all files - files=$cur* - ;; - ci|commit|revert|di*) # anything edited - files=$($status $cs| _svn_grcut '@([MADR!]*| M*|_M*)') - ;; - add) # unknown files - files=$($status $cs| _svn_grcut '\?*') - ;; - unlock) # unlock locked files - files=$($status $cs| _svn_grcut '@(??L*|?????[KOTB]*)') - ;; - resolve*) # files in conflict - files=$($status $cs| _svn_grcut '@(?C*|C*)') - ;; - praise|blame|ann*) # any svn file but added - files=$( _svn_lls all $cur* ) - ;; - p*) # prop commands - if [[ $cmd == @($propCmds) && \ - $prop == @(svn:ignore|svn:externals) ]] ; then - # directory specific props - files=$( _svn_lls dir . $cur* ) - else - # ??? added directories appear twice: foo foo/ - files="$( _svn_lls all $cur* ) - $($status $cs | _svn_grcut 'A*' )" - fi - ;; - info) # information on any file - files="$( _svn_lls all $cur* ) - $($status $cs | _svn_grcut 'A*' )" - ;; - remove|rm|del*|move|mv|rename) # changing existing files - files=$( _svn_lls all $cur* ) - ;; - mkdir) # completion in mkdir can only be for subdirs? - files=$( _svn_lls dir $cur* ) - ;; - log|lock|up*|cl*|switch) # misc, all but added files - files=$( _svn_lls all $cur* ) - ;; - merge) # may do a better job? URL/WCPATH - files=$( _svn_lls all $cur* ) - ;; - ls|list) # better job? what about URLs? - files=$( _svn_lls all $cur* ) - ;; - *) # other commands: changelist export import cat mergeinfo - local fallback=1 - ;; - esac - - # when not recursive, some relevant files may exist - # within subdirectories, so they are added here. - # should it be restricted to svn-managed subdirs? no?? - if [[ $SVN_BASH_COMPL_EXT != *recurse* ]] ; then - files="$files $( _svn_lls dir $cur* )" - fi - - # set completion depending on computed 'files' - if [[ $files ]] ; then - COMPREPLY=( $( compgen -W "$files" -- $cur ) ) - # if empty, set to nope? - [[ "${COMPREPLY[*]}" ]] || COMPREPLY=( '' ) - elif [[ ! $fallback ]] ; then - # this suggests no completion... - echo -en "\a" - COMPREPLY=( '' ) - fi - fi - # else fallback to ordinary filename completion... - return 0 - fi - - # otherwise build possible options for the command - pOpts="--username --password --no-auth-cache --non-interactive \ - --trust-server-cert --force-interactive" - mOpts="-m --message -F --file --encoding --force-log --with-revprop" - rOpts="-r --revision" - qOpts="-q --quiet" - nOpts="-N --non-recursive --depth" - gOpts="-g --use-merge-history" - cOpts="--cl --changelist" - - cmdOpts= - case $cmd in - --version) - cmdOpts="$qOpts" - ;; - add) - cmdOpts="--auto-props --no-auto-props --force --targets \ - --no-ignore --parents $nOpts $qOpts $pOpts" - ;; - blame|annotate|ann|praise) - cmdOpts="$rOpts $pOpts -v --verbose --incremental --xml \ - -x --extensions --force $gOpts" - ;; - cat) - cmdOpts="$rOpts $pOpts" - ;; - changelist|cl) - cmdOpts="--targets $pOpts $qOpts $cOpts \ - -R --recursive --depth --remove" - ;; - checkout|co) - cmdOpts="$rOpts $qOpts $nOpts $pOpts --ignore-externals \ - --force" - ;; - cleanup) - cmdOpts="--diff3-cmd $pOpts" - ;; - commit|ci) - cmdOpts="$mOpts $qOpts $nOpts --targets --editor-cmd $pOpts \ - --no-unlock $cOpts --keep-changelists \ - --include-externals" - ;; - copy|cp) - cmdOpts="$mOpts $rOpts $qOpts --editor-cmd $pOpts --parents \ - --ignore-externals" - ;; - delete|del|remove|rm) - cmdOpts="--force $mOpts $qOpts --targets --editor-cmd $pOpts \ - --keep-local" - ;; - diff|di) - cmdOpts="$rOpts -x --extensions --diff-cmd --no-diff-deleted \ - $nOpts $pOpts --force --old --new --notice-ancestry \ - -c --change --summarize $cOpts --xml --git \ - --internal-diff --show-copies-as-adds \ - --ignore-properties --properties-only --no-diff-added \ - --patch-compatible" - ;; - export) - cmdOpts="$rOpts $qOpts $pOpts $nOpts --force --native-eol \ - --ignore-externals --ignore-keywords" - ;; - help|h|\?) - cmdOpts= - ;; - import) - cmdOpts="--auto-props --no-auto-props $mOpts $qOpts $nOpts \ - --no-ignore --editor-cmd $pOpts --force" - ;; - info) - cmdOpts="$pOpts $rOpts --targets -R --recursive --depth \ - --incremental --xml $cOpts" - ;; - list|ls) - cmdOpts="$rOpts -v --verbose -R --recursive $pOpts \ - --incremental --xml --depth --include-externals" - ;; - lock) - cmdOpts="-m --message -F --file --encoding --force-log \ - --targets --force $pOpts" - ;; - log) - cmdOpts="$rOpts -v --verbose --targets $pOpts --stop-on-copy \ - --incremental --xml $qOpts -l --limit -c --change \ - $gOpts --with-all-revprops --with-revprop --depth \ - --diff --diff-cmd -x --extensions --internal-diff \ - --with-no-revprops --search --search-and" - ;; - merge) - cmdOpts="$rOpts $nOpts $qOpts --force --dry-run --diff3-cmd \ - $pOpts --ignore-ancestry -c --change -x --extensions \ - --record-only --accept --reintegrate \ - --allow-mixed-revisions -v --verbose" - ;; - mergeinfo) - cmdOpts="$rOpts $pOpts --depth --show-revs -R --recursive" - ;; - mkdir) - cmdOpts="$mOpts $qOpts --editor-cmd $pOpts --parents" - ;; - move|mv|rename|ren) - cmdOpts="$mOpts $rOpts $qOpts --force --editor-cmd $pOpts \ - --parents --allow-mixed-revisions" - ;; - patch) - cmdOpts="$qOpts $pOpts --dry-run --ignore-whitespace \ - --reverse-diff --strip" - ;; - propdel|pdel|pd) - cmdOpts="$qOpts -R --recursive $rOpts $pOpts $cOpts \ - --depth" - [[ $isRevProp || ! $prop ]] && cmdOpts="$cmdOpts --revprop" - ;; - propedit|pedit|pe) - cmdOpts="--editor-cmd $pOpts $mOpts --force" - [[ $isRevProp || ! $prop ]] && \ - cmdOpts="$cmdOpts --revprop $rOpts" - ;; - propget|pget|pg) - cmdOpts="-v --verbose -R --recursive $rOpts --strict \ - $pOpts $cOpts --depth --xml --show-inherited-props" - [[ $isRevProp || ! $prop ]] && cmdOpts="$cmdOpts --revprop" - ;; - proplist|plist|pl) - cmdOpts="-v --verbose -R --recursive $rOpts --revprop $qOpts \ - $pOpts $cOpts --depth --xml --show-inherited-props" - ;; - propset|pset|ps) - cmdOpts="$qOpts --targets -R --recursive \ - --encoding $pOpts --force $cOpts --depth" - [[ $isRevProp || ! $prop ]] && \ - cmdOpts="$cmdOpts --revprop $rOpts" - [[ $val ]] || cmdOpts="$cmdOpts -F --file" - ;; - relocate) - cmdOpts="--ignore-externals $pOpts" - ;; - resolve) - cmdOpts="--targets -R --recursive $qOpts $pOpts --accept \ - --depth" - ;; - resolved) - cmdOpts="--targets -R --recursive $qOpts $pOpts --depth" - ;; - revert) - cmdOpts="--targets -R --recursive $qOpts $cOpts \ - --depth $pOpts" - ;; - status|stat|st) - cmdOpts="-u --show-updates -v --verbose $nOpts $qOpts $pOpts \ - --no-ignore --ignore-externals --incremental --xml \ - $cOpts" - ;; - switch|sw) - cmdOpts="--relocate $rOpts $nOpts $qOpts $pOpts --diff3-cmd \ - --force --accept --ignore-externals --set-depth \ - --ignore-ancestry" - ;; - unlock) - cmdOpts="--targets --force $pOpts" - ;; - update|up) - cmdOpts="$rOpts $nOpts $qOpts $pOpts --diff3-cmd \ - --ignore-externals --force --accept $cOpts \ - --parents --editor-cmd --set-depth" - ;; - upgrade) - cmdOpts="$qOpts $pOpts" - ;; - *) - ;; - esac - - # add options that are nearly always available - [[ "$cmd" != "--version" ]] && cmdOpts="$cmdOpts $helpOpts" - cmdOpts="$cmdOpts --config-dir --config-option" - - # --accept (edit|launch) incompatible with --non-interactive - if [[ $acceptOpt == @(edit|launch) ]] ; - then - cmdOpts=${cmdOpts/ --non-interactive / } - fi - - # take out options already given - for opt in $options - do - local optBase - - # remove leading dashes and arguments - case $opt in - --*) optBase=${opt/=*/} ;; - -*) optBase=${opt:0:2} ;; - esac - - cmdOpts=" $cmdOpts " - cmdOpts=${cmdOpts/ ${optBase} / } - - # take out alternatives and mutually exclusives - case $optBase in - -v) cmdOpts=${cmdOpts/ --verbose / } ;; - --verbose) cmdOpts=${cmdOpts/ -v / } ;; - -N) cmdOpts=${cmdOpts/ --non-recursive / } ;; - --non-recursive) cmdOpts=${cmdOpts/ -N / } ;; - -R) cmdOpts=${cmdOpts/ --recursive / } ;; - --recursive) cmdOpts=${cmdOpts/ -R / } ;; - -x) cmdOpts=${cmdOpts/ --extensions / } ;; - --extensions) cmdOpts=${cmdOpts/ -x / } ;; - -q) cmdOpts=${cmdOpts/ --quiet / } ;; - --quiet) cmdOpts=${cmdOpts/ -q / } ;; - -h) cmdOpts=${cmdOpts/ --help / } ;; - --help) cmdOpts=${cmdOpts/ -h / } ;; - -l) cmdOpts=${cmdOpts/ --limit / } ;; - --limit) cmdOpts=${cmdOpts/ -l / } ;; - -r) cmdOpts=${cmdOpts/ --revision / } ;; - --revision) cmdOpts=${cmdOpts/ -r / } ;; - -c) cmdOpts=${cmdOpts/ --change / } ;; - --change) cmdOpts=${cmdOpts/ -c / } ;; - --auto-props) cmdOpts=${cmdOpts/ --no-auto-props / } ;; - --no-auto-props) cmdOpts=${cmdOpts/ --auto-props / } ;; - -g) cmdOpts=${cmdOpts/ --use-merge-history / } ;; - --use-merge-history) - cmdOpts=${cmdOpts/ -g / } ;; - -m|--message|-F|--file) - cmdOpts=${cmdOpts/ --message / } - cmdOpts=${cmdOpts/ -m / } - cmdOpts=${cmdOpts/ --file / } - cmdOpts=${cmdOpts/ -F / } - ;; - esac - - # remove help options within help subcommand - if [ $isHelpCmd ] ; then - cmdOpts=${cmdOpts/ -h / } - cmdOpts=${cmdOpts/ --help / } - fi - done - - # provide help about available options - COMPREPLY=( $( compgen -W "$cmdOpts" -- $cur ) ) - return 0 -} -complete -F _svn -o default -X '@(*/.svn|*/.svn/|.svn|.svn/)' svn - -_svnadmin () -{ - local cur cmds cmdOpts optsParam opt helpCmds optBase i - - COMPREPLY=() - cur=${COMP_WORDS[COMP_CWORD]} - - # Possible expansions, without pure-prefix abbreviations such as "h". - cmds='crashtest create deltify dump freeze help hotcopy list-dblogs \ - list-unused-dblogs load lock lslocks lstxns pack recover rmlocks \ - rmtxns setlog setrevprop setuuid unlock upgrade verify --version' - - if [[ $COMP_CWORD -eq 1 ]] ; then - COMPREPLY=( $( compgen -W "$cmds" -- $cur ) ) - return 0 - fi - - # options that require a parameter - # note: continued lines must end '|' continuing lines must start '|' - optsParam="-r|--revision|--parent-dir|--fs-type|-M|--memory-cache-size" - optsParam="$optsParam|-F|--file" - - # if not typing an option, or if the previous option required a - # parameter, then fallback on ordinary filename expansion - helpCmds='help|--help|h|\?' - if [[ ${COMP_WORDS[1]} != @($helpCmds) ]] && \ - [[ "$cur" != -* ]] || \ - [[ ${COMP_WORDS[COMP_CWORD-1]} == @($optsParam) ]] ; then - return 0 - fi - - cmdOpts= - case ${COMP_WORDS[1]} in - create) - cmdOpts="--bdb-txn-nosync --bdb-log-keep --config-dir \ - --fs-type --pre-1.4-compatible --pre-1.5-compatible \ - --pre-1.6-compatible --compatible-version" - ;; - deltify) - cmdOpts="-r --revision -q --quiet" - ;; - dump) - cmdOpts="-r --revision --incremental -q --quiet --deltas \ - -M --memory-cache-size" - ;; - freeze) - cmdOpts="-F --file" - ;; - help|h|\?) - cmdOpts="$cmds" - ;; - hotcopy) - cmdOpts="--clean-logs" - ;; - load) - cmdOpts="--ignore-uuid --force-uuid --parent-dir -q --quiet \ - --use-pre-commit-hook --use-post-commit-hook \ - --bypass-prop-validation -M --memory-cache-size" - ;; - lock|unlock) - cmdOpts="--bypass-hooks" - ;; - recover) - cmdOpts="--wait" - ;; - rmtxns) - cmdOpts="-q --quiet" - ;; - setlog) - cmdOpts="-r --revision --bypass-hooks" - ;; - setrevprop) - cmdOpts="-r --revision --use-pre-revprop-change-hook \ - --use-post-revprop-change-hook" - ;; - verify) - cmdOpts="-r --revision -q --quiet" - ;; - *) - ;; - esac - - cmdOpts="$cmdOpts --help -h" - - # take out options already given - for (( i=2; i<=$COMP_CWORD-1; ++i )) ; do - opt=${COMP_WORDS[$i]} - - case $opt in - --*) optBase=${opt/=*/} ;; - -*) optBase=${opt:0:2} ;; - esac - - cmdOpts=" $cmdOpts " - cmdOpts=${cmdOpts/ ${optBase} / } - - # take out alternatives - case $optBase in - -q) cmdOpts=${cmdOpts/ --quiet / } ;; - --quiet) cmdOpts=${cmdOpts/ -q / } ;; - -h) cmdOpts=${cmdOpts/ --help / } ;; - --help) cmdOpts=${cmdOpts/ -h / } ;; - -r) cmdOpts=${cmdOpts/ --revision / } ;; - --revision) cmdOpts=${cmdOpts/ -r / } ;; - -F) cmdOpts=${cmdOpts/ --file / } ;; - --file) cmdOpts=${cmdOpts/ -F / } ;; - -M) cmdOpts=${cmdOpts/ --memory-cache-size / } ;; - --memory-cache-size) cmdOpts=${cmdOpts/ --M / } ;; - 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 _svnadmin -o default svnadmin - -_svndumpfilter () -{ - local cur cmds cmdOpts optsParam opt helpCmds optBase i - - COMPREPLY=() - cur=${COMP_WORDS[COMP_CWORD]} - - # Possible expansions, without pure-prefix abbreviations such as "h". - cmds='exclude help include --version' - - if [[ $COMP_CWORD -eq 1 ]] ; then - COMPREPLY=( $( compgen -W "$cmds" -- $cur ) ) - return 0 - fi - - # options that require a parameter - # note: continued lines must end '|' continuing lines must start '|' - optsParam="--targets" - - # if not typing an option, or if the previous option required a - # parameter, then fallback on ordinary filename expansion - helpCmds='help|--help|h|\?' - if [[ ${COMP_WORDS[1]} != @($helpCmds) ]] && \ - [[ "$cur" != -* ]] || \ - [[ ${COMP_WORDS[COMP_CWORD-1]} == @($optsParam) ]] ; then - return 0 - fi - - cmdOpts= - case ${COMP_WORDS[1]} in - exclude|include) - cmdOpts="--drop-empty-revs --renumber-revs - --skip-missing-merge-sources --targets - --preserve-revprops --quiet" - ;; - help|h|\?) - cmdOpts="$cmds" - ;; - *) - ;; - esac - - cmdOpts="$cmdOpts --help -h" - - # take out options already given - for (( i=2; i<=$COMP_CWORD-1; ++i )) ; do - opt=${COMP_WORDS[$i]} - - case $opt in - --*) optBase=${opt/=*/} ;; - -*) optBase=${opt:0:2} ;; - esac - - cmdOpts=" $cmdOpts " - cmdOpts=${cmdOpts/ ${optBase} / } - - # take out alternatives - case $optBase in - -h) cmdOpts=${cmdOpts/ --help / } ;; - --help) cmdOpts=${cmdOpts/ -h / } ;; - 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 _svndumpfilter -o default svndumpfilter - -_svnlook () -{ - local cur cmds cmdOpts optsParam opt helpCmds optBase i - - COMPREPLY=() - cur=${COMP_WORDS[COMP_CWORD]} - - # Possible expansions, without pure-prefix abbreviations such as "h". - cmds='author cat changed date diff dirs-changed help history info \ - lock log propget proplist tree uuid youngest --version' - - if [[ $COMP_CWORD -eq 1 ]] ; then - COMPREPLY=( $( compgen -W "$cmds" -- $cur ) ) - return 0 - fi - - # options that require a parameter - # note: continued lines must end '|' continuing lines must start '|' - optsParam="-r|--revision|-t|--transaction|-l|--limit|-x|--extensions" - - # if not typing an option, or if the previous option required a - # parameter, then fallback on ordinary filename expansion - helpCmds='help|--help|h|\?' - if [[ ${COMP_WORDS[1]} != @($helpCmds) ]] && \ - [[ "$cur" != -* ]] || \ - [[ ${COMP_WORDS[COMP_CWORD-1]} == @($optsParam) ]] ; then - return 0 - fi - - cmdOpts= - case ${COMP_WORDS[1]} in - author) - cmdOpts="-r --revision -t --transaction" - ;; - cat) - cmdOpts="-r --revision -t --transaction" - ;; - changed) - cmdOpts="-r --revision -t --transaction --copy-info" - ;; - date) - cmdOpts="-r --revision -t --transaction" - ;; - diff) - cmdOpts="-r --revision -t --transaction --diff-copy-from \ - --no-diff-added --no-diff-deleted -x --extensions" - ;; - dirs-changed) - cmdOpts="-r --revision -t --transaction" - ;; - help|h|\?) - cmdOpts="$cmds" - ;; - history) - cmdOpts="-r --revision -l --limit --show-ids" - ;; - info) - cmdOpts="-r --revision -t --transaction" - ;; - lock) - cmdOpts= - ;; - log) - cmdOpts="-r --revision -t --transaction" - ;; - propget|pget|pg) - cmdOpts="-r --revision -t --transaction --revprop" - ;; - proplist|plist|pl) - cmdOpts="-r --revision -t --transaction --revprop -v --verbose --xml" - ;; - tree) - cmdOpts="-r --revision -t --transaction --full-paths -N --non-recursive --show-ids" - ;; - uuid) - cmdOpts= - ;; - youngest) - cmdOpts= - ;; - *) - ;; - esac - - cmdOpts="$cmdOpts --help -h" - - # take out options already given - for (( i=2; i<=$COMP_CWORD-1; ++i )) ; do - opt=${COMP_WORDS[$i]} - - case $opt in - --*) optBase=${opt/=*/} ;; - -*) optBase=${opt:0:2} ;; - esac - - cmdOpts=" $cmdOpts " - cmdOpts=${cmdOpts/ ${optBase} / } - - # take out alternatives - case $optBase in - -N) cmdOpts=${cmdOpts/ --non-recursive / } ;; - --non-recursive) cmdOpts=${cmdOpts/ -N / } ;; - -h) cmdOpts=${cmdOpts/ --help / } ;; - --help) cmdOpts=${cmdOpts/ -h / } ;; - -l) cmdOpts=${cmdOpts/ --limit / } ;; - --limit) cmdOpts=${cmdOpts/ -l / } ;; - -r) cmdOpts=${cmdOpts/ --revision / } ;; - --revision) cmdOpts=${cmdOpts/ -r / } ;; - -t) cmdOpts=${cmdOpts/ --transaction / } ;; - --transaction) cmdOpts=${cmdOpts/ -t / } ;; - -v) cmdOpts=${cmdOpts/ --verbose / } ;; - --verbose) cmdOpts=${cmdOpts/ -v / } ;; - -x) cmdOpts=${cmdOpts/ --extensions / } ;; - --extensions) cmdOpts=${cmdOpts/ -x / } ;; - 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 _svnlook -o default svnlook - -_svnsync () -{ - local cur cmds cmdOpts optsParam opt helpCmds optBase i - - COMPREPLY=() - cur=${COMP_WORDS[COMP_CWORD]} - - # Possible expansions, without pure-prefix abbreviations such as "h". - cmds='copy-revprops help info initialize synchronize --version' - - if [[ $COMP_CWORD -eq 1 ]] ; then - COMPREPLY=( $( compgen -W "$cmds" -- $cur ) ) - return 0 - fi - - # options that require a parameter - # note: continued lines must end '|' continuing lines must start '|' - optsParam="--config-dir|--config-option|--source-username|--source-password" - optsParam="$optsParam|--sync-username|--sync-password" - - # if not typing an option, or if the previous option required a - # parameter, then fallback on ordinary filename expansion - helpCmds='help|--help|h|\?' - if [[ ${COMP_WORDS[1]} != @($helpCmds) ]] && \ - [[ "$cur" != -* ]] || \ - [[ ${COMP_WORDS[COMP_CWORD-1]} == @($optsParam) ]] ; then - return 0 - fi - - cmdOpts= - case ${COMP_WORDS[1]} in - copy-revprops|initialize|init|synchronize|sync) - cmdOpts="--non-interactive --no-auth-cache --trust-server-cert \ - --source-username --source-password --sync-username \ - --sync-password --config-dir --config-option -q --quiet" - ;; - help|h|\?) - cmdOpts="$cmds" - ;; - info) - cmdOpts="--non-interactive --no-auth-cache --trust-server-cert \ - --source-username --source-password --sync-username \ - --sync-password --config-dir --config-option" - ;; - *) - ;; - esac - - cmdOpts="$cmdOpts --help -h" - - # take out options already given - for (( i=2; i<=$COMP_CWORD-1; ++i )) ; do - opt=${COMP_WORDS[$i]} - - case $opt in - --*) optBase=${opt/=*/} ;; - -*) optBase=${opt:0:2} ;; - esac - - cmdOpts=" $cmdOpts " - cmdOpts=${cmdOpts/ ${optBase} / } - - # take out alternatives - case $optBase in - -h) cmdOpts=${cmdOpts/ --help / } ;; - --help) cmdOpts=${cmdOpts/ -h / } ;; - -q) cmdOpts=${cmdOpts/ --quiet / } ;; - --quiet) cmdOpts=${cmdOpts/ -q / } ;; - 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 _svnsync -o default svnsync - -# reasonable completion for 'svnversion' -_svnversion () -{ - local cmdOpts=" -n --no-newline -c --committed -h --help --version " - local cur=${COMP_WORDS[COMP_CWORD]} - - COMPREPLY=() - - # parse current options - local options= wcpath= trailurl= last='none' stat= opt= i=-1 isCur= - for opt in ${COMP_WORDS[@]} - do - [[ $i -eq $COMP_CWORD ]] && stat=$last - let i++ - - # are we processing the current word? - isCur= - [[ $i -eq $COMP_CWORD ]] && isCur=1 - - # skip first command, should be 'svnversion' - if [ $last = 'none' ] ; then - last='first' - continue - fi - - # get options - if [[ $last != 'arg' && $opt == -* ]] - then - # if '--' is at the current position, it means that we are looking - # for '--*' options, and not the end of option processing. - if [[ $opt = '--' && ! $isCur ]] - then - last='arg' - else - options="$options $opt " - last='opt' - fi - continue - fi - # get arguments - if [[ $opt != -* ]] - then - last='arg' - if [[ ! $wcpath ]] - then - wcpath=$opt - elif [[ ! $trailurl ]] - then - trailurl=$opt - fi - fi - done - [[ $stat ]] || stat=$last - - # argument part - if [[ $cur != -* || $stat = 'arg' ]] - then - [[ $wcpath && $trailurl ]] && COMPREPLY=( '' ) - return 0 - fi - - # suggest options, and take out already given options - for opt in $options - do - # take out options - cmdOpts=${cmdOpts/ $opt / } - - # take out alternatives - case $opt in - -n) cmdOpts=${cmdOpts/ --no-newline / } ;; - --no-newline) cmdOpts=${cmdOpts/ -n / } ;; - -h) cmdOpts=${cmdOpts/ --help / } ;; - --help) cmdOpts=${cmdOpts/ -h / } ;; - -c) cmdOpts=${cmdOpts/ --committed / } ;; - --committed) cmdOpts=${cmdOpts/ -c / } ;; - esac - done - - COMPREPLY=( $( compgen -W "$cmdOpts" -- $cur ) ) - - return 0 -} -# -X option does not seem to work? -complete -F _svnversion -o dirnames -X '*.svn*' svnversion