# cvs(1) completion have cvs && { set_prefix() { [ -z ${prefix:-} ] || prefix=${cur%/*}/ [ -r ${prefix:-}CVS/Entries ] || prefix="" } get_entries() { local IFS=$'\n' [ -r ${prefix:-}CVS/Entries ] && \ entries=$(cut -d/ -f2 -s ${prefix:-}CVS/Entries) } get_modules() { if [ -n "$prefix" ]; then COMPREPLY=( $( command ls -d ${cvsroot}/${prefix}/!(CVSROOT) ) ) else COMPREPLY=( $( command ls -d ${cvsroot}/!(CVSROOT) ) ) fi } _cvs_commands() { cvs --help-commands 2>&1 | awk '/^( *|\t)/ { print $1 }' } _cvs_options() { cvs --help-options 2>&1 | awk '/^( *|\t)-/ { print $1 }' } _cvs_command_options() { cvs --help $1 2>&1 | sed -ne 's/^[[:space:]]*\(-[^[:space:]=[]*\).*/\1/p' } _cvs_kflags() { COMPREPLY=( $( compgen -W 'kv kvl k o b v' -- "$cur" ) ) } _cvs_roots() { local -a cvsroots cvsroots=( $CVSROOT ) [ -r ~/.cvspass ] && \ cvsroots=( "${cvsroots[@]}" $( awk '{ print $2 }' ~/.cvspass ) ) [ -r CVS/Root ] && cvsroots=( "${cvsroots[@]}" $(cat CVS/Root) ) COMPREPLY=( $( compgen -W '${cvsroots[@]}' -- "$cur" ) ) __ltrim_colon_completions "$cur" } _cvs() { local cur prev count mode i cvsroot cvsroots pwd local -a flags miss files entries changed newremoved COMPREPLY=() _get_comp_words_by_ref -n : cur prev count=0 for i in "${COMP_WORDS[@]}"; do [ $count -eq $COMP_CWORD ] && break # Last parameter was the CVSROOT, now go back to mode selection if [[ "${COMP_WORDS[((count))]}" == "$cvsroot" && "$mode" == cvsroot ]]; then mode="" fi if [ -z "$mode" ]; then case $i in -H|--help) COMPREPLY=( $( compgen -W "$( _cvs_commands )" -- "$cur" ) ) return 0 ;; -d) mode=cvsroot cvsroot=${COMP_WORDS[((count+1))]} ;; ad|add|new) mode=add ;; adm|admin|rcs) mode=admin ;; ann|annotate) mode=annotate ;; checkout|co|get) mode=checkout ;; com|commit|ci) mode=commit ;; di|dif|diff) mode=diff ;; ex|exp|export) mode=export ;; edit|unedit) mode=$i ;; hi|his|history) mode=history ;; im|imp|import) mode=import ;; re|rel|release) mode=release ;; log|rlog) mode=log ;; rdiff|patch) mode=rdiff ;; remove|rm|delete) mode=remove ;; rtag|rfreeze) mode=rtag ;; st|stat|status) mode=status ;; tag|freeze) mode=tag ;; up|upd|update) mode=update ;; esac elif [[ "$i" = -* ]]; then flags=( "${flags[@]}" $i ) fi count=$((++count)) done case $mode in add) case $prev in -m) return 0 ;; -k) _cvs_kflags return 0 ;; esac if [[ "$cur" != -* ]]; then set_prefix if [[ $COMP_CWORD -gt 1 && -r ${prefix:-}CVS/Entries ]]; then get_entries [ -z "$cur" ] && \ files=$( command ls -Ad !(CVS) ) || \ files=$( command ls -d ${cur}* 2>/dev/null ) for i in "${entries[@]}"; do files=( ${files[@]/#$i//} ) done COMPREPLY=( $( compgen -X '*~' -W '${files[@]}' -- $cur ) ) fi else COMPREPLY=( $( compgen -W "$( _cvs_command_options $mode )" \ -- "$cur" ) ) fi ;; admin) case $prev in -a|-A|-b|-c|-e|-l|-m|-n|-N|-o|-s|-t-|-u) return 0 ;; -t) _filedir return 0 ;; -k) _cvs_kflags return 0 ;; esac if [[ "$cur" = -* ]]; then COMPREPLY=( $( compgen -W "$( _cvs_command_options $mode )" \ -- "$cur" ) ) fi ;; annotate) [[ "$prev" == -@(r|D) ]] && return 0 if [[ "$cur" = -* ]]; then COMPREPLY=( $( compgen -W "$( _cvs_command_options $mode )" \ -- "$cur" ) ) else get_entries COMPREPLY=( $( compgen -W '${entries[@]}' -- "$cur" ) ) fi ;; checkout) case $prev in -r|-D|j) return 0 ;; -d) _filedir -d return 0 ;; -k) _cvs_kflags return 0 ;; esac if [[ "$cur" != -* ]]; then [ -z "$cvsroot" ] && cvsroot=$CVSROOT COMPREPLY=( $( cvs -d "$cvsroot" co -c 2> /dev/null | \ awk '{print $1}' ) ) COMPREPLY=( $( compgen -W '${COMPREPLY[@]}' -- "$cur" ) ) else COMPREPLY=( $( compgen -W "$( _cvs_command_options $mode )" \ -- "$cur" ) ) fi ;; commit) case $prev in -m|-r) return 0 ;; -F) _filedir return 0 ;; esac set_prefix if [[ "$cur" != -* && -r ${prefix:-}CVS/Entries ]]; then # if $COMP_CVS_REMOTE is not null, 'cvs commit' will # complete on remotely checked-out files (requires # passwordless access to the remote repository if [ -n "${COMP_CVS_REMOTE:-}" ]; then # this is the least computationally intensive # way found so far, but other changes # (something other than changed/removed/new) # may be missing changed=( $( cvs -q diff --brief 2>&1 | \ sed -ne 's/^Files [^ ]* and \([^ ]*\) differ$/\1/p' ) ) newremoved=( $( cvs -q diff --brief 2>&1 | \ sed -ne 's/^cvs diff: \([^ ]*\) .*, no comparison available$/\1/p' ) ) COMPREPLY=( $( compgen -W '${changed[@]:-} \ ${newremoved[@]:-}' -- "$cur" ) ) else COMPREPLY=( $(compgen -o default -- "$cur") ) fi else COMPREPLY=( $( compgen -W "$( _cvs_command_options $mode )" \ -- "$cur" ) ) fi ;; cvsroot) # TODO: works poorly because of the colons and -o default, # could we drop -o default? works ok without it in cvsps _cvs_roots ;; export) case $prev in -r|-D) return 0 ;; -d) _filedir -d return 0 ;; -k) _cvs_kflags return 0 ;; esac if [[ "$cur" != -* ]]; then [ -z "$cvsroot" ] && cvsroot=$CVSROOT COMPREPLY=( $( cvs -d "$cvsroot" co -c | awk '{print $1}' ) ) COMPREPLY=( $( compgen -W '${COMPREPLY[@]}' -- "$cur" ) ) else COMPREPLY=( $( compgen -W "$( _cvs_command_options $mode )" \ -- "$cur" ) ) fi ;; diff) if [[ "$cur" == -* ]]; then _longopt diff else get_entries COMPREPLY=( $( compgen -W '${entries[@]:-}' -- "$cur" ) ) fi ;; remove) if [[ "$cur" != -* ]]; then set_prefix if [[ $COMP_CWORD -gt 1 && -r ${prefix:-}CVS/Entries ]]; then get_entries # find out what files are missing for i in "${entries[@]}"; do [ ! -r "$i" ] && miss=( "${miss[@]}" $i ) done COMPREPLY=( $(compgen -W '${miss[@]:-}' -- "$cur") ) fi else COMPREPLY=( $( compgen -W "$( _cvs_command_options $mode )" \ -- "$cur" ) ) fi ;; import) case $prev in -I|-b|-m|-W) return 0 ;; -k) _cvs_kflags return 0 ;; esac if [[ "$cur" != -* ]]; then # starts with same algorithm as checkout [ -z "$cvsroot" ] && cvsroot=$CVSROOT prefix=${cur%/*} if [ -r ${cvsroot}/${prefix} ]; then get_modules COMPREPLY=( ${COMPREPLY[@]#$cvsroot} ) COMPREPLY=( ${COMPREPLY[@]#\/} ) fi pwd=$( pwd ) pwd=${pwd##*/} COMPREPLY=( $( compgen -W '${COMPREPLY[@]} $pwd' -- $cur ) ) else COMPREPLY=( $( compgen -W "$( _cvs_command_options $mode )" \ -- "$cur" ) ) fi ;; update) case $prev in -r|-D|-j|-I|-W) return 0 ;; -k) _cvs_kflags return 0 ;; esac if [[ "$cur" = -* ]]; then COMPREPLY=( $( compgen -W "$( _cvs_command_options $mode )" \ -- "$cur" ) ) fi ;; "") case $prev in -T) _filedir -d return 0 ;; -e|-s) return 0 ;; -z) COMPREPLY=( $( compgen -W '1 2 3 4 5 6 7 8 9' -- "$cur" ) ) return 0 ;; esac COMPREPLY=( $( compgen -W '$( _cvs_commands ) $( _cvs_options ) \ --help --help-commands --help-options --version' -- "$cur" ) ) ;; esac return 0 } complete -F _cvs -o default cvs } # Local variables: # mode: shell-script # sh-basic-offset: 4 # sh-indent-comment: t # indent-tabs-mode: nil # End: # ex: ts=4 sw=4 et filetype=sh