1
0
mirror of git://git.code.sf.net/p/zsh/code synced 2024-09-21 19:31:50 +02:00

zsh-3.1.6-pws-2

This commit is contained in:
Tanaka Akira 1999-08-31 14:05:07 +00:00
parent 5a0164d055
commit c8858e7580

View File

@ -1,309 +0,0 @@
#autoload
# This function tries to automatically complete long option names. For
# this it invokes the command from the line with the `--help' option
# and then parses the output to find possible option names. For
# options that get an argument after a `=', the function also tries to
# automatically find out what should be complete as the argument.
# The possible completions for option-arguments can be described with
# the arguments to this function. This is done by giving pairs of
# patterns and actions as consecutive arguments. The actions specify
# what should be done to complete arguemts of those options that match
# the pattern. The action may be a list of words in brackets or in
# parentheses, separated by spaces. A list in brackets denotes
# possible values for an optional argument, a list in parentheses
# gives words to complete for mandatory arguments. If the action does
# not start with a bracket or parentheses, it should be the name of a
# command (probably with arguments) that should be invoked to complete
# after the equal sign. E.g.:
#
# _long_options '*\*' '(yes no)' \
# '*=FILE*' '_files' \
# '*=DIR*' '_files -/'
#
# This makes `yes' and `no' be completed as the argument of options
# whose description ends in a star, file names for options that
# contain the substring `=FILE' in the description, and paths for
# options whose description contains `=DIR'. Note the last two
# patterns are not needed since this function always completes files
# for option descriptions containing `=FILE' and paths for option
# descriptions that contain `=DIR' or `=PATH'. These builtin patterns
# can be overridden by patterns given as arguments, though.
#
# This function also accepts the `-X', `-J', and `-V' options which
# are given to `compadd'. Finally, it accepts the option `-t'. If this
# is given, completion is only done on words starting with two hyphens.
local opt expl group test i name action ret=1 tmp suffix
setopt extendedglob
# Get the options.
group=()
expl=()
if [[ $1 = -*~--* ]]; then
while getopts "J:V:X:t" opt; do
case "$opt" in
[JV]) group=("-$opt" "$OPTARG");;
X) expl=(-X "$OPTARG");;
t) test=yes;;
esac
done
shift OPTIND-1
fi
# Test if we are completing after `--' if we were asked to do so.
[[ -n "$test" && "$PREFIX" != --* ]] && return 1
# We cache the information about options and the command name, see if
# we can use the cache.
if [[ "$words[1]" = (.|..)/* ]]; then
tmp="$PWD/$words[1]"
else
tmp="$words[1]"
fi
if [[ "$tmp" != $_lo_cache_cmd ]]; then
# No, store the new command name and clear the old parameters.
_lo_cache_cmd="$tmp"
(( $+_lo_cache_actions )) && unset "$_lo_cache_names[@]" _lo_cache_actions _lo_cache_names
local opts pattern anum=1 tmpo str
# Now get the long option names by calling the command with `--help'.
# The parameter expansion trickery first gets the lines as separate
# array elements. Then we select all lines whose first non-blank
# character is a hyphen. Since some commands document more than one
# option per line, separated by commas, we convert commas int
# newlines and then split the result again at newlines after joining
# the old array elements with newlines between them. Then we select
# those elements that start with two hyphens, remove anything up to
# those hyphens and anything from the space or comma after the
# option up to the end. Finally all elements with option strings
# that contain uppercase letters are removed.
opts=("--${(@)^${(@)${(@)${(@M)${(@ps:\n:j:\n:)${(@)${(@M)${(@f)$("$words[1]" --help)}:#[ ]#-*}//,/
}}:#[ ]#--*}#*--}%%[, ]*}:#(*-[A-Z]*|)}")
# The interpretation of the options is completely table driven. We
# use the positional parameters we were given and a few standard
# ones. Then we loop through this table.
set -- "$@" '*=FILE*' '_files' '*=(DIR|PATH)*' '_files -/' '*' ''
while [[ $# -gt 1 ]]; do
# First, we get the pattern and the action to use and take them
# from the positional parameters.
pattern="$1"
action="$2"
shift 2
# We get all options matching the pattern and take them from the
# list we have built. If no option matches the pattern, we
# continue with the next.
tmp=("${(@M)opts:##$~pattern}")
opts=("${(@)opts:##$~pattern}")
(( $#tmp )) || continue
# Now we collect the options for the pattern in an array. We also
# check if the options take an argument after a `=', and if this
# argument is optional. The name of the array built contains
# `_arg_' for mandatory arguments, `_optarg_' for optional
# arguments, and `_simple_' for options that don't get an
# argument. In `_lo_cache_names' we save the names of these
# arrays and in `_lo_cache_actions' the associated actions.
# If the action is a list of words in brackets, this denotes
# options that get an optional argument. If the action is a list
# of words in parentheses, the option has to get an argument.
# In both cases we just build the array name to use.
if [[ "$action[1]" = '[' ]]; then
name="_lo_cache_optarg_$anum"
elif [[ "$action[1]" = '(' ]]; then
name="_lo_cache_arg_$anum"
else
# If there are option strings with a `[=', we take make these
# get an optional argument...
tmpo=("${(@M)tmp:#*\[\=*}")
if (( $#tmpo )); then
# ...by removing them from the option list and storing them in
# an array.
tmp=("${(@)tmp:#*\[\=*}")
tmpo=("${(@)${(@)tmpo%%\=*}//[^a-z0-9-]}")
_lo_cache_names[anum]="_lo_cache_optarg_$anum"
_lo_cache_actions[anum]="$action"
eval "_lo_cache_optarg_${anum}=(\"\$tmpo[@]\")"
(( anum++ ))
fi
# Now we do the same for option strings containing `=', these
# are options getting an argument.
tmpo=("${(@M)tmp:#*\=*}")
if (( $#tmpo )); then
tmp=("${(@)tmp:#*\=*}")
tmpo=("${(@)${(@)tmpo%%\=*}//[^a-z0-9-]}")
_lo_cache_names[anum]="_lo_cache_arg_$anum"
_lo_cache_actions[anum]="$action"
eval "_lo_cache_arg_${anum}=(\"\$tmpo[@]\")"
(( anum++ ))
fi
# The name for the options without arguments, if any.
name="_lo_cache_simple_$anum"
fi
# Now filter out any option strings we don't like and stuff them
# in an array, if there are still some.
tmp=("${(@)${(@)tmp%%\=*}//[^a-z0-9-]}")
if (( $#tmp )); then
_lo_cache_names[anum]="$name"
_lo_cache_actions[anum]="$action"
eval "${name}=(\"\$tmp[@]\")"
(( anum++ ))
fi
done
fi
# We get the string from the line and and see if it already contains a
# equal sign.
str="$PREFIX$SUFFIX"
if [[ "$str" = *\=* ]]; then
# It contains a `=', now we ignore anything up to it, but first save
# the old contents of the special parameters we change.
local oipre opre osuf pre parto parta pat patflags anum=1
oipre="$IPREFIX"
opre="$PREFIX"
osuf="$SUFFIX"
pre="${str%%\=*}"
IPREFIX="${IPREFIX}${pre}="
PREFIX="${str#*\=}"
SUFFIX=""
# We will check if the arrays contain an option matching what's on
# the line. To do this good, we build a pattern.
[[ -n "$_comp_correct" && $#pre -le _comp_correct ]] && return 1
pat="${pre}*"
patflags=''
_match_pattern _long_options pat patflags
[[ -n "$_comp_correct" ]] && patflags="$patflags(#a$_comp_correct)"
# Then we walk through the array names. For each array we test if it
# contains the option string. If so, we `invoke' the action stored
# with the name. If the action is a list of words, we just add them,
# otherwise we invoke the command or function named.
for name in "$_lo_cache_names[@]"; do
action="$_lo_cache_actions[anum]"
if (( ${(@)${(@P)name}[(I)$pre]} )); then
if [[ "$action[1]" = (\[|\() ]]; then
compadd - ${=action[2,-2]}
elif (( $#action )); then
$=action
fi
# We found the option string, return.
return
fi
# The array did not contain the full option string, see if it
# contains a string matching the string from the line.
# If there is one, we store the option string in `parto' and the
# element from `_lo_actions' in `parta'. If we find more than one
# such option or if we already had one, we set `parto' to `-'.
tmp=("${(@M)${(@P)name}:#${~pat}}")
if [[ $#tmp -eq 1 ]]; then
if [[ -z "$parto" ]]; then
parto="$tmp[1]"
parta="$action"
else
parto=-
fi
elif (( $#tmp )); then
parto=-
fi
(( anum++ ))
done
# If we found only one matching option, we accept it and immediatly
# try to complete the string after the `='.
if [[ -n "$parto" && "$parto" != - ]]; then
IPREFIX="${parto}="
if (( $#parta )); then
if [[ "$parta[1]" = (\[|\() ]]; then
compadd - ${=parta[2,-2]}
else
$=parta
fi
else
compadd -S '' - "$PREFIX"
fi
return
fi
# The option string was not found, restore the special parameters.
IPREFIX="$oipre"
PREFIX="$opre"
SUFFIX="$osuf"
fi
# The string on the line did not contain a `=', or we couldn't
# complete the option string since there were more than one matching
# what's on the line. So we just ad the option string as possible
# matches, giving the string from the `=' on as a suffix.
if [[ "$str" = *\=* ]]; then
str="=${str#*\=}"
PREFIX="${PREFIX%%\=*}"
suffix=()
else
str=""
suffix=('-S=')
fi
anum=1
for name in "$_lo_cache_names[@]"; do
action="$_lo_cache_actions[anum]"
if [[ "$name" = *_optarg_* ]]; then
compadd -M 'r:|-=* r:|=*' -Qq "$suffix[@]" -s "$str" - \
"${(@P)name}" && ret=0
elif [[ "$name" = *_arg_* ]]; then
compadd -M 'r:|-=* r:|=*' -Q "$suffix[@]" -s "$str" - \
"${(@P)name}" && ret=0
elif [[ -z "$str" ]]; then
compadd -M 'r:|-=* r:|=*' -Q - \
"${(@P)name}" && ret=0
fi
(( anum++ ))
done
return ret