diff options
Diffstat (limited to 'completions/cvs')
-rw-r--r-- | completions/cvs | 398 |
1 files changed, 398 insertions, 0 deletions
diff --git a/completions/cvs b/completions/cvs new file mode 100644 index 0000000..ba1f062 --- /dev/null +++ b/completions/cvs @@ -0,0 +1,398 @@ +# cvs(1) completion -*- shell-script -*- + +_cvs_entries() +{ + local prefix=${cur%/*}/ IFS=$'\n' + [[ -e ${prefix:-}CVS/Entries ]] || prefix="" + entries=($(cut -d/ -f2 -s ${prefix:-}CVS/Entries 2>/dev/null)) + if [[ $entries ]]; then + entries=("${entries[@]/#/${prefix:-}}") + compopt -o filenames + fi +} + +_cvs_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_command_options() +{ + COMPREPLY=($(compgen -W '$(_parse_help "$1" "--help $2")' -- "$cur")) +} + +_cvs_kflags() +{ + COMPREPLY=($(compgen -W 'kv kvl k o b v' -- "$cur")) +} + +_cvs_roots() +{ + local -a cvsroots + [[ -v CVSROOT ]] && cvsroots=("$CVSROOT") + [[ -r ~/.cvspass ]] && cvsroots+=($(awk '{ print $2 }' ~/.cvspass)) + [[ -r CVS/Root ]] && mapfile -tO ${#cvsroots[@]} cvsroots <CVS/Root + COMPREPLY=($(compgen -W '${cvsroots[@]}' -- "$cur")) + __ltrim_colon_completions "$cur" +} + +_cvs() +{ + local cur prev words cword + _init_completion -n : || return + + local count mode i cvsroot cvsroots pwd + local -a flags files entries changed newremoved + + count=0 + for i in "${words[@]}"; do + ((count == cword)) && break + # Last parameter was the CVSROOT, now go back to mode selection + if [[ ${words[count]} == "${cvsroot-}" && ${mode-} == cvsroot ]]; then + mode="" + fi + if [[ ! -v mode ]]; then + case $i in + --help | -!(-*)H) + COMPREPLY=($(compgen -W "$(_cvs_commands)" -- "$cur")) + return + ;; + -!(-*)d) + mode=cvsroot + cvsroot=${words[count + 1]} + ;; + add | ad | new) + mode=add + ;; + admin | adm | rcs) + mode="admin" + ;; + annotate | ann | blame | rannotate | rann | ra) + mode=annotate + ;; + checkout | co | get) + mode=checkout + ;; + commit | ci | com) + mode=commit + ;; + diff | di | dif) + mode="diff" + ;; + export | ex | exp) + mode="export" + ;; + edit | unedit | editors | logout | pserver | server | watch | watchers) + mode=$i + ;; + history | hi | his) + mode=history + ;; + import | im | imp) + mode=import + ;; + log | lo | rlog | rl) + mode=log + ;; + login | logon | lgn) + mode=login + ;; + rdiff | patch | pa) + mode=rdiff + ;; + release | re | rel) + mode=release + ;; + remove | rm | delete) + mode=remove + ;; + rtag | rt | rfreeze) + mode=rtag + ;; + status | st | stat) + mode=status + ;; + tag | ta | freeze) + mode=tag + ;; + update | up | upd) + mode=update + ;; + version | ve | ver) + mode=version + ;; + esac + elif [[ $i == -* ]]; then + flags+=($i) + fi + ((count++)) + done + + case ${mode-} in + add) + case $prev in + --*) ;; + -*m) + return + ;; + -*k) + _cvs_kflags + return + ;; + esac + + if [[ $cur != -* ]]; then + _cvs_entries + [[ -z $cur ]] && files=(!(CVS)) || + files=($(command ls -d ${cur}* 2>/dev/null)) + local f + for i in "${!files[@]}"; do + if [[ ${files[i]} == ?(*/)CVS ]]; then + unset 'files[i]' + else + for f in "${entries[@]}"; do + if [[ ${files[i]} == "$f" && ! -d $f ]]; then + unset 'files[i]' + break + fi + done + fi + done + COMPREPLY=($(compgen -X "$_backup_glob" -W '${files[@]}' \ + -- "$cur")) + else + _cvs_command_options "$1" $mode + fi + ;; + admin) + case $prev in + --*) ;; + -*@([aAbcelmnNosu]|t-)) + return + ;; + -*t) + _filedir + return + ;; + -*k) + _cvs_kflags + return + ;; + esac + + if [[ $cur == -* ]]; then + _cvs_command_options "$1" $mode + else + _cvs_entries + COMPREPLY=($(compgen -W '${entries[@]}' -- "$cur")) + fi + ;; + annotate) + [[ $prev == -[rD] ]] && return + + if [[ $cur == -* ]]; then + _cvs_command_options "$1" $mode + else + _cvs_entries + COMPREPLY=($(compgen -W '${entries[@]}' -- "$cur")) + fi + ;; + checkout) + case $prev in + --*) ;; + -*[rDj]) + return + ;; + -*d) + _filedir -d + return + ;; + -*k) + _cvs_kflags + return + ;; + esac + + if [[ $cur != -* ]]; then + [[ ! -v cvsroot ]] && cvsroot=${CVSROOT-} + COMPREPLY=($(cvs -d "$cvsroot" co -c 2>/dev/null | + awk '{print $1}')) + COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur")) + else + _cvs_command_options "$1" $mode + fi + ;; + commit) + case $prev in + --*) ;; + -*[mr]) + return + ;; + -*F) + _filedir + return + ;; + esac + + if [[ $cur != -* ]]; 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 | + command sed -ne 's/^Files [^ ]* and \([^ ]*\) differ$/\1/p')) + newremoved=($(cvs -q diff --brief 2>&1 | + command sed -ne 's/^cvs diff: \([^ ]*\) .*, no comparison available$/\1/p')) + COMPREPLY=($(compgen -W '${changed[@]:-} \ + ${newremoved[@]:-}' -- "$cur")) + else + _cvs_entries + COMPREPLY=($(compgen -W '${entries[@]}' -- "$cur")) + fi + else + _cvs_command_options "$1" $mode + fi + ;; + cvsroot) + _cvs_roots + ;; + diff | log) + if [[ $cur == -* ]]; then + _cvs_command_options "$1" $mode + [[ ${COMPREPLY-} == *= ]] && compopt -o nospace + else + _cvs_entries + COMPREPLY=($(compgen -W '${entries[@]:-}' -- "$cur")) + fi + ;; + editors | watchers) + if [[ $cur == -* ]]; then + _cvs_command_options "$1" $mode + else + _cvs_entries + COMPREPLY=($(compgen -W '${entries[@]}' -- "$cur")) + fi + ;; + export) + case $prev in + --*) ;; + -*[rD]) + return + ;; + -*d) + _filedir -d + return + ;; + -*k) + _cvs_kflags + return + ;; + esac + + if [[ $cur != -* ]]; then + [[ ! -v cvsroot ]] && cvsroot=${CVSROOT-} + COMPREPLY=($(cvs -d "$cvsroot" co -c | awk '{print $1}')) + COMPREPLY=($(compgen -W '${COMPREPLY[@]}' -- "$cur")) + else + _cvs_command_options "$1" $mode + fi + ;; + import) + case $prev in + --*) ;; + -*[IbmW]) + return + ;; + -*k) + _cvs_kflags + return + ;; + esac + + if [[ $cur != -* ]]; then + # starts with same algorithm as checkout + [[ ! -v cvsroot ]] && cvsroot=${CVSROOT-} + local prefix=${cur%/*} + if [[ -r ${cvsroot}/${prefix} ]]; then + _cvs_modules + COMPREPLY=(${COMPREPLY[@]#$cvsroot}) + COMPREPLY=(${COMPREPLY[@]#\/}) + fi + pwd=$(pwd) + pwd=${pwd##*/} + COMPREPLY=($(compgen -W '${COMPREPLY[@]} $pwd' -- "$cur")) + else + _cvs_command_options "$1" $mode + fi + ;; + remove) + if [[ $cur != -* ]]; then + _cvs_entries + if [[ $prev != -f ]]; then + # find out what files are missing + for i in "${!entries[@]}"; do + [[ -r ${entries[i]} ]] && unset 'entries[i]' + done + fi + COMPREPLY=($(compgen -W '${entries[@]:-}' -- "$cur")) + else + _cvs_command_options "$1" $mode + fi + ;; + update) + case $prev in + --*) ;; + -*[rDjIW]) + return + ;; + -*k) + _cvs_kflags + return + ;; + esac + + if [[ $cur == -* ]]; then + _cvs_command_options "$1" $mode + else + _cvs_entries + COMPREPLY=($(compgen -W '${entries[@]}' -- "$cur")) + fi + ;; + "") + case $prev in + --*) ;; + -*T) + _filedir -d + return + ;; + -*[es]) + return + ;; + -*z) + COMPREPLY=($(compgen -W '{1..9}' -- "$cur")) + return + ;; + esac + + COMPREPLY=($(compgen -W '$(_cvs_commands) + $(_parse_help "$1" --help-options) --help --help-commands + --help-options --version' -- "$cur")) + ;; + esac + +} && + complete -F _cvs cvs + +# ex: filetype=sh |