# cvs(1) completion -*- shell-script -*- proc _cvs_entries { local prefix=${cur%/*}/ IFS=$'\n' [[ -e ${prefix:-}CVS/Entries ]] || setvar prefix = """" setvar entries = ''( $( cut -d/ -f2 -s ${prefix:-}CVS/Entries 2>/dev/null ) ) if [[ $entries ]] { setvar entries = ''( "${entries[@]/#/${prefix:-}}" ) compopt -o filenames } } proc _cvs_modules { if [[ -n $prefix ]] { setvar COMPREPLY = ''( $( command ls -d ${cvsroot}/${prefix}/!(CVSROOT) ) ) } else { setvar COMPREPLY = ''( $( command ls -d ${cvsroot}/!(CVSROOT) ) ) } } proc _cvs_commands { cvs --help-commands 2>&1 | awk '/^( *|\t)/ { print $1 }' } proc _cvs_command_options { setvar COMPREPLY = ''( $( compgen -W '$( _parse_help "$1" "--help $2" )' -- "$cur" ) ) } proc _cvs_kflags { setvar COMPREPLY = ''( $( compgen -W 'kv kvl k o b v' -- "$cur" ) ) } proc _cvs_roots { local -a cvsroots setvar cvsroots = ''( $CVSROOT ) [[ -r ~/.cvspass ]] && setvar cvsroots = ''( $( awk '{ print $2 }' ~/.cvspass ) ) [[ -r CVS/Root ]] && mapfile -tO ${#cvsroots[@]} cvsroots < CVS/Root setvar COMPREPLY = ''( $( compgen -W '${cvsroots[@]}' -- "$cur" ) ) __ltrim_colon_completions $cur } proc _cvs { local cur prev words cword _init_completion -n : || return local count mode i cvsroot cvsroots pwd local -a flags files entries changed newremoved setvar count = '0' for i in "${words[@]}" { [[ $count -eq $cword ]] && break # Last parameter was the CVSROOT, now go back to mode selection if [[ "${words[((count))]}" == "$cvsroot" && "$mode" == cvsroot ]] { setvar mode = """" } if [[ -z $mode ]] { case (i) { -H|--help { setvar COMPREPLY = ''( $( compgen -W "$( _cvs_commands )" -- "$cur" ) ) return 0 } -d { setvar mode = 'cvsroot' setvar cvsroot = ${words[((count+1))]} } add|ad|new { setvar mode = 'add' } admin|adm|rcs { setvar mode = 'admin' } annotate|ann|blame|rannotate|rann|ra { setvar mode = 'annotate' } checkout|co|get { setvar mode = 'checkout' } commit|ci|com { setvar mode = 'commit' } diff|di|dif { setvar mode = 'diff' } export|ex|exp { setvar mode = 'export' } edit|unedit|editors|logout|pserver|server|watch|watchers { setvar mode = "$i" } history|hi|his { setvar mode = 'history' } import|im|imp { setvar mode = 'import' } log|lo|rlog|rl { setvar mode = 'log' } login|logon|lgn { setvar mode = 'login' } rdiff|patch|pa { setvar mode = 'rdiff' } release|re|rel { setvar mode = 'release' } remove|rm|delete { setvar mode = 'remove' } rtag|rt|rfreeze { setvar mode = 'rtag' } status|st|stat { setvar mode = 'status' } tag|ta|freeze { setvar mode = 'tag' } update|up|upd { setvar mode = 'update' } version|ve|ver { setvar mode = 'version' } } } elif [[ "$i" == -* ]] { setvar flags = ''( $i ) } setvar count = $((++count)) } case (mode) { add { case (prev) { -m { return 0 } -k { _cvs_kflags return 0 } } if [[ "$cur" != -* ]] { _cvs_entries [[ -z $cur ]] && setvar files = ''( !(CVS) ) || \ setvar files = ''( $( command ls -d ${cur}* 2>/dev/null ) ) local f for i in ${!files[@]} { if [[ ${files[i]} == ?(*/)CVS ]] { unset 'files[i]' } else { for f in "${entries[@]}" { if [[ ${files[i]} == $f && ! -d $f ]] { unset 'files[i]' break } } } } setvar COMPREPLY = ''( $( compgen -X "$_backup_glob" -W '${files[@]}' \ -- "$cur" ) ) } else { _cvs_command_options $1 $mode } } admin { case (prev) { -a|-A|-b|-c|-e|-l|-m|-n|-N|-o|-s|-t-|-u { return 0 } -t { _filedir return 0 } -k { _cvs_kflags return 0 } } if [[ "$cur" == -* ]] { _cvs_command_options $1 $mode } else { _cvs_entries setvar COMPREPLY = ''( $( compgen -W '${entries[@]}' -- "$cur" ) ) } } annotate { [[ "$prev" == -[rD] ]] && return 0 if [[ "$cur" == -* ]] { _cvs_command_options $1 $mode } else { _cvs_entries setvar COMPREPLY = ''( $( compgen -W '${entries[@]}' -- "$cur" ) ) } } checkout { case (prev) { -r|-D|-j { return 0 } -d { _filedir -d return 0 } -k { _cvs_kflags return 0 } } if [[ "$cur" != -* ]] { [[ -z $cvsroot ]] && setvar cvsroot = "$CVSROOT" setvar COMPREPLY = ''( $( cvs -d "$cvsroot" co -c 2> /dev/null | \ awk '{print $1}' ) ) setvar COMPREPLY = ''( $( compgen -W '${COMPREPLY[@]}' -- "$cur" ) ) } else { _cvs_command_options $1 $mode } } commit { case (prev) { -m|-r { return 0 } -F { _filedir return 0 } } if [[ "$cur" != -* ]] { # 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:-} ]] { # this is the least computationally intensive way found so # far, but other changes (something other than # changed/removed/new) may be missing setvar changed = ''( $( cvs -q diff --brief 2>&1 | \ sed -ne 's/^Files [^ ]* and \([^ ]*\) differ$/\1/p' ) ) setvar newremoved = ''( $( cvs -q diff --brief 2>&1 | \ sed -ne 's/^cvs diff: \([^ ]*\) .*, no comparison available$/\1/p' ) ) setvar COMPREPLY = ''( $( compgen -W '${changed[@]:-} \ ${newremoved[@]:-}' -- "$cur" ) ) } else { _cvs_entries setvar COMPREPLY = ''( $( compgen -W '${entries[@]}' -- "$cur" ) ) } } else { _cvs_command_options $1 $mode } } cvsroot { _cvs_roots } diff { if [[ "$cur" == -* ]] { _cvs_command_options $1 $mode [[ $COMPREPLY == *= ]] && compopt -o nospace } else { _cvs_entries setvar COMPREPLY = ''( $( compgen -W '${entries[@]:-}' -- "$cur" ) ) } } editors|watchers { if [[ "$cur" == -* ]] { _cvs_command_options $1 $mode } else { _cvs_entries setvar COMPREPLY = ''( $( compgen -W '${entries[@]}' -- "$cur" ) ) } } export { case (prev) { -r|-D { return 0 } -d { _filedir -d return 0 } -k { _cvs_kflags return 0 } } if [[ "$cur" != -* ]] { [[ -z $cvsroot ]] && setvar cvsroot = "$CVSROOT" setvar COMPREPLY = ''( $( cvs -d "$cvsroot" co -c | awk '{print $1}' ) ) setvar COMPREPLY = ''( $( compgen -W '${COMPREPLY[@]}' -- "$cur" ) ) } else { _cvs_command_options $1 $mode } } import { case (prev) { -I|-b|-m|-W { return 0 } -k { _cvs_kflags return 0 } } if [[ "$cur" != -* ]] { # starts with same algorithm as checkout [[ -z $cvsroot ]] && setvar cvsroot = "$CVSROOT" local prefix=${cur%/*} if [[ -r ${cvsroot}/${prefix} ]] { _cvs_modules setvar COMPREPLY = ''( ${COMPREPLY[@]#$cvsroot} ) setvar COMPREPLY = ''( ${COMPREPLY[@]#\/} ) } setvar pwd = $( pwd ) setvar pwd = ${pwd##*/} setvar COMPREPLY = ''( $( compgen -W '${COMPREPLY[@]} $pwd' -- "$cur" ) ) } else { _cvs_command_options $1 $mode } } remove { if [[ "$cur" != -* ]] { _cvs_entries if [[ "$prev" != -f ]] { # find out what files are missing for i in ${!entries[@]} { [[ -r "${entries[i]}" ]] && unset 'entries[i]' } } setvar COMPREPLY = ''( $( compgen -W '${entries[@]:-}' -- "$cur" ) ) } else { _cvs_command_options $1 $mode } } update { case (prev) { -r|-D|-j|-I|-W { return 0 } -k { _cvs_kflags return 0 } } if [[ "$cur" == -* ]] { _cvs_command_options $1 $mode } else { _cvs_entries setvar COMPREPLY = ''( $( compgen -W '${entries[@]}' -- "$cur" ) ) } } "" { case (prev) { -T { _filedir -d return 0 } -e|-s { return 0 } -z { setvar COMPREPLY = ''( $( compgen -W '{1..9}' -- "$cur" ) ) return 0 } } setvar COMPREPLY = ''( $( compgen -W '$( _cvs_commands ) $( _parse_help "$1" --help-options ) --help --help-commands --help-options --version' -- "$cur" ) ) } } return 0 } && complete -F _cvs cvs # ex: ts=4 sw=4 et filetype=sh