diff options
Diffstat (limited to 'Completion/Base')
-rw-r--r-- | Completion/Base/_arguments | 182 |
1 files changed, 59 insertions, 123 deletions
diff --git a/Completion/Base/_arguments b/Completion/Base/_arguments index 3d742f0f9..120c50934 100644 --- a/Completion/Base/_arguments +++ b/Completion/Base/_arguments @@ -6,11 +6,12 @@ setopt localoptions extendedglob local long args rest ws cur nth def nm expl descr action opt arg tmp -local single uns ret=1 soptseq soptseq1 sopts +local single uns ret=1 soptseq soptseq1 sopts prefix # Associative arrays used to collect information about the options. -typeset -A opts mopts dopts dmopts odopts odmopts +typeset -A opts dopts odopts +typeset -A oneshot # See if we are using single-letter options. @@ -46,30 +47,40 @@ while (( $# )); do # is in the next word. if [[ "$1" = [^:]##-:* ]]; then - dopts[${${1%%:*}[1,-2]}]="${1#*:}" + tmp="${${1%%:*}[1,-2]}" + dopts[$tmp]="${1#*:}" elif [[ "$1" = [^:]##+:* ]]; then - odopts[${${1%%:*}[1,-2]}]="${1#*:}" + tmp="${${1%%:*}[1,-2]}" + odopts[$tmp]="${1#*:}" else - opts[${1%%:*}]="${1#*:}" + tmp="${1%%:*}" + opts[$tmp]="${1#*:}" fi else - opts[$1]='' + tmp="$1" + opts[$tmp]='' fi + oneshot[$tmp]=yes elif [[ "$1" = \*[-+]* ]]; then # The same for options that may appear more than once. if [[ "$1" = *:* ]]; then if [[ "$1" = [^:]##-:* ]]; then - dmopts[${${1[2,-1]%%:*}[1,-2]}]="${1#*:}" + tmp="${${1[2,-1]%%:*}[1,-2]}" + dopts[$tmp]="${1#*:}" elif [[ "$1" = [^:]##+:* ]]; then - odmopts[${${1[2,-1]%%:*}[1,-2]}]="${1#*:}" + tmp="${${1[2,-1]%%:*}[1,-2]}" + odopts[$tmp]="${1#*:}" else - mopts[${1[2,-1]%%:*}]="${1#*:}" + tmp="${1[2,-1]%%:*}" + opts[$tmp]="${1#*:}" fi else - mopts[${1[2,-1]}]='' + tmp="${1[2,-1]}" + opts[$tmp]='' fi + unset "oneshot[$tmp]" elif [[ "$1" = \*:* ]]; then # This is `*:...', describing `all other arguments'. @@ -91,7 +102,7 @@ while (( $# )); do done if [[ -n "$single" ]]; then - soptseq="${(@j::)${(@M)${(@k)opts[(R)]}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)mopts[(R)]}:#[-+]?}#[-+]}" + soptseq="${(@j::)${(@M)${(@k)opts[(R)]}:#[-+]?}#[-+]}" if [[ -n "$soptseq" ]]; then soptseq="[$soptseq]#" soptseq1="$soptseq#" @@ -99,7 +110,7 @@ if [[ -n "$single" ]]; then soptseq='' soptseq1='' fi - sopts="${(@j::)${(@M)${(@k)opts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)mopts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)dopts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)dmopts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)odopts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)odmopts}:#[-+]?}#[-+]}" + sopts="${(@j::)${(@M)${(@k)opts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)dopts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)odopts}:#[-+]?}#[-+]}" else soptseq='' soptseq1='' @@ -168,18 +179,13 @@ else # associative array so that we don't offer them again. def="$opts[$ws[1]]" - unset "opts[$ws[1]]" - elif (( $+mopts[$ws[1]] )); then - def="$mopts[$ws[1]]" + [[ -n "$oneshot[$ws[1]]" ]] && unset "opts[$ws[1]]" else uns='' if [[ -n "$sopts" && "$ws[1]" = [-+]${~soptseq}[$sopts] ]]; then - if (( $+opts[${ws[1][1]}${ws[1][-1]}] )); then - def="$opts[${ws[1][1]}${ws[1][-1]}]" - uns="${ws[1][2,-1]}" - opt='' - elif (( $+mopts[${ws[1][1]}${ws[1][-1]}] )); then - def="$mopts[${ws[1][1]}${ws[1][-1]}]" + tmp="${ws[1][1]}${ws[1][-1]}" + if (( $+opts[$tmp] )); then + def="$opts[$tmp]" uns="${ws[1][2,-1]}" opt='' fi @@ -187,7 +193,7 @@ else # If the word is none of the simple options, test for those # whose first argument has to or may come directly after the - # option. This is done in four loops looking very much alike. + # option. This is done in two loops looking very much alike. if [[ -n "$opt" && $#dopts -ne 0 ]]; then @@ -218,7 +224,7 @@ else opt='' def="$dopts[$tmp[1]]" - unset "dopts[$tmp[1]]" + [[ -n "$oneshot[$tmp[1]]" ]] && unset "dopts[$tmp[1]]" if [[ "$def" = ?*:*:* ]]; then def="${def#?*:*:}" else @@ -226,30 +232,6 @@ else fi fi fi - if [[ -n "$opt" && $#dmopts -ne 0 ]]; then - tmp=( "${(@k)dmopts}" ) - while (( $#tmp )); do - if [[ -n "$sopts" && $tmp[1] = [-+]? ]]; then - if [[ "$ws[1]" = ${tmp[1][1]}${~soptseq}${tmp[1][2]}* ]]; then - uns="${ws[1][2,-1]%%${tmp[1][2]}*}${tmp[1][2]}" - break; - fi - elif [[ "$ws[1]" = ${tmp[1]}* ]]; then - break - fi - shift 1 tmp - done - - if (( $#tmp )); then - opt='' - def="$dmopts[$tmp[1]]" - if [[ "$def" = ?*:*:* ]]; then - def="${def#?*:*:}" - else - def='' - fi - fi - fi if [[ -n "$opt" && $#odopts -ne 0 ]]; then tmp=( "${(@k)odopts}" ) while (( $#tmp )); do @@ -267,14 +249,15 @@ else if (( $#tmp )); then opt='' def="$odopts[$tmp[1]]" - unset "odopts[$tmp[1]]" + [[ -n "$oneshot[$tmp[1]]" ]] && unset "odopts[$tmp[1]]" # For options whose first argument *may* come after the # option, we skip over the first description only if there # is something after the option name on the line. if [[ ( -z "$sopts" && "$ws[1]" != "$tmp[1]" ) || - ( -n "$sopts" && $tmp[1] = [-+]? && "$ws[1]" != ${tmp[1][1]}${~soptseq}${tmp[1][2]} ) ]]; then + ( -n "$sopts" && ( ( $tmp[1] = [-+]? && "$ws[1]" != "${tmp[1][1]}"${~soptseq}"${tmp[1][2]}" ) || + ( $tmp[1] != [-+]? && "$ws[1]" != "$tmp[1]" ) ) ) ]]; then if [[ "$def" = ?*:*:* ]]; then def="${def#?*:*:}" else @@ -283,41 +266,16 @@ else fi fi fi - if [[ -n "$opt" && $#odmopts -ne 0 ]]; then - tmp=( "${(@k)odmopts}" ) - while (( $#tmp )); do - if [[ -n "$sopts" && $tmp[1] = [-+]? ]]; then - if [[ "$ws[1]" = ${tmp[1][1]}${~soptseq}${tmp[1][2]}* ]]; then - uns="${ws[1][2,-1]%%${tmp[1][2]}*}${tmp[1][2]}" - break; - fi - elif [[ "$ws[1]" = ${tmp[1]}* ]]; then - break - fi - shift 1 tmp - done - - if (( $#tmp )); then - opt='' - def="$odmopts[$tmp[1]]" - if [[ ( -z "$sopts" && "$ws[1]" != "$tmp[1]" ) || - ( -n "$sopts" && $tmp[1] = [-+]? && "$ws[1]" != ${tmp[1][1]}${~soptseq}${tmp[1][2]} ) ]]; then - if [[ "$def" = ?*:*:* ]]; then - def="${def#?*:*:}" - else - def='' - fi - fi - fi - fi [[ -n "$sopts" && -n "$opt" && "$ws[1]" = [-+]${~soptseq} ]] && \ uns="${ws[1][2,-1]}" - [[ -n "$uns" ]] && + if [[ -n "$uns" ]]; then + uns="${(j::)${(@k)oneshot[(I)${ws[1][1]}[$uns]]#[-+]}}" unset "opts[${(@)^opts[(I)${ws[1][1]}[$uns]]}]" \ "dopts[${(@)^dopts[(I)${ws[1][1]}[$uns]]}]" \ "odopts[${(@)^odopts[(I)${ws[1][1]}[$uns]]}]" + fi # If we didn't find a matching option description and we were # told to use normal argument descriptions, just increase @@ -356,7 +314,7 @@ else # In any case, we have to complete option names here, but we may # be in a string that starts with an option names and continues with - # the first argument, test that (again, four loops). + # the first argument, test that (again, two loops). opt=yes if (( $#dopts )); then @@ -364,11 +322,12 @@ else # Get the option names. tmp=( "${(@k)dopts}" ) + prefix="$PREFIX" while (( $#tmp )); do if [[ -n "$sopts" && $tmp[1] = [-+]? ]] && compset -P "${tmp[1][1]}${~soptseq}${tmp[1][2]}"; then def="$dopts[$tmp[1]]" opt='' - uns="${PREFIX[2,-1]%%${tmp[1][2]}*}${tmp[1][2]}" + uns="${prefix[2,-1]%%${tmp[1][2]}*}${tmp[1][2]}" break elif compset -P "$tmp[1]"; then @@ -382,29 +341,14 @@ else shift 1 tmp done fi - if [[ -n "$opt" && $#dmopts -ne 0 ]]; then - tmp=( "${(@k)dmopts}" ) - while (( $#tmp )); do - if [[ -n "$sopts" && $tmp[1] = [-+]? ]] && compset -P "${tmp[1][1]}${~soptseq}${tmp[1][2]}"; then - def="$dmopts[$tmp[1]]" - opt='' - uns="${PREFIX[2,-1]%%${tmp[1][2]}*}${tmp[1][2]}" - break - elif compset -P "$tmp[1]"; then - def="$dmopts[$tmp[1]]" - opt='' - break - fi - shift 1 tmp - done - fi if [[ -n "$opt" && $#odopts -ne 0 ]]; then tmp=( "${(@k)odopts}" ) + prefix="$PREFIX" while (( $#tmp )); do if [[ -n "$sopts" && $tmp[1] = [-+]? ]] && compset -P "${tmp[1][1]}${~soptseq}${tmp[1][2]}"; then def="$odopts[$tmp[1]]" opt='' - uns="${PREFIX[2,-1]%%${tmp[1][2]}*}${tmp[1][2]}" + uns="${prefix[2,-1]%%${tmp[1][2]}*}${tmp[1][2]}" break elif compset -P "$tmp[1]"; then def="$odopts[$tmp[1]]" @@ -414,30 +358,16 @@ else shift 1 tmp done fi - if [[ -n "$opt" && $#odmopts -ne 0 ]]; then - tmp=( "${(@k)odmopts}" ) - while (( $#tmp )); do - if [[ -n "$sopts" && $tmp[1] = [-+]? ]] && compset -P "${tmp[1][1]}${~soptseq}${tmp[1][2]}"; then - def="$odmopts[$tmp[1]]" - opt='' - uns="${PREFIX[2,-1]%%${tmp[1][2]}*}${tmp[1][2]}" - break - elif compset -P "$tmp[1]"; then - def="$odmopts[$tmp[1]]" - opt='' - break - fi - shift 1 tmp - done - fi - [[ -n "$sopts" && -n "$opt" && "$PREFIX" = [-+]* ]] && \ + [[ -n "$sopts" && -n "$opt" && "$PREFIX" = [-+]${~soptseq}[$sopts] ]] && \ uns="${PREFIX[2,-1]}" - [[ -n "$uns" ]] && - unset "opts[${(@)^opts[(I)${pre[1]}[$uns]]}]" \ - "dopts[${(@)^dopts[(I)${pre[1]}[$uns]]}]" \ - "odopts[${(@)^odopts[(I)${pre[1]}[$uns]]}]" + if [[ -n "$uns" ]]; then + uns="${(j::)${(@k)oneshot[(I)${ws[1][1]}[$uns]]#[-+]}}" + unset "opts[${(@)^opts[(I)${pre[1]}[$uns]]}]" \ + "dopts[${(@)^dopts[(I)${pre[1]}[$uns]]}]" \ + "odopts[${(@)^odopts[(I)${pre[1]}[$uns]]}]" + fi if [[ -n "$opt" ]]; then @@ -447,12 +377,18 @@ else if [[ "$compconfig[option_prefix]" != *(short|all)* || "$PREFIX" = [-+]* ]]; then _description expl option - if [[ -n "$sopts" && -n "$PREFIX" && -n "$soptseq" && "$PREFIX" = [-+]${~soptseq1} ]]; then - compadd "$expl[@]" -Q - "$PREFIX" && ret=0 + if [[ -n "$sopts" && -n "$PREFIX" && "$PREFIX" = [-+]${~soptseq}[$sopts] ]]; then + if [[ "$PREFIX" = [-+]${~soptseq1} ]]; then + compadd "$expl[@]" -Q - "${PREFIX}${(@k)^opts[(I)${PREFIX[1]}?]#?}" \ + "${PREFIX}${(@k)^dopts[(I)${PREFIX[1]}?]#?}" \ + "${PREFIX}${(@k)^odopts[(I)${PREFIX[1]}?]#?}" && ret=0 + else + # The last option takes an argument in next word. + compadd "$expl[@]" -Q - "${PREFIX}" && ret=0 + fi else - compadd "$expl[@]" -Q - "${(@k)opts}" "${(@k)mopts}" \ - "${(@k)odopts}" "${(@k)odmopts}" && ret=0 - compadd "$expl[@]" -QS '' - "${(@k)dopts}" "${(@k)dmopts}" && ret=0 + compadd "$expl[@]" -Q - "${(@k)opts}" "${(@k)odopts}" && ret=0 + compadd "$expl[@]" -QS '' - "${(@k)dopts}" && ret=0 fi fi [[ $#long -ne 0 && @@ -503,5 +439,5 @@ else # Set the return value. - [[ nm -ne "$compstate[nmatches]" ]] + [[ nm -ne "$compstate[nmatches]" ]] fi |