mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-11-19 05:24:23 +01:00
zsh-3.1.6-pws-2
This commit is contained in:
parent
5a0164d055
commit
c8858e7580
@ -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
|
Loading…
Reference in New Issue
Block a user