From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4558 invoked from network); 20 Aug 1999 12:59:31 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 20 Aug 1999 12:59:31 -0000 Received: (qmail 29531 invoked by alias); 20 Aug 1999 12:59:22 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 7457 Received: (qmail 29522 invoked from network); 20 Aug 1999 12:59:21 -0000 Date: Fri, 20 Aug 1999 14:59:20 +0200 (MET DST) Message-Id: <199908201259.OAA00799@beta.informatik.hu-berlin.de> From: Sven Wischnowsky To: zsh-workers@sunsite.auc.dk In-reply-to: Tanaka Akira's message of 19 Aug 1999 23:38:50 +0900 Subject: Re: PATCH: completion Tanaka Akira wrote: > I feel `_arguments' is very good as basis of that. Is it easy to > extend `_arguments' to handle short options? Not that easy and some people probably don't like the way option names are completed with this patch, but still... I haven't changed `_cvs' (btw., maybe this should be split into smaller functions and put in its own directory?). Bye Sven diff -u od/Zsh/compsys.yo Doc/Zsh/compsys.yo --- od/Zsh/compsys.yo Fri Aug 20 14:33:55 1999 +++ Doc/Zsh/compsys.yo Fri Aug 20 14:31:11 1999 @@ -939,12 +939,18 @@ builtins and which make sure that the var(message) given in the description will be shown above the matches. -Finally, this function can be made to automatically call the +Normally the option names are taken as multi-character names and a +word from the line is considered to contain only one option (or +none). By giving the tt(-s) option to this function (as the first +argument), options are considered to be one-character options and the +string from the line may contain more than one such option letter. + +This function can also be made to automatically call the tt(_long_options) function where appropriate by giving it the string `tt(--)' as an argument. All arguments after this will be given unchanged to the tt(_long_options) function. -This function also uses one configuration key: tt(option_prefix). If +Finally, this function uses one configuration key: tt(option_prefix). If this is set to a string containing `tt(short)' or `tt(all)' as a substring, option names beginning with a single minus sign are added as possible matches only if the word on the line begins with a minus diff -u -r oc/Base/_arguments Completion/Base/_arguments --- oc/Base/_arguments Fri Aug 20 14:33:55 1999 +++ Completion/Base/_arguments Fri Aug 20 13:32:59 1999 @@ -5,12 +5,20 @@ setopt localoptions extendedglob -local long args rest ws cur nth def nm expl descr action opt arg tmp ret=1 +local long args rest ws cur nth def nm expl descr action opt arg tmp +local single uns ret=1 # Associative arrays used to collect information about the options. typeset -A opts mopts dopts dmopts odopts odmopts +# See if we are using single-letter options. + +if [[ "$1" = -s ]]; then + shift + single=yes +fi + # See if we support long options, too. nth=$argv[(I)--] @@ -141,19 +149,33 @@ if (( $+opts[$ws[1]] )); then # Options that may only be given once are removed from the - # associative array so that we are not offered them again. + # 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]]" else + uns='' + if [[ -n "$single" && "$ws[1]" = [-+]* ]]; then + if [[ $#opts -ne 0 && + "$ws[1]" = ${ws[1][1]}*[${(kj::)opts[(R)?*]#?}] ]]; then + def="$opts[${ws[1][1]}${ws[1][-1]}]" + uns="${ws[1][2,-1]}" + opt='' + elif [[ $#mopts -ne 0 && + "$ws[1]" = ${ws[1][1]}*[${(kj::)mopts[(R)?*]#?}] ]]; then + def="$mopts[${ws[1][1]}${ws[1][-1]}]" + uns="${ws[1][2,-1]}" + opt='' + fi + fi # 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. - if (( $#dopts )); then + if [[ -n "$opt" && $#dopts -ne 0 ]]; then # First we get the option names. @@ -163,7 +185,14 @@ # with one of the option names. while (( $#tmp )); do - [[ "$ws[1]" = ${tmp[1]}* ]] && break + if [[ -n "$single" ]]; then + if [[ "$ws[1]" = ${tmp[1][1]}*${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 @@ -175,7 +204,7 @@ opt='' def="$dopts[$tmp[1]]" - unset "dopts[$tmp[1]]" + [[ -z "$single" ]] && unset "dopts[$tmp[1]]" if [[ "$def" = ?*:*:* ]]; then def="${def#?*:*:}" else @@ -186,7 +215,14 @@ if [[ -n "$opt" && $#dmopts -ne 0 ]]; then tmp=( "${(@k)dmopts}" ) while (( $#tmp )); do - [[ "$ws[1]" = ${tmp[1]}* ]] && break + if [[ -n "$single" ]]; then + if [[ "$ws[1]" = ${tmp[1][1]}*${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 @@ -203,20 +239,28 @@ if [[ -n "$opt" && $#odopts -ne 0 ]]; then tmp=( "${(@k)odopts}" ) while (( $#tmp )); do - [[ "$ws[1]" = ${tmp[1]}* ]] && break + if [[ -n "$single" ]]; then + if [[ "$ws[1]" = ${tmp[1][1]}*${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="$odopts[$tmp[1]]" - unset "odopts[$tmp[1]]" + [[ -z "$single" ]] && 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 [[ "$ws[1]" != "$tmp[1]" ]]; then + if [[ ( -z "$single" && "$ws[1]" != "$tmp[1]" ) || + ( -n "$single" && "$ws[1]" != *${tmp[1][2]} ) ]]; then if [[ "$def" = ?*:*:* ]]; then def="${def#?*:*:}" else @@ -228,14 +272,22 @@ if [[ -n "$opt" && $#odmopts -ne 0 ]]; then tmp=( "${(@k)odmopts}" ) while (( $#tmp )); do - [[ "$ws[1]" = ${tmp[1]}* ]] && break + if [[ -n "$single" ]]; then + if [[ "$ws[1]" = ${tmp[1][1]}*${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 [[ "$ws[1]" != "$tmp[1]" ]]; then + if [[ ( -z "$single" && "$ws[1]" != "$tmp[1]" ) || + ( -n "$single" && "$ws[1]" != *${tmp[1][2]} ) ]]; then if [[ "$def" = ?*:*:* ]]; then def="${def#?*:*:}" else @@ -245,6 +297,14 @@ fi fi + [[ -n "$single" && -n "$opt" && "$ws[1]" = [-+]* ]] && \ + uns="${ws[1][2,-1]}" + + [[ -n "$uns" ]] && + unset "opts[${(@)^opts[(I)${ws[1][1]}[$uns]]}]" \ + "dopts[${(@)^dopts[(I)${ws[1][1]}[$uns]]}]" \ + "odopts[${(@)^odopts[(I)${ws[1][1]}[$uns]]}]" + # If we didn't find a matching option description and we were # told to use normal argument descriptions, just increase # our counter `nth'. @@ -265,6 +325,9 @@ nm="$compstate[nmatches]" if [[ -z "$def" || "$def" = :* ]]; then + local pre="$PREFIX" + + uns='' # We either don't have a description for an argument of an option # or we have a description for a optional argument. @@ -288,7 +351,12 @@ tmp=( "${(@k)dopts}" ) while (( $#tmp )); do - if compset -P "$tmp[1]"; then + if [[ -n "$single" ]] && compset -P "${tmp[1][1]}*${tmp[1][2]}"; then + def="$dopts[$tmp[1]]" + opt='' + uns="${PREFIX[2,-1]%%${tmp[1][2]}*}${tmp[1][2]}" + break + elif compset -P "$tmp[1]"; then # The current string starts with the option name, so ignore # that and complete the rest of the string. @@ -303,7 +371,12 @@ if [[ -n "$opt" && $#dmopts -ne 0 ]]; then tmp=( "${(@k)dmopts}" ) while (( $#tmp )); do - if compset -P "$tmp[1]"; then + if [[ -n "$single" ]] && compset -P "${tmp[1][1]}*${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 @@ -314,7 +387,12 @@ if [[ -n "$opt" && $#odopts -ne 0 ]]; then tmp=( "${(@k)odopts}" ) while (( $#tmp )); do - if compset -P "$tmp[1]"; then + if [[ -n "$single" ]] && compset -P "${tmp[1][1]}*${tmp[1][2]}"; then + def="$odopts[$tmp[1]]" + opt='' + uns="${PREFIX[2,-1]%%${tmp[1][2]}*}${tmp[1][2]}" + break + elif compset -P "$tmp[1]"; then def="$odopts[$tmp[1]]" opt='' break @@ -325,7 +403,12 @@ if [[ -n "$opt" && $#odmopts -ne 0 ]]; then tmp=( "${(@k)odmopts}" ) while (( $#tmp )); do - if compset -P "$tmp[1]"; then + if [[ -n "$single" ]] && compset -P "${tmp[1][1]}*${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 @@ -333,17 +416,43 @@ shift 1 tmp done fi + + [[ -n "$single" && -n "$opt" && "$PREFIX" = [-+]* ]] && \ + 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 "$opt" ]]; then # We aren't in an argument directly after a option name, so # all option names are possible matches. if [[ "$compconfig[option_prefix]" != *(short|all)* || - "$PREFIX" = -* ]]; then + "$PREFIX" = [-+]* ]]; then _description expl option - compadd "$expl[@]" - "${(@k)opts}" "${(@k)mopts}" \ - "${(@k)dopts}" "${(@k)dmopts}" \ - "${(@k)odopts}" "${(@k)odmopts}" && ret=0 + if [[ -n "$single" ]]; then + if [[ -z "$PREFIX" || "$PREFIX" = ? ]]; then + compadd "$expl[@]" - "${(@k)opts}" "${(@k)mopts}" \ + "${(@k)dopts}" "${(@k)dmopts}" \ + "${(@k)odopts}" "${(@k)odmopts}" && + ret=0 + else + compadd "$expl[@]" - "${PREFIX}${(@k)^opts[(I)${PREFIX[1]}*]#?}" \ + "${PREFIX}${(@k)^mopts[(I)${PREFIX[1]}*]#?}" \ + "${PREFIX}${(@k)^dopts[(I)${PREFIX[1]}*]#?}" \ + "${PREFIX}${(@k)^dmopts[(I)${PREFIX[1]}*]#?}" \ + "${PREFIX}${(@k)^odopts[(I)${PREFIX[1]}*]#?}" \ + "${PREFIX}${(@k)^odmopts[(I)${PREFIX[1]}*]#?}" && + ret=0 + fi + else + compadd "$expl[@]" - "${(@k)opts}" "${(@k)mopts}" \ + "${(@k)dopts}" "${(@k)dmopts}" \ + "${(@k)odopts}" "${(@k)odmopts}" && ret=0 + fi fi [[ $#long -ne 0 && ( "$compconfig[option_prefix]" != *(long|all)* || -- Sven Wischnowsky wischnow@informatik.hu-berlin.de