c875723bef
This way it's clearer to users that an argument is expected. It's likely that this commit does not catch all such cases, but it should do it for most of the affected commands I have installed.
381 lines
11 KiB
Bash
381 lines
11 KiB
Bash
# cvs(1) completion
|
|
|
|
have cvs || return
|
|
|
|
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_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
|
|
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 miss files entries changed newremoved
|
|
|
|
count=0
|
|
for i in "${words[@]}"; do
|
|
[ $count -eq $cword ] && break
|
|
# Last parameter was the CVSROOT, now go back to mode selection
|
|
if [[ "${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=${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+=( $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 [[ $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
|
|
_cvs_command_options "$1" $mode
|
|
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
|
|
_cvs_command_options "$1" $mode
|
|
fi
|
|
;;
|
|
annotate)
|
|
[[ "$prev" == -@(r|D) ]] && return 0
|
|
|
|
if [[ "$cur" = -* ]]; then
|
|
_cvs_command_options "$1" $mode
|
|
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
|
|
_cvs_command_options "$1" $mode
|
|
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
|
|
_cvs_command_options "$1" $mode
|
|
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
|
|
_cvs_command_options "$1" $mode
|
|
fi
|
|
;;
|
|
diff)
|
|
if [[ "$cur" == -* ]]; then
|
|
_cvs_command_options "$1" $mode
|
|
[[ $COMPREPLY == *= ]] && compopt -o nospace
|
|
else
|
|
get_entries
|
|
COMPREPLY=( $( compgen -W '${entries[@]:-}' -- "$cur" ) )
|
|
fi
|
|
;;
|
|
remove)
|
|
if [[ "$cur" != -* ]]; then
|
|
set_prefix
|
|
if [[ $cword -gt 1 && -r ${prefix:-}CVS/Entries ]]; then
|
|
get_entries
|
|
# find out what files are missing
|
|
for i in "${entries[@]}"; do
|
|
[ ! -r "$i" ] && miss+=( $i )
|
|
done
|
|
COMPREPLY=( $(compgen -W '${miss[@]:-}' -- "$cur") )
|
|
fi
|
|
else
|
|
_cvs_command_options "$1" $mode
|
|
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
|
|
_cvs_command_options "$1" $mode
|
|
fi
|
|
;;
|
|
update)
|
|
case $prev in
|
|
-r|-D|-j|-I|-W)
|
|
return 0
|
|
;;
|
|
-k)
|
|
_cvs_kflags
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
if [[ "$cur" = -* ]]; then
|
|
_cvs_command_options "$1" $mode
|
|
fi
|
|
;;
|
|
"")
|
|
case $prev in
|
|
-T)
|
|
_filedir -d
|
|
return 0
|
|
;;
|
|
-e|-s)
|
|
return 0
|
|
;;
|
|
-z)
|
|
COMPREPLY=( $( compgen -W '{1..9}' -- "$cur" ) )
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
COMPREPLY=( $( compgen -W '$( _cvs_commands ) \
|
|
$( _parse_help "$1" --help-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
|