diff options
author | Tanaka Akira <akr@users.sourceforge.net> | 1999-04-15 18:20:19 +0000 |
---|---|---|
committer | Tanaka Akira <akr@users.sourceforge.net> | 1999-04-15 18:20:19 +0000 |
commit | 04a89199d02a3ee6c4b3d89a6c782bdb0a4f1bc8 (patch) | |
tree | 2215f99f95d55660fc939a029bf965c454d080b5 /Completion/Base | |
parent | 7a0415cfd70a02b2280d27556c6c54cef1c86e1a (diff) | |
download | zsh-04a89199d02a3ee6c4b3d89a6c782bdb0a4f1bc8.tar.gz zsh-04a89199d02a3ee6c4b3d89a6c782bdb0a4f1bc8.tar.xz zsh-04a89199d02a3ee6c4b3d89a6c782bdb0a4f1bc8.zip |
zsh-3.1.5-pws-12 zsh-3.1.5-pws-12
Diffstat (limited to 'Completion/Base')
-rw-r--r-- | Completion/Base/.distfiles | 6 | ||||
-rw-r--r-- | Completion/Base/_command_names | 10 | ||||
-rw-r--r-- | Completion/Base/_condition | 8 | ||||
-rw-r--r-- | Completion/Base/_default | 2 | ||||
-rw-r--r-- | Completion/Base/_long_options | 309 | ||||
-rw-r--r-- | Completion/Base/_match_pattern | 6 | ||||
-rw-r--r-- | Completion/Base/_subscript | 9 |
7 files changed, 342 insertions, 8 deletions
diff --git a/Completion/Base/.distfiles b/Completion/Base/.distfiles new file mode 100644 index 000000000..7e7635fa6 --- /dev/null +++ b/Completion/Base/.distfiles @@ -0,0 +1,6 @@ +DISTFILES_SRC=' + .distfiles + _brace_parameter _command_names _condition _default _equal + _long_options _match_pattern _match_pattern.orig _match_test _parameter + _precommand _redirect _subscript _tilde _vars +' diff --git a/Completion/Base/_command_names b/Completion/Base/_command_names index eab314dfa..f21af674c 100644 --- a/Completion/Base/_command_names +++ b/Completion/Base/_command_names @@ -1,7 +1,11 @@ #defcomp -command- -local nm=$compstate[nmatches] +local nm=$compstate[nmatches] ret=1 -compgen -c +compgen -c && ret=0 -[[ nm -eq compstate[nmatches] ]] && _path_files -/g "*(*)" +if [[ nm -eq compstate[nmatches] ]]; then + _path_files -/g "*(*)" +else + return ret +fi diff --git a/Completion/Base/_condition b/Completion/Base/_condition index fb6b98b1b..db1adfd9a 100644 --- a/Completion/Base/_condition +++ b/Completion/Base/_condition @@ -7,6 +7,10 @@ if [[ "$prev" = -o ]]; then elif [[ "$prev" = -([no]t|ef) ]]; then _files else - _files - compgen -v + local ret=1 + + _files && ret=0 + compgen -v && ret=0 + + return ret fi diff --git a/Completion/Base/_default b/Completion/Base/_default index 569bd6382..9ea1a09db 100644 --- a/Completion/Base/_default +++ b/Completion/Base/_default @@ -9,6 +9,6 @@ # and insert the line `[[ compstate[nmatches] -eq 0 ]] || return' after # `compcall'. -compcall || return +compcall || return 0 _files diff --git a/Completion/Base/_long_options b/Completion/Base/_long_options new file mode 100644 index 000000000..a5d92632c --- /dev/null +++ b/Completion/Base/_long_options @@ -0,0 +1,309 @@ +#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 diff --git a/Completion/Base/_match_pattern b/Completion/Base/_match_pattern index 3df115d5b..91930a571 100644 --- a/Completion/Base/_match_pattern +++ b/Completion/Base/_match_pattern @@ -28,4 +28,10 @@ # like the `r:|[.-]=* r:|=*'. To make this work, the function `_match_test' # would have to be changed to `(( compstate[matcher] <= 2 ))' # +# When automatic correction is used (see the file `_main_complete'), you +# probably don't want to set matching flags here as that may make the +# results slightly unpredictable. For this, change the line above to: +# +# [[ compstate[matcher] -lt 0 ]] && eval "${3}='(#l)'" +# # The default implementation of this function is empty. diff --git a/Completion/Base/_subscript b/Completion/Base/_subscript index d50fd8335..670739a9a 100644 --- a/Completion/Base/_subscript +++ b/Completion/Base/_subscript @@ -1,5 +1,10 @@ #defcomp -subscript- -_compalso -math- +local ret=1 + +_compalso -math- && ret=0 + [[ ${(Pt)${compstate[parameter]}} = assoc* ]] && - compgen -k "( ${(kP)${compstate[parameter]}} )" + compgen -k "( ${(kP)${compstate[parameter]}} )" && ret=0 + +return ret |